stimeo-ui 0.1.0.pre.beta.2 → 0.1.0.pre.beta.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 43ec968d086165fbfd9daeda12d003a6cf0cb9e8375a9abfb34924aab3383959
4
- data.tar.gz: 8c1fde6bff018d4f47ac745df3e18b2eaaa95d3658ea1ce05fd03bda5b35dc46
3
+ metadata.gz: 778527340281767df85850342901a668c8f54f451ed25526b4ca6a6f280c32f3
4
+ data.tar.gz: b343d8b09c9827d9ee379fe7604424183086826d81593a712549a6af6ca46ee2
5
5
  SHA512:
6
- metadata.gz: 0ab3a420ebc50b56abce77cd1a4b36be4c3891d4495bd4c2ab8961a42978dc6f79443822ab389dea100b308d236064e76c2e3a0445e0daeb260e7ce4653c71d1
7
- data.tar.gz: 1ffc55e37df21a692a21da69f4e98b303ca1600bc57286a132584425392be40f654ba6570227c70436934f5b0ca2bf3d0a5dee9c39c2f24f61e70632e2992751
6
+ metadata.gz: 62a2f1c1dd34706ace247fc1cd9d1f581458cda076f533532c064d2c4fec40d42037e1e70aba19e6bb8a7ed11eba08565ba8ab61bd325c8ce89c3ac710036f17
7
+ data.tar.gz: a862d0e7f53905d014c0938f26484047626adb34e8ea96272d33eda4532ce6fc36819554119698b9989d9cf456f95aab52627841cd620a2de2f08c569e10762e
data/CHANGELOG.md CHANGED
@@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
  While the version is `0.x`, the public API (the `stimeo--*` data attributes) may
8
8
  change between releases.
9
9
 
10
+ ## [0.1.0-beta.3] - 2026-07-18
11
+
12
+ Maintenance release: one bug fix in the focus-trap primitive shared by the
13
+ modal overlay controllers.
14
+
15
+ ### Fixed
16
+
17
+ - dialog, alert-dialog, confirm, drawer, command-palette, sidebar: navigating
18
+ away while the overlay is open no longer bakes the background scroll lock
19
+ into Turbo's page cache. A restored page previously treated the locked
20
+ `<body>` as its baseline, so closing the overlay could leave the page
21
+ unscrollable; the shared focus trap now reverts its side effects on
22
+ `turbo:before-cache`.
23
+ - drawer: the usage example in the API reference now shows the backdrop
24
+ overlay `hidden` at rest and a neutral `<div>` as the panel element.
25
+
10
26
  ## [0.1.0-beta.2] - 2026-07-12
11
27
 
12
28
  The Inspector grows two new faces: an MCP server for AI coding agents and a
@@ -70,6 +86,7 @@ Initial public alpha: 101 behavior-only, accessible Stimulus controllers driven
70
86
  by `data-*` attributes, shipping no CSS. Published to npm (with provenance) and
71
87
  RubyGems.
72
88
 
89
+ [0.1.0-beta.3]: https://github.com/taiyaky/stimeo-ui/releases/tag/v0.1.0-beta.3
73
90
  [0.1.0-beta.2]: https://github.com/taiyaky/stimeo-ui/releases/tag/v0.1.0-beta.2
74
91
  [0.1.0-beta.1]: https://github.com/taiyaky/stimeo-ui/releases/tag/v0.1.0-beta.1
75
92
  [0.1.0-alpha.1]: https://github.com/taiyaky/stimeo-ui/releases/tag/v0.1.0-alpha.1
data/README.md CHANGED
@@ -31,7 +31,7 @@ owns the look entirely.
31
31
  ### Rails with importmap (recommended)
32
32
 
33
33
  ```bash
34
- bundle add stimeo-ui --version "0.1.0.pre.beta.2"
34
+ bundle add stimeo-ui --version "0.1.0.pre.beta.3"
35
35
  bin/rails generate stimeo:install
36
36
  ```
