studio-engine 0.38.0 → 0.39.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +35 -1
- data/app/views/layouts/_navbar.html.erb +9 -7
- data/app/views/studio/banners/_app_banner.html.erb +6 -3
- data/app/views/studio/banners/_stack.html.erb +34 -50
- data/lib/studio/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bb273757252724d41962bac1a7c6318c0d04006ff41c1ba29735ad413c0b57fc
|
|
4
|
+
data.tar.gz: 618a5a39311ac9a316c649a502b44fa6540e8dc70c776fc3c3b2c17455473479
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9b7bcf2d4dca51566942a2179a6f06e6c4a70293acab99b5a747a76785d9cba69cf51e4992e02410e82e9602f6c317605866ed1bd5b59bbf452954eae5d620aa
|
|
7
|
+
data.tar.gz: 1136131a5250c8a014edeb8ddd602c23dced903a82b99d3c57eb3bf27dd2394b735c993d08a559ff6132b8ffcdf337a4d6a91d8f4396ef8ab83c7679b7e2c4d7
|
data/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,41 @@
|
|
|
2
2
|
|
|
3
3
|
The format is [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). This project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html) — `MAJOR.MINOR.PATCH`. Consumer Rails apps install the released RubyGems package with `gem "studio-engine", "~> 0.6"`; bumping the gem version and updating consumer lockfiles is a release.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 0.39.0 — 2026-08-11
|
|
6
|
+
|
|
7
|
+
### Removed
|
|
8
|
+
|
|
9
|
+
- **`--studio-bars-h` is gone.** 0.33 advertised this CSS custom property as the
|
|
10
|
+
contract between the bar stack and a consumer's navbar, and the navbar's
|
|
11
|
+
sticky `top` read it. It no longer exists: the stack now sits in normal flow
|
|
12
|
+
directly above the navbar and simply occupies its own height, so a navbar
|
|
13
|
+
sticky at `top: 0` starts underneath the bars with nothing to compute.
|
|
14
|
+
|
|
15
|
+
**No consumer breaks.** A navbar still spelling `top: var(--studio-bars-h,
|
|
16
|
+
0px)` resolves to its `0px` fallback — exactly where the new layout wants it —
|
|
17
|
+
so an adopting app self-heals with no change. Verified against
|
|
18
|
+
`mcritchie-studio` (which carries that spelling) and `turf-monster` (which
|
|
19
|
+
never adopted the stack).
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- **The navbar no longer jumps on load or navigation.** The removed property was
|
|
24
|
+
published twice and the two publishers could disagree: the server rendered an
|
|
25
|
+
ESTIMATE (bar count × a fixed unit) and a `ResizeObserver` then MEASURED the
|
|
26
|
+
real height and overwrote it. The header painted at the estimate and moved
|
|
27
|
+
when the measurement landed, moved again whenever a webfont changed a bar's
|
|
28
|
+
real height, and during a view transition the outgoing and incoming headers
|
|
29
|
+
composited at two different tops — so the navbar visibly drew twice. A
|
|
30
|
+
position only CSS can set cannot disagree with itself.
|
|
31
|
+
|
|
32
|
+
The estimate, the `ResizeObserver`, and the inline `<style>`/`<script>` the
|
|
33
|
+
stack used to emit are all gone. Reported from QA by the operator.
|
|
34
|
+
|
|
35
|
+
**Trade, recorded deliberately:** the bars now scroll away rather than
|
|
36
|
+
pinning. Two pinned siblings of unknown height cannot stack in CSS alone —
|
|
37
|
+
one must measure the other, and that measurement *is* the defect.
|
|
38
|
+
|
|
39
|
+
## 0.38.0 — 2026-08-10
|
|
6
40
|
|
|
7
41
|
**The email registry becomes the email catalog.** 0.37 gave every app a shared
|
|
8
42
|
page for its transactional email banners. This folds in the rest — **what each
|
|
@@ -38,13 +38,15 @@
|
|
|
38
38
|
%>
|
|
39
39
|
|
|
40
40
|
<header x-data="{ scrolled: false }" <%= '@scroll.window="scrolled = scrolled ? (window.scrollY > 5) : (window.scrollY > 60)"'.html_safe unless is_preview %>
|
|
41
|
-
<%# top
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
41
|
+
<%# top-0, a STATIC value, and never a custom property. Any bars render as
|
|
42
|
+
this header's sibling in normal flow (studio/banners/_stack), so they
|
|
43
|
+
already occupy their own height above it and there is nothing to
|
|
44
|
+
offset by. An offset read from a runtime-published property is what
|
|
45
|
+
made this header jump: it painted at a server estimate, moved when the
|
|
46
|
+
measurement landed, moved again on a webfont swap, and drew twice
|
|
47
|
+
during a view transition composited at two different tops. Only CSS
|
|
48
|
+
can set this top now, so none of that is reachable. %>
|
|
49
|
+
class="<%= is_preview ? 'bg-page' : "#{'vt-pinned-header ' if pin_header}sticky top-0 z-50 bg-page transition-shadow duration-300" %>"
|
|
48
50
|
:class="scrolled && 'shadow-lg border-b border-subtle is-scrolled'">
|
|
49
51
|
<style>
|
|
50
52
|
.user-nav-col { width: 14rem; }
|
|
@@ -24,9 +24,12 @@
|
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
# INTRINSIC height — content decides, and
|
|
28
|
-
#
|
|
29
|
-
#
|
|
27
|
+
# INTRINSIC height — content decides, and the LAYOUT absorbs the result: the
|
|
28
|
+
# stack sits in normal flow, so a bar simply occupies the height it needs and
|
|
29
|
+
# nothing has to measure it. (It once did measure, publishing --studio-bars-h;
|
|
30
|
+
# that jumped, and 0.39.0 removed it.) An earlier cut declared a fixed height
|
|
31
|
+
# so the stack could compute its total server-side; that was rejected
|
|
32
|
+
# deliberately — and the reason still holds — because it cannot express
|
|
30
33
|
# a bar that needs to be taller, or two bars stacked, without every consuming
|
|
31
34
|
# app being reworked. The apps should respond to what the bar needs, not the
|
|
32
35
|
# other way round.
|
|
@@ -12,22 +12,31 @@
|
|
|
12
12
|
0, 1 or 2, and growing. Nesting each new bar inside the navbar coupled two
|
|
13
13
|
unrelated components and meant every new bar edited the navbar. Here the bars
|
|
14
14
|
do not know the navbar exists, and the navbar does not know which bars
|
|
15
|
-
rendered —
|
|
15
|
+
rendered — it simply starts below whatever space they take.
|
|
16
16
|
|
|
17
|
-
HOW THE
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
HOW THE SPACE IS RESERVED. By the LAYOUT, and by nothing else. The stack sits
|
|
18
|
+
in normal flow directly above the navbar, so the bars occupy their own height
|
|
19
|
+
the way any block does, and the navbar — sticky at top:0 — starts underneath
|
|
20
|
+
them with no offset to compute. A taller bar, or a second, or a third, simply
|
|
21
|
+
takes more room and pushes the navbar down. Nothing measures, nothing
|
|
22
|
+
publishes, nothing repaints.
|
|
20
23
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
the
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
This replaced a measured custom property (--studio-bars-h: a server-rendered
|
|
25
|
+
estimate of count times a fixed unit, overwritten by a ResizeObserver reading
|
|
26
|
+
the real height). It worked, and it JUMPED: the header painted at the estimate
|
|
27
|
+
and moved when the measurement landed, then moved again whenever a webfont
|
|
28
|
+
changed the bar's real height — and during a view transition the outgoing and
|
|
29
|
+
incoming headers composited at two different tops, so the navbar visibly drew
|
|
30
|
+
twice. A position that only CSS can set cannot do any of that.
|
|
26
31
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
32
|
+
THE TRADE, recorded so it is a decision and not a regression: the bars scroll
|
|
33
|
+
away with the page instead of pinning. Only the navbar stays. Two pinned
|
|
34
|
+
siblings of unknown height cannot stack in CSS alone — one has to measure the
|
|
35
|
+
other — so pinning the bars is what cost the offset variable. The navbar keeps
|
|
36
|
+
its pin; the bars are ambient labels, seen on every page load because a Turbo
|
|
37
|
+
visit lands at the top. An overlay that must clear the chrome should position
|
|
38
|
+
off --nav-bottom (published in layouts/studio/_head), which already reports the
|
|
39
|
+
header's live bottom edge and accounts for chrome above it.
|
|
31
40
|
|
|
32
41
|
Locals (all optional):
|
|
33
42
|
preview — true inside a navbar-preview render; renders nothing, so a
|
|
@@ -61,42 +70,17 @@
|
|
|
61
70
|
end
|
|
62
71
|
end
|
|
63
72
|
|
|
64
|
-
# count
|
|
65
|
-
#
|
|
66
|
-
#
|
|
67
|
-
|
|
73
|
+
# No count is kept. The old code counted bars to compute an offset, and had to
|
|
74
|
+
# use count { } rather than count(true) because show_impersonation is a truthy
|
|
75
|
+
# USER object, not the literal true — a mistake that once published a one-bar
|
|
76
|
+
# height for a two-bar stack. Normal flow needs no count at all: whatever
|
|
77
|
+
# rendered takes the room it needs.
|
|
78
|
+
any_bar = show_environment || show_impersonation
|
|
68
79
|
%>
|
|
69
|
-
<% if
|
|
70
|
-
<%#
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
<div class="studio-bar-stack
|
|
75
|
-
<script>
|
|
76
|
-
// Publishes the stack's REAL height, so the navbar offsets by what the bars
|
|
77
|
-
// actually need. Idempotent and re-bound on Turbo navigation — a stale
|
|
78
|
-
// observer pointed at a detached node silently stops updating, and the
|
|
79
|
-
// navbar would then sit at yesterday's offset.
|
|
80
|
-
(function () {
|
|
81
|
-
var apply = function () {
|
|
82
|
-
var el = document.querySelector("[data-studio-bar-stack]");
|
|
83
|
-
if (!el) {
|
|
84
|
-
document.documentElement.style.removeProperty("--studio-bars-h");
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
if (window.__studioBarObserver) window.__studioBarObserver.disconnect();
|
|
88
|
-
var publish = function () {
|
|
89
|
-
var h = Math.round(el.getBoundingClientRect().height);
|
|
90
|
-
if (h > 0) document.documentElement.style.setProperty("--studio-bars-h", h + "px");
|
|
91
|
-
};
|
|
92
|
-
publish();
|
|
93
|
-
if (window.ResizeObserver) {
|
|
94
|
-
window.__studioBarObserver = new ResizeObserver(publish);
|
|
95
|
-
window.__studioBarObserver.observe(el);
|
|
96
|
-
}
|
|
97
|
-
};
|
|
98
|
-
apply();
|
|
99
|
-
document.addEventListener("turbo:load", apply);
|
|
100
|
-
})();
|
|
101
|
-
</script>
|
|
80
|
+
<% if any_bar %>
|
|
81
|
+
<%# Normal flow, deliberately. No sticky, no z-index, no measured offset: the
|
|
82
|
+
navbar is the only pinned chrome, so the bars simply take their own height
|
|
83
|
+
above it. Not sticky also keeps the paint order right — the pinned navbar
|
|
84
|
+
is positioned, so it draws over these bars as they scroll up behind it. %>
|
|
85
|
+
<div class="studio-bar-stack w-full" data-studio-bar-stack><%= bars %></div>
|
|
102
86
|
<% end %>
|
data/lib/studio/version.rb
CHANGED