@jungherz-de/glasskit-elements 1.23.0 → 1.24.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/CHANGELOG.md CHANGED
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ---
9
9
 
10
+ ## [1.24.0] – 2026-10-14
11
+
12
+ Versions stay aligned with GlassKit at 1.24.0, which this release is built against (peer dependency `>=1.24.0`).
13
+
14
+ ### Added
15
+
16
+ - **Solid surfaces: `data-surface="solid"` on `<html>`.** GlassKit 1.24.0's preset makes every surface opaque and turns blur and gloss off. Its tokens reach the shadow roots by inheritance, also on a page that loads only these elements, because the preset is part of the tokens the bundle puts on the document. The theme wrapper of each element mirrors the attribute, as it mirrors `data-theme` and `data-density`: set from the start, followed on every change, removed with the attribute, and caught up when a moved element comes back. Measured in Chromium, WebKit and Firefox: card, buttons, field, select, textarea, toggle, checkbox, radio, list, segmented control, search and accordion item each show the same pixels inside over a red and over a blue page, and blur computes to `0px` in every shadow root. ([GlassKit #9](https://github.com/JUNGHERZ/GlassKit/issues/9))
17
+
18
+ Without the attribute, docs, showcase and landing pages render pixel-identical to 1.23.0.
19
+
20
+ ---
21
+
10
22
  ## [1.23.0] – 2026-10-14
11
23
 
12
24
  Versions realign with GlassKit at 1.23.0, which this release is built against (peer dependency `>=1.23.0`).
@@ -840,7 +852,8 @@ Starting with this release, GlassKit Elements version numbers are aligned with G
840
852
 
841
853
  ---
842
854
 
843
- [Unreleased]: https://github.com/JUNGHERZ/GlassKit-Elements/compare/v1.23.0...HEAD
855
+ [Unreleased]: https://github.com/JUNGHERZ/GlassKit-Elements/compare/v1.24.0...HEAD
856
+ [1.24.0]: https://github.com/JUNGHERZ/GlassKit-Elements/releases/tag/v1.24.0
844
857
  [1.23.0]: https://github.com/JUNGHERZ/GlassKit-Elements/releases/tag/v1.23.0
845
858
  [1.22.3]: https://github.com/JUNGHERZ/GlassKit-Elements/releases/tag/v1.22.3
846
859
  [1.22.2]: https://github.com/JUNGHERZ/GlassKit-Elements/releases/tag/v1.22.2
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  <a href="#"><img src="https://img.shields.io/badge/vanilla_JS-no_dependencies-44cc11?style=flat-square" alt="Vanilla JS"></a>
6
6
  <a href="#"><img src="https://img.shields.io/badge/components-36-7ec8e3?style=flat-square" alt="36 Components"></a>
7
7
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue?style=flat-square" alt="MIT License"></a>
8
- <a href="CHANGELOG.md"><img src="https://img.shields.io/badge/changelog-v1.23.0-lightgrey?style=flat-square" alt="Changelog"></a>
8
+ <a href="CHANGELOG.md"><img src="https://img.shields.io/badge/changelog-v1.24.0-lightgrey?style=flat-square" alt="Changelog"></a>
9
9
  <a href="https://www.npmjs.com/package/@jungherz-de/glasskit-elements"><img src="https://img.shields.io/badge/npm-%40jungherz--de%2Fglasskit--elements-cb3837?style=flat-square&logo=npm" alt="npm"></a>
10
10
  </p>
11
11
 
