Skip to content

Mirror data-density from <html> onto the theme wrapper, re-sync wrappers on reconnect - #10

Merged
dobexx merged 1 commit into
mainfrom
feature/density-tokens
Oct 5, 2026
Merged

dobexx merged 1 commit into
mainfrom
feature/density-tokens

Conversation

@dobexx

@dobexx dobexx commented Oct 5, 2026

Copy link
Copy Markdown
Member

Summary

GlassKit 1.21.0 (companion PR: JUNGHERZ/GlassKit#5) turns the control sizes into density tokens with a compact preset, data-density="compact" on <html>. GlassKit Elements follows it the way it follows data-theme:

  • The global MutationObserver watches data-density next to data-theme and data-glk-defaults and mirrors it onto each element's .glk-wrapper: set when the wrapper is created, synced on change, removed when <html> has none. GlkElement gains _syncDensity() next to _syncTheme(); the observer dispatches by the attribute that changed.
  • Fix: an element detached while the theme changed came back with the old data-theme on its wrapper (the observer only reaches connected elements). Since 1.20.0 that value also sets the wrapper's color-scheme, so a select's list or a date picker in such an element showed the other scheme. Both attributes are now re-read on every reconnect.

The compact values themselves arrive by inheritance: GlassKit puts the preset into tokensCss, which the elements already place on the document, so a project's own [data-density='compact'] { --gl-btn-height: 36px; } reaches the shadow roots too; with data-glk-defaults="off" the preset comes from glasskit.css on the page. The wrapper attribute lets rules keyed on it (component rules, hostStyles of project subclasses) match inside shadow roots, as with the theme.

Build

dist/ is rebuilt with the lockfile's GlassKit 1.20.0, so it carries only the base.js change and passes the "dist matches source" check. The compact sizes need GlassKit 1.21.0: before releasing, install it, rebuild, and move the peer dependency (and the CDN pins and the "wrapping GlassKit CSS" version that check-versions enforces).

Verification (Playwright 1.63, Chromium and WebKit; scratch build against the GlassKit branch)

  • Without data-density, left to right and right to left: every element measures as with 1.20.0; test page, index, showcase and docs (EN/DE) are pixel-identical apart from regions that also differ between two renders of 1.20.0, for the committed dist/ and for the scratch build.
  • With data-density="compact" on <html> (at load and toggled at runtime, with and without glasskit.css, both directions): <glk-input>, <glk-select>, <glk-search> 40px with 12px padding; <glk-button> 40/32/48; <glk-textarea> 88; <glk-list-item> 48; <glk-toggle> 44×26 with an 18px thumb; <glk-checkbox>/<glk-radio> 20; <glk-modal> actions 44.
  • Every wrapper carries data-density="compact" after the switch and loses it with <html>; an element created after the switch starts with it. A <glk-select> detached during a theme and density switch comes back light, compact, 40px and color-scheme: light (on 1.20.0: dark, color-scheme: dark, 52px).
  • With data-glk-defaults="off" and no stylesheet, the elements keep 1.20.0's sizes through GlassKit's fallbacks; with glasskit.css on the page compact works.
  • Project overrides reach <glk-button>: :root { --gl-btn-height: 48px } → 48px, [data-density="compact"] { --gl-btn-height: 36px } → 36px.
  • npm run check:versions and npm run check:package pass.

Docs

README (Density, architecture), SKILL.md (density, core concepts, subclass rules, reconnect note, rules and mistakes), docs.html and de/docs.html (Theming → Density, after the token-defaults paragraphs), CHANGELOG (Unreleased above 1.20.0, link definition from v1.20.0).

GlassKit 1.21.0 puts the sizes of fields, buttons, toggles, checkboxes,
radios, list rows and modal actions into density tokens, with
data-density="compact" on <html> as a denser preset. The values reach
every shadow root by inheritance: GlassKit puts the preset into
tokensCss, which the elements place on the document, so a project's own
density values arrive there too; with data-glk-defaults="off" the
preset comes from glasskit.css on the page.

The global MutationObserver now also watches data-density and mirrors
it onto each element's .glk-wrapper: set when the wrapper is created,
synced on change, removed when <html> has none. A rule keyed on the
attribute (a component rule, a subclass's hostStyles) therefore matches
inside the shadow root, as it does for data-theme. GlkElement gains
_syncDensity() next to _syncTheme(); the observer dispatches by the
attribute that changed, as it already does for data-glk-defaults.

Fixed: an element reconnected after a theme switch kept the old
data-theme on its wrapper, because the observer only reaches connected
elements; since 1.20.0 that also left its native parts in the other
color-scheme. Both attributes are now read again on every reconnect.

dist/ rebuilt against GlassKit 1.20.0 from the lockfile; the compact
sizes come along with the rebuild against GlassKit 1.21.0. Verified in
Chromium and WebKit with a bundle built against the GlassKit branch:
without the attribute every element measures as with 1.20.0, left to
right and right to left, and index, showcase and docs (EN/DE) render
pixel-identical outside regions that differ between any two renders;
with it, the compact values at load and switched at runtime, with and
without glasskit.css on the page; wrappers follow <html>, late and
reconnected elements included.

Docs (EN/DE), SKILL.md, README.
@dobexx
dobexx merged commit 561c085 into main Oct 5, 2026
2 checks passed
dobexx added a commit that referenced this pull request Oct 5, 2026
…nect

Releases pull request #10 against GlassKit 1.21.0, which is now the
peer minimum: data-density on <html> is mirrored onto every element's
theme wrapper like data-theme, the compact density tokens arrive by
inheritance, and an element that was out of the document while the
theme or density changed catches up when it is connected again. The
bundles are rebuilt against GlassKit 1.21.0; without data-density the
pages render pixel-identical to 1.20.0 in Chromium and WebKit.
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