forked from extern/bruno
feat: dark-mode (code editor)
This commit is contained in:
parent
23400a77f8
commit
04a0a37ca4
@ -2,12 +2,31 @@ import styled from 'styled-components';
|
|||||||
|
|
||||||
const StyledWrapper = styled.div`
|
const StyledWrapper = styled.div`
|
||||||
div.CodeMirror {
|
div.CodeMirror {
|
||||||
border: solid 1px var(--color-codemirror-border);
|
background: ${(props) => props.theme.codemirror.bg};
|
||||||
|
border: solid 1px ${(props) => props.theme.codemirror.border};
|
||||||
}
|
}
|
||||||
|
|
||||||
textarea.cm-editor {
|
textarea.cm-editor {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Todo: dark mode temporary fix
|
||||||
|
// Clean this
|
||||||
|
.cm-s-monokai span.cm-property, .cm-s-monokai span.cm-attribute {
|
||||||
|
color: #9cdcfe !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-s-monokai span.cm-string {
|
||||||
|
color: #ce9178 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-s-monokai span.cm-number{
|
||||||
|
color: #b5cea8 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-s-monokai span.cm-atom{
|
||||||
|
color: #569cd6 !important;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default StyledWrapper;
|
export default StyledWrapper;
|
||||||
|
@ -39,6 +39,7 @@ export default class QueryEditor extends React.Component {
|
|||||||
foldGutter: true,
|
foldGutter: true,
|
||||||
gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
|
gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
|
||||||
readOnly: this.props.readOnly ? 'nocursor' : false,
|
readOnly: this.props.readOnly ? 'nocursor' : false,
|
||||||
|
theme: this.props.theme === 'dark' ? 'monokai' : 'default',
|
||||||
extraKeys: {
|
extraKeys: {
|
||||||
'Cmd-Enter': () => {
|
'Cmd-Enter': () => {
|
||||||
if (this.props.onRun) {
|
if (this.props.onRun) {
|
||||||
@ -87,6 +88,12 @@ export default class QueryEditor extends React.Component {
|
|||||||
this.editor.setValue(this.props.value);
|
this.editor.setValue(this.props.value);
|
||||||
this.editor.setOption('mode', this.props.mode);
|
this.editor.setOption('mode', this.props.mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.props.theme !== prevProps.theme && this.editor) {
|
||||||
|
this.cachedValue = this.props.value;
|
||||||
|
this.editor.setValue(this.props.value);
|
||||||
|
this.editor.setOption('theme', this.props.theme === 'dark' ? 'monokai' : 'default');
|
||||||
|
}
|
||||||
this.ignoreChangeEvent = false;
|
this.ignoreChangeEvent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,8 @@ import styled from 'styled-components';
|
|||||||
|
|
||||||
const StyledWrapper = styled.div`
|
const StyledWrapper = styled.div`
|
||||||
div.CodeMirror {
|
div.CodeMirror {
|
||||||
border: solid 1px var(--color-codemirror-border);
|
background: ${(props) => props.theme.codemirror.bg};
|
||||||
|
border: solid 1px ${(props) => props.theme.codemirror.border};
|
||||||
/* todo: find a better way */
|
/* todo: find a better way */
|
||||||
height: calc(100vh - 250px);
|
height: calc(100vh - 250px);
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ const Wrapper = styled.div`
|
|||||||
font-size: 0.8125rem;
|
font-size: 0.8125rem;
|
||||||
|
|
||||||
.body-mode-selector {
|
.body-mode-selector {
|
||||||
background: #efefef;
|
background: ${(props) => props.theme.requestTabPanel.bodyModeSelect.color};
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
|
|
||||||
.dropdown-item {
|
.dropdown-item {
|
||||||
|
@ -4,6 +4,7 @@ import CodeEditor from 'components/CodeEditor';
|
|||||||
import FormUrlEncodedParams from 'components/RequestPane/FormUrlEncodedParams';
|
import FormUrlEncodedParams from 'components/RequestPane/FormUrlEncodedParams';
|
||||||
import MultipartFormParams from 'components/RequestPane/MultipartFormParams';
|
import MultipartFormParams from 'components/RequestPane/MultipartFormParams';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
|
import { useTheme } from 'providers/Theme';
|
||||||
import { updateRequestBody } from 'providers/ReduxStore/slices/collections';
|
import { updateRequestBody } from 'providers/ReduxStore/slices/collections';
|
||||||
import { sendRequest, saveRequest } from 'providers/ReduxStore/slices/collections/actions';
|
import { sendRequest, saveRequest } from 'providers/ReduxStore/slices/collections/actions';
|
||||||
import StyledWrapper from './StyledWrapper';
|
import StyledWrapper from './StyledWrapper';
|
||||||
@ -12,6 +13,9 @@ const RequestBody = ({ item, collection }) => {
|
|||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const body = item.draft ? get(item, 'draft.request.body') : get(item, 'request.body');
|
const body = item.draft ? get(item, 'draft.request.body') : get(item, 'request.body');
|
||||||
const bodyMode = item.draft ? get(item, 'draft.request.body.mode') : get(item, 'request.body.mode');
|
const bodyMode = item.draft ? get(item, 'draft.request.body.mode') : get(item, 'request.body.mode');
|
||||||
|
const {
|
||||||
|
storedTheme
|
||||||
|
} = useTheme();
|
||||||
|
|
||||||
const onEdit = (value) => {
|
const onEdit = (value) => {
|
||||||
dispatch(
|
dispatch(
|
||||||
@ -41,7 +45,7 @@ const RequestBody = ({ item, collection }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledWrapper className="w-full">
|
<StyledWrapper className="w-full">
|
||||||
<CodeEditor value={bodyContent[bodyMode] || ''} onEdit={onEdit} onRun={onRun} onSave={onSave} mode={codeMirrorMode[bodyMode]} />
|
<CodeEditor theme={storedTheme} value={bodyContent[bodyMode] || ''} onEdit={onEdit} onRun={onRun} onSave={onSave} mode={codeMirrorMode[bodyMode]} />
|
||||||
</StyledWrapper>
|
</StyledWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ const Wrapper = styled.div`
|
|||||||
}
|
}
|
||||||
|
|
||||||
thead {
|
thead {
|
||||||
color: ${(props) => props.theme.table.thead.color};;
|
color: ${(props) => props.theme.table.thead.color};
|
||||||
font-size: 0.8125rem;
|
font-size: 0.8125rem;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
@ -23,8 +23,6 @@ const Wrapper = styled.div`
|
|||||||
|
|
||||||
.btn-add-header {
|
.btn-add-header {
|
||||||
font-size: 0.8125rem;
|
font-size: 0.8125rem;
|
||||||
margin-block: 10px;
|
|
||||||
padding: 5px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type='text'] {
|
input[type='text'] {
|
||||||
|
@ -124,7 +124,7 @@ const RequestHeaders = ({ item, collection }) => {
|
|||||||
: null}
|
: null}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<button className="btn-add-header select-none" onClick={addHeader}>
|
<button className="btn-add-header text-link pr-2 py-3 mt-2 select-none" onClick={addHeader}>
|
||||||
+ Add Header
|
+ Add Header
|
||||||
</button>
|
</button>
|
||||||
</StyledWrapper>
|
</StyledWrapper>
|
||||||
|
@ -1,12 +1,17 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import CodeEditor from 'components/CodeEditor';
|
import CodeEditor from 'components/CodeEditor';
|
||||||
|
import { useTheme } from 'providers/Theme';
|
||||||
import StyledWrapper from './StyledWrapper';
|
import StyledWrapper from './StyledWrapper';
|
||||||
|
|
||||||
const QueryResult = ({ value, width }) => {
|
const QueryResult = ({ value, width }) => {
|
||||||
|
const {
|
||||||
|
storedTheme
|
||||||
|
} = useTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledWrapper className="px-3 w-full" style={{ maxWidth: width }}>
|
<StyledWrapper className="px-3 w-full" style={{ maxWidth: width }}>
|
||||||
<div className="h-full">
|
<div className="h-full">
|
||||||
<CodeEditor value={value || ''} readOnly />
|
<CodeEditor theme={storedTheme} value={value || ''} readOnly />
|
||||||
</div>
|
</div>
|
||||||
</StyledWrapper>
|
</StyledWrapper>
|
||||||
);
|
);
|
||||||
|
@ -22,7 +22,7 @@ const Wrapper = styled.div`
|
|||||||
|
|
||||||
tbody {
|
tbody {
|
||||||
tr:nth-child(odd) {
|
tr:nth-child(odd) {
|
||||||
background-color: var(--color-table-stripe);
|
background-color: ${(props) => props.theme.table.striped};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,12 @@ import { createGlobalStyle } from 'styled-components';
|
|||||||
|
|
||||||
const GlobalStyle = createGlobalStyle`
|
const GlobalStyle = createGlobalStyle`
|
||||||
.CodeMirror-gutters {
|
.CodeMirror-gutters {
|
||||||
background-color: var(--color-codemirror-background);
|
background-color: ${(props) => props.theme.codemirror.gutter.bg} !important;
|
||||||
border-right: solid 1px var(--color-codemirror-border);
|
border-right: solid 1px ${(props) => props.theme.codemirror.border};
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-link {
|
||||||
|
color: ${(props) => props.theme.textLink};
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
|
@ -6,6 +6,8 @@ import RequestTabPanel from 'components/RequestTabPanel';
|
|||||||
import Sidebar from 'components/Sidebar';
|
import Sidebar from 'components/Sidebar';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import StyledWrapper from './StyledWrapper';
|
import StyledWrapper from './StyledWrapper';
|
||||||
|
import 'codemirror/theme/material.css';
|
||||||
|
import 'codemirror/theme/monokai.css';
|
||||||
|
|
||||||
const SERVER_RENDERED = typeof navigator === 'undefined' || global['PREVENT_CODEMIRROR_RENDER'] === true;
|
const SERVER_RENDERED = typeof navigator === 'undefined' || global['PREVENT_CODEMIRROR_RENDER'] === true;
|
||||||
if (!SERVER_RENDERED) {
|
if (!SERVER_RENDERED) {
|
||||||
|
@ -9,8 +9,6 @@
|
|||||||
--color-tab-inactive: rgb(155 155 155);
|
--color-tab-inactive: rgb(155 155 155);
|
||||||
--color-tab-active-border: #546de5;
|
--color-tab-active-border: #546de5;
|
||||||
--color-layout-border: #dedede;
|
--color-layout-border: #dedede;
|
||||||
--color-codemirror-border: #efefef;
|
|
||||||
--color-codemirror-background: rgb(243, 243, 243);
|
|
||||||
--color-text-link: #1663bb;
|
--color-text-link: #1663bb;
|
||||||
--color-text-danger: rgb(185, 28, 28);
|
--color-text-danger: rgb(185, 28, 28);
|
||||||
--color-background-danger: #dc3545;
|
--color-background-danger: #dc3545;
|
||||||
@ -21,7 +19,6 @@
|
|||||||
--color-method-patch: rgb(52 52 52);
|
--color-method-patch: rgb(52 52 52);
|
||||||
--color-method-options: rgb(52 52 52);
|
--color-method-options: rgb(52 52 52);
|
||||||
--color-method-head: rgb(52 52 52);
|
--color-method-head: rgb(52 52 52);
|
||||||
--color-table-stripe: #f3f3f3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
@ -53,7 +50,3 @@ body::-webkit-scrollbar-thumb, .CodeMirror-vscrollbar::-webkit-scrollbar-thumb {
|
|||||||
background-color: #cdcdcd;
|
background-color: #cdcdcd;
|
||||||
border-radius: 5rem;
|
border-radius: 5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-link {
|
|
||||||
color: var(--color-text-link);
|
|
||||||
}
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
const darkTheme = {
|
const darkTheme = {
|
||||||
brand: '#546de5',
|
brand: '#546de5',
|
||||||
text: '#d4d4d4',
|
text: '#d4d4d4',
|
||||||
|
textLink: '#569cd6',
|
||||||
bg: '#1e1e1e',
|
bg: '#1e1e1e',
|
||||||
|
|
||||||
menubar: {
|
menubar: {
|
||||||
@ -61,6 +62,9 @@ const darkTheme = {
|
|||||||
dragbar: {
|
dragbar: {
|
||||||
border: '#444',
|
border: '#444',
|
||||||
activeBorder: '#8a8a8a'
|
activeBorder: '#8a8a8a'
|
||||||
|
},
|
||||||
|
bodyModeSelect: {
|
||||||
|
color: 'transparent'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -130,14 +134,19 @@ const darkTheme = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
codemirror: {
|
codemirror: {
|
||||||
|
bg: '#1e1e1e',
|
||||||
|
border: 'transparent',
|
||||||
|
gutter: {
|
||||||
|
bg: '#1e1e1e'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
table: {
|
table: {
|
||||||
border: '#333',
|
border: '#333',
|
||||||
thead : {
|
thead : {
|
||||||
color: 'rgb(204, 204, 204)'
|
color: 'rgb(204, 204, 204)'
|
||||||
}
|
},
|
||||||
|
striped: '#2A2D2F'
|
||||||
},
|
},
|
||||||
|
|
||||||
'primary-text': '#ffffff',
|
'primary-text': '#ffffff',
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
const lightTheme = {
|
const lightTheme = {
|
||||||
brand: '#546de5',
|
brand: '#546de5',
|
||||||
text: 'rgb(52, 52, 52)',
|
text: 'rgb(52, 52, 52)',
|
||||||
|
textLink: '#1663bb',
|
||||||
bg: '#fff',
|
bg: '#fff',
|
||||||
|
|
||||||
menubar: {
|
menubar: {
|
||||||
@ -61,6 +62,9 @@ const lightTheme = {
|
|||||||
dragbar: {
|
dragbar: {
|
||||||
border: '#efefef',
|
border: '#efefef',
|
||||||
activeBorder: 'rgb(200, 200, 200)'
|
activeBorder: 'rgb(200, 200, 200)'
|
||||||
|
},
|
||||||
|
bodyModeSelect: {
|
||||||
|
color: '#efefef'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -104,7 +108,7 @@ const lightTheme = {
|
|||||||
|
|
||||||
tabs: {
|
tabs: {
|
||||||
active: {
|
active: {
|
||||||
color: '${(props) => props.theme.tabs.active.color}',
|
color: 'rgb(50, 46, 44)',
|
||||||
border: '#546de5'
|
border: '#546de5'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -130,14 +134,19 @@ const lightTheme = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
codemirror: {
|
codemirror: {
|
||||||
|
bg: 'white',
|
||||||
|
border: '#efefef',
|
||||||
|
gutter: {
|
||||||
|
bg: '#f3f3f3'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
table: {
|
table: {
|
||||||
border: '#efefef',
|
border: '#efefef',
|
||||||
thead : {
|
thead : {
|
||||||
color: '#616161'
|
color: '#616161'
|
||||||
}
|
},
|
||||||
|
striped: '#f3f3f3'
|
||||||
},
|
},
|
||||||
|
|
||||||
'primary-text': 'rgb(52 52 52)',
|
'primary-text': 'rgb(52 52 52)',
|
||||||
|
Loading…
Reference in New Issue
Block a user