Skip to content

Commit 5c5009b

Browse files
refactor: remove js calcs.
1 parent 5d4aff9 commit 5c5009b

7 files changed

Lines changed: 88 additions & 65 deletions

File tree

docs/next-steps.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,7 @@ Focused follow-up work for `@knighted/develop`.
2323
- Explore authoring and running component-focused tests in-browser (for example, a Vitest-compatible flow) using CDN-delivered tooling.
2424
- Define a lightweight test UX that supports writing tests, running them on demand, and displaying results in-app.
2525

26-
6. **Panel sizing without JS height sync**
27-
- Revisit the current side-layout preview height calculation and investigate a pure CSS replacement.
28-
- Keep existing behavior constraints: preview should not exceed the combined editor stack height in side layouts, and preview content should scroll internally when it overflows.
29-
30-
7. **CDN failure recovery UX**
26+
6. **CDN failure recovery UX**
3127
- Detect transient CDN/module loading failures and surface a clear recovery action in-app.
3228
- Add a user-triggered retry path (for example, Reload page / Force reload) when runtime bootstrap imports fail.
3329
- Consider an optional automatic one-time retry before showing recovery controls, while avoiding infinite reload loops.

playwright/app.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ test('side layout config keeps preview scrolling inside preview host', async ({
141141
expect(scrollConfig?.minHeight).toBe('0px')
142142
})
143143

144-
test('expanded component and styles min-height stay consistent in side layouts', async ({
144+
test('expanded component and styles can shrink consistently in side layouts', async ({
145145
page,
146146
}) => {
147147
await waitForInitialRender(page)
@@ -160,8 +160,8 @@ test('expanded component and styles min-height stay consistent in side layouts',
160160
}
161161
})
162162

163-
expect(minHeights.component).toBeGreaterThan(0)
164-
expect(minHeights.styles).toBeGreaterThan(0)
163+
expect(minHeights.component).toBeGreaterThanOrEqual(0)
164+
expect(minHeights.styles).toBeGreaterThanOrEqual(0)
165165
expect(Math.abs(minHeights.component - minHeights.styles)).toBeLessThanOrEqual(1)
166166
}
167167
})

src/app.js

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ const appGrid = document.querySelector('.app-grid')
1616
const appGridLayoutButtons = document.querySelectorAll('[data-app-grid-layout]')
1717
const appThemeButtons = document.querySelectorAll('[data-app-theme]')
1818
const panelCollapseButtons = document.querySelectorAll('[data-panel-collapse]')
19-
const editorsStack = document.querySelector('.panels-stack--editors')
2019
const componentPanel = document.getElementById('component-panel')
2120
const stylesPanel = document.getElementById('styles-panel')
2221
const previewPanel = document.getElementById('preview-panel')
@@ -189,23 +188,6 @@ const syncPanelCollapseButtons = () => {
189188
}
190189
}
191190

