Skip to content

Commit 73d913c

Browse files
feat: sync style-mode. (#49)
1 parent 919b63a commit 73d913c

4 files changed

Lines changed: 126 additions & 8 deletions

File tree

playwright/github-pr-drawer.spec.ts

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1133,7 +1133,7 @@ test('Reloaded active PR context from URL metadata keeps Push mode and status re
11331133
expect(upsertRequests[1]?.body.message).toBe(defaultCommitMessage)
11341134
})
11351135

1136-
test('Reloaded active PR context syncs editor content from GitHub branch', async ({
1136+
test('Reloaded active PR context syncs editor content from GitHub branch and restores style mode', async ({
11371137
page,
11381138
}) => {
11391139
const remoteComponentSource = 'export const App = () => <main>Synced from PR</main>'
@@ -1237,6 +1237,7 @@ test('Reloaded active PR context syncs editor content from GitHub branch', async
12371237
componentFilePath: 'examples/component/App.tsx',
12381238
stylesFilePath: 'examples/styles/app.css',
12391239
renderMode: 'react',
1240+
styleMode: 'sass',
12401241
baseBranch: 'main',
12411242
headBranch: 'develop/open-pr-test',
12421243
prTitle: 'Existing PR context from storage',
@@ -1249,6 +1250,7 @@ test('Reloaded active PR context syncs editor content from GitHub branch', async
12491250

12501251
await connectByotWithSingleRepo(page)
12511252
await expect(page.getByLabel('Render mode')).toHaveValue('react')
1253+
await expect(page.getByLabel('Style mode')).toHaveValue('sass')
12521254

12531255
await expect
12541256
.poll(async () =>
@@ -1269,6 +1271,73 @@ test('Reloaded active PR context syncs editor content from GitHub branch', async
12691271
})
12701272
})
12711273

1274+
test('Reloaded active PR context falls back to css style mode for unsupported value', async ({
1275+
page,
1276+
}) => {
1277+
await page.route('https://api.github.com/user/repos**', async route => {
1278+
await route.fulfill({
1279+
status: 200,
1280+
contentType: 'application/json',
1281+
body: JSON.stringify([
1282+
{
1283+
id: 11,
1284+
owner: { login: 'knightedcodemonkey' },
1285+
name: 'develop',
1286+
full_name: 'knightedcodemonkey/develop',
1287+
default_branch: 'main',
1288+
permissions: { push: true },
1289+
},
1290+
]),
1291+
})
1292+
})
1293+
1294+
await mockRepositoryBranches(page, {
1295+
'knightedcodemonkey/develop': ['main', 'release', 'develop/open-pr-test'],
1296+
})
1297+
1298+
await page.route(
1299+
'https://api.github.com/repos/knightedcodemonkey/develop/pulls/2',
1300+
async route => {
1301+
await route.fulfill({
1302+
status: 200,
1303+
contentType: 'application/json',
1304+
body: JSON.stringify({
1305+
number: 2,
1306+
state: 'open',
1307+
title: 'Existing PR context from storage',
1308+
html_url: 'https://github.com/knightedcodemonkey/develop/pull/2',
1309+
head: { ref: 'develop/open-pr-test' },
1310+
base: { ref: 'main' },
1311+
}),
1312+
})
1313+
},
1314+
)
1315+
1316+
await waitForAppReady(page, `${appEntryPath}?feature-ai=true`)
1317+
1318+
await page.evaluate(() => {
1319+
localStorage.setItem(
1320+
'knighted:develop:github-pr-config:knightedcodemonkey/develop',
1321+
JSON.stringify({
1322+
componentFilePath: 'examples/component/App.tsx',
1323+
stylesFilePath: 'examples/styles/app.css',
1324+
renderMode: 'react',
1325+
styleMode: 'scss',
1326+
baseBranch: 'main',
1327+
headBranch: 'develop/open-pr-test',
1328+
prTitle: 'Existing PR context from storage',
1329+
prBody: 'Saved body',
1330+
isActivePr: true,
1331+
pullRequestUrl: 'https://github.com/knightedcodemonkey/develop/pull/2',
1332+
}),
1333+
)
1334+
})
1335+
1336+
await connectByotWithSingleRepo(page)
1337+
await expect(page.getByLabel('Render mode')).toHaveValue('react')
1338+
await expect(page.getByLabel('Style mode')).toHaveValue('css')
1339+
})
1340+
12721341
test('Open PR drawer validates unsafe filepaths', async ({ page }) => {
12731342
await waitForAppReady(page, `${appEntryPath}?feature-ai=true`)
12741343
await connectByotWithSingleRepo(page)

playwright/helpers/app-test-helpers.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,8 +226,6 @@ export const connectByotWithSingleRepo = async (page: Page) => {
226226
const repoSelect = page.getByLabel('Pull request repository')
227227
await expect(repoSelect).toHaveValue('knightedcodemonkey/develop')
228228

229-
await expect(repoSelect).toHaveValue('knightedcodemonkey/develop')
230-
231229
await expect(
232230
page.getByRole('button', {
233231
name: /Open pull request|Push commit to active pull request branch/,

src/app.js

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,7 @@ prDrawerController = createGitHubPrDrawer({
815815
getStylesSource: () => getCssSource(),
816816
getTopLevelDeclarations,
817817
getRenderMode: () => renderMode.value,
818+
getStyleMode: () => styleMode.value,
818819
getDrawerSide: () => {
819820
const layout = getCurrentLayout()
820821
return layout === 'preview-left' ? 'left' : 'right'
@@ -872,6 +873,9 @@ prDrawerController = createGitHubPrDrawer({
872873
onRestoreRenderMode: mode => {
873874
applyRenderMode({ mode, fromActivePrContext: true })
874875
},
876+
onRestoreStyleMode: mode => {
877+
applyStyleMode({ mode })
878+
},
875879
})
876880

877881
prDrawerController.setToken(githubAiContextState.token)
@@ -926,6 +930,13 @@ const getStyleEditorLanguage = mode => {
926930
return 'css'
927931
}
928932

933+
const normalizeStyleMode = mode => {
934+
if (mode === 'module') return 'module'
935+
if (mode === 'less') return 'less'
936+
if (mode === 'sass') return 'sass'
937+
return 'css'
938+
}
939+
929940
const createEditorHost = textarea => {
930941
const host = document.createElement('div')
931942
host.className = 'editor-host'
@@ -1437,21 +1448,32 @@ function applyRenderMode({ mode, fromActivePrContext = false }) {
14371448
maybeRender()
14381449
}
14391450

1440-
renderMode.addEventListener('change', () => {
1441-
applyRenderMode({ mode: renderMode.value })
1442-
})
1443-
styleMode.addEventListener('change', () => {
1451+
function applyStyleMode({ mode }) {
1452+
const nextMode = normalizeStyleMode(mode)
1453+
1454+
if (styleMode.value !== nextMode) {
1455+
styleMode.value = nextMode
1456+
}
1457+
14441458
resetDiagnosticsFlow()
14451459

14461460
if (cssCodeEditor) {
14471461
suppressEditorChangeSideEffects = true
14481462
try {
1449-
cssCodeEditor.setLanguage(getStyleEditorLanguage(styleMode.value))
1463+
cssCodeEditor.setLanguage(getStyleEditorLanguage(nextMode))
14501464
} finally {
14511465
suppressEditorChangeSideEffects = false
14521466
}
14531467
}
1468+
14541469
maybeRender()
1470+
}
1471+
1472+
renderMode.addEventListener('change', () => {
1473+
applyRenderMode({ mode: renderMode.value })
1474+
})
1475+
styleMode.addEventListener('change', () => {
1476+
applyStyleMode({ mode: styleMode.value })
14551477
})
14561478
shadowToggle.addEventListener('change', maybeRender)
14571479
autoRenderToggle.addEventListener('change', () => {

src/modules/github-pr-drawer.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,18 @@ const defaultPrConfig = {
2525
const defaultCommitMessage = 'chore: sync editor updates from @knighted/develop'
2626

2727
const supportedRenderModes = new Set(['dom', 'react'])
28+
const supportedStyleModes = new Set(['css', 'module', 'less', 'sass'])
2829

2930
const normalizeRenderMode = value => {
3031
const mode = toSafeText(value).toLowerCase()
3132
return supportedRenderModes.has(mode) ? mode : 'dom'
3233
}
3334

35+
const normalizeStyleMode = value => {
36+
const mode = toSafeText(value).toLowerCase()
37+
return supportedStyleModes.has(mode) ? mode : 'css'
38+
}
39+
3440
const getRepositoryPrConfigStorageKey = repositoryFullName =>
3541
`${prConfigStoragePrefix}${repositoryFullName}`
3642

@@ -133,6 +139,7 @@ const getActiveRepositoryPrContext = repositoryFullName => {
133139
componentFilePath: componentFilePath.value,
134140
stylesFilePath: stylesFilePath.value,
135141
renderMode: normalizeRenderMode(savedConfig.renderMode),
142+
styleMode: normalizeStyleMode(savedConfig.styleMode),
136143
prTitle,
137144
prBody: typeof savedConfig.prBody === 'string' ? savedConfig.prBody : '',
138145
baseBranch,
@@ -395,13 +402,15 @@ export const createGitHubPrDrawer = ({
395402
getStylesSource,
396403
getTopLevelDeclarations,
397404
getRenderMode,
405+
getStyleMode,
398406
getDrawerSide,
399407
confirmBeforeSubmit,
400408
onPullRequestOpened,
401409
onPullRequestCommitPushed,
402410
onActivePrContextChange,
403411
onSyncActivePrEditorContent,
404412
onRestoreRenderMode,
413+
onRestoreStyleMode,
405414
}) => {
406415
if (!featureEnabled) {
407416
toggleButton?.setAttribute('hidden', '')
@@ -548,6 +557,19 @@ export const createGitHubPrDrawer = ({
548557
onRestoreRenderMode(mode)
549558
}
550559

560+
const emitStyleModeRestore = activeContext => {
561+
if (typeof onRestoreStyleMode !== 'function') {
562+
return
563+
}
564+
565+
if (!activeContext) {
566+
return
567+
}
568+
569+
const mode = normalizeStyleMode(activeContext?.styleMode)
570+
onRestoreStyleMode(mode)
571+
}
572+
551573
const emitActivePrContextChange = () => {
552574
if (typeof onActivePrContextChange !== 'function') {
553575
return
@@ -556,6 +578,7 @@ export const createGitHubPrDrawer = ({
556578
const activeContext = getCurrentActivePrContext()
557579
onActivePrContextChange(activeContext)
558580
emitRenderModeRestore(activeContext)
581+
emitStyleModeRestore(activeContext)
559582
}
560583

561584
const setStatus = (text, level = 'neutral') => {
@@ -762,6 +785,7 @@ export const createGitHubPrDrawer = ({
762785
...savedConfig,
763786
isActivePr: true,
764787
renderMode: normalizeRenderMode(savedConfig.renderMode),
788+
styleMode: normalizeStyleMode(savedConfig.styleMode),
765789
headBranch: nextHeadBranch,
766790
baseBranch: nextBaseBranch,
767791
pullRequestNumber: resolvedPullRequest.number,
@@ -1061,6 +1085,7 @@ export const createGitHubPrDrawer = ({
10611085

10621086
const values = getFormValues()
10631087
const currentRenderMode = normalizeRenderMode(getRenderMode?.())
1088+
const currentStyleMode = normalizeStyleMode(getStyleMode?.())
10641089
const existingConfig = readRepositoryPrConfig(repositoryFullName)
10651090
const isActivePr = existingConfig?.isActivePr === true
10661091

@@ -1078,6 +1103,7 @@ export const createGitHubPrDrawer = ({
10781103
? existingConfig.stylesFilePath
10791104
: values.stylesFilePath,
10801105
renderMode: currentRenderMode,
1106+
styleMode: currentStyleMode,
10811107
isActivePr: true,
10821108
pullRequestNumber: existingConfig?.pullRequestNumber,
10831109
pullRequestUrl: existingConfig?.pullRequestUrl,
@@ -1099,6 +1125,7 @@ export const createGitHubPrDrawer = ({
10991125
prTitle: values.prTitle,
11001126
prBody: values.prBody,
11011127
renderMode: currentRenderMode,
1128+
styleMode: currentStyleMode,
11021129
isActivePr: false,
11031130
pullRequestNumber: existingConfig?.pullRequestNumber,
11041131
pullRequestUrl: existingConfig?.pullRequestUrl,
@@ -1199,6 +1226,7 @@ export const createGitHubPrDrawer = ({
11991226
: ''
12001227
: values.prBody
12011228
const currentRenderMode = normalizeRenderMode(getRenderMode?.())
1229+
const currentStyleMode = normalizeStyleMode(getStyleMode?.())
12021230
const targetComponentPathValue = isPushCommitMode
12031231
? activeContext?.componentFilePath
12041232
: values.componentFilePath
@@ -1348,6 +1376,7 @@ export const createGitHubPrDrawer = ({
13481376
componentFilePath: componentPathValidation.value,
13491377
stylesFilePath: stylesPathValidation.value,
13501378
renderMode: currentRenderMode,
1379+
styleMode: currentStyleMode,
13511380
baseBranch: targetBaseBranch,
13521381
headBranch: targetHeadBranch,
13531382
prTitle: targetPrTitle,

0 commit comments

Comments
 (0)