Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"**/packages/*/tsconfig.json": true,
"**/packages/*/custom-elements.json": true,
"**/packages/*/package-meta.json": true,
"**/packages/*/README.md": true,
"**/dist-docs": true,
},

Expand All @@ -43,6 +44,7 @@
"**/packages/*/tsconfig.json": true,
"**/packages/**/custom-elements.json": true,
"**/packages/**/package-meta.json": true,
"**/packages/*/README.md": true,
"**/dist-docs": true,
},

Expand All @@ -63,6 +65,7 @@
"**/packages/*/tsconfig.json": true,
"**/packages/**/custom-elements.json": true,
"**/packages/**/package-meta.json": true,
"**/packages/*/README.md": true,
"**/dist-docs": true,
},

Expand Down
10 changes: 0 additions & 10 deletions ARCHITECTURE.md

This file was deleted.

19 changes: 0 additions & 19 deletions DECISIONS.md

This file was deleted.

16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Your HTML __*is*__ the app! Drop-in custom elements that each have a single resp

- **Back to the future** Welcome back to building static HTML5 apps. A break from complex JavaScript apps that compile to HTML.
- **Little to no JavaScript** You no longer need to write JS for the vast majority of UI cases. You may still call-out to your own pure functions for complex cases.
- **Native++** Just HTML with a derivative of CSS, named Quark, sprinkled on top.
- **Native++** It's real HTML. With a separate, synergistic guest: Quark.
- **No magic** No special frameworks, build processes, rendering wizardry, or "HTML-in-my-JS" / "JS-in-my-HTML" DSLs.
- **Progressively enhanced** Drop into existing static/server-side-rendered sites. Neutron and Quark can also be used independently.
- **Fully composable** Templates, templating, behavior, and custom logic are all decoupled & robust.
Expand Down Expand Up @@ -61,7 +61,7 @@ Then `import "@excom/nucleus-kit"` and `@import "@excom/nucleus-kit/basic.css"`.

