Skip to content

feat(ui): the kit offers a full set of widgets, and its properties card follows the Support Code by itself - #204

Open
derek-miller wants to merge 5 commits into
mainfrom
feat/kit-widgets
Open

derek-miller wants to merge 5 commits into
mainfrom
feat/kit-widgets

Conversation

@derek-miller

Copy link
Copy Markdown
Contributor

The UI kit now offers a full set of widgets, Bootstrap-style, so a custom Composer tab picks what it needs instead of carrying its own copy. The kit's properties card also follows the Support Code's window by itself.

Derek, on the kit v2 adoption PRs: "even if there were styles that are generic that we could fold into the template that would be fine too. Think of it like bootstrap where it offers a full site's styles for all kinds of widgets, you dont have to use them all but they are there." He picked all three tiers below, with one look for each widget where the pages' versions differed.

The card and the Support Code. Every DriverCentral driver with the properties card has to send the card its list again as the Support Code opens and closes the Lua window, since Log Level's choices change and no property handler runs. Each driver wired that by hand, and one got it wrong: zigbee3's open card kept offering Trace and Ultra after the hour ended.

  • lib.support-code gains follow(fn), called alongside the driver's own onChange, each caught as before so the typed code never prints.
  • TabProperties:serve() follows the window in a DriverCentral build and resends PROPERTIES.
  • CONTRIBUTING says the card follows it by itself; a driver's onChange is only for what else it shows.

Tier 1, style.css. Chip colors, the .btn-link button and .input-valid join the base. New .kit-* widgets:

  • state dots with a label, chip toggles, counts, tags and dotted-underline tips
  • section labels, key/value rows, and the tile with an optional second unit
  • a switch, message lines, a popover box, an output box and a code textarea
  • a label-and-control form grid, a range with its readout, a number with its unit, a checklist
  • a legend, a styled details section, a short highlight
  • layout helpers: rows, two- and three-column grids, an actions row, and columns a table drops at narrow widths

Tier 2 and 3, components. Each is a JS and CSS pair in src/lib/ui, on Kit, embedded only by a page that uses it:

  • collapse: groups that fold under a caret with Expand all, their state kept by key across a string-rendered page's redraws.
  • menu: Kit.splitButton, a button with an arrow and its menu; a pick, a click elsewhere or Escape closes it.
  • combobox: a searchable dropdown that stays open across redraws, with keyboard choice.
  • color: the color picker that replaces Edge's (whose dropper misreads Composer's window), with offered and recent colors, hex, sliders and a dropper.
  • pickgrid: Kit.pickGrid, a picture grid to pick from, and Kit.dropZone, a file drop, choose and paste zone.

Template. The scope test's BASE list takes the new base selectors and its pairs check takes the five components; make render-ui-js, the build check, the ui and ui-expressions snapshots and copier's help text list them.

Tests. Node, on the shared fake DOM: collapse, menu, combobox, color and pickgrid, each failing under a deliberate break. Lua: the Support Code's followers (told on opening and closing, a raising one reported without the code), and the card's resend, which fails without the hook. Locally, make render-checks passes for ui, ui-expressions and default, make build-checks for ui and ui-expressions, and make invalid-combinations.

What uses it. The four kit adoption PRs (finitelabs/control4-finite-labs-essentials#89, finitelabs/control4-influxdb#97, finitelabs/control4-dynamic-buttons#48, finitelabs/control4-zigbee3#433) are re-rolled onto this tag. Their pages drop about 1,000 lines between them and each driver drops its hand-wired Support Code push. Their doc screenshots are reshot, and every tab feature is checked live on dev before their merge asks.

svc-finitelabs[bot]
svc-finitelabs Bot previously approved these changes Nov 11, 2026

@svc-finitelabs svc-finitelabs Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving with two nits. The riskiest path is the Support Code hook: the follower runs under its own pcall, after the driver's onChange, and its error print leaves out the typed value. The indented --#ifdef in serve() matches preprocess.py's ^\s*--\s*#ifdef pattern, so an OSS build drops both the require and the hook. Beyond CI, I ran make render-checks for ui and ui-expressions and mutated a scratch render. Each of these broke a test: dropping the hook, skipping the followers, an unguarded follower, collapse's setAll keeping hand-set groups, menu ignoring Escape, combobox's ArrowUp wrap and search filter, color's Esc keeping the pick, pickgrid taking a paste inside an input, and set() losing the mark. The local build leg stops at dp3's encrypt step because of this host's M2Crypto/OpenSSL mismatch, so I'm relying on CI's build legs for that.

Comment thread template/src/lib/support-code.lua Outdated
end

--- Calls `callback(open)` as the window opens and closes, alongside the driver's `onChange`, for a library whose view
--- changes with it: lib.ui.tab-properties' card, whose Log Level list does.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: naming the one caller (lib.ui.tab-properties' card) will go stale once a second library follows. "for a library whose view changes with the window" says the same and stays true.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 89e19a2: the doc now says "for a library whose view changes with the window", with no caller named.

Comment thread template/src/lib/ui/combobox.js Outdated
var isOpen = key === openKey;
var label = Kit.str(options.label);
var html =
'<div class="kit-combo' + (isOpen ? " open" : "") + (options.className ? " " + options.className : "") + '" data-combo="' + Kit.esc(key) + '"' +

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: collapse and menu put their hooks under data-kit-* (data-kit-collapse, data-kit-menu), but this one is a bare data-combo, which is more likely to collide with a page's own attribute. data-kit-combo would match the other two.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 89e19a2: the hook is data-kit-combo, matching data-kit-collapse and data-kit-menu; the combobox test follows.

@svc-finitelabs svc-finitelabs Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both nits are fixed. The combobox now uses data-kit-combo everywhere it is written or queried (the markup, control(), and the click and keydown delegates), and no data-combo is left anywhere in the tree, so the hook and its lookups can't drift apart. follow's doc no longer names a caller.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant