@stacksjs/defaults 0.75.146 → 0.75.148

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.
@@ -2,7 +2,7 @@
2
2
  "publisher": "Stacks",
3
3
  "name": "vscode-stacks",
4
4
  "displayName": "Stacks",
5
- "version": "0.75.146",
5
+ "version": "0.75.148",
6
6
  "description": "Stacks, built into VS Code: stx templates, pickier linting and formatting, encrypted env files, the dev server preview and every buddy command. No other extensions required.",
7
7
  "license": "MIT",
8
8
  "funding": "https://github.com/sponsors/chrisbbreuer",
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stacksjs/defaults",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "0.75.146",
5
+ "version": "0.75.148",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+https://github.com/stacksjs/stacks.git",
@@ -55,7 +55,7 @@
55
55
  "dependencies": {
56
56
  "@iconify-json/f7": "^1.2.2",
57
57
  "@iconify-json/hugeicons": "^1.2.35",
58
- "@stacksjs/mobile": "0.75.146",
58
+ "@stacksjs/mobile": "0.75.148",
59
59
  "@stacksjs/sanitizer": "^0.2.422",
60
60
  "@xterm/addon-fit": "^0.11.0",
61
61
  "@xterm/xterm": "^6.0.0",
@@ -84,7 +84,16 @@ describe('Native components', () => {
84
84
  it('backs out through history, and sticks within the page rather than its wrapper', () => {
85
85
  const bar = read('NativeNavBar')
86
86
  expect(bar).toContain('if (goBack()) event.preventDefault()')
87
- expect(bar).toContain('[data-stx-scope]:has(> .native-nav) { display: contents; }')
87
+ expect(bar).toContain('[data-stx-scope]:has(> .native-nav),')
88
+ // A header component wrapping the bar adds a wrapper of its own.
89
+ expect(bar).toContain('[data-stx-scope]:has(> [data-stx-scope] > .native-nav) { display: contents; }')
90
+ // The actions keep their buttons' width; a long title truncates instead of running under them.
91
+ expect(bar).toContain('grid-template-columns: minmax(0, 1fr) auto minmax(max-content, 1fr);')
92
+ expect(bar).toContain('.native-nav-actions { justify-content: flex-end; container-type: normal; }')
93
+ // The back link follows a parent path known only in the browser.
94
+ expect(bar).toContain("const navBack = useReactiveProp<string>('back', '')")
95
+ expect(bar).toContain(':href="navBack()" :show="navBack()"')
96
+ expect(bar).not.toContain('@if(back)')
88
97
  expect(bar).toContain("useReactiveProp<string>('title', '')")
89
98
  })
90
99
 
@@ -67,9 +67,14 @@ onMount(() => {
67
67
  })
68
68
  onDestroy(() => stopScroll?.())
69
69
 
70
+ // Reactive like the title: a screen whose parent is known only in the browser
71
+ // (`:back="'/m/workout/' + id"`) had no back button at all, because the
72
+ // server rendered the link only when it knew the path.
73
+ const navBack = useReactiveProp<string>('back', '')
74
+
70
75
  const barClass = derived(() => {
71
76
  const collapsed = (!isLarge() && !onScroll()) || scrolled()
72
- return `native-nav-bar${isLarge() ? ' is-large' : ''}${collapsed ? ' is-collapsed' : ''}${scrolled() ? ' is-scrolled' : ''}`
77
+ return `native-nav-bar${isLarge() ? ' is-large' : ''}${collapsed ? ' is-collapsed' : ''}${scrolled() ? ' is-scrolled' : ''}${navBack() ? ' has-back' : ''}`
73
78
  })
74
79
 
75
80
  function tapBack(event: MouseEvent): void {
@@ -83,12 +88,10 @@ function tapBack(event: MouseEvent): void {
83
88
  <div ref="nativeNav" class="native-nav" data-native-nav-bar>
84
89
  <header :class="barClass()">
85
90
  <div class="native-nav-side">
86
- @if(back)
87
- <a href="{{ back }}" class="native-nav-back" :aria-label="backText()" draggable="false" data-native-back @click="tapBack">
88
- <NativeSymbol name="chevron.backward" icon="i-lucide-chevron-left" weight="semibold" class="native-nav-back-icon" />
89
- <span class="native-nav-back-label">{{ backText() }}</span>
90
- </a>
91
- @endif
91
+ <a href="{{ back }}" :href="navBack()" :show="navBack()" style="{{ back ? '' : 'display: none' }}" class="native-nav-back" :aria-label="backText()" draggable="false" data-native-back @click="tapBack">
92
+ <NativeSymbol name="chevron.backward" icon="i-lucide-chevron-left" weight="semibold" class="native-nav-back-icon" />
93
+ <span class="native-nav-back-label">{{ backText() }}</span>
94
+ </a>
92
95
  <slot name="leading" />
93
96
  </div>
94
97
  <p class="native-nav-title" aria-hidden="{{ large ? 'true' : 'false' }}">{{ navTitle() }}</p>
@@ -105,16 +108,23 @@ function tapBack(event: MouseEvent): void {
105
108
  <style>
106
109
  /* The element stx wraps each component in is a box too, as tall as the bar
107
110
  and its title; the bar stuck inside it and scrolled away with the title.
108
- Both boxes step aside so the bar sticks to the page. */
111
+ Both boxes step aside so the bar sticks to the page, and so does the
112
+ wrapper of an app's own header component around this one (HQ's
113
+ MobileHeader): one box more, and the bar scrolled away again. */
109
114
  .native-nav,
110
- [data-stx-scope]:has(> .native-nav) { display: contents; }
115
+ [data-stx-scope]:has(> .native-nav),
116
+ [data-stx-scope]:has(> [data-stx-scope] > .native-nav) { display: contents; }
111
117
 
112
118
  .native-nav-bar {
113
119
  position: sticky;
114
120
  top: env(safe-area-inset-top, 0px);
115
121
  z-index: 30;
116
122
  display: grid;
117
- grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
123
+ /* The actions never shrink below their buttons: three of them (a
124
+ workout's keep-awake, messages, account) ran under a long title. The
125
+ title gives way and truncates instead; the back side keeps at least
126
+ its chevron. */
127
+ grid-template-columns: minmax(0, 1fr) auto minmax(max-content, 1fr);
118
128
  gap: 0.5rem;
119
129
  align-items: center;
120
130
  min-height: 2.75rem;
@@ -161,7 +171,9 @@ function tapBack(event: MouseEvent): void {
161
171
  too narrow for its word and keep only the chevron, as iOS does, rather
162
172
  than running into the title. */
163
173
  .native-nav-side { display: flex; gap: 0.25rem; align-items: center; min-width: 0; container-type: inline-size; }
164
- .native-nav-actions { justify-content: flex-end; }
174
+ .native-nav-bar.has-back { grid-template-columns: minmax(2.75rem, 1fr) auto minmax(max-content, 1fr); }
175
+ /* Sized by its buttons, so not a size container (that made its minimum 0). */
176
+ .native-nav-actions { justify-content: flex-end; container-type: normal; }
165
177
 
166
178
  .native-nav-title {
167
179
  max-width: 60vw;