mirror of
https://github.com/chinchang/web-maker.git
synced 2025-08-04 04:17:33 +02:00
Merge pull request #338 from chinchang/command-palette-311
Command palette 311
This commit is contained in:
19
src/commandPaletteService.js
Normal file
19
src/commandPaletteService.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
export const commandPaletteService = {
|
||||||
|
subscriptions: {},
|
||||||
|
subscribe(eventName, callback) {
|
||||||
|
this.subscriptions[eventName] = this.subscriptions[eventName] || [];
|
||||||
|
this.subscriptions[eventName].push(callback);
|
||||||
|
return () => {
|
||||||
|
this.subscriptions[eventName].splice(
|
||||||
|
this.subscriptions[eventName].indexOf(callback),
|
||||||
|
1
|
||||||
|
);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
publish(eventName, ...args) {
|
||||||
|
const callbacks = this.subscriptions[eventName] || [];
|
||||||
|
callbacks.forEach(callback => {
|
||||||
|
callback.apply(null, args);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
34
src/commands.js
Normal file
34
src/commands.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
export const SWITCH_FILE_EVENT = 'switchFileEvent';
|
||||||
|
export const NEW_CREATION_EVENT = 'newCreationEvent';
|
||||||
|
export const OPEN_SAVED_CREATIONS_EVENT = 'openSavedCreationsEvent';
|
||||||
|
export const SAVE_EVENT = 'saveEvent';
|
||||||
|
export const OPEN_SETTINGS_EVENT = 'openSettingsEvent';
|
||||||
|
export const SHOW_KEYBOARD_SHORTCUTS_EVENT = 'showKeyboardShortcutsEvent';
|
||||||
|
|
||||||
|
export const commands = [
|
||||||
|
{
|
||||||
|
name: 'Start New Creation',
|
||||||
|
event: NEW_CREATION_EVENT,
|
||||||
|
keyboardShortcut: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Open Creation',
|
||||||
|
event: OPEN_SAVED_CREATIONS_EVENT,
|
||||||
|
keyboardShortcut: 'Cmd+O'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Save Creation',
|
||||||
|
event: SAVE_EVENT,
|
||||||
|
keyboardShortcut: 'Cmd+S'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Open Settings',
|
||||||
|
event: OPEN_SETTINGS_EVENT,
|
||||||
|
keyboardShortcut: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Show Keyboard Shortcuts',
|
||||||
|
event: SHOW_KEYBOARD_SHORTCUTS_EVENT,
|
||||||
|
keyboardShortcut: ''
|
||||||
|
}
|
||||||
|
];
|
124
src/components/CommandPalette.jsx
Normal file
124
src/components/CommandPalette.jsx
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
import { h, Component } from 'preact';
|
||||||
|
import Modal from './Modal';
|
||||||
|
import { AutoFocusInput } from './common';
|
||||||
|
import { commands, SWITCH_FILE_EVENT } from '../commands';
|
||||||
|
|
||||||
|
import { commandPaletteService } from '../commandPaletteService';
|
||||||
|
import { FileIcon } from './FileIcon';
|
||||||
|
import { UP_KEY, DOWN_KEY, ENTER_KEY } from '../keyboardKeys';
|
||||||
|
|
||||||
|
function getFolder(filePath) {
|
||||||
|
const split = filePath.split('/');
|
||||||
|
if (split.length > 1) {
|
||||||
|
split.length = split.length - 1;
|
||||||
|
return split.join('/');
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
function Row({ item, onClick, isSelected }) {
|
||||||
|
return (
|
||||||
|
<li>
|
||||||
|
<button
|
||||||
|
class={`command-palette__option-row ${
|
||||||
|
isSelected ? 'command-palette__option-row--selected' : ''
|
||||||
|
}`}
|
||||||
|
onClick={onClick}
|
||||||
|
>
|
||||||
|
{item.path ? <FileIcon file={item} /> : null}
|
||||||
|
{item.name}
|
||||||
|
{item.path ? (
|
||||||
|
<span class="command-palette__option-subtitle">
|
||||||
|
{getFolder(item.path)}
|
||||||
|
</span>
|
||||||
|
) : null}
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export class CommandPalette extends Component {
|
||||||
|
state = { list: [], search: '', selectedIndex: 0 };
|
||||||
|
componentDidUpdate(previousProps) {
|
||||||
|
if (this.props.show && !previousProps.show) {
|
||||||
|
this.state.search = '';
|
||||||
|
|
||||||
|
this.isCommandMode = this.props.isCommandMode;
|
||||||
|
if (this.isCommandMode) {
|
||||||
|
this.setState({ search: '>' });
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
list: this.getFilteredList()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getFilteredList(search = '') {
|
||||||
|
const list = this.isCommandMode ? commands : this.props.files;
|
||||||
|
return list.filter(
|
||||||
|
item =>
|
||||||
|
item.name
|
||||||
|
.toLowerCase()
|
||||||
|
.indexOf(this.isCommandMode ? search.substr(1) : search) !== -1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
keyDownHandler(e) {
|
||||||
|
const diff = { [UP_KEY]: -1, [DOWN_KEY]: 1 }[e.which];
|
||||||
|
if (diff) {
|
||||||
|
this.setState({
|
||||||
|
selectedIndex:
|
||||||
|
(this.state.selectedIndex + diff) % this.state.list.length
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (e.which === ENTER_KEY) {
|
||||||
|
this.selectOption(this.state.list[this.state.selectedIndex]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inputHandler(e) {
|
||||||
|
const search = e.target.value;
|
||||||
|
this.setState({ search });
|
||||||
|
this.isCommandMode = search.indexOf('>') === 0;
|
||||||
|
this.setState({
|
||||||
|
list: this.getFilteredList(search),
|
||||||
|
selectedIndex: 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
optionClickHandler(option) {
|
||||||
|
this.selectOption(option);
|
||||||
|
}
|
||||||
|
selectOption(option) {
|
||||||
|
commandPaletteService.publish(
|
||||||
|
option.path ? SWITCH_FILE_EVENT : option.event,
|
||||||
|
option
|
||||||
|
);
|
||||||
|
this.props.closeHandler();
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
show={this.props.show}
|
||||||
|
closeHandler={this.props.closeHandler}
|
||||||
|
noOverlay
|
||||||
|
hideCloseButton
|
||||||
|
>
|
||||||
|
<AutoFocusInput
|
||||||
|
type="search"
|
||||||
|
placeholder="Search"
|
||||||
|
value={this.state.search}
|
||||||
|
onInput={this.inputHandler.bind(this)}
|
||||||
|
onKeyUp={this.keyDownHandler.bind(this)}
|
||||||
|
/>
|
||||||
|
<ul class="command-palette__option-list">
|
||||||
|
{this.state.list.map((item, index) => (
|
||||||
|
<Row
|
||||||
|
isSelected={this.state.selectedIndex === index}
|
||||||
|
item={item}
|
||||||
|
onClick={this.optionClickHandler.bind(this, item)}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@@ -17,6 +17,8 @@ import 'codemirror/mode/meta';
|
|||||||
import { deferred } from '../deferred';
|
import { deferred } from '../deferred';
|
||||||
import { SidePane } from './SidePane';
|
import { SidePane } from './SidePane';
|
||||||
import { Console } from './Console';
|
import { Console } from './Console';
|
||||||
|
import { SWITCH_FILE_EVENT } from '../commands';
|
||||||
|
import { commandPaletteService } from '../commandPaletteService';
|
||||||
|
|
||||||
const minCodeWrapSize = 33;
|
const minCodeWrapSize = 33;
|
||||||
|
|
||||||
@@ -105,6 +107,21 @@ export default class ContentWrapFiles extends Component {
|
|||||||
}
|
}
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.onRef(this);
|
this.props.onRef(this);
|
||||||
|
this.commandPaletteSubscriptions = [];
|
||||||
|
this.commandPaletteSubscriptions.push(
|
||||||
|
commandPaletteService.subscribe(SWITCH_FILE_EVENT, file => {
|
||||||
|
const targetFile = getFileFromPath(
|
||||||
|
this.props.currentItem.files,
|
||||||
|
file.path
|
||||||
|
);
|
||||||
|
if (targetFile.file) {
|
||||||
|
this.fileSelectHandler(targetFile.file);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
componentWillUnmount() {
|
||||||
|
this.commandPaletteSubscriptions.forEach(unsubscribeFn => unsubscribeFn());
|
||||||
}
|
}
|
||||||
|
|
||||||
getEditorOptions(fileName = '') {
|
getEditorOptions(fileName = '') {
|
||||||
|
@@ -24,13 +24,20 @@ export default class Modal extends Component {
|
|||||||
}
|
}
|
||||||
componentDidUpdate(prevProps) {
|
componentDidUpdate(prevProps) {
|
||||||
if (this.props.show !== prevProps.show) {
|
if (this.props.show !== prevProps.show) {
|
||||||
document.body.classList[this.props.show ? 'add' : 'remove'](
|
if (!this.props.noOverlay) {
|
||||||
'overlay-visible'
|
document.body.classList[this.props.show ? 'add' : 'remove'](
|
||||||
);
|
'overlay-visible'
|
||||||
|
);
|
||||||
|
}
|
||||||
if (this.props.show) {
|
if (this.props.show) {
|
||||||
// HACK: refs will evaluate on next tick due to portals
|
// HACK: refs will evaluate on next tick due to portals
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.overlayEl.querySelector('.js-modal__close-btn').focus();
|
const closeButton = this.overlayEl.querySelector(
|
||||||
|
'.js-modal__close-btn'
|
||||||
|
);
|
||||||
|
if (closeButton) {
|
||||||
|
closeButton.focus();
|
||||||
|
}
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
/* We insert a dummy hidden input which will take focus as soon as focus
|
/* We insert a dummy hidden input which will take focus as soon as focus
|
||||||
@@ -63,15 +70,17 @@ export default class Modal extends Component {
|
|||||||
onClick={this.onOverlayClick.bind(this)}
|
onClick={this.onOverlayClick.bind(this)}
|
||||||
>
|
>
|
||||||
<div class="modal__content">
|
<div class="modal__content">
|
||||||
<button
|
{this.props.hideCloseButton ? null : (
|
||||||
type="button"
|
<button
|
||||||
onClick={this.props.closeHandler}
|
type="button"
|
||||||
aria-label="Close modal"
|
onClick={this.props.closeHandler}
|
||||||
title="Close"
|
aria-label="Close modal"
|
||||||
class="js-modal__close-btn modal__close-btn"
|
title="Close"
|
||||||
>
|
class="js-modal__close-btn modal__close-btn"
|
||||||
Close
|
>
|
||||||
</button>
|
Close
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
{this.props.children}
|
{this.props.children}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -55,6 +55,15 @@ import { Js13KModal } from './Js13KModal';
|
|||||||
import { CreateNewModal } from './CreateNewModal';
|
import { CreateNewModal } from './CreateNewModal';
|
||||||
import { Icons } from './Icons';
|
import { Icons } from './Icons';
|
||||||
import JSZip from 'jszip';
|
import JSZip from 'jszip';
|
||||||
|
import { CommandPalette } from './CommandPalette';
|
||||||
|
import {
|
||||||
|
OPEN_SAVED_CREATIONS_EVENT,
|
||||||
|
SAVE_EVENT,
|
||||||
|
OPEN_SETTINGS_EVENT,
|
||||||
|
NEW_CREATION_EVENT,
|
||||||
|
SHOW_KEYBOARD_SHORTCUTS_EVENT
|
||||||
|
} from '../commands';
|
||||||
|
import { commandPaletteService } from '../commandPaletteService';
|
||||||
|
|
||||||
if (module.hot) {
|
if (module.hot) {
|
||||||
require('preact/debug');
|
require('preact/debug');
|
||||||
@@ -84,7 +93,8 @@ export default class App extends Component {
|
|||||||
isAskToImportModalOpen: false,
|
isAskToImportModalOpen: false,
|
||||||
isOnboardModalOpen: false,
|
isOnboardModalOpen: false,
|
||||||
isJs13KModalOpen: false,
|
isJs13KModalOpen: false,
|
||||||
isCreateNewModalOpen: false
|
isCreateNewModalOpen: false,
|
||||||
|
isCommandPaletteOpen: false
|
||||||
};
|
};
|
||||||
this.state = {
|
this.state = {
|
||||||
isSavedItemPaneOpen: false,
|
isSavedItemPaneOpen: false,
|
||||||
@@ -491,8 +501,20 @@ export default class App extends Component {
|
|||||||
this.editorWithFocus.focus();
|
this.editorWithFocus.focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
openSettings() {
|
||||||
|
this.setState({ isSettingsModalOpen: true });
|
||||||
|
}
|
||||||
|
openKeyboardShortcuts() {
|
||||||
|
this.setState({ isKeyboardShortcutsModalOpen: true });
|
||||||
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
document.body.style.height = `${window.innerHeight}px`;
|
function setBodySize() {
|
||||||
|
document.body.style.height = `${window.innerHeight}px`;
|
||||||
|
}
|
||||||
|
window.addEventListener('resize', () => {
|
||||||
|
setBodySize();
|
||||||
|
});
|
||||||
|
|
||||||
// Editor keyboard shortucuts
|
// Editor keyboard shortucuts
|
||||||
window.addEventListener('keydown', event => {
|
window.addEventListener('keydown', event => {
|
||||||
@@ -532,6 +554,12 @@ export default class App extends Component {
|
|||||||
// We might be listening on keydown for some input inside the app. In that case
|
// We might be listening on keydown for some input inside the app. In that case
|
||||||
// we don't want this to trigger which in turn focuses back the last editor.
|
// we don't want this to trigger which in turn focuses back the last editor.
|
||||||
this.closeSavedItemsPane();
|
this.closeSavedItemsPane();
|
||||||
|
} else if ((event.ctrlKey || event.metaKey) && event.keyCode === 80) {
|
||||||
|
this.setState({
|
||||||
|
isCommandPaletteOpen: true,
|
||||||
|
isCommandPaletteInCommandMode: !!event.shiftKey
|
||||||
|
});
|
||||||
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -548,6 +576,29 @@ export default class App extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
const commandPalleteHooks = {
|
||||||
|
[NEW_CREATION_EVENT]: () => {
|
||||||
|
this.openNewCreationModal();
|
||||||
|
},
|
||||||
|
[OPEN_SAVED_CREATIONS_EVENT]: () => {
|
||||||
|
this.openSavedItemsPane();
|
||||||
|
},
|
||||||
|
[SAVE_EVENT]: () => {
|
||||||
|
this.saveItem();
|
||||||
|
},
|
||||||
|
[OPEN_SETTINGS_EVENT]: () => {
|
||||||
|
this.openSettings();
|
||||||
|
},
|
||||||
|
[SHOW_KEYBOARD_SHORTCUTS_EVENT]: () => {
|
||||||
|
this.openKeyboardShortcuts();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
for (let eventName in commandPalleteHooks) {
|
||||||
|
commandPaletteService.subscribe(
|
||||||
|
eventName,
|
||||||
|
commandPalleteHooks[eventName]
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
closeAllOverlays() {
|
closeAllOverlays() {
|
||||||
@@ -915,8 +966,7 @@ export default class App extends Component {
|
|||||||
this.forkItem(item);
|
this.forkItem(item);
|
||||||
}, 350);
|
}, 350);
|
||||||
}
|
}
|
||||||
newBtnClickHandler() {
|
openNewCreationModal() {
|
||||||
trackEvent('ui', 'newBtnClick');
|
|
||||||
if (this.state.unsavedEditCount) {
|
if (this.state.unsavedEditCount) {
|
||||||
var shouldDiscard = confirm(
|
var shouldDiscard = confirm(
|
||||||
'You have unsaved changes. Do you still want to create something new?'
|
'You have unsaved changes. Do you still want to create something new?'
|
||||||
@@ -932,6 +982,10 @@ export default class App extends Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
newBtnClickHandler() {
|
||||||
|
trackEvent('ui', 'newBtnClick');
|
||||||
|
this.openNewCreationModal();
|
||||||
|
}
|
||||||
openBtnClickHandler() {
|
openBtnClickHandler() {
|
||||||
trackEvent('ui', 'openBtnClick');
|
trackEvent('ui', 'openBtnClick');
|
||||||
this.openSavedItemsPane();
|
this.openSavedItemsPane();
|
||||||
@@ -1396,9 +1450,7 @@ export default class App extends Component {
|
|||||||
prefs={this.state.prefs}
|
prefs={this.state.prefs}
|
||||||
layoutBtnClickHandler={this.layoutBtnClickHandler.bind(this)}
|
layoutBtnClickHandler={this.layoutBtnClickHandler.bind(this)}
|
||||||
helpBtnClickHandler={() => this.setState({ isHelpModalOpen: true })}
|
helpBtnClickHandler={() => this.setState({ isHelpModalOpen: true })}
|
||||||
settingsBtnClickHandler={() =>
|
settingsBtnClickHandler={this.openSettings.bind(this)}
|
||||||
this.setState({ isSettingsModalOpen: true })
|
|
||||||
}
|
|
||||||
notificationsBtnClickHandler={this.notificationsBtnClickHandler.bind(
|
notificationsBtnClickHandler={this.notificationsBtnClickHandler.bind(
|
||||||
this
|
this
|
||||||
)}
|
)}
|
||||||
@@ -1410,9 +1462,9 @@ export default class App extends Component {
|
|||||||
)}
|
)}
|
||||||
codepenBtnClickHandler={this.codepenBtnClickHandler.bind(this)}
|
codepenBtnClickHandler={this.codepenBtnClickHandler.bind(this)}
|
||||||
saveHtmlBtnClickHandler={this.saveHtmlBtnClickHandler.bind(this)}
|
saveHtmlBtnClickHandler={this.saveHtmlBtnClickHandler.bind(this)}
|
||||||
keyboardShortcutsBtnClickHandler={() =>
|
keyboardShortcutsBtnClickHandler={this.openKeyboardShortcuts.bind(
|
||||||
this.setState({ isKeyboardShortcutsModalOpen: true })
|
this
|
||||||
}
|
)}
|
||||||
screenshotBtnClickHandler={this.screenshotBtnClickHandler.bind(
|
screenshotBtnClickHandler={this.screenshotBtnClickHandler.bind(
|
||||||
this
|
this
|
||||||
)}
|
)}
|
||||||
@@ -1553,6 +1605,14 @@ export default class App extends Component {
|
|||||||
onTemplateSelect={this.templateSelectHandler.bind(this)}
|
onTemplateSelect={this.templateSelectHandler.bind(this)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<CommandPalette
|
||||||
|
show={this.state.isCommandPaletteOpen}
|
||||||
|
closeHandler={() => this.setState({ isCommandPaletteOpen: false })}
|
||||||
|
files={linearizeFiles(this.state.currentItem.files || [])}
|
||||||
|
isCommandMode={this.state.isCommandPaletteInCommandMode}
|
||||||
|
closeHandler={() => this.setState({ isCommandPaletteOpen: false })}
|
||||||
|
/>
|
||||||
|
|
||||||
<Portal into="body">
|
<Portal into="body">
|
||||||
<div
|
<div
|
||||||
class="modal-overlay"
|
class="modal-overlay"
|
||||||
|
@@ -26,3 +26,9 @@ export function A(props) {
|
|||||||
export function Button(props) {
|
export function Button(props) {
|
||||||
return <Clickable Tag={'button'} {...props} />;
|
return <Clickable Tag={'button'} {...props} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function AutoFocusInput(props) {
|
||||||
|
return (
|
||||||
|
<input ref={el => el && setTimeout(() => el.focus(), 100)} {...props} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
6
src/keyboardKeys.js
Normal file
6
src/keyboardKeys.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export const ENTER_KEY = 13;
|
||||||
|
export const ESCAPE_KEY = 27;
|
||||||
|
export const LEFT_KEY = 37;
|
||||||
|
export const UP_KEY = 38;
|
||||||
|
export const RIGHT_KEY = 39;
|
||||||
|
export const DOWN_KEY = 40;
|
@@ -1,5 +1,6 @@
|
|||||||
:root {
|
:root {
|
||||||
--color-text: #d4cde9;
|
--color-text: #e2daf9;
|
||||||
|
--color-text-dark-1: #b3aec4;
|
||||||
--color-bg: #252637;
|
--color-bg: #252637;
|
||||||
--color-popup: #3a2b63;
|
--color-popup: #3a2b63;
|
||||||
--code-font-size: 16px;
|
--code-font-size: 16px;
|
||||||
@@ -74,6 +75,10 @@ button {
|
|||||||
.d-i {
|
.d-i {
|
||||||
display: inline;
|
display: inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.d-b {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
.flex {
|
.flex {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
@@ -1688,28 +1693,6 @@ body:not(.is-app) .show-when-app {
|
|||||||
.is-file-mode .hide-in-file-mode {
|
.is-file-mode .hide-in-file-mode {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
@media screen and (max-width: 600px) {
|
|
||||||
body {
|
|
||||||
font-size: 70%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-header {
|
|
||||||
overflow-x: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-header__btn-wrap {
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal__content {
|
|
||||||
padding: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.saved-items-pane {
|
|
||||||
width: 77vw;
|
|
||||||
padding: 10px 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Codemirror themes basic bg styles. This is here so that there is no big FOUC
|
/* Codemirror themes basic bg styles. This is here so that there is no big FOUC
|
||||||
while the theme CSS file is loading */
|
while the theme CSS file is loading */
|
||||||
@@ -1807,3 +1790,47 @@ while the theme CSS file is loading */
|
|||||||
.cm-s-midnight .CodeMirror-activeline-background {
|
.cm-s-midnight .CodeMirror-activeline-background {
|
||||||
background: #253540;
|
background: #253540;
|
||||||
}
|
}
|
||||||
|
.command-palette__option-list {
|
||||||
|
margin: 0;
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 0;
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
.command-palette__option-row {
|
||||||
|
padding: 4px 5px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
border: 0;
|
||||||
|
background: transparent;
|
||||||
|
color: var(--color-text);
|
||||||
|
}
|
||||||
|
.command-palette__option-row--selected {
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
.command-palette__option-subtitle {
|
||||||
|
color: var(--color-text-dark-1);
|
||||||
|
margin-left: 10px;
|
||||||
|
font-size: 0.8em;
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 600px) {
|
||||||
|
body {
|
||||||
|
font-size: 70%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-header {
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-header__btn-wrap {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal__content {
|
||||||
|
padding: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.saved-items-pane {
|
||||||
|
width: 77vw;
|
||||||
|
padding: 10px 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user