37
37
 
@@ -49,6 +49,7 @@ var FocusTrap = class {
49
49
  }
50
50
  if (this.#flag(this.#options.isolate, true)) this.#isolateBackground();
51
51
  document.addEventListener("keydown", this.#onKeydown);
52
+ document.addEventListener("turbo:before-cache", this.#onBeforeCache);
52
53
  if (this.#flag(this.#options.autoFocus, true)) this.#focusInitial();
53
54
  }
54
55
  /**
@@ -62,6 +63,7 @@ var FocusTrap = class {
62
63
  if (!this.#activeState) return;
63
64
  this.#activeState = false;
64
65
  document.removeEventListener("keydown", this.#onKeydown);
66
+ document.removeEventListener("turbo:before-cache", this.#onBeforeCache);
65
67
  if (this.#scrollLocked) {
66
68
  document.body.style.overflow = this.#previousBodyOverflow;
67
69
  this.#scrollLocked = false;
@@ -77,6 +79,17 @@ var FocusTrap = class {
77
79
  if (option === void 0) return fallback;
78
80
  return typeof option === "function" ? option() : option;
79
81
  }
82
+ /**
83
+ * Reverts the side effects just before Turbo caches the page snapshot, so an
84
+ * overlay left open does not bake the scroll lock into `body[style]` — a
85
+ * restored page would feed that locked value back into {@link activate} as the
86
+ * baseline, and closing would then never unlock the page. Markup state stays
87
+ * untouched (restore-open designs reopen against a clean baseline), and focus
88
+ * is left alone mid-navigation. The listener lives only while active.
89
+ */
90
+ #onBeforeCache = () => {
91
+ this.deactivate({ restoreFocus: false });
92
+ };
80
93
  /** Handles `Escape` (delegated) and `Tab` (focus trap) while active. */
81
94
  #onKeydown = (event) => {
82
95
  if (event.key === "Escape") {
@@ -49,6 +49,7 @@ var FocusTrap = class {
49
49
  }
50
50
  if (this.#flag(this.#options.isolate, true)) this.#isolateBackground();
51
51
  document.addEventListener("keydown", this.#onKeydown);
52
+ document.addEventListener("turbo:before-cache", this.#onBeforeCache);
52
53
  if (this.#flag(this.#options.autoFocus, true)) this.#focusInitial();
53
54
  }
54
55
  /**
@@ -62,6 +63,7 @@ var FocusTrap = class {
62
63
  if (!this.#activeState) return;
63
64
  this.#activeState = false;
64
65
  document.removeEventListener("keydown", this.#onKeydown);
66
+ document.removeEventListener("turbo:before-cache", this.#onBeforeCache);
65
67
  if (this.#scrollLocked) {
66
68
  document.body.style.overflow = this.#previousBodyOverflow;
67
69
  this.#scrollLocked = false;
@@ -77,6 +79,17 @@ var FocusTrap = class {
77
79
  if (option === void 0) return fallback;
78
80
  return typeof option === "function" ? option() : option;
79
81
  }
82
+ /**
83
+ * Reverts the side effects just before Turbo caches the page snapshot, so an
84
+ * overlay left open does not bake the scroll lock into `body[style]` — a
85
+ * restored page would feed that locked value back into {@link activate} as the
86
+ * baseline, and closing would then never unlock the page. Markup state stays
87
+ * untouched (restore-open designs reopen against a clean baseline), and focus
88
+ * is left alone mid-navigation. The listener lives only while active.
89
+ */
90
+ #onBeforeCache = () => {
91
+ this.deactivate({ restoreFocus: false });
92
+ };
80
93
  /** Handles `Escape` (delegated) and `Tab` (focus trap) while active. */
81
94
  #onKeydown = (event) => {
82
95
  if (event.key === "Escape") {
@@ -49,6 +49,7 @@ var FocusTrap = class {
49
49
  }
50
50
  if (this.#flag(this.#options.isolate, true)) this.#isolateBackground();
51
51
  document.addEventListener("keydown", this.#onKeydown);
52
+ document.addEventListener("turbo:before-cache", this.#onBeforeCache);
52
53
  if (this.#flag(this.#options.autoFocus, true)) this.#focusInitial();
53
54
  }
54
55
  /**
@@ -62,6 +63,7 @@ var FocusTrap = class {
62
63
  if (!this.#activeState) return;
63
64
  this.#activeState = false;
64
65
  document.removeEventListener("keydown", this.#onKeydown);
66
+ document.removeEventListener("turbo:before-cache", this.#onBeforeCache);
65
67
  if (this.#scrollLocked) {
66
68
  document.body.style.overflow = this.#previousBodyOverflow;
67
69
  this.#scrollLocked = false;
@@ -77,6 +79,17 @@ var FocusTrap = class {
77
79
  if (option === void 0) return fallback;
78
80
  return typeof option === "function" ? option() : option;
79
81
  }
82
+ /**
83
+ * Reverts the side effects just before Turbo caches the page snapshot, so an
84
+ * overlay left open does not bake the scroll lock into `body[style]` — a
85
+ * restored page would feed that locked value back into {@link activate} as the
86
+ * baseline, and closing would then never unlock the page. Markup state stays
87
+ * untouched (restore-open designs reopen against a clean baseline), and focus
88
+ * is left alone mid-navigation. The listener lives only while active.
89
+ */
90
+ #onBeforeCache = () => {
91
+ this.deactivate({ restoreFocus: false });
92
+ };
80
93
  /** Handles `Escape` (delegated) and `Tab` (focus trap) while active. */
81
94
  #onKeydown = (event) => {
82
95
  if (event.key === "Escape") {
@@ -49,6 +49,7 @@ var FocusTrap = class {
49
49
  }
50
50
  if (this.#flag(this.#options.isolate, true)) this.#isolateBackground();
51
51
  document.addEventListener("keydown", this.#onKeydown);
52
+ document.addEventListener("turbo:before-cache", this.#onBeforeCache);
52
53
  if (this.#flag(this.#options.autoFocus, true)) this.#focusInitial();
53
54
  }
54
55
  /**
@@ -62,6 +63,7 @@ var FocusTrap = class {
62
63
  if (!this.#activeState) return;
63
64
  this.#activeState = false;
64
65
  document.removeEventListener("keydown", this.#onKeydown);
66
+ document.removeEventListener("turbo:before-cache", this.#onBeforeCache);
65
67
  if (this.#scrollLocked) {
66
68
  document.body.style.overflow = this.#previousBodyOverflow;
67
69
  this.#scrollLocked = false;
@@ -77,6 +79,17 @@ var FocusTrap = class {
77
79
  if (option === void 0) return fallback;
78
80
  return typeof option === "function" ? option() : option;
79
81
  }
82
+ /**
83
+ * Reverts the side effects just before Turbo caches the page snapshot, so an
84
+ * overlay left open does not bake the scroll lock into `body[style]` — a
85
+ * restored page would feed that locked value back into {@link activate} as the
86
+ * baseline, and closing would then never unlock the page. Markup state stays
87
+ * untouched (restore-open designs reopen against a clean baseline), and focus
88
+ * is left alone mid-navigation. The listener lives only while active.
89
+ */
90
+ #onBeforeCache = () => {
91
+ this.deactivate({ restoreFocus: false });
92
+ };
80
93
  /** Handles `Escape` (delegated) and `Tab` (focus trap) while active. */
81
94
  #onKeydown = (event) => {
82
95
  if (event.key === "Escape") {
@@ -118,7 +118,7 @@ var SortableController = class extends Controller {
118
118
  * Mirrors a step into the `status` live region. Copy is localizable through
119
119
  * `data-grabbed` / `data-moved` / `data-dropped` / `data-canceled` templates on
120
120
  * the status element (`%{name}` / `%{position}` / `%{total}` placeholders);
121
- * terse English is the fallback (same channel design as `stimeo--feed`).
121
+ * terse English is the fallback (the library's shared status-channel design).
122
122
  */
123
123
  #announce(key, item) {
124
124
  if (!this.hasStatusTarget) return;
data/dist/index.js CHANGED
@@ -118,6 +118,7 @@ var FocusTrap = class {
118
118
  }
119
119
  if (this.#flag(this.#options.isolate, true)) this.#isolateBackground();
120
120
  document.addEventListener("keydown", this.#onKeydown);
121
+ document.addEventListener("turbo:before-cache", this.#onBeforeCache);
121
122
  if (this.#flag(this.#options.autoFocus, true)) this.#focusInitial();
122
123
  }
123
124
  /**
@@ -131,6 +132,7 @@ var FocusTrap = class {
131
132
  if (!this.#activeState) return;
132
133
  this.#activeState = false;
133
134
  document.removeEventListener("keydown", this.#onKeydown);
135
+ document.removeEventListener("turbo:before-cache", this.#onBeforeCache);
134
136
  if (this.#scrollLocked) {
135
137
  document.body.style.overflow = this.#previousBodyOverflow;
136
138
  this.#scrollLocked = false;
@@ -146,6 +148,17 @@ var FocusTrap = class {
146
148
  if (option === void 0) return fallback;
147
149
  return typeof option === "function" ? option() : option;
148
150
  }
151
+ /**
152
+ * Reverts the side effects just before Turbo caches the page snapshot, so an
153
+ * overlay left open does not bake the scroll lock into `body[style]` — a
154
+ * restored page would feed that locked value back into {@link activate} as the
155
+ * baseline, and closing would then never unlock the page. Markup state stays
156
+ * untouched (restore-open designs reopen against a clean baseline), and focus
157
+ * is left alone mid-navigation. The listener lives only while active.
158
+ */
159
+ #onBeforeCache = () => {
160
+ this.deactivate({ restoreFocus: false });
161
+ };
149
162
  /** Handles `Escape` (delegated) and `Tab` (focus trap) while active. */
150
163
  #onKeydown = (event) => {
151
164
  if (event.key === "Escape") {
@@ -11273,7 +11286,7 @@ var SortableController = class extends Controller {
11273
11286
  * Mirrors a step into the `status` live region. Copy is localizable through
11274
11287
  * `data-grabbed` / `data-moved` / `data-dropped` / `data-canceled` templates on
11275
11288
  * the status element (`%{name}` / `%{position}` / `%{total}` placeholders);
11276
- * terse English is the fallback (same channel design as `stimeo--feed`).
11289
+ * terse English is the fallback (the library's shared status-channel design).
11277
11290
  */
11278
11291
  #announce(key, item) {
11279
11292
  if (!this.hasStatusTarget) return;
@@ -2,9 +2,9 @@
2
2
 
3
3
  module Stimeo
4
4
  module UI
5
- # Kept in lockstep with package.json: npm `0.1.0-beta.2` ⇔ gem
6
- # `0.1.0.pre.beta.2` (RubyGems forbids dashes). Bump both together —
5
+ # Kept in lockstep with package.json: npm `0.1.0-beta.3` ⇔ gem
6
+ # `0.1.0.pre.beta.3` (RubyGems forbids dashes). Bump both together —
7
7
  # see RELEASING.md for the synchronized release procedure.
8
- VERSION = "0.1.0.pre.beta.2"
8
+ VERSION = "0.1.0.pre.beta.3"
9
9
  end
10
10
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stimeo-ui
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.pre.beta.2
4
+ version: 0.1.0.pre.beta.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stimeo Labs
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-07-12 00:00:00.000000000 Z
11
+ date: 2026-07-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties