@excom/include-content 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/.rush/temp/chunked-rush-logs/include-content.apply-exports.chunks.jsonl +1 -0
  2. package/.rush/temp/chunked-rush-logs/include-content.build_docs.chunks.jsonl +1 -0
  3. package/.rush/temp/chunked-rush-logs/include-content.build_package-metas.chunks.jsonl +1 -0
  4. package/.rush/temp/operation/apply-exports/all.log +1 -0
  5. package/.rush/temp/operation/apply-exports/log-chunks.jsonl +1 -0
  6. package/.rush/temp/operation/apply-exports/state.json +3 -0
  7. package/.rush/temp/operation/build_docs/all.log +1 -0
  8. package/.rush/temp/operation/build_docs/log-chunks.jsonl +1 -0
  9. package/.rush/temp/operation/build_docs/state.json +3 -0
  10. package/.rush/temp/operation/build_package-metas/all.log +1 -0
  11. package/.rush/temp/operation/build_package-metas/log-chunks.jsonl +1 -0
  12. package/.rush/temp/operation/build_package-metas/state.json +3 -0
  13. package/.rush/temp/shrinkwrap-deps.json +3 -0
  14. package/config/rig.json +5 -0
  15. package/include-content.ts +176 -0
  16. package/index.css +5 -0
  17. package/index.ts +17 -0
  18. package/package.json +45 -0
  19. package/rush-logs/include-content.apply-exports.cache.log +1 -0
  20. package/rush-logs/include-content.apply-exports.log +1 -0
  21. package/rush-logs/include-content.build_docs.cache.log +1 -0
  22. package/rush-logs/include-content.build_docs.log +1 -0
  23. package/rush-logs/include-content.build_package-metas.cache.log +1 -0
  24. package/rush-logs/include-content.build_package-metas.log +1 -0
  25. package/src/include-content.css +66 -0
  26. package/support/custom-elements.json +277 -0
  27. package/support/demos/lazy.html +19 -0
  28. package/support/demos/persist-content.html +23 -0
  29. package/support/demos/portal.html +8 -0
  30. package/support/demos/simple.html +16 -0
  31. package/support/demos/template-include.html +7 -0
  32. package/support/demos/template-ref.html +7 -0
  33. package/support/dist-docs/include-content.md +265 -0
  34. package/support/docs/README.md +64 -0
  35. package/support/package-meta.json +360 -0
  36. package/support/tests/include-content.test.ts +764 -0
  37. package/support/tests/lazy.view.test.ts +22 -0
  38. package/support/tests/persist-content.view.test.ts +33 -0
  39. package/support/tests/portal.view.test.ts +21 -0
  40. package/support/tests/simple.view.test.ts +23 -0
  41. package/support/tests/template-include.view.test.ts +35 -0
  42. package/support/tests/template-ref.view.test.ts +21 -0
  43. package/tsconfig.json +5 -0
