cnc-block
A scrollable pane that can hold another route. Point href at a block and that block
renders inside — server-side on the first paint, then re-fetched and swapped when the href
changes. With no href it is simply a flex column that scrolls, holding whatever you
slot into it.
Quick start
Name a route in href. Nothing is fetched on mount — the fragment is already in
the HTML the server sent.
block-content
Fragment A —
/widgets/block-content
A block of its own, rendered by the server and spliced in where the
cnc-block
sits. It has its own controller and its own request.
no query on the href
<cnc-block href="/widgets/block-content"></cnc-block>
cnc-block and x-block
The embedding itself is x-block, a directive that works on any element — see
Reactive embed
. cnc-block is that directive plus three conveniences:
-
A layout. The host is
flex flex-col flex-1and the content area isflex-1 overflow-auto, so the pane takes the space it is given and scrolls its content rather than the page. -
An attribute instead of an expression.
x-blocktakes a JavaScript expression, so a literal route has to be writtenx-block="'/route'"with the inner quotes.hrefis a plain attribute. name, which nothing on the raw directive offers.
| Want | Write |
|---|---|
| A fixed route inline, no layout of its own | <div x-block="'/route'"> |
| A scrolling pane in an application shell | <cnc-block href="/route"> |
| A pane whose route is part of the page's address | <cnc-block name="panel" href="/route"> |
Things to know
- An href that names no route renders nothing. Not an error, not a message, not the children you slotted — the pane is simply empty. There is no fallback slot, so check the route exists.
-
The embedded block is a real block.
It brings its own controller, its own
$req, its own scope and its own hydration. It is not a template partial sharing the parent's state; pass what it needs through the query string. -
The pane wants a height to be worth using.
Its scrolling comes from
flex-1andoverflow-auto, which do nothing until an ancestor constrains the height. Inside anapp-layoutcentre area that is already true; on a free-flowing page, set one. -
nameis inert. It resolves in the widget'sinit()by reading$req.query['__' + name], but a widget'sinit()runs against the render scope, where$reqis only{ path }— the query string never reaches it. Only a block controller is given$req.query. Use the$hrefworkaround above.
Usage guidance
Reach for cnc-block when a region of the page has a life of its own — a detail
pane beside a list, the body of a tabbed workspace, a dashboard cell that reloads on its own
schedule. Each region stays a route you can open, test and cache by itself. When the region is
just markup that belongs to this page, slot it in directly; a block boundary you do not need
costs a controller and a scope. For a pane the user can drag and resize, use
cnc-workspace, and for one that overlays the page rather than sitting in it, use
cnc-drawer
or cnc-modal.