192-
const syncSidePreviewHeight = () => {
193-
if (!appGrid || !editorsStack) {
194-
return
195-
}
196-
197-
const layout = getCurrentLayout()
198-
if (layout !== 'preview-right' && layout !== 'preview-left') {
199-
appGrid.style.removeProperty('--side-editors-height')
200-
return
201-
}
202-
203-
const height = Math.round(editorsStack.getBoundingClientRect().height)
204-
if (height > 0) {
205-
appGrid.style.setProperty('--side-editors-height', `${height}px`)
206-
}
207-
}
208-
209191
const applyPanelCollapseState = () => {
210192
normalizePanelCollapseState()
211193

@@ -253,6 +235,7 @@ const applyPanelCollapseState = () => {
253235
'app-grid--preview-collapsed-horizontal',
254236
panelCollapseState.preview && previewAxis === 'horizontal',
255237
)
238+
appGrid.classList.toggle('app-grid--preview-collapsed', panelCollapseState.preview)
256239
appGrid.classList.toggle('app-grid--component-collapsed', panelCollapseState.component)
257240
appGrid.classList.toggle('app-grid--styles-collapsed', panelCollapseState.styles)
258241
appGrid.classList.toggle(
@@ -265,7 +248,6 @@ const applyPanelCollapseState = () => {
265248
)
266249

267250
syncPanelCollapseButtons()
268-
syncSidePreviewHeight()
269251
}
270252

271253
const togglePanelCollapse = panelName => {
@@ -692,13 +674,6 @@ if (typeof compactViewportMediaQuery.addEventListener === 'function') {
692674
compactViewportMediaQuery.onchange = handleCompactViewportChange
693675
}
694676

695-
if (typeof ResizeObserver !== 'undefined' && editorsStack) {
696-
const sidePreviewHeightObserver = new ResizeObserver(() => {
697-
syncSidePreviewHeight()
698-
})
699-
sidePreviewHeightObserver.observe(editorsStack)
700-
}
701-
702677
applyAppGridLayout(getInitialAppGridLayout(), { persist: false })
703678
applyTheme(getInitialTheme(), { persist: false })
704679
applyPanelCollapseState()

src/styles/base.css

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,10 @@
176176
box-sizing: border-box;
177177
}
178178

179+
html {
180+
height: 100%;
181+
}
182+
179183
.sr-only {
180184
position: absolute;
181185
width: 1px;
@@ -191,7 +195,19 @@
191195
body {
192196
margin: 0;
193197
padding: 0;
194-
min-height: 100vh;
198+
height: 100dvh;
199+
min-height: 100dvh;
200+
display: grid;
201+
grid-template-rows: auto minmax(0, 1fr) auto;
202+
overflow: hidden;
195203
background: linear-gradient(180deg, var(--app-bg-start) 0%, var(--app-bg-end) 100%);
196204
color: var(--shell-text);
197205
}
206+
207+
@media (max-width: 900px) {
208+
body {
209+
height: auto;
210+
min-height: 100dvh;
211+
overflow: auto;
212+
}
213+
}

src/styles/layout-shell.css

Lines changed: 63 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,24 @@
6868
}
6969

7070
.app-grid {
71-
--panel-max-height-default: clamp(360px, calc(100dvh - 290px), 680px);
72-
--panel-max-height-side: clamp(420px, calc(100dvh - 230px), 860px);
71+
--expanded-panel-min-height: 360px;
72+
--editors-row-flex: 1.25fr;
73+
--preview-row-flex: 0.75fr;
7374
display: grid;
7475
grid-template-columns: repeat(2, minmax(320px, 1fr));
76+
grid-template-rows: auto minmax(0, var(--editors-row-flex)) minmax(
77+
0,
78+
var(--preview-row-flex)
79+
);
7580
grid-template-areas:
7681
'layout-controls layout-controls'
7782
'editors editors'
7883
'preview preview';
7984
gap: 18px;
8085
padding: 24px;
86+
min-height: 0;
87+
height: 100%;
88+
overflow: hidden;
8189
}
8290

8391
.panels-stack {
@@ -88,8 +96,10 @@
8896
grid-area: editors;
8997
display: grid;
9098
grid-template-columns: repeat(2, minmax(320px, 1fr));
99+
grid-template-rows: minmax(0, 1fr);
91100
gap: 18px;
92101
min-width: 0;
102+
min-height: 0;
93103
}
94104

95105
.app-grid.app-grid--component-collapsed-horizontal:not(.app-grid--preview-right):not(
@@ -109,12 +119,11 @@
109119
.app-grid.app-grid--component-collapsed-horizontal.app-grid--styles-collapsed-horizontal:not(
110120
.app-grid--preview-right
111121
):not(.app-grid--preview-left) {
112-
grid-template-rows: auto auto minmax(320px, 1fr);
122+
grid-template-rows: auto auto minmax(0, 1fr);
113123
grid-template-areas:
114124
'layout-controls layout-controls'
115125
'editors editors'
116126
'preview preview';
117-
min-height: max(520px, calc(100dvh - 210px));
118127
}
119128

120129
.app-grid.app-grid--component-collapsed-horizontal.app-grid--styles-collapsed-horizontal:not(
@@ -125,13 +134,18 @@
125134
justify-content: start;
126135
}
127136

137+
.app-grid.app-grid--preview-collapsed:not(.app-grid--preview-right):not(
138+
.app-grid--preview-left
139+
) {
140+
grid-template-rows: auto minmax(0, 1fr) auto;
141+
}
142+
128143
.app-grid--preview-right {
129144
grid-template-columns: repeat(2, minmax(320px, 1fr));
130145
grid-template-rows: auto minmax(0, 1fr);
131146
grid-template-areas:
132147
'layout-controls layout-controls'
133148
'editors preview';
134-
min-height: max(520px, calc(100dvh - 210px));
135149
}
136150

137151
.app-grid--preview-right .panels-stack--editors {
@@ -167,7 +181,6 @@
167181
grid-template-areas:
168182
'layout-controls layout-controls'
169183
'preview editors';
170-
min-height: max(520px, calc(100dvh - 210px));
171184
}
172185

173186
.app-grid--preview-left .panels-stack--editors {
@@ -257,26 +270,50 @@
257270
}
258271

259272
.component-panel {
260-
max-height: var(--panel-max-height-default);
273+
height: 100%;
274+
min-height: var(--expanded-panel-min-height);
275+
}
276+
277+
.component-panel.panel--collapsed-horizontal,
278+
.component-panel.panel--collapsed-vertical {
261279
min-height: 0;
262280
}
263281

264282
.styles-panel {
265-
max-height: var(--panel-max-height-default);
283+
height: 100%;
284+
min-height: var(--expanded-panel-min-height);
285+
}
286+
287+
.styles-panel.panel--collapsed-horizontal,
288+
.styles-panel.panel--collapsed-vertical {
266289
min-height: 0;
267290
}
268291

269292
.preview-panel {
270-
max-height: var(--panel-max-height-default);
271293
grid-area: preview;
272294
position: relative;
295+
height: 100%;
296+
min-height: var(--expanded-panel-min-height);
297+
max-height: 100%;
298+
overflow: hidden;
299+
}
300+
301+
.preview-panel .panel-content {
302+
min-height: 0;
303+
max-height: 100%;
304+
overflow: hidden;
305+
}
306+
307+
.preview-panel.panel--collapsed-horizontal,
308+
.preview-panel.panel--collapsed-vertical {
309+
min-height: 0;
273310
}
274311

275312
.app-grid--preview-right .preview-panel,
276313
.app-grid--preview-left .preview-panel {
277314
min-height: 0;
278-
height: var(--side-editors-height, auto);
279-
max-height: var(--side-editors-height, var(--panel-max-height-side));
315+
height: 100%;
316+
max-height: none;
280317
overflow: hidden;
281318
}
282319

@@ -289,24 +326,16 @@
289326
.app-grid--preview-right .styles-panel,
290327
.app-grid--preview-left .component-panel,
291328
.app-grid--preview-left .styles-panel {
329+
height: 100%;
292330
min-height: 0;
293-
max-height: var(--panel-max-height-side);
294-
}
295-
296-
.app-grid--preview-right
297-
.component-panel:not(.panel--collapsed-vertical):not(.panel--collapsed-horizontal),
298-
.app-grid--preview-right
299-
.styles-panel:not(.panel--collapsed-vertical):not(.panel--collapsed-horizontal),
300-
.app-grid--preview-left
301-
.component-panel:not(.panel--collapsed-vertical):not(.panel--collapsed-horizontal),
302-
.app-grid--preview-left
303-
.styles-panel:not(.panel--collapsed-vertical):not(.panel--collapsed-horizontal) {
304-
min-height: 360px;
331+
max-height: none;
305332
}
306333

307334
@media (max-width: 900px) {
308335
.app-grid {
309336
grid-template-columns: minmax(0, 1fr);
337+
grid-template-rows: auto auto auto;
338+
height: auto;
310339
grid-template-areas:
311340
'layout-controls'
312341
'editors'
@@ -322,7 +351,17 @@
322351
.app-grid--preview-left .component-panel,
323352
.app-grid--preview-left .styles-panel,
324353
.app-grid--preview-left .preview-panel {
325-
max-height: none;
354+
height: auto;
355+
min-height: var(--expanded-panel-min-height);
356+
}
357+
358+
.component-panel.panel--collapsed-horizontal,
359+
.component-panel.panel--collapsed-vertical,
360+
.styles-panel.panel--collapsed-horizontal,
361+
.styles-panel.panel--collapsed-vertical,
362+
.preview-panel.panel--collapsed-horizontal,
363+
.preview-panel.panel--collapsed-vertical {
364+
min-height: 0;
326365
}
327366

328367
.panels-stack--editors {

src/styles/panels-editor.css

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@
88
overflow: hidden;
99
}
1010

11-
.panel.preview {
12-
min-height: 280px;
13-
}
14-
1511
.panel-header {
1612
display: flex;
1713
align-items: center;

src/styles/preview-controls.css

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
.preview-host {
22
--preview-host-display: block;
3-
--preview-host-flex: 1 1 auto;
4-
--preview-host-min-height: 180px;
3+
--preview-host-flex: 1 1 0%;
4+
--preview-host-min-height: 0;
55
--preview-host-padding: 18px;
66
--preview-host-overflow: auto;
77
--preview-host-position: relative;
88
--preview-host-z-index: 1;
99
display: var(--preview-host-display);
1010
flex: var(--preview-host-flex);
1111
min-height: var(--preview-host-min-height);
12+
max-height: 100%;
1213
padding: var(--preview-host-padding);
1314
overflow: var(--preview-host-overflow);
1415
position: var(--preview-host-position);

0 commit comments

Comments
 (0)