@@ -0,0 +1,19 @@
1
+ <section>
2
+ <p>Scroll down…</p>
3
+ <include-content lazy-load lazy-unload observer-root="section:has(> :scope)"
4
+ observer-root-margin="0px" observer-threshold="0.5">
5
+ <template>
6
+ <p>Rendered at 50% visibility. Scroll away to remove
7
+ (<code>lazy-unload</code>).</p>
8
+ </template>
9
+ </include-content>
10
+ <p>Keep scrolling…</p>
11
+ <style>
12
+ #demo-include-content-lazy > :first-child {
13
+ include-content {
14
+ /* Prevent size collapse → render/unrender loop */
15
+ min-height: 108px;
16
+ }
17
+ }
18
+ </style>
19
+ </section>
@@ -0,0 +1,23 @@
1
+ <div>
2
+ <quark-sheet>
3
+ :scope {
4
+ @on change {
5
+ include-content { is-active: if(event.target.checked: ""; else: none); }
6
+ }
7
+ }
8
+ </quark-sheet>
9
+ <form>
10
+ <label>
11
+ <input type="checkbox" name="is-active" checked />
12
+ Active
13
+ </label>
14
+ </form>
15
+ <include-content is-active persist-content>
16
+ <template>
17
+ <label>
18
+ Type, then toggle Active —
19
+ <input type="text" placeholder="value is kept" />
20
+ </label>
21
+ </template>
22
+ </include-content>
23
+ </div>
@@ -0,0 +1,8 @@
1
+ <div>
2
+ <include-content is-active host-ref="#ic-portal-mount">
3
+ <template>
4
+ <p>Portaled into the aside.</p>
5
+ </template>
6
+ </include-content>
7
+ <aside id="ic-portal-mount"></aside>
8
+ </div>
@@ -0,0 +1,16 @@
1
+ <div>
2
+ <a>Hover me</a>
3
+ <include-content lazy-load>
4
+ <template>
5
+ <p>HTML inserted</p>
6
+ </template>
7
+ </include-content>
8
+ <small role="note">See Live document tab for DOM changes.</small>
9
+ <style>
10
+ #demo-include-content-simple > :first-child {
11
+ a:not(:hover) + include-content:not([is-active]) {
12
+ display: none;
13
+ }
14
+ }
15
+ </style>
16
+ </div>
@@ -0,0 +1,7 @@
1
+ <div>
2
+ <template id="ic-include-piece">
3
+ <p>A reusable view piece.</p>
4
+ </template>
5
+ <include-content is-active template-ref="#ic-include-piece"></include-content>
6
+ <include-content is-active template-ref="/fragments/remote-include.html"></include-content>
7
+ </div>
@@ -0,0 +1,7 @@
1
+ <div>
2
+ <template id="ic-shared-template">
3
+ <p>Shared template — both hosts render this node.</p>
4
+ </template>
5
+ <include-content is-active template-ref="#ic-shared-template"></include-content>
6
+ <include-content idle-load template-ref="#ic-shared-template"></include-content>
7
+ </div>
@@ -0,0 +1,265 @@
1
+ # include-content
2
+
3
+ One-stop shop for rendering a view when & where you need it — lazy-loading/unloading, conditional rendering, portalling… no app JS required.
4
+
5
+
6
+ ```html
7
+ <div>
8
+ <a>Hover me</a>
9
+ <include-content lazy-load>
10
+ <template>
11
+ <p>HTML inserted</p>
12
+ </template>
13
+ </include-content>
14
+ <small role="note">See Live document tab for DOM changes.</small>
15
+ <style>
16
+ #demo-include-content-simple > :first-child {
17
+ a:not(:hover) + include-content:not([is-active]) {
18
+ display: none;
19
+ }
20
+ }
21
+ </style>
22
+ </div>
23
+ ```
24
+
25
+
26
+ ## Features
27
+
28
+ - **Zero JS** Sophisticated UX from a simple HTML-only API, as with all Nucleus Kit elements.
29
+ - **Lazy (un)load** Lazy load and lazy unload your views
30
+ - **Eager / idle** Prioritize critical content; defer the rest
31
+ - **Prefetch** Warm templates so they're ready on activate
32
+ - **Shared / remote templates** Point at a DOM `<template>` or URL
33
+ - **Choose the host** Portal into light DOM, shadow, author iframe, or any selector
34
+ - **Keep state** Reuse the same tree across toggles
35
+ - **Animatable** Built-in fade, or bring your own with `.instant`
36
+
37
+ ## Installation
38
+
39
+
40
+ `@excom/include-content` v0.1.0
41
+
42
+ ```bash
43
+ pnpm add @excom/include-content
44
+ ```
45
+
46
+ ```bash
47
+ npm install @excom/include-content
48
+ ```
49
+
50
+ ```bash
51
+ yarn add @excom/include-content
52
+ ```
53
+
54
+ ### Import
55
+
56
+ ```ts
57
+ import "@excom/include-content";
58
+ ```
59
+
60
+
61
+
62
+ ## Usage
63
+
64
+ Put a `<template>` inside (or set `template-ref`) and pick when it should appear. For conditional rendering, use Quark or JS to toggle `is-active`.
65
+
66
+ ```html
67
+ <include-content lazy-load template-ref="/path/to/view.html"></include-content>
68
+ ```
69
+
70
+ ### API Reference
71
+
72
+
73
+ #### Attributes
74
+
75
+ | Name | Surface | Type | Default | Values | Description | Inherited from |
76
+ | --- | --- | --- | --- | --- | --- | --- |
77
+ | `idle-load` | option | `boolean` | | | Activate after first paint, when the browser is idle. Useful for below-the-fold / secondary views that should not compete with critical content. | |
78
+ | `lazy-load` | option | `boolean` | | | Activate when this element is on screen. Pair with `lazy-unload` for lazy load and lazy unload of views. | |
79
+ | `lazy-unload` | option | `boolean` | | | Deactivate (unrender) when no longer on screen. Use with `lazy-load` to free DOM for off-screen views. | |
80
+ | `observer-root` | option | `string` | | `<CSS Selector>` | Scroll container for lazy load / unload. Defaults to the viewport. | |
81
+ | `observer-root-margin` | option | `string` | `"-1px -1px -1px -1px"` | `<length>` \| `<percentage>` | How far outside the root counts as "visible". Expand (e.g. `500px`) to lazy-load a view *before* it enters the viewport so users never see an empty slot; shrink (default `-1px`) so edge-flush elements wait until they truly enter. | |
82
+ | `observer-threshold` | option | `number` | | | Fraction of the element that must be visible (`0`–`1`) before activating. | |
83
+ | `observer-delay` | option | `number` | `0` | | Minimum time visible before activating (ms). Ignored where unsupported. Useful for ensuring lazy load is not triggered when a programmatic smooth scroll zips the user right past the element. | |
84
+ | `template-ref` | option | `string` | `":scope > template"` | `<CSS Selector>` \| `<URL>` | Source `<template>` — in-document selector or remote URL. Changing mid-flight aborts and reloads. Can use `:scope` to relatively select elements: e.g. `main:has(:scope) > template` | `@excom/renderable-element` |
85
+ | `bypass-cache` | option | `boolean` | | | Skip the in-memory response cache (URL `template-ref` only). | `@excom/renderable-element` |
86
+ | `pre-fetch` | option | `string` | `"lazy"` | `""` \| `"eager"` \| `"idle"` \| `"lazy"` | When to fetch the template, independent of when it renders. `""` aliases `eager`. | `@excom/renderable-element` |
87
+ | `persist-content` | option | `boolean` | | | Reuse the same live nodes across unrender / render (held on `_persistedTree`) so form values, scroll position, and subtree state survive toggles. | `@excom/renderable-element` |
88
+ | `host-ref` | option | `string` | | `"shadow"` \| `"iframe"` \| `<CSS Selector>` | Where rendered children land. Unset = this element's light DOM. `shadow` attaches an open shadow root. `iframe` paints into a child `<iframe data-render-host>` body (you supply the iframe — useful for sandboxed / third-party document isolation). Any other value is a portal selector. | `@excom/renderable-element` |
89
+ | `ready-on` | option | `string` | | `<Event Name>` | Event name that marks rendered children "ready". Until it fires, `delaying-ready` is set so CSS can hide the host for a coordinated paint / view transition. | `@excom/renderable-element` |
90
+ | `is-active` | hybrid | `boolean` | | | Master switch. Set to load (if needed) and render; unset to unrender. Drive from visibility, route match, hover, etc. | `@excom/renderable-element` |
91
+ | `is-loading` | state | `boolean` | | | Template fetch in flight. | `@excom/renderable-element` |
92
+ | `did-load` | state | `boolean` | | | Template resolved at least once. Stays set across `is-active` toggles so consumers know later paints are warm (URL refs reuse the shared fetch cache in kit-utils). Cleared when `template-ref` changes or `--reload` forces a fresh resolve. | `@excom/renderable-element` |
93
+ | `is-error` | state | `boolean` | | | Latest template fetch rejected (excluding abort). Fires with the `error` event. | `@excom/renderable-element` |
94
+ | `delaying-ready` | state | `boolean` | | | Between `render` and the matching `ready-on` event. Hook with CSS for coordinated paints / view transitions. | `@excom/renderable-element` |
95
+
96
+ #### Recognized Elements
97
+
98
+ | Relationship | Selector | Required | Description | Inherited from |
99
+ | --- | --- | --- | --- | --- |
100
+ | `template` | child | no | Optional immediate `<template>` child used when `template-ref` is the default `":scope > template"`. Not required when `template-ref` points at a selector or URL elsewhere. | `@excom/renderable-element` |
101
+ | `iframe[data-render-host]` | child | no | Required when `host-ref="iframe"`. Content paints into `iframe.contentDocument.body`. Provide your own iframe (e.g. with `srcdoc`); the element will not create one. | `@excom/renderable-element` |
102
+
103
+ #### Fires
104
+
105
+ | Name | Type | Description | Inherited from |
106
+ | --- | --- | --- | --- |
107
+ | `include-content-render` | `RenderableRenderEvent` (`CustomEvent & { type: "{tag}-render"; detail: () => Promise<void>; bubbles: true; cancelable: true; composed: true }`) | Cancelable. Dispatched when the element becomes active and is about to place template content into the host. `event.detail` is a thunk that performs the load (if not already loaded) and renders the children, returning a Promise that resolves once the corresponding `ready-on` event fires (or immediately if `ready-on` is unset). The promise rejects if the element is torn down mid-flight (`startTeardown` while loading / `delaying-ready`). Call `preventDefault()` to defer rendering and invoke `event.detail()` later. | `@excom/renderable-element` |
108
+ | `include-content-unrender` | `RenderableUnrenderEvent` (`CustomEvent & { type: "{tag}-unrender"; detail: () => void; bubbles: true; cancelable: true; composed: true }`) | Cancelable. Dispatched when the element becomes inactive and content is already painted. `event.detail` is a thunk that removes the rendered children. Call `preventDefault()` to defer the removal. Not fired when teardown cancels an in-flight load — that path emits `aborted` instead. | `@excom/renderable-element` |
109
+ | `include-content-did-render` | `RenderableDidRenderEvent` (`CustomEvent & { type: "{tag}-did-render"; detail: void; bubbles: true; cancelable: true; composed: true }`) | Dispatched after the template content has actually been placed into the host. | `@excom/renderable-element` |
110
+ | `include-content-did-unrender` | `RenderableDidUnrenderEvent` (`CustomEvent & { type: "{tag}-did-unrender"; detail: void; bubbles: true; cancelable: true; composed: true }`) | Dispatched after rendered children have been removed from the host. | `@excom/renderable-element` |
111
+ | `include-content-error` | `RenderableErrorEvent` (`CustomEvent & { type: "{tag}-error"; detail: void; bubbles: true; cancelable: true; composed: true }`) | Dispatched when the template promise rejects with anything other than an `AbortError`. | `@excom/renderable-element` |
112
+ | `include-content-aborted` | `RenderableAbortedEvent` (`CustomEvent & { type: "{tag}-aborted"; detail: void; bubbles: true; cancelable: true; composed: true }`) | Dispatched when an in-flight load / ready wait is canceled because `is-active` was unset (via `startTeardown`). | `@excom/renderable-element` |
113
+
114
+ #### Commands
115
+
116
+ | Command | Action | Inherited from |
117
+ | --- | --- | --- |
118
+ | `--reload` | Aborts any in-flight fetch and re-resolves the template, bypassing the cache for URL refs (useful after remote content changes). | `@excom/renderable-element` |
119
+
120
+ #### Default actions
121
+
122
+ | Event | Default behavior (unless preventDefault() is called) | Inherited from |
123
+ | --- | --- | --- |
124
+ | `include-content-render` | Invokes `event.detail()` to load (if needed) and render the template into the host. | `@excom/renderable-element` |
125
+ | `include-content-unrender` | Invokes `event.detail()` to remove rendered children from the host. | `@excom/renderable-element` |
126
+
127
+ #### CSS Custom Properties
128
+
129
+ | Name | Syntax | Default | Description |
130
+ | --- | --- | --- | --- |
131
+ | `--include-content-transition-duration` | `<time>` | `0.15s` | Fade-in duration. |
132
+ | `--include-content-transition-ease` | `*` | `ease-in` | Fade-in easing. |
133
+
134
+ #### CSS Classes
135
+
136
+ | Name | Description |
137
+ | --- | --- |
138
+ | `.instant` | Skip the built-in fade — bring your own animation / view transition. Also opts-out if the element is portalling content elsewhere ([host-ref]) |
139
+
140
+ #### CSS Aliases
141
+
142
+ | Alias | Kind | Matches | Description |
143
+ | --- | --- | --- | --- |
144
+ | `:--include-content` | element | `include-content`, `.tag-include-content` | |
145
+ | `:--include-content--lazy-load` | state | `[lazy-load]`, `[data-lazy-load]` | |
146
+ | `:--include-content--lazy-unload` | state | `[lazy-unload]`, `[data-lazy-unload]` | |
147
+ | `:--include-content--did-load` | state | `[did-load]`, `[data-did-load]` | |
148
+ | `:--include-content--is-active` | state | `[is-active]`, `[aria-current]` | |
149
+ | `:--include-content--host-shadow` | state | `[host-ref="shadow"]`, `[data-host-ref="shadow"]` | |
150
+
151
+
152
+
153
+ ### Examples
154
+
155
+ #### Template include
156
+
157
+ Break your app into smaller views. Point `template-ref` at a `<template>` or a URL with `is-active` to render it immediately. This demo does both.
158
+
159
+
160
+ ```html
161
+ <div>
162
+ <template id="ic-include-piece">
163
+ <p>A reusable view piece.</p>
164
+ </template>
165
+ <include-content is-active template-ref="#ic-include-piece"></include-content>
166
+ <include-content is-active template-ref="/fragments/remote-include.html"></include-content>
167
+ </div>
168
+ ```
169
+
170
+
171
+ #### Lazy Load & Unload
172
+
173
+ `lazy-load` waits until on screen; `lazy-unload` removes it when it leaves. Give the host a real `min-height` so the trigger isn't ambiguous. Tune with `observer-root`, `observer-root-margin`, `observer-threshold`, and `observer-delay` — e.g. expand the margin to pre-render before the user scrolls to it. If remote template, pair with `pre-fetch="idle"` to warm the cache early.
174
+
175
+
176
+ ```html
177
+ <section>
178
+ <p>Scroll down…</p>
179
+ <include-content lazy-load lazy-unload observer-root="section:has(> :scope)"
180
+ observer-root-margin="0px" observer-threshold="0.5">
181
+ <template>
182
+ <p>Rendered at 50% visibility. Scroll away to remove
183
+ (<code>lazy-unload</code>).</p>
184
+ </template>
185
+ </include-content>
186
+ <p>Keep scrolling…</p>
187
+ <style>
188
+ #demo-include-content-lazy > :first-child {
189
+ include-content {
190
+ /* Prevent size collapse → render/unrender loop */
191
+ min-height: 108px;
192
+ }
193
+ }
194
+ </style>
195
+ </section>
196
+ ```
197
+
198
+
199
+ #### Portal elsewhere
200
+
201
+ By default content lands in the element's light DOM. Set `host-ref` to
202
+ `shadow`, `iframe` (with a child `<iframe data-render-host>`), or any CSS
203
+ selector to render somewhere else. The iframe host only moves nodes: custom
204
+ elements inside it upgrade only if that document loads their definitions.
205
+
206
+
207
+ ```html
208
+ <div>
209
+ <include-content is-active host-ref="#ic-portal-mount">
210
+ <template>
211
+ <p>Portaled into the aside.</p>
212
+ </template>
213
+ </include-content>
214
+ <aside id="ic-portal-mount"></aside>
215
+ </div>
216
+ ```
217
+
218
+
219
+ #### Keep tree state
220
+
221
+ Toggling `is-active` off leaves `did-load` set (warm re-resolve; URL
222
+ refs hit the shared fetch cache). `persist-content` goes further and
223
+ reuses the same live nodes so implicit state (form values, open details,
224
+ etc.) survives toggles.
225
+
226
+
227
+ ```html
228
+ <div>
229
+ <quark-sheet>
230
+ :scope {
231
+ @on change {
232
+ include-content { is-active: if(event.target.checked: ""; else: none); }
233
+ }
234
+ }
235
+ </quark-sheet>
236
+ <form>
237
+ <label>
238
+ <input type="checkbox" name="is-active" checked />
239
+ Active
240
+ </label>
241
+ </form>
242
+ <include-content is-active persist-content>
243
+ <template>
244
+ <label>
245
+ Type, then toggle Active —
246
+ <input type="text" placeholder="value is kept" />
247
+ </label>
248
+ </template>
249
+ </include-content>
250
+ </div>
251
+ ```
252
+
253
+ ## Demo sources
254
+
255
+ ### template-ref
256
+
257
+ ```html
258
+ <div>
259
+ <template id="ic-shared-template">
260
+ <p>Shared template — both hosts render this node.</p>
261
+ </template>
262
+ <include-content is-active template-ref="#ic-shared-template"></include-content>
263
+ <include-content idle-load template-ref="#ic-shared-template"></include-content>
264
+ </div>
265
+ ```
@@ -0,0 +1,64 @@
1
+ # include-content
2
+
3
+ One-stop shop for rendering a view when & where you need it — lazy-loading/unloading, conditional rendering, portalling… no app JS required.
4
+
5
+ <include-content data-demo="simple"></include-content>
6
+
7
+ ## Features
8
+
9
+ - **Zero JS** Sophisticated UX from a simple HTML-only API, as with all Nucleus Kit elements.
10
+ - **Lazy (un)load** Lazy load and lazy unload your views
11
+ - **Eager / idle** Prioritize critical content; defer the rest
12
+ - **Prefetch** Warm templates so they're ready on activate
13
+ - **Shared / remote templates** Point at a DOM `<template>` or URL
14
+ - **Choose the host** Portal into light DOM, shadow, author iframe, or any selector
15
+ - **Keep state** Reuse the same tree across toggles
16
+ - **Animatable** Built-in fade, or bring your own with `.instant`
17
+
18
+ ## Installation
19
+
20
+ <include-content is-active template-ref="/views/install-section/install-section.html"></include-content>
21
+
22
+ ## Usage
23
+
24
+ Put a `<template>` inside (or set `template-ref`) and pick when it should appear. For conditional rendering, use Quark or JS to toggle `is-active`.
25
+
26
+ ```html
27
+ <include-content lazy-load template-ref="/path/to/view.html"></include-content>
28
+ ```
29
+
30
+ ### API Reference
31
+
32
+ <include-content is-active template-ref="/views/api-reference/api-reference.html"></include-content>
33
+
34
+ ### Examples
35
+
36
+ #### Template include
37
+
38
+ Break your app into smaller views. Point `template-ref` at a `<template>` or a URL with `is-active` to render it immediately. This demo does both.
39
+
40
+ <include-content data-demo="template-include"></include-content>
41
+
42
+ #### Lazy Load & Unload
43
+
44
+ `lazy-load` waits until on screen; `lazy-unload` removes it when it leaves. Give the host a real `min-height` so the trigger isn't ambiguous. Tune with `observer-root`, `observer-root-margin`, `observer-threshold`, and `observer-delay` — e.g. expand the margin to pre-render before the user scrolls to it. If remote template, pair with `pre-fetch="idle"` to warm the cache early.
45
+
46
+ <include-content data-demo="lazy"></include-content>
47
+
48
+ #### Portal elsewhere
49
+
50
+ By default content lands in the element's light DOM. Set `host-ref` to
51
+ `shadow`, `iframe` (with a child `<iframe data-render-host>`), or any CSS
52
+ selector to render somewhere else. The iframe host only moves nodes: custom
53
+ elements inside it upgrade only if that document loads their definitions.
54
+
55
+ <include-content data-demo="portal"></include-content>
56
+
57
+ #### Keep tree state
58
+
59
+ Toggling `is-active` off leaves `did-load` set (warm re-resolve; URL
60
+ refs hit the shared fetch cache). `persist-content` goes further and
61
+ reuses the same live nodes so implicit state (form values, open details,
62
+ etc.) survives toggles.
63
+
64
+ <include-content data-demo="persist-content"></include-content>