Content-rich sites, complex data-driven business rules, progressive enhancement of static/server-rendered pages, embedded user experiences. See [Limitations](https://excom.dev/nucleus/docs/limitations) for the edges.

The Nucleus Stack also opens up novel possibilities that were not easily served by any UI technology before: zero-build-tool UIs (e.g. on-the-fly generation), declarative & auditable target for LLM UI building, plain text assembly to rich UX (like a CMS), incremental upgrading of static/legacy SSR sites, resource-constrained web UIs (especially where scripting needs to be validated or limited, like an ATM), embedded UX (such as upgrading markdown with embedded functionality).
The Nucleus Stack also opens up new possibilities that were not easily served by any UI technology before: zero-build-tool UIs (e.g. on-the-fly generation), declarative & auditable target for LLM UI building, plain text assembly to rich UX (like a CMS), incremental upgrading of static/legacy SSR sites, resource-constrained web UIs (especially where scripting needs to be validated or limited, like an ATM), embedded UX (such as upgrading markdown with embedded functionality).

## Dogfood is nutritious

Expand All @@ -75,7 +75,11 @@ The Nucleus Stack is MIT licensed and will remain free and open source. This is

## Start here

1. [Quick Start](https://excom.dev/nucleus/docs/quick_start) A working page, in five minutes.
2. [Core Concepts](https://excom.dev/nucleus/docs/core_concepts) The mental model, in one sitting.
3. [Using Elements](https://excom.dev/nucleus/docs/using_elements) and [Orchestrating](https://excom.dev/nucleus/docs/orchestrating) The two skills you'll use daily.
4. [Diving Deeper](https://excom.dev/nucleus/docs/diving_deeper) The architecture behind it all, for the curious and the skeptical.
- [Quick Start - A working page, in five minutes.](https://excom.dev/nucleus/docs/quick_start)
- [Core Concepts - The mental model, in one sitting.](https://excom.dev/nucleus/docs/core_concepts)
- [Using Elements - The Nucleus Kit catalog and how elements behave.](https://excom.dev/nucleus/docs/using_elements)
- [Orchestrating - Get familiar with Quark.](https://excom.dev/nucleus/docs/orchestrating)
- [Styling - Valence.css themes, tokens, and state-driven CSS.](https://excom.dev/nucleus/docs/styling)
- [Building Views - Structure a real app: routes, views, lazy loading.](https://excom.dev/nucleus/docs/building_views)
- Other Guides - [Business Logic](https://excom.dev/nucleus/docs/business_logic), [Creating Elements](https://excom.dev/nucleus/docs/creating_elements), [Best Practices](https://excom.dev/nucleus/docs/best_practices), [Troubleshooting](https://excom.dev/nucleus/docs/troubleshooting), [Debugging with Agents](https://excom.dev/nucleus/docs/debugging_with_agents)
- [Diving Deeper - The architecture behind it all, for the curious and the skeptical.](https://excom.dev/nucleus/docs/diving_deeper)
4 changes: 0 additions & 4 deletions TASKS.md

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "@excom/content-carousel",
"comment": "Auto-play tests poll for the advanced slide instead of sleeping a fixed 80 ms (flaked on loaded CI runners); no runtime change",
"type": "patch"
}
],
"packageName": "@excom/content-carousel",
"email": "133191653+excom-dev@users.noreply.github.com"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"changes": [
{
"packageName": "@excom/content-carousel",
"comment": "Fix an issue where `provision` did not follow slides added or removed, and `last-move` and `content-carousel-slide-changed` did not follow `is-active` moving from one slide to another (a swipe): each change sets one provision, and a carousel moved in the DOM no longer sets it again",
"type": "patch"
},
{
"packageName": "@excom/content-carousel",
"comment": "Update the internal `autoPlayIntervalId` property to `_autoPlayIntervalId`, as its other private properties are named; it was never an attribute, so markup is unaffected",
"type": "patch"
}
],
"packageName": "@excom/content-carousel"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"changes": [
{
"packageName": "@excom/content-drawer",
"comment": "Update `content-drawer` so only an `.absolute` drawer styles its parent, as `position: relative; overflow: clip` (was every drawer, with `overflow: hidden`): a fixed or sticky drawer no longer clips its parent, and sticky descendants keep working",
"type": "minor"
},
{
"packageName": "@excom/content-drawer",
"comment": "Update a closed `content-drawer` to be `visibility: hidden` once its slide-out ends, taking it out of the tab order and the accessibility tree: a custom `transition` on a closed drawer must keep `visibility 0s <duration>`, and a closed drawer shown in the layout needs `visibility: visible`",
"type": "minor"
},
{
"packageName": "@excom/content-drawer",
"comment": "Update the docs: the backdrop never reads the drawer's own variables, so set `--content-drawer-transition-duration`, `--content-drawer-transition-ease` and `--content-drawer-overlay-z-index` on the parent, the backdrop or `:root`",
"type": "none"
}
],
"packageName": "@excom/content-drawer"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@excom/detect-browser",
"comment": "Update the Safari demo to show an install hint instead of loading polyfills",
"type": "none"
}
],
"packageName": "@excom/detect-browser"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@excom/dom-observer",
"comment": "Update the demos to write State from `@on` blocks and `prop(\"provision\")` instead of JS handlers",
"type": "none"
}
],
"packageName": "@excom/dom-observer"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@excom/event-handler",
"comment": "Update the demos to write State from `@on` blocks and `prop(\"provision\")` instead of JS handlers",
"type": "none"
}
],
"packageName": "@excom/event-handler"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"changes": [
{
"packageName": "@excom/fetchable-element",
"comment": "Add `did-load` from `loadable-element`: set on the first success, kept while a refresh runs, cleared on an error",
"type": "minor"
},
{
"packageName": "@excom/fetchable-element",
"comment": "Update failed-request logging to one line: an error status (400 or above) logs a warning, `<tag>: request failed` with the response, which the default `KitLogger` level hides; a network or parse failure logs an error; an abort logs nothing",
"type": "minor"
}
],
"packageName": "@excom/fetchable-element"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "@excom/gesture-handler",
"comment": "Hand a `handoff-ref` overscroll to the gesture only when every scroller between the pointer and the element is at its limit, so content scrolled inside a nested scroller scrolls back before the sheet moves",
"type": "minor"
}
],
"packageName": "@excom/gesture-handler",
"email": "133191653+excom-dev@users.noreply.github.com"
}
11 changes: 11 additions & 0 deletions common/changes/@excom/heft-rig/main_2026-09-23-dist-files.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "@excom/heft-rig",
"comment": "Package metas read `exports` from the built `dist/exports.generated.json` when package.json has none (it is only applied at publish time), so the docs-site \"View Dist Files\" dialog is no longer empty",
"type": "patch"
}
],
"packageName": "@excom/heft-rig",
"email": "133191653+excom-dev@users.noreply.github.com"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"changes": [
{
"packageName": "@excom/include-content",
"comment": "Update the docs: a `<script>` inside a URL template does not run; stylesheets, `<style>` and `<quark-sheet>` do",
"type": "none"
},
{
"packageName": "@excom/include-content",
"comment": "Update the tests for two `include-content` elements on the same template URL: the second still loads when the first disconnects during the load",
"type": "none"
}
],
"packageName": "@excom/include-content"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@excom/kit-logger",
"comment": "Fix an issue where `KitLogManager` ignored its `level` option: the level became the environment level (no output at all when `VITE_LOG_LEVEL` is unset) and `0` became 1; an explicit level now wins, `0` included, then the environment level, then 1",
"type": "patch"
}
],
"packageName": "@excom/kit-logger"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "@excom/kit-router",
"comment": "Add `previousStates` / `nextStates` getters to `KitRouter`, listing the tracked history states before and after the active entry",
"type": "minor"
}
],
"packageName": "@excom/kit-router",
"email": "133191653+excom-dev@users.noreply.github.com"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{
"changes": [
{
"packageName": "@excom/kit-router",
"comment": "Update `matchNested` in `KitRoute` to match the pattern's own path as well as its child paths: `/users` matches `/users`, `/users/` and `/users/42`, never `/usersx`, and `/` matches every path",
"type": "minor"
},
{
"packageName": "@excom/kit-router",
"comment": "Update a page reload to report `move: null` in `KitRouteData` (it was the last move before the reload), as any page load that is not a back or forward traversal does",
"type": "minor"
},
{
"packageName": "@excom/kit-router",
"comment": "Add `query` to `KitRouteData`, holding `location.search` as an object",
"type": "minor"
},
{
"packageName": "@excom/kit-router",
"comment": "Add relative paths to routes and navigation: `KitRoute`, `pushState()` and `replaceState()` resolve `checkout` against the page's `<base>`, and `resolveHref()` is exported",
"type": "minor"
},
{
"packageName": "@excom/kit-router",
"comment": "Fix an issue where history entries with the same URL shared their scroll offset and move: each entry keeps its own, a scroll offset of 0 is saved, and the offset is saved when the page is left or reloaded",
"type": "patch"
},
{
"packageName": "@excom/kit-router",
"comment": "Fix the route data in `KitRouteData` after a typed URL, a link from another site or a fragment link: the entry is added to the tracked states, and every entry's `history.state` carries an `id`, the first entry included",
"type": "patch"
},
{
"packageName": "@excom/kit-router",
"comment": "Fix `canGoForward()` after `replaceState()` on an entry reached by going back, and `canGoBack()` after `replaceState()` on the first entry",
"type": "patch"
},
{
"packageName": "@excom/kit-router",
"comment": "Fix an issue where a same-origin frame overwrote the page's saved history, so a page embedding one lost its scroll restore on reload",
"type": "patch"
},
{
"packageName": "@excom/kit-router",
"comment": "Fix `params` for a route built from a regular expression: named groups (`(?<id>\\d+)`) give `params.id`, URL-decoded, unmatched groups are left out, and unnamed groups are no longer stored, so read them from `match` (every group used to land under the key `undefined`)",
"type": "patch"
},
{
"packageName": "@excom/kit-router",
"comment": "Fix `params` for a path pattern that holds a capture group of its own, such as `/(a|b)/:id`: placeholders keep their names (the group shifted them, so a param landed under the key `undefined`), a group the author names, such as `(?<lang>en|de)`, becomes a param, and a placeholder that did not take part in the match is left out (it was the string `\"undefined\"`)",
"type": "patch"
},
{
"packageName": "@excom/kit-router",
"comment": "Fix an issue where a path pattern with a non-capturing group, such as `/(?:a|b)/:id`, made `KitRoute` throw",
"type": "patch"
},
{
"packageName": "@excom/kit-router",
"comment": "Fix an issue where a route built from a regular expression with the `g` flag gave empty `params`, and with the `y` flag missed every second match: both now match like one without the flag",
"type": "patch"
}
],
"packageName": "@excom/kit-router"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"changes": [
{
"packageName": "@excom/kit-utils",
"comment": "Add `matchesKey()`, the keyboard filter behind Quark's `key:` and `keycode-filter`, which also names the space bar `Space` / `Spacebar` and the plus key `plus`",
"type": "minor"
},
{
"packageName": "@excom/kit-utils",
"comment": "Add `resolveModuleUrl()`, and update `resolveModuleReference()` to load an absolute `http(s)` URL as it is (it prefixed the page origin) and to refuse other schemes such as `data:` and `blob:`",
"type": "minor"
},
{
"packageName": "@excom/kit-utils",
"comment": "Update `fetchTemplate()` and `fetchPlainText()` to reject with `HTTP <status>: <url>` on an error status instead of returning the error page as content",
"type": "minor"
},
{
"packageName": "@excom/kit-utils",
"comment": "Update `resolveTemplateContent()` and `fetchPlainText()` so `reqInit.signal` ends only that caller's wait: the shared request goes on and fills the cache, so other callers waiting on the same URL get the content (an abort used to fail them all), a time limit such as `AbortSignal.timeout(…)` no longer limits the request itself, only that wait (the uncached `fetchTemplate()` still passes its signal to `fetch`), and an already aborted signal fails at once, before any request starts",
"type": "minor"
},
{
"packageName": "@excom/kit-utils",
"comment": "Fix an issue where a failed template or plain-text request stayed cached for the page: the next call fetches again",
"type": "patch"
}
],
"packageName": "@excom/kit-utils"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"changes": [
{
"packageName": "@excom/listenable-element",
"comment": "Add the key names `space` / `spacebar` and `plus` to `keycode-filter` (`shift+space`), and `cmd` as an alias of `meta`",
"type": "minor"
},
{
"packageName": "@excom/listenable-element",
"comment": "Update a `keycode-filter` holding only spaces to match no key and warn once (it was no filter); write `space` for the space bar",
"type": "minor"
}
],
"packageName": "@excom/listenable-element"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@excom/loadable-element",
"comment": "Add `did-load`: set on the first success, kept while a refresh loads and after a cancel, and cleared on an error, so content can stay on screen during a refresh with `[did-load]` instead of `[is-success]`",
"type": "minor"
}
],
"packageName": "@excom/loadable-element"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@excom/neutron",
"comment": "Fix an issue where an effect naming a property the element does not have was skipped silently under test runners: it throws `NeutronError` there too, as in a browser",
"type": "patch"
}
],
"packageName": "@excom/neutron"
}
Loading
Loading