handzon-core 0.15.1 → 0.15.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "handzon-core",
3
- "version": "0.15.1",
3
+ "version": "0.15.3",
4
4
  "description": "Core framework for Handzon — layouts, components, content + AI libs, and server runtime (handlers, DB, auth, migration runner) consumed by Handzon scaffolds.",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -172,6 +172,8 @@ const slug = tutorial.id;
172
172
  letter-spacing: -0.015em;
173
173
  margin: 0.5rem 0 0.25rem;
174
174
  line-height: 1.2;
175
+ min-height: calc(1.15rem * 1.2 * 2);
176
+ text-wrap: balance;
175
177
  }
176
178
  .sb-title a { color: var(--color-fg); text-decoration: none; }
177
179
  .sb-meta {
@@ -14,29 +14,13 @@ import UserMenuIsland from "./UserMenu.tsx";
14
14
  // fallback to the cached signed-in state, removing the nav reload flash.
15
15
  const AUTH_SNAPSHOT_KEY = "hz-auth-snapshot";
16
16
  const TOKENS_HREF = withBase("/settings/tokens");
17
-
18
- const GITHUB_ICON_PATH =
19
- "M12 .5C5.65.5.5 5.65 5.65.5 12c0 5.08 3.29 9.39 7.86 10.91.58.11.79-.25.79-.55v-2.02c-3.2.7-3.88-1.36-3.88-1.36-.52-1.33-1.28-1.68-1.28-1.68-1.04-.71.08-.7.08-.7 1.15.08 1.76 1.18 1.76 1.18 1.03 1.76 2.7 1.25 3.36.96.1-.74.4-1.25.72-1.54-2.55-.29-5.24-1.27-5.24-5.66 0-1.25.45-2.27 1.18-3.07-.12-.29-.51-1.45.11-3.03 0 0 .96-.31 3.15 1.17a10.94 10.94 0 0 1 5.76 0c2.19-1.48 3.15-1.17 3.15-1.17.62 1.58.23 2.74.11 3.03.74.8 1.18 1.82 1.18 3.07 0 4.4-2.69 5.37-5.25 5.65.41.35.78 1.04.78 2.11v3.13c0 .3.21.66.79.55C20.71 21.39 24 17.08 24 12 24 5.65 18.85.5 12 .5z";
20
17
  ---
21
18
  <div class="user-menu-shell">
22
19
  <div class="user-menu um-fallback" data-user-menu-fallback aria-hidden="true">
23
- {/* Signed-out placeholder. Shown by default; the inline script below
24
- hides it when a cached signed-in snapshot exists. */}
25
- <span class="um-fallback-variant" data-um-fallback-signedout>
26
- <button type="button" class="um-btn" disabled tabindex="-1">
27
- <svg
28
- class="um-gh"
29
- viewBox="0 0 24 24"
30
- width="14"
31
- height="14"
32
- fill="currentColor"
33
- aria-hidden="true"
34
- >
35
- <path d={GITHUB_ICON_PATH} />
36
- </svg>
37
- <span>Sign in with GitHub</span>
38
- </button>
39
- </span>
20
+ {/* Neutral placeholder. The static page cannot read Auth.js' HttpOnly
21
+ session cookie, so do not show a signed-out GitHub button until
22
+ the client fetch resolves. */}
23
+ <span class="um-fallback-variant um-fallback-spacer" data-um-fallback-spacer></span>
40
24
  {/* Signed-in placeholder. Hidden until the inline script fills in the
41
25
  cached avatar + name and reveals it. Mirrors the island's
42
26
  signed-in layout so the swap on hydration is invisible. */}
@@ -97,9 +81,9 @@ const GITHUB_ICON_PATH =
97
81
  if (!user) return; // signed out → keep the default placeholder
98
82
  var root = document.querySelector("[data-user-menu-fallback]");
99
83
  if (!root) return;
100
- var signedOut = root.querySelector("[data-um-fallback-signedout]");
84
+ var spacer = root.querySelector("[data-um-fallback-spacer]");
101
85
  var signedIn = root.querySelector("[data-um-fallback-signedin]");
102
- if (!signedOut || !signedIn) return;
86
+ if (!spacer || !signedIn) return;
103
87
 
104
88
  var label = user.name || user.email || "Signed in";
105
89
  var first = String(label).trim().split(/\s+/)[0] || "Signed in";
@@ -118,7 +102,7 @@ const GITHUB_ICON_PATH =
118
102
  initial.textContent = label.trim().charAt(0).toUpperCase();
119
103
  initial.hidden = false;
120
104
  }
121
- signedOut.hidden = true;
105
+ spacer.hidden = true;
122
106
  signedIn.hidden = false;
123
107
  } catch (e) {
124
108
  /* ignore — fall back to the default signed-out placeholder */
@@ -180,6 +164,11 @@ const GITHUB_ICON_PATH =
180
164
  .um-fallback-variant[hidden] {
181
165
  display: none;
182
166
  }
167
+ .um-fallback-spacer {
168
+ display: inline-block;
169
+ width: 11.5rem;
170
+ height: calc(1em + 0.6rem + 2px);
171
+ }
183
172
  .um-btn {
184
173
  display: inline-flex;
185
174
  align-items: center;
@@ -1,4 +1,4 @@
1
- import { useEffect, useState } from "react";
1
+ import { useEffect, useLayoutEffect, useState } from "react";
2
2
  import { withBase } from "../../lib/base";
3
3
 
4
4
  /**
@@ -132,7 +132,7 @@ export default function UserMenu() {
132
132
  };
133
133
  }, []);
134
134
 
135
- useEffect(() => {
135
+ useLayoutEffect(() => {
136
136
  // Only retire the static fallback once the island has something to
137
137
  // show in its place (a known user or the wired sign-in form) or the
138
138
  // fetch has resolved with nothing to show (Tier-1). Until then, keep
@@ -6,8 +6,12 @@
6
6
  display: grid;
7
7
  place-items: center;
8
8
  border-radius: 0;
9
+ min-height: var(--mermaid-min-height, 14rem);
9
10
  }
10
11
  .mermaid-wrap :global(svg) { max-width: 100%; height: auto; }
12
+ pre.mermaid {
13
+ min-height: var(--mermaid-min-height, 14rem);
14
+ }
11
15
  .mermaid-error {
12
16
  padding: 0.75rem;
13
17
  background: color-mix(in oklab, var(--color-danger) 14%, var(--color-bg));