Skip to content

Commit 893e7a1

Browse files
Support dark + light mode in the playground (#16388)
###### Microsoft Reviewers: [Open in CodeFlow](https://microsoft.github.io/open-pr/?codeflow=https://github.com/Azure/bicep/pull/16388)
1 parent 1003e02 commit 893e7a1

File tree

6 files changed

+47
-4
lines changed

6 files changed

+47
-4
lines changed

src/playground/src/components/BicepEditor.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ interface Props {
1414

1515
const editorOptions: editor.IStandaloneEditorConstructionOptions = {
1616
language: 'bicep',
17-
theme: 'vs-dark',
1817
scrollBeyondLastLine: false,
1918
automaticLayout: true,
2019
minimap: {

src/playground/src/components/CodeEditor.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import * as monaco from 'monaco-editor';
44
import React, { createRef, useEffect, useState } from 'react';
55
import { DotnetInterop } from '../utils/interop';
6+
import { useColorMode } from '../utils/colorModes';
67

78
interface Props {
89
options: monaco.editor.IStandaloneEditorConstructionOptions,
@@ -14,10 +15,15 @@ export const CodeEditor : React.FC<Props> = (props) => {
1415
const { options, initialContent, onContentChange } = props;
1516
const editorRef = createRef<HTMLDivElement>();
1617
const [model, setModel] = useState<monaco.editor.ITextModel>();
18+
const [editor, setEditor] = useState<monaco.editor.IStandaloneCodeEditor>();
19+
const colorMode = useColorMode();
1720

1821
useEffect(() => {
1922
async function initializeEditor() {
20-
const editor = monaco.editor.create(editorRef.current!, options);
23+
const editor = monaco.editor.create(editorRef.current!, {
24+
...options,
25+
theme: colorMode === 'dark' ? 'vs-dark' : 'vs',
26+
});
2127
const model = editor.getModel()!;
2228

2329
editor.onDidChangeModelContent(async () => {
@@ -28,6 +34,7 @@ export const CodeEditor : React.FC<Props> = (props) => {
2834
}
2935
});
3036

37+
setEditor(editor);
3138
setModel(model);
3239
}
3340

@@ -38,6 +45,13 @@ export const CodeEditor : React.FC<Props> = (props) => {
3845
model?.setValue(initialContent);
3946
}, [initialContent, model]);
4047

48+
useEffect(() => {
49+
editor?.updateOptions({
50+
...options,
51+
theme: colorMode === 'dark' ? 'vs-dark' : 'vs',
52+
});
53+
}, [colorMode]);
54+
4155
return (
4256
<div ref={editorRef} style={{height: '100%', width: '100%'}} />
4357
);

src/playground/src/components/JsonEditor.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ interface JsonEditorProps {
1010

1111
const editorOptions: editor.IStandaloneEditorConstructionOptions = {
1212
language: 'json',
13-
theme: 'vs-dark',
1413
scrollBeyondLastLine: false,
1514
automaticLayout: true,
1615
minimap: {

src/playground/src/index.css

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ html, body {
33
border: 0;
44
margin: 0;
55
overflow: hidden;
6-
background-color: #1e1e1e;
76
}
87

98
.app-container {

src/playground/src/main.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@ import { aiKey } from '../package.json';
88
import './index.css';
99
import { initializeInterop } from './utils/interop';
1010
import { App } from './App';
11+
import { getColorMode } from './utils/colorModes';
1112

13+
const updateTheme = () => document.documentElement.setAttribute('data-bs-theme', getColorMode());
14+
15+
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', updateTheme);
16+
window.addEventListener('DOMContentLoaded', updateTheme);
1217

1318
const root = createRoot(document.getElementById('root')!);
1419
root.render(
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
import { useEffect, useState } from "react";
4+
5+
type colorMode = "dark" | "light";
6+
7+
export function getColorMode(): colorMode {
8+
return window.matchMedia("(prefers-color-scheme: dark)").matches
9+
? "dark"
10+
: "light";
11+
}
12+
13+
export function useColorMode() {
14+
const [colorMode, setColorMode] = useState<colorMode>(getColorMode());
15+
16+
useEffect(() => {
17+
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
18+
const updateColorMode = () => setColorMode(getColorMode());
19+
20+
mediaQuery.addEventListener("change", updateColorMode);
21+
return () => {
22+
mediaQuery.removeEventListener("change", updateColorMode);
23+
};
24+
}, []);
25+
26+
return colorMode;
27+
}

0 commit comments

Comments
 (0)