add some custom themes
This commit is contained in:
parent
f3f18ffca7
commit
1e3f09f69b
9 changed files with 184 additions and 7 deletions
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
.cm-theme {
|
.cm-theme {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cm-theme-light {
|
.cm-theme-light {
|
||||||
|
|
|
||||||
36
packages/react/src/themes/blackscreen.js
Normal file
36
packages/react/src/themes/blackscreen.js
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
import { tags as t } from '@lezer/highlight';
|
||||||
|
import { createTheme } from '@uiw/codemirror-themes';
|
||||||
|
export const settings = {
|
||||||
|
background: 'black',
|
||||||
|
foreground: 'white', // whats that?
|
||||||
|
caret: 'white',
|
||||||
|
selection: '#ffffff20',
|
||||||
|
selectionMatch: '#036dd626',
|
||||||
|
lineHighlight: '#ffffff10',
|
||||||
|
gutterBackground: 'transparent',
|
||||||
|
gutterForeground: '#8a919966',
|
||||||
|
};
|
||||||
|
export default createTheme({
|
||||||
|
theme: 'dark',
|
||||||
|
settings,
|
||||||
|
styles: [
|
||||||
|
{ tag: t.keyword, color: 'white' },
|
||||||
|
{ tag: t.operator, color: 'white' },
|
||||||
|
{ tag: t.special(t.variableName), color: 'white' },
|
||||||
|
{ tag: t.typeName, color: 'white' },
|
||||||
|
{ tag: t.atom, color: 'white' },
|
||||||
|
{ tag: t.number, color: 'white' },
|
||||||
|
{ tag: t.definition(t.variableName), color: 'white' },
|
||||||
|
{ tag: t.string, color: 'white' },
|
||||||
|
{ tag: t.special(t.string), color: 'white' },
|
||||||
|
{ tag: t.comment, color: 'white' },
|
||||||
|
{ tag: t.variableName, color: 'white' },
|
||||||
|
{ tag: t.tagName, color: 'white' },
|
||||||
|
{ tag: t.bracket, color: 'white' },
|
||||||
|
{ tag: t.meta, color: 'white' },
|
||||||
|
{ tag: t.attributeName, color: 'white' },
|
||||||
|
{ tag: t.propertyName, color: 'white' },
|
||||||
|
{ tag: t.className, color: 'white' },
|
||||||
|
{ tag: t.invalid, color: 'white' },
|
||||||
|
],
|
||||||
|
});
|
||||||
39
packages/react/src/themes/bluescreen.js
Normal file
39
packages/react/src/themes/bluescreen.js
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { tags as t } from '@lezer/highlight';
|
||||||
|
import { createTheme } from '@uiw/codemirror-themes';
|
||||||
|
export const settings = {
|
||||||
|
background: '#051DB5',
|
||||||
|
foreground: 'white', // whats that?
|
||||||
|
caret: 'white',
|
||||||
|
selection: 'rgba(128, 203, 196, 0.5)',
|
||||||
|
selectionMatch: '#036dd626',
|
||||||
|
// lineHighlight: '#8a91991a', // original
|
||||||
|
lineHighlight: '#00000050',
|
||||||
|
gutterBackground: 'transparent',
|
||||||
|
// gutterForeground: '#8a919966',
|
||||||
|
gutterForeground: '#8a919966',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default createTheme({
|
||||||
|
theme: 'dark',
|
||||||
|
settings,
|
||||||
|
styles: [
|
||||||
|
{ tag: t.keyword, color: 'white' },
|
||||||
|
{ tag: t.operator, color: 'white' },
|
||||||
|
{ tag: t.special(t.variableName), color: 'white' },
|
||||||
|
{ tag: t.typeName, color: 'white' },
|
||||||
|
{ tag: t.atom, color: 'white' },
|
||||||
|
{ tag: t.number, color: 'white' },
|
||||||
|
{ tag: t.definition(t.variableName), color: 'white' },
|
||||||
|
{ tag: t.string, color: 'white' },
|
||||||
|
{ tag: t.special(t.string), color: 'white' },
|
||||||
|
{ tag: t.comment, color: 'white' },
|
||||||
|
{ tag: t.variableName, color: 'white' },
|
||||||
|
{ tag: t.tagName, color: 'white' },
|
||||||
|
{ tag: t.bracket, color: 'white' },
|
||||||
|
{ tag: t.meta, color: 'white' },
|
||||||
|
{ tag: t.attributeName, color: 'white' },
|
||||||
|
{ tag: t.propertyName, color: 'white' },
|
||||||
|
{ tag: t.className, color: 'white' },
|
||||||
|
{ tag: t.invalid, color: 'white' },
|
||||||
|
],
|
||||||
|
});
|
||||||
38
packages/react/src/themes/gameboy.js
Normal file
38
packages/react/src/themes/gameboy.js
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
import { tags as t } from '@lezer/highlight';
|
||||||
|
import { createTheme } from '@uiw/codemirror-themes';
|
||||||
|
export const settings = {
|
||||||
|
background: '#9bbc0f',
|
||||||
|
foreground: '#0f380f', // whats that?
|
||||||
|
caret: '#0f380f',
|
||||||
|
selection: '#306230',
|
||||||
|
selectionMatch: '#ffffff26',
|
||||||
|
lineHighlight: '#8bac0f',
|
||||||
|
lineBackground: '#9bbc0f50',
|
||||||
|
gutterBackground: 'transparent',
|
||||||
|
gutterForeground: '#0f380f',
|
||||||
|
light: true,
|
||||||
|
};
|
||||||
|
export default createTheme({
|
||||||
|
theme: 'light',
|
||||||
|
settings,
|
||||||
|
styles: [
|
||||||
|
{ tag: t.keyword, color: '#0f380f' },
|
||||||
|
{ tag: t.operator, color: '#0f380f' },
|
||||||
|
{ tag: t.special(t.variableName), color: '#0f380f' },
|
||||||
|
{ tag: t.typeName, color: '#0f380f' },
|
||||||
|
{ tag: t.atom, color: '#0f380f' },
|
||||||
|
{ tag: t.number, color: '#0f380f' },
|
||||||
|
{ tag: t.definition(t.variableName), color: '#0f380f' },
|
||||||
|
{ tag: t.string, color: '#0f380f' },
|
||||||
|
{ tag: t.special(t.string), color: '#0f380f' },
|
||||||
|
{ tag: t.comment, color: '#0f380f' },
|
||||||
|
{ tag: t.variableName, color: '#0f380f' },
|
||||||
|
{ tag: t.tagName, color: '#0f380f' },
|
||||||
|
{ tag: t.bracket, color: '#0f380f' },
|
||||||
|
{ tag: t.meta, color: '#0f380f' },
|
||||||
|
{ tag: t.attributeName, color: '#0f380f' },
|
||||||
|
{ tag: t.propertyName, color: '#0f380f' },
|
||||||
|
{ tag: t.className, color: '#0f380f' },
|
||||||
|
{ tag: t.invalid, color: '#0f380f' },
|
||||||
|
],
|
||||||
|
});
|
||||||
38
packages/react/src/themes/whitescreen.js
Normal file
38
packages/react/src/themes/whitescreen.js
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
import { tags as t } from '@lezer/highlight';
|
||||||
|
import { createTheme } from '@uiw/codemirror-themes';
|
||||||
|
export const settings = {
|
||||||
|
background: 'white',
|
||||||
|
foreground: 'black', // whats that?
|
||||||
|
caret: 'black',
|
||||||
|
selection: 'rgba(128, 203, 196, 0.5)',
|
||||||
|
selectionMatch: '#ffffff26',
|
||||||
|
lineHighlight: '#cccccc50',
|
||||||
|
lineBackground: '#ffffff50',
|
||||||
|
gutterBackground: 'transparent',
|
||||||
|
gutterForeground: 'black',
|
||||||
|
light: true,
|
||||||
|
};
|
||||||
|
export default createTheme({
|
||||||
|
theme: 'light',
|
||||||
|
settings,
|
||||||
|
styles: [
|
||||||
|
{ tag: t.keyword, color: 'black' },
|
||||||
|
{ tag: t.operator, color: 'black' },
|
||||||
|
{ tag: t.special(t.variableName), color: 'black' },
|
||||||
|
{ tag: t.typeName, color: 'black' },
|
||||||
|
{ tag: t.atom, color: 'black' },
|
||||||
|
{ tag: t.number, color: 'black' },
|
||||||
|
{ tag: t.definition(t.variableName), color: 'black' },
|
||||||
|
{ tag: t.string, color: 'black' },
|
||||||
|
{ tag: t.special(t.string), color: 'black' },
|
||||||
|
{ tag: t.comment, color: 'black' },
|
||||||
|
{ tag: t.variableName, color: 'black' },
|
||||||
|
{ tag: t.tagName, color: 'black' },
|
||||||
|
{ tag: t.bracket, color: 'black' },
|
||||||
|
{ tag: t.meta, color: 'black' },
|
||||||
|
{ tag: t.attributeName, color: 'black' },
|
||||||
|
{ tag: t.propertyName, color: 'black' },
|
||||||
|
{ tag: t.className, color: 'black' },
|
||||||
|
{ tag: t.invalid, color: 'black' },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
@ -4,8 +4,7 @@ import { useEffect, useState } from 'react';
|
||||||
import { prebake } from '../repl/prebake';
|
import { prebake } from '../repl/prebake';
|
||||||
import { themes, settings } from '../repl/themes.mjs';
|
import { themes, settings } from '../repl/themes.mjs';
|
||||||
import './MiniRepl.css';
|
import './MiniRepl.css';
|
||||||
|
import useStore from '../useStore.mjs';
|
||||||
const theme = localStorage.getItem('strudel-theme') || 'strudelTheme';
|
|
||||||
|
|
||||||
let modules;
|
let modules;
|
||||||
if (typeof window !== 'undefined') {
|
if (typeof window !== 'undefined') {
|
||||||
|
|
@ -29,6 +28,9 @@ if (typeof window !== 'undefined') {
|
||||||
|
|
||||||
export function MiniRepl({ tune, drawTime, punchcard, canvasHeight = 100 }) {
|
export function MiniRepl({ tune, drawTime, punchcard, canvasHeight = 100 }) {
|
||||||
const [Repl, setRepl] = useState();
|
const [Repl, setRepl] = useState();
|
||||||
|
const {
|
||||||
|
state: { theme },
|
||||||
|
} = useStore();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// we have to load this package on the client
|
// we have to load this package on the client
|
||||||
// because codemirror throws an error on the server
|
// because codemirror throws an error on the server
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import { nanoid } from 'nanoid';
|
||||||
import React, { useCallback, useLayoutEffect, useRef, useState } from 'react';
|
import React, { useCallback, useLayoutEffect, useRef, useState } from 'react';
|
||||||
import { loadedSamples } from './Repl';
|
import { loadedSamples } from './Repl';
|
||||||
import { Reference } from './Reference';
|
import { Reference } from './Reference';
|
||||||
import { themes, themeColors } from './themes.mjs';
|
import { themes } from './themes.mjs';
|
||||||
import useStore from '../useStore.mjs';
|
import useStore from '../useStore.mjs';
|
||||||
|
|
||||||
export function Footer({ context }) {
|
export function Footer({ context }) {
|
||||||
|
|
@ -209,7 +209,7 @@ function SamplesTab() {
|
||||||
|
|
||||||
function ButtonGroup({ value, onChange, items }) {
|
function ButtonGroup({ value, onChange, items }) {
|
||||||
return (
|
return (
|
||||||
<div className="flex grow">
|
<div className="flex grow border border-foreground rounded-md">
|
||||||
{Object.entries(items).map(([key, label], i, arr) => (
|
{Object.entries(items).map(([key, label], i, arr) => (
|
||||||
<button
|
<button
|
||||||
key={key}
|
key={key}
|
||||||
|
|
@ -282,7 +282,7 @@ function SettingsTab() {
|
||||||
const { theme, keybindings, fontSize } = state;
|
const { theme, keybindings, fontSize } = state;
|
||||||
return (
|
return (
|
||||||
<div className="text-foreground p-4 space-y-4">
|
<div className="text-foreground p-4 space-y-4">
|
||||||
<div className="grid grid-cols-2 gap-2">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
<FormItem label="Theme">
|
<FormItem label="Theme">
|
||||||
<SelectInput
|
<SelectInput
|
||||||
options={themeOptions}
|
options={themeOptions}
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,17 @@ import {
|
||||||
} from '@uiw/codemirror-themes-all';
|
} from '@uiw/codemirror-themes-all';
|
||||||
|
|
||||||
import strudelTheme from '@strudel.cycles/react/src/themes/strudel-theme';
|
import strudelTheme from '@strudel.cycles/react/src/themes/strudel-theme';
|
||||||
|
import bluescreen, { settings as bluescreenSettings } from '@strudel.cycles/react/src/themes/bluescreen';
|
||||||
|
import blackscreen, { settings as blackscreenSettings } from '@strudel.cycles/react/src/themes/blackscreen';
|
||||||
|
import whitescreen, { settings as whitescreenSettings } from '@strudel.cycles/react/src/themes/whitescreen';
|
||||||
|
import gameboy, { settings as gameboySettings } from '@strudel.cycles/react/src/themes/gameboy';
|
||||||
|
|
||||||
export const themes = {
|
export const themes = {
|
||||||
strudelTheme,
|
strudelTheme,
|
||||||
|
bluescreen,
|
||||||
|
blackscreen,
|
||||||
|
whitescreen,
|
||||||
|
gameboy,
|
||||||
abcdef,
|
abcdef,
|
||||||
androidstudio,
|
androidstudio,
|
||||||
atomone,
|
atomone,
|
||||||
|
|
@ -82,6 +90,10 @@ export const settings = {
|
||||||
// gutterForeground: '#8a919966',
|
// gutterForeground: '#8a919966',
|
||||||
gutterForeground: '#8a919966',
|
gutterForeground: '#8a919966',
|
||||||
},
|
},
|
||||||
|
bluescreen: bluescreenSettings,
|
||||||
|
blackscreen: blackscreenSettings,
|
||||||
|
whitescreen: whitescreenSettings,
|
||||||
|
gameboy: gameboySettings,
|
||||||
abcdef: {
|
abcdef: {
|
||||||
background: '#0f0f0f',
|
background: '#0f0f0f',
|
||||||
lineBackground: '#0f0f0f50',
|
lineBackground: '#0f0f0f50',
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useEvent } from '@strudel.cycles/react';
|
// import { useEvent } from '@strudel.cycles/react';
|
||||||
import * as Store from '../public/store.mjs';
|
import * as Store from '../public/store.mjs';
|
||||||
|
import {} from 'react';
|
||||||
|
|
||||||
function useStore() {
|
function useStore() {
|
||||||
const [state, setState] = useState(Store.get());
|
const [state, setState] = useState(Store.get());
|
||||||
|
|
@ -8,4 +9,14 @@ function useStore() {
|
||||||
return { state, update: Store.updateState };
|
return { state, update: Store.updateState };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: dedupe
|
||||||
|
function useEvent(name, onTrigger, useCapture = false) {
|
||||||
|
useEffect(() => {
|
||||||
|
document.addEventListener(name, onTrigger, useCapture);
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener(name, onTrigger, useCapture);
|
||||||
|
};
|
||||||
|
}, [onTrigger]);
|
||||||
|
}
|
||||||
|
|
||||||
export default useStore;
|
export default useStore;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue