diff --git a/docs-app/app/docs-support/index.ts b/docs-app/app/docs-support/index.ts new file mode 100644 index 0000000000..6c5ba5260d --- /dev/null +++ b/docs-app/app/docs-support/index.ts @@ -0,0 +1,8 @@ +// Real ES module backing the `docs-support` bare specifier that live demo +// fences import from. Runtime `.md` docs resolve that specifier through +// setupKolay's dynamic `modules` map (see routes/application.ts); build-time +// `.gjs.md` docs go through real imports instead, resolved via the +// `resolve.alias` entry in vite.config.mjs pointing at this file. +export { default as ThemeSupport } from './theme-support'; +export { default as ThemeSwitcher } from './theme-switcher'; +export { default as didInsert } from '@ember/render-modifiers/modifiers/did-insert'; diff --git a/docs-app/app/docs-support/rehype-shadow-demo.ts b/docs-app/app/docs-support/rehype-shadow-demo.ts index 6038929d57..e5afb6a5ed 100644 --- a/docs-app/app/docs-support/rehype-shadow-demo.ts +++ b/docs-app/app/docs-support/rehype-shadow-demo.ts @@ -48,10 +48,24 @@ function forEachRawNode(node: unknown, visit: (node: RawNode) => void) { * Rather than teaching repl-sdk's compiler about shadow roots, this plugin * renames each live demo's placeholder tag to `` (a * custom element registered in `shadow-demo-element.ts`), which performs the - * actual `attachShadow` + style-import once the demo's rendered element is - * appended into it. Fences marked `no-shadow` are left as plain `
`s. + * actual `attachShadow` once the demo's rendered element is appended into + * it. Fences marked `no-shadow` are left as plain `
`s. + * + * Kolay has since grown a generic `wrapDemos` rehype plugin (`kolay/wrap-demos`, + * merged in universal-ember/kolay#361, unreleased as of kolay 5.4.0 - it ships + * in the pending 6.0.0). It is *not* a drop-in replacement for this: it wraps + * the placeholder in a component invocation (`{placeholder}`) + * rather than renaming it, which puts the placeholder inside the wrapper's + * shadow root. repl-sdk grafts each compiled demo in afterwards via + * `element.querySelector('#')` (see repl-sdk's + * `src/compilers/markdown.js` / `src/compilers/ember/gmd.js`), and that lookup + * does not cross a shadow boundary - so a shadow-DOM wrapper would trip its + * "Could not find placeholder / target element" assertion. Renaming the + * placeholder itself, as below, keeps it in the light DOM and is why this + * works. `wrapDemos` is still useful for non-isolating chrome (borders, + * labels) once kolay 6 lands. */ -export function rehypeShadowDemo() { +export function rehypeShadowDemo({ forBuildTimeInjection = false } = {}) { return (tree: unknown, file: VFileLike) => { const liveCode = file.data?.liveCode ?? []; const shadowed = new Set( @@ -71,7 +85,19 @@ export function rehypeShadowDemo() { if (!id || !shadowed.has(id)) return; - node.value = ``; + // kolay's build-time `.gjs.md` compiler (gjs-md.js's + // rehypeInjectComponentInvocation) finds this node by its `id` and + // injects the demo's compiled component invocation by string-replacing + // the node's *literal* `
` - it doesn't re-run the placeholder + // regex, so it doesn't know about ``. An inner + // `
` gives it something to match, and CarbonShadowDemo re-parents + // any child into the shadow root regardless of its tag, so the extra + // wrapper is otherwise inert. Runtime `.md` grafts by `id` directly + // onto `` (see shadow-demo-element.ts), so it does + // not need this and keeps the original two-attribute form. + node.value = forBuildTimeInjection + ? `
` + : ``; }); }; } diff --git a/docs-app/app/docs-support/shadow-demo-element.ts b/docs-app/app/docs-support/shadow-demo-element.ts index ae4c4b96da..0ac1ecd426 100644 --- a/docs-app/app/docs-support/shadow-demo-element.ts +++ b/docs-app/app/docs-support/shadow-demo-element.ts @@ -1,10 +1,16 @@ -const STYLESHEET_SELECTOR = 'link[rel="stylesheet"]'; const TAG_NAME = 'carbon-shadow-demo'; /** - * Style-isolates a live glimdown demo in its own shadow root, importing the - * app's stylesheets (mirroring ember-primitives' ``) - * so the isolated demo still picks up Carbon's styling. + * Style-isolates a live glimdown demo in its own shadow root. + * + * Nothing is imported into the shadow root on our behalf: this used to copy + * the document's `` tags in as `@import`s (mirroring + * ember-primitives' ``), but that was dropped again + * because the demos that need Carbon's CSS already inline it themselves -- + * they render `` (see `theme-support.gts`), which emits a + * `