Skip to content

Commit 7e86c46

Browse files
refactor: some cleanup.
1 parent 5c5009b commit 7e86c46

6 files changed

Lines changed: 167 additions & 51 deletions

File tree

playwright/app.spec.ts

Lines changed: 61 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,17 @@ const setStylesEditorSource = async (page: Page, source: string) => {
3232
const getCollapseButton = (page: Page, panelName: 'component' | 'styles' | 'preview') =>
3333
page.locator(`#collapse-${panelName}`)
3434

35+
const getToolsButton = (page: Page, panelName: 'component' | 'styles') =>
36+
page.locator(`#tools-${panelName}`)
37+
38+
const ensurePanelToolsVisible = async (page: Page, panelName: 'component' | 'styles') => {
39+
const button = getToolsButton(page, panelName)
40+
const isPressed = await button.getAttribute('aria-pressed')
41+
if (isPressed !== 'true') {
42+
await button.click()
43+
}
44+
}
45+
3546
const expectCollapseButtonState = async (
3647
page: Page,
3748
panelName: 'component' | 'styles' | 'preview',
@@ -263,9 +274,43 @@ test('does not persist panel collapse state across reload', async ({ page }) =>
263274
})
264275
})
265276

277+
test('gear tools toggles default inactive and switch active/inactive per panel', async ({
278+
page,
279+
}) => {
280+
await waitForInitialRender(page)
281+
282+
const componentPanel = page.locator('#component-panel')
283+
const stylesPanel = page.locator('#styles-panel')
284+
const componentTools = getToolsButton(page, 'component')
285+
const stylesTools = getToolsButton(page, 'styles')
286+
287+
await expect(componentPanel).toHaveClass(/panel--tools-hidden/)
288+
await expect(stylesPanel).toHaveClass(/panel--tools-hidden/)
289+
await expect(componentTools).toHaveAttribute('aria-pressed', 'false')
290+
await expect(stylesTools).toHaveAttribute('aria-pressed', 'false')
291+
292+
await componentTools.click()
293+
await expect(componentPanel).not.toHaveClass(/panel--tools-hidden/)
294+
await expect(componentTools).toHaveAttribute('aria-pressed', 'true')
295+
await expect(componentTools).toHaveAttribute('title', 'Hide component tools')
296+
297+
await componentTools.click()
298+
await expect(componentPanel).toHaveClass(/panel--tools-hidden/)
299+
await expect(componentTools).toHaveAttribute('aria-pressed', 'false')
300+
await expect(componentTools).toHaveAttribute('title', 'Show component tools')
301+
302+
await stylesTools.click()
303+
await expect(stylesPanel).not.toHaveClass(/panel--tools-hidden/)
304+
await expect(stylesTools).toHaveAttribute('aria-pressed', 'true')
305+
await expect(stylesTools).toHaveAttribute('title', 'Hide styles tools')
306+
})
307+
266308
test('renders in react mode with css modules', async ({ page }) => {
267309
await waitForInitialRender(page)
268310

311+
await ensurePanelToolsVisible(page, 'component')
312+
await ensurePanelToolsVisible(page, 'styles')
313+
269314
await page.getByLabel('ShadowRoot (open)').uncheck()
270315
await page.locator('#render-mode').selectOption('react')
271316
await page.locator('#style-mode').selectOption('module')
@@ -326,21 +371,21 @@ test('jsx syntax errors affect status but not diagnostics toggle severity', asyn
326371
test('requires render button when auto render is disabled', async ({ page }) => {
327372
await waitForInitialRender(page)
328373

374+
await ensurePanelToolsVisible(page, 'component')
375+
await ensurePanelToolsVisible(page, 'styles')
376+
329377
const autoRenderToggle = page.getByLabel('Auto render')
330378
const renderButton = page.getByRole('button', { name: 'Render' })
331379
const styleMode = page.locator('#style-mode')
332-
const styleWarning = page.locator('#style-warning')
333380

334-
await expect(styleWarning).toHaveText('')
335381
await autoRenderToggle.uncheck()
336382
await expect(renderButton).toBeVisible()
337383

338384
await styleMode.selectOption('module')
339-
await expect(styleWarning).toHaveText('')
340385

341386
await renderButton.click()
342387
await expect(page.locator('#status')).toHaveText('Rendered')
343-
await expect(styleWarning).toContainText('CSS Modules are compiled in-browser')
388+
await expect(page.locator('#preview-host pre')).toHaveCount(0)
344389
})
345390

346391
test('persists layout and theme across reload', async ({ page }) => {
@@ -361,30 +406,30 @@ test('persists layout and theme across reload', async ({ page }) => {
361406
test('renders with less style mode', async ({ page }) => {
362407
await waitForInitialRender(page)
363408

409+
await ensurePanelToolsVisible(page, 'styles')
410+
364411
await page.getByLabel('ShadowRoot (open)').uncheck()
365412
await page.locator('#style-mode').selectOption('less')
366413
await expect(page.locator('#status')).toHaveText('Rendered')
367-
await expect(page.locator('#style-warning')).toContainText(
368-
'Less is compiled in-browser via @knighted/css/browser.',
369-
)
370414
await expectPreviewHasRenderedContent(page)
371415
})
372416

373417
test('renders with sass style mode', async ({ page }) => {
374418
await waitForInitialRender(page)
375419

420+
await ensurePanelToolsVisible(page, 'styles')
421+
376422
await page.getByLabel('ShadowRoot (open)').uncheck()
377423
await page.locator('#style-mode').selectOption('sass')
378424
await expect(page.locator('#status')).toHaveText('Rendered')
379-
await expect(page.locator('#style-warning')).toContainText(
380-
'Sass is compiled in-browser via @knighted/css/browser.',
381-
)
382425
await expectPreviewHasRenderedContent(page)
383426
})
384427

385428
test('style compilation errors populate styles diagnostics scope', async ({ page }) => {
386429
await waitForInitialRender(page)
387430

431+
await ensurePanelToolsVisible(page, 'styles')
432+
388433
await page.locator('#style-mode').selectOption('sass')
389434
await setStylesEditorSource(page, '.card { color: $missing; }')
390435

@@ -443,6 +488,8 @@ test('clearing styles keeps diagnostics error state but resets status styling',
443488
}) => {
444489
await waitForInitialRender(page)
445490

491+
await ensurePanelToolsVisible(page, 'component')
492+
446493
await setComponentEditorSource(
447494
page,
448495
["const count: number = 'oops'", 'const App = () => <button>ready</button>'].join(
@@ -477,6 +524,8 @@ test('clear component diagnostics removes type errors and restores rendered stat
477524
}) => {
478525
await waitForInitialRender(page)
479526

527+
await ensurePanelToolsVisible(page, 'component')
528+
480529
await setComponentEditorSource(
481530
page,
482531
["const count: number = 'oops'", 'const App = () => <button>ready</button>'].join(
@@ -507,6 +556,8 @@ test('clear component diagnostics removes type errors and restores rendered stat
507556
test('clear all diagnostics removes style compile diagnostics', async ({ page }) => {
508557
await waitForInitialRender(page)
509558

559+
await ensurePanelToolsVisible(page, 'styles')
560+
510561
await page.locator('#style-mode').selectOption('sass')
511562
await setStylesEditorSource(page, '.card { color: $missing; }')
512563

src/app.js

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const statusNode = document.getElementById('status')
1515
const appGrid = document.querySelector('.app-grid')
1616
const appGridLayoutButtons = document.querySelectorAll('[data-app-grid-layout]')
1717
const appThemeButtons = document.querySelectorAll('[data-app-theme]')
18+
const editorToolsButtons = document.querySelectorAll('[data-editor-tools-toggle]')
1819
const panelCollapseButtons = document.querySelectorAll('[data-panel-collapse]')
1920
const componentPanel = document.getElementById('component-panel')
2021
const stylesPanel = document.getElementById('styles-panel')
@@ -31,7 +32,6 @@ const clearStylesButton = document.getElementById('clear-styles')
3132
const shadowToggle = document.getElementById('shadow-toggle')
3233
const jsxEditor = document.getElementById('jsx-editor')
3334
const cssEditor = document.getElementById('css-editor')
34-
const styleWarning = document.getElementById('style-warning')
3535
const diagnosticsToggle = document.getElementById('diagnostics-toggle')
3636
const diagnosticsDrawer = document.getElementById('diagnostics-drawer')
3737
const diagnosticsClose = document.getElementById('diagnostics-close')
@@ -144,6 +144,28 @@ const panelCollapseState = {
144144
preview: false,
145145
}
146146

147+
const panelToolsState = {
148+
component: false,
149+
styles: false,
150+
}
151+
152+
const applyEditorToolsVisibility = () => {
153+
componentPanel?.classList.toggle('panel--tools-hidden', !panelToolsState.component)
154+
stylesPanel?.classList.toggle('panel--tools-hidden', !panelToolsState.styles)
155+
156+
for (const button of editorToolsButtons) {
157+
const panelName = button.dataset.editorToolsToggle
158+
if (!panelName || !(panelName in panelToolsState)) {
159+
continue
160+
}
161+
162+
const isVisible = panelToolsState[panelName]
163+
button.setAttribute('aria-pressed', isVisible ? 'true' : 'false')
164+
button.setAttribute('aria-label', `${isVisible ? 'Hide' : 'Show'} ${panelName} tools`)
165+
button.setAttribute('title', `${isVisible ? 'Hide' : 'Show'} ${panelName} tools`)
166+
}
167+
}
168+
147169
const normalizePanelCollapseState = () => {
148170
const collapsedPanels = Object.entries(panelCollapseState)
149171
.filter(([, isCollapsed]) => isCollapsed)
@@ -410,7 +432,6 @@ renderRuntime = createRenderRuntimeController({
410432
renderMode,
411433
styleMode,
412434
shadowToggle,
413-
styleWarning,
414435
getCssSource: () => getCssSource(),
415436
getJsxSource: () => getJsxSource(),
416437
getPreviewHost: () => previewHost,
@@ -653,6 +674,18 @@ for (const button of appThemeButtons) {
653674
})
654675
}
655676

677+
for (const button of editorToolsButtons) {
678+
button.addEventListener('click', () => {
679+
const panelName = button.dataset.editorToolsToggle
680+
if (!panelName || !(panelName in panelToolsState)) {
681+
return
682+
}
683+
684+
panelToolsState[panelName] = !panelToolsState[panelName]
685+
applyEditorToolsVisibility()
686+
})
687+
}
688+
656689
for (const button of panelCollapseButtons) {
657690
button.addEventListener('click', () => {
658691
const panelName = button.dataset.panelCollapse
@@ -676,6 +709,7 @@ if (typeof compactViewportMediaQuery.addEventListener === 'function') {
676709

677710
applyAppGridLayout(getInitialAppGridLayout(), { persist: false })
678711
applyTheme(getInitialTheme(), { persist: false })
712+
applyEditorToolsVisibility()
679713
applyPanelCollapseState()
680714

681715
updateRenderButtonVisibility()

src/index.html

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ <h1>
130130
</div>
131131

132132
<div class="panels-stack panels-stack--editors">
133-
<section class="panel component-panel" id="component-panel">
133+
<section class="panel component-panel panel--tools-hidden" id="component-panel">
134134
<div class="panel-header panel-header--grid">
135135
<h2>Component</h2>
136136
<div class="controls controls--quick-actions panel-header-quick-actions">
@@ -151,6 +151,21 @@ <h2>Component</h2>
151151
</svg>
152152
<span class="panel-collapse-toggle__label">Collapse</span>
153153
</button>
154+
<button
155+
class="icon-button editor-tools-toggle"
156+
id="tools-component"
157+
type="button"
158+
data-editor-tools-toggle="component"
159+
aria-pressed="false"
160+
title="Show component tools"
161+
aria-label="Show component tools"
162+
>
163+
<svg viewBox="0 0 24 24" aria-hidden="true">
164+
<path
165+
d="M20.017 14.669L23 13.564l-.012-3.208-2.996-1.085a8.455 8.455 0 0 0-.437-1.05l1.329-2.893-2.277-2.26-2.886 1.351a8.396 8.396 0 0 0-1.052-.436L13.564 1l-3.208.012-1.085 2.996a8.485 8.485 0 0 0-1.05.437L5.328 3.116l-2.26 2.276L4.419 8.28a8.378 8.378 0 0 0-.436 1.052L1 10.436l.012 3.208 2.996 1.085a8.46 8.46 0 0 0 .437 1.05l-1.329 2.893 2.276 2.26 2.887-1.351a8.383 8.383 0 0 0 1.052.436L10.436 23l3.208-.012 1.085-2.996a8.478 8.478 0 0 0 1.05-.437l2.893 1.329 2.26-2.276-1.351-2.887a8.382 8.382 0 0 0 .436-1.052zm-.287 3.73l-1.275 1.285-2.694-1.238-.429.215a7.612 7.612 0 0 1-.928.385l-.452.156-1.01 2.789-1.81.007-1.03-2.779-.456-.151a7.394 7.394 0 0 1-.926-.385l-.43-.21-2.688 1.257-1.286-1.275 1.239-2.695-.216-.43a7.551 7.551 0 0 1-.386-.926l-.155-.452-2.79-1.01-.005-1.81 2.777-1.03.152-.456a7.46 7.46 0 0 1 .384-.927l.212-.43L4.27 5.601l1.275-1.285 2.694 1.238.429-.215a7.612 7.612 0 0 1 .928-.385l.452-.156 1.01-2.789 1.81-.007 1.03 2.779.456.151a7.35 7.35 0 0 1 .925.385l.43.211L18.4 4.27l1.285 1.275-1.239 2.695.216.43a7.551 7.551 0 0 1 .386.926l.155.452 2.79 1.01.005 1.81-2.777 1.03-.152.456a7.46 7.46 0 0 1-.384.927l-.212.43zM12 7.2a4.8 4.8 0 1 0 4.8 4.8A4.8 4.8 0 0 0 12 7.2zm0 8.6a3.8 3.8 0 1 1 3.8-3.8 3.804 3.804 0 0 1-3.8 3.8z"
166+
></path>
167+
</svg>
168+
</button>
154169
<button
155170
class="icon-button"
156171
id="copy-component"
@@ -208,7 +223,7 @@ <h2>Component</h2>
208223
</div>
209224
</section>
210225

211-
<section class="panel styles-panel" id="styles-panel">
226+
<section class="panel styles-panel panel--tools-hidden" id="styles-panel">
212227
<div class="panel-header panel-header--grid">
213228
<h2>Styles</h2>
214229
<div class="controls controls--quick-actions panel-header-quick-actions">
@@ -229,6 +244,21 @@ <h2>Styles</h2>
229244
</svg>
230245
<span class="panel-collapse-toggle__label">Collapse</span>
231246
</button>
247+
<button
248+
class="icon-button editor-tools-toggle"
249+
id="tools-styles"
250+
type="button"
251+
data-editor-tools-toggle="styles"
252+
aria-pressed="false"
253+
title="Show styles tools"
254+
aria-label="Show styles tools"
255+
>
256+
<svg viewBox="0 0 24 24" aria-hidden="true">
257+
<path
258+
d="M20.017 14.669L23 13.564l-.012-3.208-2.996-1.085a8.455 8.455 0 0 0-.437-1.05l1.329-2.893-2.277-2.26-2.886 1.351a8.396 8.396 0 0 0-1.052-.436L13.564 1l-3.208.012-1.085 2.996a8.485 8.485 0 0 0-1.05.437L5.328 3.116l-2.26 2.276L4.419 8.28a8.378 8.378 0 0 0-.436 1.052L1 10.436l.012 3.208 2.996 1.085a8.46 8.46 0 0 0 .437 1.05l-1.329 2.893 2.276 2.26 2.887-1.351a8.383 8.383 0 0 0 1.052.436L10.436 23l3.208-.012 1.085-2.996a8.478 8.478 0 0 0 1.05-.437l2.893 1.329 2.26-2.276-1.351-2.887a8.382 8.382 0 0 0 .436-1.052zm-.287 3.73l-1.275 1.285-2.694-1.238-.429.215a7.612 7.612 0 0 1-.928.385l-.452.156-1.01 2.789-1.81.007-1.03-2.779-.456-.151a7.394 7.394 0 0 1-.926-.385l-.43-.21-2.688 1.257-1.286-1.275 1.239-2.695-.216-.43a7.551 7.551 0 0 1-.386-.926l-.155-.452-2.79-1.01-.005-1.81 2.777-1.03.152-.456a7.46 7.46 0 0 1 .384-.927l.212-.43L4.27 5.601l1.275-1.285 2.694 1.238.429-.215a7.612 7.612 0 0 1 .928-.385l.452-.156 1.01-2.789 1.81-.007 1.03 2.779.456.151a7.35 7.35 0 0 1 .925.385l.43.211L18.4 4.27l1.285 1.275-1.239 2.695.216.43a7.551 7.551 0 0 1 .386.926l.155.452 2.79 1.01.005 1.81-2.777 1.03-.152.456a7.46 7.46 0 0 1-.384.927l-.212.43zM12 7.2a4.8 4.8 0 1 0 4.8 4.8A4.8 4.8 0 0 0 12 7.2zm0 8.6a3.8 3.8 0 1 1 3.8-3.8 3.804 3.804 0 0 1-3.8 3.8z"
259+
></path>
260+
</svg>
261+
</button>
232262
<button
233263
class="icon-button"
234264
id="copy-styles"
@@ -275,7 +305,6 @@ <h2>Styles</h2>
275305
</div>
276306
<div class="panel-content" id="styles-panel-content">
277307
<textarea id="css-editor" spellcheck="false"></textarea>
278-
<div class="panel-footer" id="style-warning"></div>
279308
</div>
280309
</section>
281310
</div>

src/modules/defaults.js

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export const defaultJsx = [
55
'}',
66
'',
77
'const CounterButton = ({ label, onClick }: CounterButtonProps) => (',
8-
' <button id="counter-button" type="button" onClick={onClick}>',
8+
' <button class="counter-button" type="button" onClick={onClick}>',
99
' {label}',
1010
' </button>',
1111
')',
@@ -34,10 +34,9 @@ export const defaultReactJsx = [
3434
'',
3535
'const CounterButton = ({ label, active, onClick }: CounterButtonProps) => (',
3636
' <button',
37-
' id="counter-button"',
3837
' type="button"',
3938
' data-active={active ? "true" : "false"}',
40-
' className={active ? "is-even" : ""}',
39+
' className={active ? "counter-button is-even" : "counter-button"}',
4140
' onClick={onClick}',
4241
' >',
4342
' {label}',
@@ -62,7 +61,7 @@ export const defaultReactJsx = [
6261
'',
6362
].join('\n')
6463

65-
export const defaultCss = `#counter-button {
64+
export const defaultCss = `.counter-button {
6665
margin: 0;
6766
padding: 0.75rem 1rem;
6867
border: 1px solid #3558b8;
@@ -74,20 +73,20 @@ export const defaultCss = `#counter-button {
7473
transition: background-color 120ms ease;
7574
}
7675
77-
#counter-button:hover {
76+
.counter-button:hover {
7877
background: #dce6ff;
7978
}
8079
81-
#counter-button[data-active='true'] {
80+
.counter-button[data-active='true'] {
8281
background: #3558b8;
8382
color: #fff;
8483
}
8584
86-
#counter-button.is-even {
85+
.counter-button.is-even {
8786
border-style: dashed;
8887
}
8988
90-
#counter-button:focus-visible {
89+
.counter-button:focus-visible {
9190
outline: 2px solid #6a84d8;
9291
outline-offset: 2px;
9392
}

0 commit comments

Comments
 (0)