@mundogamernetwork/shared-ui 1.16.5 → 1.16.7

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.
@@ -14,6 +14,7 @@ const { performLogout } = useLogout();
14
14
 
15
15
  const runtimeConfig = useRuntimeConfig();
16
16
  const accountsBaseUrl = runtimeConfig.public.mgSharedUi?.accountsBaseUrl || runtimeConfig.public.accountsBaseUrl;
17
+ const supportUrl = `${accountsBaseUrl}/account/support/new`;
17
18
  const features = runtimeConfig.public.mgSharedUi?.features ?? {};
18
19
  const pricingUrl = runtimeConfig.public.mgSharedUi?.pricingUrl || "";
19
20
  const { locale } = useI18n();
@@ -58,11 +59,51 @@ const handleToggleOnline = () => {
58
59
  </script>
59
60
 
60
61
  <template>
62
+ <!--
63
+ The 'signed-in' class below is a reactive :class binding on THIS SAME
64
+ element — it hit the identical never-repatched-after-hydration-mismatch
65
+ symptom the inner v-if/v-else branches did (see the comment above
66
+ MgLoginRegisterMenu/section further down), and unlike that inner swap,
67
+ there's no sibling-vnode :key trick available to fix an ancestor's own
68
+ class binding on itself (verified: a :key on this element does NOT
69
+ force it to re-evaluate — key only affects sibling-vnode comparison,
70
+ not a component's own reactive re-render). The width rule that used to
71
+ key off '.signed-in' now uses :has(.signed-in-menu) instead — real DOM
72
+ structure, correct regardless of whether this class ever catches up.
73
+ The class stays here for anything else that legitimately keys off it
74
+ (e.g. a host's own CSS); just don't rely on it for layout in this file.
75
+ -->
61
76
  <div ref="refDiv" :class="{ 'ui-config-user': true, 'signed-in': signedIn }">
62
77
  <div ref="wrapper" class="ui-config-user__content">
63
- <MgLoginRegisterMenu v-if="!signedIn" :dropdown="false" />
64
-
65
- <div v-else class="signed-in-menu">
78
+ <!--
79
+ This MUST render a different root tag than MgLoginRegisterMenu's
80
+ own root (a <div>) a plain :key difference is NOT enough here.
81
+ signedIn always starts false and flips true only after the async
82
+ /auth/user check resolves (SSR never has the session, so every
83
+ load — not just a race — renders guest first, then the real
84
+ state client-side). When both branches are <div>s, whatever
85
+ code path handles that guest→signed-in swap (traced to Vue's
86
+ hydration-mismatch recovery, not the plain runtime v-if/v-else
87
+ patch — a distinct :key on each branch demonstrably did NOT
88
+ stop it) reuses the existing DOM node instead of replacing it:
89
+ the node keeps MgLoginRegisterMenu's own class
90
+ ("mg-login-register") and scope attribute while only its
91
+ children get patched to the signed-in markup. Result: the
92
+ signed-in content renders styled by the GUEST component's CSS
93
+ (340px guest width instead of 240px, and .username/
94
+ .btn-primary-outline/.status-toggle never match their real
95
+ ".signed-in-menu" ancestor selector, so they fall through to
96
+ unstyled/inherited color instead of var(--active) — text goes
97
+ near-invisible on any host whose global default text color is
98
+ dark, e.g. jobs-frontend's Bootstrap default). A genuinely
99
+ different tag (section, not div) forces a real replace — this
100
+ was verified against a live reproduction, not just reasoned
101
+ about; do not "simplify" this back to <div> without re-testing
102
+ the actual guest→signed-in transition, not just a hard reload.
103
+ -->
104
+ <MgLoginRegisterMenu v-if="!signedIn" key="guest" :dropdown="false" />
105
+
106
+ <section v-else key="signed-in" class="signed-in-menu">
66
107
  <div class="row info-row ps-0">
67
108
  <div class="col-auto px-3">
68
109
  <div v-if="!user?.avatar_url" class="no-avatar-wrapper">
@@ -113,6 +154,12 @@ const handleToggleOnline = () => {
113
154
  </a>
114
155
  </div>
115
156
 
157
+ <div class="row info-row">
158
+ <a :href="supportUrl" target="_blank" class="support-link">
159
+ {{ $t("account_menu.buttons.support", "Support") }}
160
+ </a>
161
+ </div>
162
+
116
163
  <div v-if="features.statusOnline" class="row info-row my-3">
117
164
  <div class="status-toggle">
118
165
  <span>{{ $t("account_menu.buttons.show_online") }}</span>
@@ -130,7 +177,7 @@ const handleToggleOnline = () => {
130
177
  {{ $t("account_menu.buttons.logout") }}
131
178
  </button>
132
179
  </div>
133
- </div>
180
+ </section>
134
181
  </div>
135
182
  </div>
136
183
  </template>
@@ -163,7 +210,16 @@ const handleToggleOnline = () => {
163
210
  overflow-y: auto;
164
211
  transition: all ease 0.5s;
165
212
 
166
- &:not(.signed-in) {
213
+ // Derived from the actual rendered content (:has), not the .signed-in
214
+ // class this element also carries. That class is a reactive :class
215
+ // binding on THIS SAME element (see the guest→signed-in transition
216
+ // comment above the template's MgLoginRegisterMenu/section) — it hit
217
+ // the identical never-repatched symptom the inner branch did, and
218
+ // unlike the inner v-if/v-else swap, there's no sibling-vnode :key
219
+ // trick available for an ancestor's own class binding on itself.
220
+ // :has(.signed-in-menu) reads real DOM structure instead, so it's
221
+ // correct regardless of whether that class binding ever catches up.
222
+ &:not(:has(.signed-in-menu)) {
167
223
  width: 340px;
168
224
  }
169
225
 
@@ -284,6 +340,26 @@ const handleToggleOnline = () => {
284
340
  }
285
341
  }
286
342
 
343
+ .support-link {
344
+ display: block;
345
+ width: 100%;
346
+ text-align: center;
347
+ font-size: 0.75rem;
348
+ font-weight: 400;
349
+ // Deliberately quieter than .plans-pricing-link — this is a low-key
350
+ // secondary affordance, not a conversion CTA, so it stays on a muted
351
+ // text token instead of each host's accent color.
352
+ color: var(--secondary-info-fg, var(--inactive));
353
+ text-decoration: none;
354
+ padding: 4px 0;
355
+ margin-top: 8px;
356
+
357
+ &:hover {
358
+ text-decoration: underline;
359
+ color: var(--active);
360
+ }
361
+ }
362
+
287
363
  .status-toggle {
288
364
  display: flex;
289
365
  justify-content: space-between;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mundogamernetwork/shared-ui",
3
- "version": "1.16.5",
3
+ "version": "1.16.7",
4
4
  "description": "Mundo Gamer Network - Shared UI Layer (Nuxt 3)",
5
5
  "type": "module",
6
6
  "main": "./nuxt.config.ts",