@@ -55,7 +55,7 @@ It is the **app layer** of the GlassKit family — three layers, one design lang
55
55
  | 🪶 **Lightweight** | 156 KB minified / 28 KB gzipped (IIFE bundle, GlassKit's component rules included), no external dependencies |
56
56
  | 📦 **Three bundle formats** | IIFE for `<script>`, minified IIFE for production, ESM for bundlers & tree-shaking |
57
57
  | 🎛️ **Form Participation** | Input, toggle, checkbox, radio, select — all work natively with `<form>` via `ElementInternals`: value, reset and, since 1.20.0, validity; `<glk-button type="submit">` submits |
58
- | 🌗 **Theme Sync** | Automatic dark/light mode sync via `data-theme` on `<html>`, compact controls via `data-density` |
58
+ | 🌗 **Theme Sync** | Automatic dark/light mode sync via `data-theme` on `<html>`, compact controls via `data-density`, opaque surfaces via `data-surface` |
59
59
  | 📱 **Mobile-first** | Inherits GlassKit's mobile-optimized design with `safe-area-inset` support |
60
60
 
61
61
  ---
@@ -66,7 +66,7 @@ It is the **app layer** of the GlassKit family — three layers, one design lang
66
66
 
67
67
  ```html
68
68
  <!-- 1. GlassKit CSS -->
69
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/glasskit@1.23/glasskit.min.css">
69
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/glasskit@1.24/glasskit.min.css">
70
70
 
71
71
  <!-- 2. GlassKit Elements -->
72
72
  <script src="https://cdn.jsdelivr.net/npm/@jungherz-de/glasskit-elements/dist/glasskit-elements.min.js"></script>
@@ -104,7 +104,7 @@ The per-component files leave `@jungherz-de/glasskit/glasskit-styles.js` as an e
104
104
  <!DOCTYPE html>
105
105
  <html data-theme="dark">
106
106
  <head>
107
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/glasskit@1.23/glasskit.min.css">
107
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/glasskit@1.24/glasskit.min.css">
108
108
  <script src="https://cdn.jsdelivr.net/npm/@jungherz-de/glasskit-elements/dist/glasskit-elements.min.js"></script>
109
109
  </head>
110
110
  <body>
@@ -216,6 +216,18 @@ Fields and buttons become 40px high instead of 52 and 56, toggles, checkboxes an
216
216
 
217
217
  > **Requires GlassKit CSS >= 1.21.0.** The sizes are GlassKit's density tokens, so they reach every shadow root by inheritance, like the brand colors below — and so do your own: `[data-density='compact'] { --gl-btn-height: 36px; }`. With `data-glk-defaults="off"` the preset comes from `glasskit.css` on the page, like every other token. The global observer mirrors `data-density` onto each element's theme wrapper as well, so a rule keyed on the attribute matches inside the shadow root too.
218
218
 
219
+ ### Solid surfaces
220
+
221
+ Not every screen wants glass. Set `data-surface="solid"` on `<html>`, next to `data-theme` (since 1.24.0):
222
+
223
+ ```html
224
+ <html data-theme="dark" data-surface="solid">
225
+ ```
226
+
227
+ Every surface becomes opaque, in the colour the glass shows over the theme's middle background, and blur and gloss are off; `removeAttribute('data-surface')` switches back at runtime. Without the attribute nothing changes.
228
+
229
+ > **Requires GlassKit CSS >= 1.24.0.** The preset is tokens only, so it reaches every shadow root by inheritance, and so do your own values: `[data-surface='solid'] { --gl-surface-2: #17313d; }`. With `data-glk-defaults="off"` it comes from `glasskit.css` on the page. The observer mirrors `data-surface` onto each element's theme wrapper, like `data-theme` and `data-density`.
230
+
219
231
  ### Printing
220
232
 
221
233
  Print dialogs leave out background graphics by default. With GlassKit 1.21.1 the parts that carry a state keep their colours on paper — checkbox, radio, toggle, progress, the current step, the chosen day, the slider thumb, the tone dots — inside the elements as well. A dark page prints light text and surfaces on white paper; a page meant for printing switches to the light theme for it, and the elements follow:
package/SKILL.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: glasskit-elements
3
- description: GlassKit Elements is a vanilla-JS Web Components library (v1.23.0) wrapping GlassKit CSS v1.23.0. It provides 36 custom elements with the `glk-` prefix, Dark/Light mode with automatic theme sync, Shadow DOM encapsulation, and form-associated custom elements. Use this reference whenever generating HTML that uses `<glk-*>` tags to ensure correct attributes, slots, events, and composition.
3
+ description: GlassKit Elements is a vanilla-JS Web Components library (v1.24.0) wrapping GlassKit CSS v1.24.0. It provides 36 custom elements with the `glk-` prefix, Dark/Light mode with automatic theme sync, Shadow DOM encapsulation, and form-associated custom elements. Use this reference whenever generating HTML that uses `<glk-*>` tags to ensure correct attributes, slots, events, and composition.
4
4
  ---
5
5
 
6
6
  # GlassKit Elements – AI Component Reference
@@ -18,7 +18,7 @@ description: GlassKit Elements is a vanilla-JS Web Components library (v1.23.0)
18
18
  npm install @jungherz-de/glasskit-elements @jungherz-de/glasskit
19
19
  ```
20
20
 
21
- Peer dependency `@jungherz-de/glasskit >=1.23.0` is required — 1.23.0 lets list text wrap app-wide through tokens, 1.22.2 hands a click on a disabled control in an input affix to the field, 1.22.1 lets date and time fields shrink in narrow columns, 1.22.0 brings the input affixes behind the `prefix` / `suffix` slots, 1.21.2 gives disabled controls their look, 1.21.1 keeps the controls' state on paper, 1.21.0 brings the density tokens behind `data-density`, 1.20.0 the rules the elements build on since then (the dialog overlay, hidden list slots, empty control labels, control inputs on top); 1.9.0 is the release that made the stylesheet splittable, which is what lets document-level branding reach the elements at all.
21
+ Peer dependency `@jungherz-de/glasskit >=1.24.0` is required — 1.24.0 brings the solid surface preset behind `data-surface`, 1.23.0 lets list text wrap app-wide through tokens, 1.22.2 hands a click on a disabled control in an input affix to the field, 1.22.1 lets date and time fields shrink in narrow columns, 1.22.0 brings the input affixes behind the `prefix` / `suffix` slots, 1.21.2 gives disabled controls their look, 1.21.1 keeps the controls' state on paper, 1.21.0 brings the density tokens behind `data-density`, 1.20.0 the rules the elements build on since then (the dialog overlay, hidden list slots, empty control labels, control inputs on top); 1.9.0 is the release that made the stylesheet splittable, which is what lets document-level branding reach the elements at all.
22
22
 
23
23
  ### Import (ES modules)
24
24
 
@@ -93,6 +93,14 @@ A single module-level `MutationObserver` watches `data-theme` on `<html>` and sy
93
93
 
94
94
  Denser controls for admin screens, desktop layouts and narrow forms: fields and buttons 40px instead of 52 and 56, smaller toggles, checkboxes and radios, denser list rows and modal actions. Without the attribute nothing changes; `removeAttribute('data-density')` switches back at runtime. The sizes are GlassKit's density tokens (GlassKit 1.21.0 or later), so they reach every shadow root by inheritance, and a project's own values do too (`[data-density='compact'] { --gl-btn-height: 36px; }`); with `data-glk-defaults="off"` the preset comes from `glasskit.css` on the page, like every other token. The same observer mirrors `data-density` onto each element's theme wrapper — set it on `<html>` only, never on individual elements.
95
95
 
96
+ ### Solid surfaces (since 1.24.0)
97
+
98
+ ```html
99
+ <html data-theme="dark" data-surface="solid">
100
+ ```
101
+
102
+ Opaque surfaces without blur and gloss, for admin screens, forms on a plain background and designs without glass: every surface in the colour the glass shows over the theme's middle background. Without the attribute nothing changes; `removeAttribute('data-surface')` switches back at runtime. It is GlassKit's solid surface preset (GlassKit 1.24.0 or later): tokens only, so it reaches every shadow root by inheritance, and a project's own values do too (`[data-surface='solid'] { --gl-surface-2: … }`); with `data-glk-defaults="off"` it comes from `glasskit.css` on the page. The observer mirrors `data-surface` onto each element's theme wrapper, like `data-theme` and `data-density`, so a rule keyed on it (a subclass's `hostStyles`) matches inside the shadow root — set it on `<html>` only.
103
+
96
104
 
97
105
  ### Printing (since 1.21.1)
98
106
 
@@ -119,7 +127,7 @@ addEventListener('afterprint', () => {
119
127
  | Tag prefix | `glk-*` (analogous to the `glass-*` CSS prefix) |
120
128
  | Rendering | Shadow DOM (`mode: 'open'`) with `adoptedStyleSheets` |
121
129
  | Stylesheet sharing | GlassKit's `componentsSheet` is the same `CSSStyleSheet` object in every element — no CSS duplication. Token declarations live on the document, not in the shadow roots |
122
- | Theme sync | Global MutationObserver on `<html data-theme>` and `<html data-density>` |
130
+ | Theme sync | Global MutationObserver on `<html data-theme>`, `<html data-density>` and `<html data-surface>` (since 1.24.0) |
123
131
  | Events | Custom `glk-*` events, all `bubbles: true, composed: true` |
124
132
  | Form participation | `GlkFormElement` uses `ElementInternals` (`static formAssociated = true`): value, reset and — since 1.20.0 — the inner field's validity |
125
133
  | Focus | Form elements with one field delegate focus (since 1.20.0): `element.focus()`, a click on the label, a `<label for>` land in the field |
@@ -53,16 +53,16 @@ function syncDefaultTokens() {
53
53
 
54
54
  injectDefaultTokens();
55
55
 
56
- // ── Global Theme & Density Sync ──
57
- // Single MutationObserver that watches data-theme and data-density on <html>
58
- // and notifies all GlkElement instances.
56
+ // ── Global Theme, Density & Surface Sync ──
57
+ // Single MutationObserver that watches data-theme, data-density and
58
+ // data-surface on <html> and notifies all GlkElement instances.
59
59
  //
60
- // The density tokens themselves arrive from <html> by inheritance, like every
61
- // other token: GlassKit's [data-density="compact"] preset is part of
62
- // tokensCss, not of the components sheet. The wrapper mirrors the attribute
63
- // anyway, as it mirrors data-theme — a rule keyed on it (a component rule, a
64
- // subclass's hostStyles) can match inside a shadow root only on an element
65
- // there.
60
+ // The density and surface tokens themselves arrive from <html> by
61
+ // inheritance, like every other token: GlassKit's [data-density="compact"]
62
+ // and [data-surface="solid"] presets are part of tokensCss, not of the
63
+ // components sheet. The wrapper mirrors the attributes anyway, as it mirrors
64
+ // data-theme — a rule keyed on one (a component rule, a subclass's
65
+ // hostStyles) can match inside a shadow root only on an element there.
66
66
 
67
67
  const instances = new Set();
68
68
 
@@ -75,6 +75,11 @@ function getCurrentDensity() {
75
75
  return document.documentElement.getAttribute('data-density');
76
76
  }
77
77
 
78
+ /** The surface preset on <html> (since 1.24.0), or null, like the density. */
79
+ function getCurrentSurface() {
80
+ return document.documentElement.getAttribute('data-surface');
81
+ }
82
+
78
83
  function syncAllThemes() {
79
84
  const theme = getCurrentTheme();
80
85
  for (const instance of instances) {
@@ -89,15 +94,23 @@ function syncAllDensities() {
89
94
  }
90
95
  }
91
96
 
97
+ function syncAllSurfaces() {
98
+ const surface = getCurrentSurface();
99
+ for (const instance of instances) {
100
+ instance._syncSurface(surface);
101
+ }
102
+ }
103
+
92
104
  if (typeof window !== 'undefined' && typeof MutationObserver !== 'undefined') {
93
105
  const observer = new MutationObserver(records => {
94
106
  if (records.some(r => r.attributeName === 'data-theme')) syncAllThemes();
95
107
  if (records.some(r => r.attributeName === 'data-density')) syncAllDensities();
108
+ if (records.some(r => r.attributeName === 'data-surface')) syncAllSurfaces();
96
109
  if (records.some(r => r.attributeName === DEFAULTS_ATTR)) syncDefaultTokens();
97
110
  });
98
111
  observer.observe(document.documentElement, {
99
112
  attributes: true,
100
- attributeFilter: ['data-theme', 'data-density', DEFAULTS_ATTR]
113
+ attributeFilter: ['data-theme', 'data-density', 'data-surface', DEFAULTS_ATTR]
101
114
  });
102
115
  }
103
116
 
@@ -235,17 +248,19 @@ class GlkElement extends HTMLElement {
235
248
  this._wrapper.className = 'glk-wrapper';
236
249
  this._wrapper.setAttribute('data-theme', getCurrentTheme());
237
250
  this._syncDensity(getCurrentDensity());
251
+ this._syncSurface(getCurrentSurface());
238
252
  this._shadow.appendChild(this._wrapper);
239
253
 
240
254
  this.render();
241
255
  if (this.constructor.formAssociated) this._syncDisabled();
242
256
  } else {
243
257
  // Back in the document. While it was out, the observer did not reach
244
- // it, so a theme or density switched in the meantime is caught up here
245
- // — the wrapper's data-theme also sets the color-scheme of the native
246
- // parts inside.
258
+ // it, so a theme, density or surface switched in the meantime is
259
+ // caught up here — the wrapper's data-theme also sets the color-scheme
260
+ // of the native parts inside.
247
261
  this._syncTheme(getCurrentTheme());
248
262
  this._syncDensity(getCurrentDensity());
263
+ this._syncSurface(getCurrentSurface());
249
264
  }
250
265
 
251
266
  // Everything below runs on every connect, not just the first. Moving an
@@ -315,6 +330,16 @@ class GlkElement extends HTMLElement {
315
330
  }
316
331
  }
317
332
 
333
+ /** Mirrors data-surface from <html> (since 1.24.0), like the density. */
334
+ _syncSurface(surface) {
335
+ if (!this._wrapper) return;
336
+ if (surface) {
337
+ this._wrapper.setAttribute('data-surface', surface);
338
+ } else {
339
+ this._wrapper.removeAttribute('data-surface');
340
+ }
341
+ }
342
+
318
343
  /** Subclasses override to build inner DOM inside this._wrapper. */
319
344
  render() {}
320
345