← All Pull Requests

Register ::adom-table, a generic filterable/sortable table widget #1

Merged opened by Ray 2026-09-01

Registers one generic table widget. Closes adom/widgets#2, which has the full rationale.

{ "name": "adom-table", "mode": "frontend",
  "script": "https://wiki.adom.inc/adom/component-widgets/render/widgets/adom-table.js",
  "element": "adom-table", "attrs": ["src","columns","heading","filter","facet","sort","dim"] }

Short version: the same table has been hand-built three times as a bespoke section frame (adom/stm32f103c8t6 pinout, adom/repo-ownership ownership list, footprint variants). Each copy re-implements filtering, click-to-sort, faceting, height reporting and theming, and they have already drifted. Two of the six currently registered widgets are themselves tables with this logic inlined.

::adom-table is not component-specific — it takes a JSON array and renders it:

::adom-table{src="/adom/repo-ownership/render/ownership.json" facet="owner" sort="app" heading="adom applications"}

What is in this change

  • widgets.json — one appended entry (7 of the 32 cap; 7 attrs of the 12 cap).
  • README.md — the "Four load from adom/component-widgets" sentence is now "Five", and a row in the current-widgets table.

No existing entry is touched.

Verified

  • Script is live and serves from the registry-gated route: https://wiki.adom.inc/adom/component-widgets/render/widgets/adom-table.js → 200.
  • widgets.json still parses; the entry matches the documented registration shape.
  • Rendered in a real browser against the runtime with 201 rows (the live ownership.json): filter, facet="owner", sort="app" and the row counter all behave. Also rendered at 8 rows from the demo dataset shipped alongside the script as widgets/adom-table-demo.json, so this is reproducible without access to a private page.
  • adom-widget's own linter: clean.

One dependency worth knowing about

Building this found a runtime bug — inline <script type="application/json"> data was invisible whenever the definition was already registered when the parser reached the element (connectedCallback fires on the opening tag, before children exist). That is the documented data path for a README, since the readme frame is an opaque origin where fetch is blocked. Fixed and merged as adom-inc/adom-widget#2; readers on the deployed runtime are unaffected either way, because the wiki injects widget scripts after parse.

Not merging this myself — adom/widgets is org-owned and yours.

Diff Skip to comments (3)

--- a/widgets.json+++ b/widgets.json@@ -1,20 +1,24 @@⋯ 15 unchanged lines ⋯     "element": "adom-symbol-variants", "attrs": ["src", "mpn", "layout", "outline"] },   { "name": "adom-footprint-variants", "mode": "frontend",     "script": "https://wiki.adom.inc/john/footprint-widgets/render/widgets/footprint-variants-widget.js",-    "element": "adom-footprint-variants", "attrs": ["src", "variant", "heading"] }+    "element": "adom-footprint-variants", "attrs": ["src", "variant", "heading"] },+  { "name": "adom-table", "mode": "frontend",+    "script": "https://wiki.adom.inc/adom/component-widgets/render/widgets/adom-table.js",+    "element": "adom-table", "attrs": ["src", "columns", "heading", "filter", "facet", "sort", "dim"] } ]+--- a/README.md+++ b/README.md@@ -1,57 +1,59 @@⋯ 44 unchanged lines ⋯  ## Current widgets -Four load from adom/component-widgets and take a JSON `src`; adom-symbol-variants loads from adom/adom-symbol and takes a component page.json `src`:+Five load from adom/component-widgets and take a JSON `src`; adom-symbol-variants loads from adom/adom-symbol and takes a component page.json `src`:  | tag | shows | |---|---|⋯ 3 unchanged lines ⋯ | `::adom-heatsink-via{src="..."}` | thermal via layout | | `::adom-symbol-variants{src="..."}` | alternate schematic-symbol layouts (2-column, square, grouped, chip outline), generated in the browser | | `::adom-footprint-variants{src="..."}` | footprint-variant family (baseline, heatsink vias, 300 µm solder balls, rounded pads), parsed live from the page's `.kicad_mod` files; takes an adom-footprint `variants.json` `src` — loads from john/footprint-widgets |+| `::adom-table{src="..."}` | any JSON array as a filterable, sortable table — generic, not component-specific; `columns` `heading` `filter` `facet` `sort` `dim` |+

Comments

Ray · 1mo ago

Follow-up while this sits: building ::adom-table made it obvious that the two halves of the widget lifecycle live on two surfaces that don't reference each other. This page's README assumes you already have a script URL; adom-widget's SKILL.md covered authoring in detail and never mentioned ::tag{}, widgets.json, /widget-script/ or WIDGET_TAG_UNREGISTERED at all.

I've fixed the authoring side — adom-inc/adom-widget#4 adds a "Shipping it" section that hands off to this page as the authority, and specifically documents the thing I got wrong: that /widget-script/<name>.js is registry-gated, so a host page can stay private and an anonymous 404 on the raw URL is expected. Your "How scripts are served" paragraph is what corrected me.

The reciprocal one-liner belongs here — something like a pointer from "Registering a widget" to the adom-widget skill for how to write one. I've deliberately not opened a second PR for a single line while this one is pending; happy to add it here if you'd rather, or fold it in when you merge.

Colby Knox · 1mo ago

Registered, merged (07c18ea). The DRY case is exactly what the registry is for: three bespoke table frames re-implementing filter, sort, faceting, height-reporting and theming, already drifting, plus two of the six existing widgets being tables with the logic inlined. One generic ::adom-table retires all of that.

Curator review before registering, since a registered widget renders on any page:

  • Script escapes EVERY interpolation via window.AdomWidget.esc: cell values, caption/heading, column keys and labels, and the facet options. No unescaped path into the innerHTML row builder.
  • No eval / new Function, no external fetch, no cross-host script; JSON comes from the inline
Ray · 1mo ago

Disclosure, and it is already fixed: the script this entry points at was broken when you merged it, and I did not catch it before opening the PR.

The wiki's widget frame loads exactly ONE script and provides no runtime. All six pre-existing registered widgets are self-contained (adom-pinout calls customElements.define directly and never touches window.AdomWidget). adom-table was built on the adom-widget runtime, and its first line is a silent if (!window.AdomWidget) return, so on a real page it defined nothing and rendered nothing at all. No error, which is what made it invisible to me.

I only found it because you asked a different question and I went to check which surface actually serves the runtime. My earlier verification was a local page where I loaded the runtime myself, so it proved the widget worked, not that the DEPLOYED path worked. That is the gap.

Measured in a replica of your frame (same head-loaded single script, same src= attribute):

before   defined=false  hasRuntime=false  shadow=false  rows=0
after    defined=true   hasRuntime=true   shadow=true   rows=8

Fixed by bundling the runtime into the served script, so it is self-contained like the others: adom/component-widgets commit 69b8086, and https://wiki.adom.inc/widget-script/adom-table.js now serves 28KB and renders. No registry change needed, the entry and URL are unchanged.

Worth knowing generally: any widget written on the adom-widget runtime will be silently dead as a registered tag unless it bundles the runtime. I am adding that to the adom-widget skill so the next person does not repeat it. If you would rather the frame provided the runtime once instead of every script carrying its own copy, that is a git-wiki change and your call, and I am happy to open the issue.

Log in to comment.