studio-engine 0.106.0.rc1 → 0.106.0.rc2
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 +11 -0
- data/app/assets/tailwind/studio_engine/engine.css +16 -0
- data/app/views/layouts/_navbar.html.erb +17 -0
- data/lib/studio/navbar_wordmark.rb +57 -0
- data/lib/studio/version.rb +1 -1
- data/lib/studio.rb +16 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: be24916d860667899a893bce707087ca252ac14dcc8525974a1ff54f48b45f0b
|
|
4
|
+
data.tar.gz: 2b97f80181cf0af261fcfc623b18fc0212f4547eee5fd49fbe5042bd780d73f1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 619518448f747b05444d75f6cf662055a13a03c5a7adb5b8eb46ca24f9eb416ed934a8d6e03bbcfde331b367f6e039877150b067231e2e6cb09fe518f5b25fc7
|
|
7
|
+
data.tar.gz: 5453348e783a3d4c65968a1a7ef91aab01772244d51378730c31efc4e842c3936c51a371daf99c907d8999a01b7e954b2a5b802dcbe2f8026670b91c98ca6d57
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,17 @@ The format is [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). This pro
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **`config.navbar_wordmark`: a brand lockup image in the engine navbar, off by
|
|
10
|
+
default.** Set it to `{ light: "/brand/navbar-light.svg", dark:
|
|
11
|
+
"/brand/navbar-dark.svg" }` and `layouts/_navbar` draws the lockup in place of
|
|
12
|
+
the "Navbar Logo" image and the `app_name` text, inside the same root link and
|
|
13
|
+
brand h1, with `alt` set to `app_name`. Both files render and engine.css shows
|
|
14
|
+
the one matching the root's `dark` class. Its height follows the logo's
|
|
15
|
+
collapse size and it scales down inside the phone column. Unset, the navbar is
|
|
16
|
+
byte-identical. See `docs/NAVBAR_SETUP.md`.
|
|
17
|
+
|
|
7
18
|
## 0.106.0 — 2026-10-14
|
|
8
19
|
|
|
9
20
|
### Changed
|
|
@@ -540,6 +540,22 @@ body.modal-open .studio-app-banner {
|
|
|
540
540
|
.nav-shell .nav-title { font-size: var(--nav-title-size); line-height: var(--nav-title-lead); }
|
|
541
541
|
.nav-shell .nav-title span:last-child { font-size: var(--nav-title-lead-size); }
|
|
542
542
|
|
|
543
|
+
/* Studio.navbar_wordmark: a brand lockup image in place of the logo and
|
|
544
|
+
title. HEIGHT-LED: it rides --nav-logo-size, so it collapses exactly as
|
|
545
|
+
the logo does in every band, and its width is the artwork's own. On a
|
|
546
|
+
phone the left column is what is left beside the user column's
|
|
547
|
+
min(14rem, 46vw) cap; the brand box and the image both carry min-width 0
|
|
548
|
+
and the image max-width 100%, so a wide lockup scales down inside that
|
|
549
|
+
column (object-fit keeps its aspect, pinned left) instead of painting
|
|
550
|
+
over the user nav. Both theme files render and the root's `dark` class
|
|
551
|
+
picks one: the light file on a light page, the dark file on a dark page. */
|
|
552
|
+
.nav-wordmark-brand { display: flex; align-items: center; min-width: 0; margin: 0; }
|
|
553
|
+
.nav-wordmark { display: block; width: auto; max-width: 100%; min-width: 0; object-fit: contain; object-position: left center; }
|
|
554
|
+
.nav-shell .nav-wordmark { height: var(--nav-logo-size); }
|
|
555
|
+
.nav-wordmark-dark { display: none; }
|
|
556
|
+
.dark .nav-wordmark-light { display: none; }
|
|
557
|
+
.dark .nav-wordmark-dark { display: block; }
|
|
558
|
+
|
|
543
559
|
@media (max-width: 767px) {
|
|
544
560
|
.nav-title { flex-direction: column; gap: 0; }
|
|
545
561
|
.nav-title span:first-child { margin-bottom: -4px; }
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
last_word = words.pop
|
|
43
43
|
prefix = words.join(" ")
|
|
44
44
|
logo_path = Studio.logo_for("Navbar Logo")
|
|
45
|
+
wordmark = Studio.navbar_wordmark
|
|
45
46
|
%>
|
|
46
47
|
|
|
47
48
|
<%# nav-shell is the --nav-p scope: the engine's nav-collapse controller (studio/nav_collapse) writes
|
|
@@ -143,6 +144,21 @@
|
|
|
143
144
|
<div class="flex-1 min-w-0 px-4">
|
|
144
145
|
<div class="flex items-center gap-6 min-w-0">
|
|
145
146
|
<%= link_to root_path, class: "nav-logo-link inline-flex items-center gap-3 group min-w-0" do %>
|
|
147
|
+
<% if wordmark %>
|
|
148
|
+
<%# Studio.navbar_wordmark: the brand lockup (icon + words as one
|
|
149
|
+
artwork) replaces the logo AND the title text. Both theme files
|
|
150
|
+
render; engine.css (.nav-wordmark-light / -dark) shows the one
|
|
151
|
+
matching the root's `dark` class, so a toggle needs no script.
|
|
152
|
+
The brand_tag still wraps it, so the page keeps its h1 and the
|
|
153
|
+
h1's accessible name is the alt text. Height follows
|
|
154
|
+
--nav-logo-size; width is the artwork's own, shrinking with the
|
|
155
|
+
column (the min-w-0 chain above; the brand box's own min-width 0
|
|
156
|
+
is in engine.css) rather than spilling. %>
|
|
157
|
+
<<%= brand_tag %> class="nav-wordmark-brand">
|
|
158
|
+
<img src="<%= wordmark[:light] %>" alt="<%= Studio.app_name %>" class="nav-wordmark nav-wordmark-light">
|
|
159
|
+
<img src="<%= wordmark[:dark] %>" alt="<%= Studio.app_name %>" class="nav-wordmark nav-wordmark-dark">
|
|
160
|
+
</<%= brand_tag %>>
|
|
161
|
+
<% else %>
|
|
146
162
|
<% if logo_path %>
|
|
147
163
|
<%# No w-*/h-* utility here: .nav-shell .nav-logo sizes it off --nav-p.
|
|
148
164
|
transition-transform, NOT transition-all — the hover lift still
|
|
@@ -155,6 +171,7 @@
|
|
|
155
171
|
`truncate` on the h1 would clip the flex CONTAINER and leave the
|
|
156
172
|
spans drawing outside it, which is the bug rather than the fix. %>
|
|
157
173
|
<<%= brand_tag %> class="nav-title font-extrabold text-heading tracking-tight min-w-0"><span class="truncate"><%= prefix %></span><span class="text-primary truncate"><%= last_word %></span></<%= brand_tag %>>
|
|
174
|
+
<% end %>
|
|
158
175
|
<% end %>
|
|
159
176
|
<%# Desktop nav — Studio.navbar_links %>
|
|
160
177
|
<nav class="hidden md:flex items-center gap-4"<%= ' aria-label="Main"'.html_safe if navbar_links.any? %>>
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Studio.navbar_wordmark: an opt-in brand lockup image (an icon plus the app's
|
|
4
|
+
# words, made as one piece of artwork) that the engine navbar draws in place of
|
|
5
|
+
# the "Navbar Logo" image and the app_name text. Pure Ruby, so the unit suite
|
|
6
|
+
# covers it without the dummy app.
|
|
7
|
+
#
|
|
8
|
+
# The config is nil (the default, and the navbar renders as it always has) or
|
|
9
|
+
# a Hash naming one file per theme:
|
|
10
|
+
#
|
|
11
|
+
# config.navbar_wordmark = { light: "/brand/navbar-light.svg",
|
|
12
|
+
# dark: "/brand/navbar-dark.svg" }
|
|
13
|
+
#
|
|
14
|
+
# light is the artwork drawn on a LIGHT page, dark the artwork drawn on a DARK
|
|
15
|
+
# page (the root carries the `dark` class). Both images render; engine.css hides
|
|
16
|
+
# the one that does not match the theme, so a toggle swaps them with no script.
|
|
17
|
+
module Studio
|
|
18
|
+
module NavbarWordmark
|
|
19
|
+
class InvalidConfig < ArgumentError; end
|
|
20
|
+
|
|
21
|
+
THEMES = %i[light dark].freeze
|
|
22
|
+
|
|
23
|
+
module_function
|
|
24
|
+
|
|
25
|
+
# The config as { light: String, dark: String }, or nil when unset.
|
|
26
|
+
def normalize(config)
|
|
27
|
+
return nil if config.nil?
|
|
28
|
+
|
|
29
|
+
validate!(config)
|
|
30
|
+
THEMES.to_h { |theme| [theme, fetch(config, theme).strip] }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def validate!(config)
|
|
34
|
+
return nil if config.nil?
|
|
35
|
+
|
|
36
|
+
unless config.is_a?(Hash)
|
|
37
|
+
raise InvalidConfig, "Studio.navbar_wordmark must be nil or a Hash of " \
|
|
38
|
+
"{ light: path, dark: path } (got #{config.inspect})"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
extra = config.keys.map(&:to_sym) - THEMES
|
|
42
|
+
raise InvalidConfig, "Studio.navbar_wordmark takes only :light and :dark (got #{extra.inspect})" if extra.any?
|
|
43
|
+
|
|
44
|
+
THEMES.each do |theme|
|
|
45
|
+
value = fetch(config, theme)
|
|
46
|
+
next if value.is_a?(String) && !value.strip.empty?
|
|
47
|
+
|
|
48
|
+
raise InvalidConfig, "Studio.navbar_wordmark[:#{theme}] must be a non-blank path (got #{value.inspect})"
|
|
49
|
+
end
|
|
50
|
+
nil
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def fetch(config, theme)
|
|
54
|
+
config.key?(theme) ? config[theme] : config[theme.to_s]
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
data/lib/studio/version.rb
CHANGED
data/lib/studio.rb
CHANGED
|
@@ -33,6 +33,7 @@ require "studio/site_footer"
|
|
|
33
33
|
require "studio/booking"
|
|
34
34
|
require "studio/navbar_links"
|
|
35
35
|
require "studio/navbar_identity"
|
|
36
|
+
require "studio/navbar_wordmark"
|
|
36
37
|
require "studio/auth_labels"
|
|
37
38
|
require "studio/profile_sections"
|
|
38
39
|
require "studio/profile_image"
|
|
@@ -245,6 +246,21 @@ module Studio
|
|
|
245
246
|
|
|
246
247
|
mattr_reader :sign_in_label, default: NavbarIdentity::DEFAULT_SIGN_IN_LABEL
|
|
247
248
|
|
|
249
|
+
# ---- Navbar wordmark ----
|
|
250
|
+
# A brand lockup image (icon plus words as one artwork) drawn in place of the
|
|
251
|
+
# "Navbar Logo" and the app_name text. nil, the default, renders the navbar
|
|
252
|
+
# byte-identical to before. light is the file for a light page, dark the file
|
|
253
|
+
# for a dark page; both render and engine.css shows the one matching the
|
|
254
|
+
# root's `dark` class. Rules: lib/studio/navbar_wordmark.rb.
|
|
255
|
+
#
|
|
256
|
+
# config.navbar_wordmark = { light: "/brand/navbar-light.svg",
|
|
257
|
+
# dark: "/brand/navbar-dark.svg" }
|
|
258
|
+
mattr_reader :navbar_wordmark, default: nil
|
|
259
|
+
|
|
260
|
+
def self.navbar_wordmark=(config)
|
|
261
|
+
@@navbar_wordmark = NavbarWordmark.normalize(config)
|
|
262
|
+
end
|
|
263
|
+
|
|
248
264
|
def self.sign_in_label=(label)
|
|
249
265
|
NavbarIdentity.validate_label!(label)
|
|
250
266
|
@@sign_in_label = label
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: studio-engine
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.106.0.
|
|
4
|
+
version: 0.106.0.rc2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alex McRitchie
|
|
@@ -760,6 +760,7 @@ files:
|
|
|
760
760
|
- lib/studio/name_parts.rb
|
|
761
761
|
- lib/studio/navbar_identity.rb
|
|
762
762
|
- lib/studio/navbar_links.rb
|
|
763
|
+
- lib/studio/navbar_wordmark.rb
|
|
763
764
|
- lib/studio/newsletter.rb
|
|
764
765
|
- lib/studio/oauth_identity.rb
|
|
765
766
|
- lib/studio/partial_block.rb
|