@ashley-shrok/viewmodel-shell 2.0.0 → 2.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.
package/dist/browser.js CHANGED
@@ -792,9 +792,11 @@ export class BrowserAdapter {
792
792
  }
793
793
  link(n, parent) {
794
794
  const a = document.createElement("a");
795
- a.className = "vms-link";
795
+ a.className = n.active ? "vms-link vms-link--active" : "vms-link";
796
796
  a.href = n.href;
797
797
  a.textContent = n.label;
798
+ if (n.active)
799
+ a.setAttribute("aria-current", "page");
798
800
  if (n.external) {
799
801
  a.target = "_blank";
800
802
  a.rel = "noopener noreferrer";
package/dist/index.d.ts CHANGED
@@ -271,6 +271,11 @@ export interface LinkNode {
271
271
  href: string;
272
272
  /** true = open outside current app context (browser: new tab + noopener) */
273
273
  external?: boolean;
274
+ /** true = this link points at the current location (nav "you are here").
275
+ * Emits `.vms-link--active` + `aria-current="page"`. Server-owned: the
276
+ * backend decides which nav item is active from its route/state, exactly
277
+ * like every other view decision — there is no client-side route matching. */
278
+ active?: boolean;
274
279
  }
275
280
  export interface ImageNode {
276
281
  type: "image";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ashley-shrok/viewmodel-shell",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "A server-driven UI framework where the wire format is structured enough that agents can build full-stack apps without ever opening a browser and all UI tests are pure unit tests with no browser runtime. Server returns a JSON tree of typed nodes; a thin TypeScript adapter renders it to DOM. Backend-agnostic — a .NET reference backend ships with the repo, but any language can produce the JSON contract.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -235,6 +235,11 @@ body {
235
235
  flex-direction: row;
236
236
  flex-wrap: wrap;
237
237
  align-items: center;
238
+ /* Horizontal clusters (navbars, toolbars, header rows) need more breathing
239
+ room between siblings than the tight vertical --vms-space-sm rhythm. This
240
+ is the one place the row preset DOES redeclare gap (D-30 left it inherited;
241
+ nav links at 0.75rem read cramped). */
242
+ gap: var(--vms-space-lg);
238
243
  }
239
244
  .vms-page--row > .vms-page__title,
240
245
  .vms-section--row > .vms-section__heading { flex: 0 0 100%; }
@@ -642,6 +647,13 @@ select.vms-field__input { cursor: pointer; padding-right: var(--vms-space-xl);
642
647
  align-self: flex-start;
643
648
  }
644
649
  .vms-link:hover { border-bottom-color: var(--vms-accent); }
650
+ /* Active / current nav item ("you are here"). Solid underline + stronger
651
+ weight so the current location reads at a glance; server-owned via
652
+ LinkNode.active (emits aria-current="page" too). */
653
+ .vms-link--active {
654
+ border-bottom-color: var(--vms-accent);
655
+ font-weight: 600;
656
+ }
645
657
 
646
658
  /* ── Image ── */
647
659
  .vms-image { max-width: 100%; height: auto; display: block; }