mirror of
https://github.com/Kong/insomnia
synced 2024-11-07 22:30:15 +00:00
Dedicated tab for request descriptions (#317)
* Added tab for mardown descriptions * Some fixes * Fix dropdown menu theme * Track description editing
This commit is contained in:
parent
be047d4018
commit
0e57b40ba3
16
app/common/markdown-to-html.js
Normal file
16
app/common/markdown-to-html.js
Normal file
@ -0,0 +1,16 @@
|
||||
import marked from 'marked';
|
||||
|
||||
marked.setOptions({
|
||||
renderer: new marked.Renderer(),
|
||||
gfm: true,
|
||||
tables: true,
|
||||
breaks: false,
|
||||
pedantic: false,
|
||||
sanitize: true,
|
||||
smartLists: true,
|
||||
smartypants: false
|
||||
});
|
||||
|
||||
export function markdownToHTML (markdown) {
|
||||
return marked(markdown);
|
||||
}
|
@ -173,6 +173,7 @@ class Dropdown extends PureComponent {
|
||||
|
||||
const menuClasses = classnames({
|
||||
'dropdown__menu': true,
|
||||
'theme--dropdown__menu': true,
|
||||
'dropdown__menu--open': open,
|
||||
'dropdown__menu--outlined': outline,
|
||||
'dropdown__menu--up': dropUp,
|
||||
|
@ -61,12 +61,11 @@ CodeMirror.defineOption('environmentAutocomplete', null, (cm, options) => {
|
||||
return;
|
||||
}
|
||||
|
||||
// Put the hints in a container with class "dropdown__menu" (for themes)
|
||||
let hintsContainer = document.querySelector('#hints-container');
|
||||
if (!hintsContainer) {
|
||||
const el = document.createElement('div');
|
||||
el.id = 'hints-container';
|
||||
el.className = 'dropdown__menu';
|
||||
el.className = 'theme--dropdown__menu';
|
||||
document.body.appendChild(el);
|
||||
hintsContainer = el;
|
||||
}
|
||||
@ -97,7 +96,7 @@ CodeMirror.defineOption('environmentAutocomplete', null, (cm, options) => {
|
||||
}
|
||||
|
||||
// Good for debugging
|
||||
// closeOnUnfocus: false
|
||||
// ,closeOnUnfocus: false
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,23 +1,18 @@
|
||||
import React, {PropTypes, PureComponent} from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import autobind from 'autobind-decorator';
|
||||
import classnames from 'classnames';
|
||||
import marked from 'marked';
|
||||
import highlight from 'highlight.js';
|
||||
import {Tab, TabList, TabPanel, Tabs} from 'react-tabs';
|
||||
import {trackEvent} from '../../analytics';
|
||||
import Button from './base/button';
|
||||
import CodeEditor from './codemirror/code-editor';
|
||||
import * as misc from '../../common/misc';
|
||||
import MarkdownPreview from './markdown-preview';
|
||||
|
||||
@autobind
|
||||
class MarkdownEditor extends PureComponent {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
markdown: props.defaultValue,
|
||||
compiled: '',
|
||||
renderError: ''
|
||||
markdown: props.defaultValue
|
||||
};
|
||||
}
|
||||
|
||||
@ -27,64 +22,21 @@ class MarkdownEditor extends PureComponent {
|
||||
|
||||
_handleChange (markdown) {
|
||||
this.props.onChange(markdown);
|
||||
this._compileMarkdown(markdown);
|
||||
this.setState({markdown});
|
||||
|
||||
// So we don't track on every keystroke, give analytics a longer timeout
|
||||
clearTimeout(this._analyticsTimeout);
|
||||
this._analyticsTimeout = setTimeout(() => {
|
||||
trackEvent('Request', 'Edit Description');
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
async _compileMarkdown (markdown) {
|
||||
const newState = {markdown};
|
||||
try {
|
||||
const rendered = await this.props.handleRender(markdown);
|
||||
newState.compiled = marked(rendered);
|
||||
} catch (err) {
|
||||
newState.renderError = err.message;
|
||||
}
|
||||
|
||||
this.setState(newState);
|
||||
_setEditorRef (n) {
|
||||
this._editor = n;
|
||||
}
|
||||
|
||||
_setPreviewRef (n) {
|
||||
this._preview = n;
|
||||
}
|
||||
|
||||
_highlightCodeBlocks () {
|
||||
if (!this._preview) {
|
||||
return;
|
||||
}
|
||||
|
||||
const el = ReactDOM.findDOMNode(this._preview);
|
||||
for (const block of el.querySelectorAll('pre > code')) {
|
||||
highlight.highlightBlock(block);
|
||||
}
|
||||
|
||||
for (const a of el.querySelectorAll('a')) {
|
||||
a.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
misc.clickLink(e.target.getAttribute('href'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
componentWillMount () {
|
||||
this._compileMarkdown(this.state.markdown);
|
||||
}
|
||||
|
||||
componentDidUpdate () {
|
||||
this._highlightCodeBlocks();
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
marked.setOptions({
|
||||
renderer: new marked.Renderer(),
|
||||
gfm: true,
|
||||
tables: true,
|
||||
breaks: false,
|
||||
pedantic: false,
|
||||
sanitize: true,
|
||||
smartLists: true,
|
||||
smartypants: false
|
||||
});
|
||||
|
||||
this._highlightCodeBlocks();
|
||||
focusEnd () {
|
||||
this._editor && this._editor.focusEnd();
|
||||
}
|
||||
|
||||
render () {
|
||||
@ -102,7 +54,7 @@ class MarkdownEditor extends PureComponent {
|
||||
handleGetRenderContext
|
||||
} = this.props;
|
||||
|
||||
const {markdown, compiled, renderError} = this.state;
|
||||
const {markdown} = this.state;
|
||||
|
||||
const classes = classnames(
|
||||
'markdown-editor',
|
||||
@ -130,6 +82,7 @@ class MarkdownEditor extends PureComponent {
|
||||
<TabPanel className="markdown-editor__edit">
|
||||
<div className="form-control form-control--outlined">
|
||||
<CodeEditor
|
||||
ref={this._setEditorRef}
|
||||
hideGutters
|
||||
hideLineNumbers
|
||||
dynamicHeight={!tall}
|
||||
@ -153,12 +106,10 @@ class MarkdownEditor extends PureComponent {
|
||||
</div>
|
||||
</TabPanel>
|
||||
<TabPanel className="markdown-editor__preview">
|
||||
{renderError && <p className="notice error no-margin">Failed to render: {renderError}</p>}
|
||||
<div className="markdown-editor__preview__content selectable"
|
||||
ref={this._setPreviewRef}
|
||||
dangerouslySetInnerHTML={{__html: compiled}}>
|
||||
{/* Set from above */}
|
||||
</div>
|
||||
<MarkdownPreview
|
||||
markdown={markdown}
|
||||
handleRender={handleRender}
|
||||
/>
|
||||
</TabPanel>
|
||||
</Tabs>
|
||||
);
|
||||
|
100
app/ui/components/markdown-preview.js
Normal file
100
app/ui/components/markdown-preview.js
Normal file
@ -0,0 +1,100 @@
|
||||
import React, {PropTypes, PureComponent} from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import classnames from 'classnames';
|
||||
import autobind from 'autobind-decorator';
|
||||
import highlight from 'highlight.js';
|
||||
import * as misc from '../../common/misc';
|
||||
import {markdownToHTML} from '../../common/markdown-to-html';
|
||||
|
||||
@autobind
|
||||
class MarkdownPreview extends PureComponent {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
compiled: '',
|
||||
renderError: ''
|
||||
};
|
||||
}
|
||||
|
||||
async _compileMarkdown (markdown) {
|
||||
try {
|
||||
const rendered = await this.props.handleRender(markdown);
|
||||
this.setState({
|
||||
compiled: markdownToHTML(rendered),
|
||||
renderError: ''
|
||||
});
|
||||
} catch (err) {
|
||||
this.setState({
|
||||
renderError: err.message,
|
||||
compiled: ''
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_setPreviewRef (n) {
|
||||
this._preview = n;
|
||||
}
|
||||
|
||||
_highlightCodeBlocks () {
|
||||
if (!this._preview) {
|
||||
return;
|
||||
}
|
||||
|
||||
const el = ReactDOM.findDOMNode(this._preview);
|
||||
for (const block of el.querySelectorAll('pre > code')) {
|
||||
highlight.highlightBlock(block);
|
||||
}
|
||||
|
||||
for (const a of el.querySelectorAll('a')) {
|
||||
a.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
misc.clickLink(e.target.getAttribute('href'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
componentWillMount () {
|
||||
this._compileMarkdown(this.props.markdown);
|
||||
}
|
||||
|
||||
componentDidUpdate () {
|
||||
this._highlightCodeBlocks();
|
||||
}
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
this._compileMarkdown(nextProps.markdown);
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this._highlightCodeBlocks();
|
||||
}
|
||||
|
||||
render () {
|
||||
const {className} = this.props;
|
||||
const {compiled, renderError} = this.state;
|
||||
|
||||
return (
|
||||
<div ref={this._setPreviewRef} className={classnames('markdown-preview', className)}>
|
||||
{renderError && (
|
||||
<p className="notice error no-margin">
|
||||
Failed to render: {renderError}
|
||||
</p>
|
||||
)}
|
||||
<div className="markdown-preview__content" dangerouslySetInnerHTML={{__html: compiled}}>
|
||||
{/* Set from above */}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
MarkdownPreview.propTypes = {
|
||||
// Required
|
||||
markdown: PropTypes.string.isRequired,
|
||||
handleRender: PropTypes.func.isRequired,
|
||||
|
||||
// Optional
|
||||
className: PropTypes.string
|
||||
};
|
||||
|
||||
export default MarkdownPreview;
|
@ -23,7 +23,7 @@ class RequestRenderErrorModal extends PureComponent {
|
||||
|
||||
_handleShowRequestSettings () {
|
||||
this.hide();
|
||||
showModal(RequestSettingsModal, this.state.request);
|
||||
showModal(RequestSettingsModal, {request: this.state.request});
|
||||
}
|
||||
|
||||
show ({request, error}) {
|
||||
|
@ -24,6 +24,10 @@ class RequestSettingsModal extends PureComponent {
|
||||
this.modal = n;
|
||||
}
|
||||
|
||||
_setEditorRef (n) {
|
||||
this._editor = n;
|
||||
}
|
||||
|
||||
async _updateRequestSettingBoolean (e) {
|
||||
const value = e.target.checked;
|
||||
const setting = e.target.name;
|
||||
@ -47,14 +51,20 @@ class RequestSettingsModal extends PureComponent {
|
||||
this.setState({showDescription: true});
|
||||
}
|
||||
|
||||
show (request) {
|
||||
show ({request, forceEditMode}) {
|
||||
this.modal.show();
|
||||
const hasDescription = !!request.description;
|
||||
this.setState({
|
||||
request,
|
||||
showDescription: hasDescription,
|
||||
defaultPreviewMode: hasDescription
|
||||
showDescription: forceEditMode || hasDescription,
|
||||
defaultPreviewMode: hasDescription && !forceEditMode
|
||||
});
|
||||
|
||||
if (forceEditMode) {
|
||||
setTimeout(() => {
|
||||
this._editor.focusEnd();
|
||||
}, 400);
|
||||
}
|
||||
}
|
||||
|
||||
hide () {
|
||||
@ -103,6 +113,7 @@ class RequestSettingsModal extends PureComponent {
|
||||
</div>
|
||||
{showDescription ? (
|
||||
<MarkdownEditor
|
||||
ref={this._setEditorRef}
|
||||
className="margin-top"
|
||||
defaultPreviewMode={defaultPreviewMode}
|
||||
fontSize={editorFontSize}
|
||||
|
@ -16,6 +16,9 @@ import * as querystring from '../../common/querystring';
|
||||
import * as db from '../../common/database';
|
||||
import * as models from '../../models';
|
||||
import Hotkey from './hotkey';
|
||||
import {showModal} from './modals/index';
|
||||
import RequestSettingsModal from './modals/request-settings-modal';
|
||||
import MarkdownPreview from './markdown-preview';
|
||||
|
||||
@autobind
|
||||
class RequestPane extends PureComponent {
|
||||
@ -25,6 +28,17 @@ class RequestPane extends PureComponent {
|
||||
this._handleUpdateRequestUrl = debounce(this._handleUpdateRequestUrl);
|
||||
}
|
||||
|
||||
_handleEditDescriptionAdd () {
|
||||
this._handleEditDescription(true);
|
||||
}
|
||||
|
||||
_handleEditDescription (addDescription) {
|
||||
showModal(RequestSettingsModal, {
|
||||
request: this.props.request,
|
||||
forceEditMode: addDescription
|
||||
});
|
||||
}
|
||||
|
||||
async _autocompleteUrls () {
|
||||
const docs = await db.withDescendants(
|
||||
this.props.workspace,
|
||||
@ -106,6 +120,10 @@ class RequestPane extends PureComponent {
|
||||
trackEvent('Request Pane', 'View', 'Headers');
|
||||
}
|
||||
|
||||
_trackTabDescription () {
|
||||
trackEvent('Request Pane', 'View', 'Description');
|
||||
}
|
||||
|
||||
_trackTabAuthentication () {
|
||||
trackEvent('Request Pane', 'View', 'Authentication');
|
||||
}
|
||||
@ -249,6 +267,16 @@ class RequestPane extends PureComponent {
|
||||
Header {numHeaders > 0 && <span className="bubble">{numHeaders}</span>}
|
||||
</button>
|
||||
</Tab>
|
||||
<Tab onClick={this._trackTabDescription}>
|
||||
<button>
|
||||
Description
|
||||
{request.description && (
|
||||
<span className="bubble space-left">
|
||||
<i className="fa fa--skinny fa-check txt-xxs"/>
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
</Tab>
|
||||
</TabList>
|
||||
<TabPanel className="editor-wrapper">
|
||||
<BodyEditor
|
||||
@ -334,6 +362,37 @@ class RequestPane extends PureComponent {
|
||||
</button>
|
||||
</div>
|
||||
</TabPanel>
|
||||
<TabPanel key={uniqueKey}>
|
||||
{request.description ? (
|
||||
<div>
|
||||
<div className="pull-right pad bg-default">
|
||||
<button className="btn btn--clicky" onClick={this._handleEditDescription}>
|
||||
Edit
|
||||
</button>
|
||||
</div>
|
||||
<MarkdownPreview
|
||||
className="pad"
|
||||
markdown={request.description}
|
||||
handleRender={handleRender}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div className="overflow-hidden editor vertically-center text-center">
|
||||
<p className="pad text-sm text-center">
|
||||
<span className="super-faint">
|
||||
<i className="fa fa-file-text-o"
|
||||
style={{fontSize: '8rem', opacity: 0.3}}
|
||||
/>
|
||||
</span>
|
||||
<br/><br/>
|
||||
<button className="btn btn--clicky faint"
|
||||
onClick={this._handleEditDescriptionAdd}>
|
||||
Add Description
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</TabPanel>
|
||||
</Tabs>
|
||||
</section>
|
||||
);
|
||||
|
@ -58,12 +58,7 @@ class SidebarRequestRow extends PureComponent {
|
||||
}
|
||||
|
||||
_handleShowRequestSettings () {
|
||||
showModal(RequestSettingsModal, this.props.request);
|
||||
}
|
||||
|
||||
_handleClickDescription () {
|
||||
trackEvent('Request', 'Click Description Icon');
|
||||
this._handleShowRequestSettings();
|
||||
showModal(RequestSettingsModal, {request: this.props.request});
|
||||
}
|
||||
|
||||
setDragDirection (dragDirection) {
|
||||
@ -121,15 +116,6 @@ class SidebarRequestRow extends PureComponent {
|
||||
className="inline-block"
|
||||
onEditStart={this._handleEditStart}
|
||||
onSubmit={this._handleRequestUpdateName}/>
|
||||
{request.description && (
|
||||
<a title={isActive ? 'View description' : null}
|
||||
onClick={isActive ? this._handleClickDescription : null}
|
||||
className={classnames('space-left super-duper-faint a--nocolor', {
|
||||
'icon': isActive
|
||||
})}>
|
||||
<i className="fa fa-file-text-o space-left"/>
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
|
@ -154,7 +154,7 @@ class Wrapper extends PureComponent {
|
||||
}
|
||||
|
||||
_handleShowRequestSettingsModal () {
|
||||
showModal(RequestSettingsModal, this.props.activeRequest);
|
||||
showModal(RequestSettingsModal, {request: this.props.activeRequest});
|
||||
}
|
||||
|
||||
_handleDeleteResponses () {
|
||||
|
@ -88,7 +88,7 @@ class App extends PureComponent {
|
||||
key: KEY_COMMA,
|
||||
callback: () => {
|
||||
if (this.props.activeRequest) {
|
||||
showModal(RequestSettingsModal, this.props.activeRequest);
|
||||
showModal(RequestSettingsModal, {request: this.props.activeRequest});
|
||||
trackEvent('HotKey', 'Request Settings');
|
||||
}
|
||||
}
|
||||
|
@ -35,170 +35,5 @@
|
||||
max-height: 35vh;
|
||||
padding: @padding-sm;
|
||||
overflow: auto;
|
||||
|
||||
.markdown-editor__preview__content {
|
||||
max-width: 34em;
|
||||
margin-right: auto;
|
||||
|
||||
h1 {
|
||||
font-size: @font-size-xxl;
|
||||
border-bottom: 1px solid var(--hl-sm);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: @font-size-xl;
|
||||
border-bottom: 1px solid var(--hl-sm);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: @font-size-lg;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: @font-size-md;
|
||||
font-weight: bold;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: @font-size-sm;
|
||||
font-weight: bold;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: @font-size-sm;
|
||||
font-weight: bold;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
& > * {
|
||||
line-height: 1.7em;
|
||||
margin: @padding-sm 0 @padding-md 0;
|
||||
padding: 0;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 0.4em solid var(--hl-md);
|
||||
padding: @padding-xxs @padding-md;
|
||||
|
||||
p {
|
||||
margin: @padding-xs 0;
|
||||
}
|
||||
}
|
||||
|
||||
*:not(pre) > code {
|
||||
padding: @padding-xxs @padding-xs;
|
||||
font-size: @font-size-sm;
|
||||
line-height: @font-size-xs;
|
||||
font-family: @font-monospace;
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: var(--hl-xs);
|
||||
border: 1px solid var(--hl-sm);
|
||||
border-radius: @radius-sm;
|
||||
}
|
||||
|
||||
pre > code {
|
||||
padding: @padding-sm;
|
||||
}
|
||||
|
||||
& > ul {
|
||||
padding-left: @padding-xs;
|
||||
list-style: disc;
|
||||
|
||||
ul {
|
||||
list-style: circle;
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-left: @padding-md;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
.hljs-meta,
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: var(--hl);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-subst {
|
||||
color: var(--color-font);
|
||||
}
|
||||
|
||||
.hljs-number,
|
||||
.hljs-literal,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-type,
|
||||
.hljs-class .hljs-title,
|
||||
.hljs-tag .hljs-attr {
|
||||
color: var(--color-surprise);
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-selector-id,
|
||||
.hljs-doctag {
|
||||
color: var(--color-danger);
|
||||
}
|
||||
|
||||
.hljs-string {
|
||||
color: var(--color-notice);
|
||||
}
|
||||
|
||||
.hljs-subst {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-attr,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-attribute {
|
||||
color: var(--color-success);
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
background: #fdd;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
background: #dfd;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
170
app/ui/css/components/markdown-preview.less
Normal file
170
app/ui/css/components/markdown-preview.less
Normal file
@ -0,0 +1,170 @@
|
||||
@import '../constants/dimensions';
|
||||
@import '../constants/colors';
|
||||
@import '../constants/fonts';
|
||||
|
||||
.markdown-preview {
|
||||
.markdown-preview__content {
|
||||
max-width: 34em;
|
||||
margin-right: auto;
|
||||
|
||||
h1 {
|
||||
font-size: @font-size-xxl;
|
||||
border-bottom: 1px solid var(--hl-sm);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: @font-size-xl;
|
||||
border-bottom: 1px solid var(--hl-sm);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: @font-size-lg;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: @font-size-md;
|
||||
font-weight: bold;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: @font-size-sm;
|
||||
font-weight: bold;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: @font-size-sm;
|
||||
font-weight: bold;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
& > * {
|
||||
line-height: 1.7em;
|
||||
margin: @padding-sm 0 @padding-md 0;
|
||||
padding: 0;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 0.4em solid var(--hl-md);
|
||||
padding: @padding-xxs @padding-md;
|
||||
|
||||
p {
|
||||
margin: @padding-xs 0;
|
||||
}
|
||||
}
|
||||
|
||||
*:not(pre) > code {
|
||||
padding: @padding-xxs @padding-xs;
|
||||
font-size: @font-size-sm;
|
||||
line-height: @font-size-xs;
|
||||
font-family: @font-monospace;
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: var(--hl-xs);
|
||||
border: 1px solid var(--hl-sm);
|
||||
border-radius: @radius-sm;
|
||||
}
|
||||
|
||||
pre > code {
|
||||
padding: @padding-sm;
|
||||
}
|
||||
|
||||
& > ul {
|
||||
padding-left: @padding-xs;
|
||||
list-style: disc;
|
||||
|
||||
ul {
|
||||
list-style: circle;
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-left: @padding-md;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
.hljs-meta,
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: var(--hl);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-subst {
|
||||
color: var(--color-font);
|
||||
}
|
||||
|
||||
.hljs-number,
|
||||
.hljs-literal,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-type,
|
||||
.hljs-class .hljs-title,
|
||||
.hljs-tag .hljs-attr {
|
||||
color: var(--color-surprise);
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-selector-id,
|
||||
.hljs-doctag {
|
||||
color: var(--color-danger);
|
||||
}
|
||||
|
||||
.hljs-string {
|
||||
color: var(--color-notice);
|
||||
}
|
||||
|
||||
.hljs-subst {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-attr,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-attribute {
|
||||
color: var(--color-success);
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
background: #fdd;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
background: #dfd;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -77,7 +77,7 @@ body {
|
||||
}
|
||||
|
||||
.pane__header,
|
||||
.dropdown__menu,
|
||||
.theme--dropdown__menu,
|
||||
.modal {
|
||||
--color-bg: #fff;
|
||||
--color-font: #555;
|
||||
@ -115,7 +115,7 @@ body {
|
||||
// Light Parts
|
||||
.request-pane,
|
||||
.response-pane,
|
||||
.dropdown__menu,
|
||||
.theme--dropdown__menu,
|
||||
.modal {
|
||||
--hl-xxs: rgba(130, 130, 130, 0.05);
|
||||
--hl-xs: rgba(130, 130, 130, 0.1);
|
||||
@ -164,7 +164,7 @@ body {
|
||||
--color-bg: #fafaff;
|
||||
}
|
||||
|
||||
.dropdown__menu {
|
||||
.theme--dropdown__menu {
|
||||
--color-bg: #fff;
|
||||
--color-font: #666;
|
||||
}
|
||||
@ -186,13 +186,13 @@ body {
|
||||
--color-bg: #232421;
|
||||
--color-font: #ddd;
|
||||
|
||||
--hl-xxs: rgba(120, 120, 120, 0.05);
|
||||
--hl-xs: rgba(120, 120, 120, 0.1);
|
||||
--hl-sm: rgba(120, 120, 120, 0.2);
|
||||
--hl-md: rgba(120, 120, 120, 0.3);
|
||||
--hl-lg: rgba(120, 120, 120, 0.5);
|
||||
--hl-xl: rgba(120, 120, 120, 0.8);
|
||||
--hl: rgba(120, 120, 120, 1);
|
||||
--hl-xxs: rgba(130, 130, 130, 0.05);
|
||||
--hl-xs: rgba(130, 130, 130, 0.1);
|
||||
--hl-sm: rgba(130, 130, 130, 0.2);
|
||||
--hl-md: rgba(130, 130, 130, 0.3);
|
||||
--hl-lg: rgba(130, 130, 130, 0.5);
|
||||
--hl-xl: rgba(130, 130, 130, 0.8);
|
||||
--hl: rgba(140, 140, 140, 1);
|
||||
|
||||
.tag {
|
||||
--color-success: #6ea932;
|
||||
@ -208,7 +208,7 @@ body {
|
||||
--color-font: #ddd;
|
||||
}
|
||||
|
||||
.dropdown__menu,
|
||||
.theme--dropdown__menu,
|
||||
.modal {
|
||||
--color-bg: #282925;
|
||||
}
|
||||
@ -217,7 +217,7 @@ body {
|
||||
--color-font: #ccc;
|
||||
}
|
||||
|
||||
.dropdown__menu {
|
||||
.theme--dropdown__menu {
|
||||
--color-font: #aaa;
|
||||
}
|
||||
}
|
||||
@ -273,7 +273,7 @@ body {
|
||||
--color-font: #657b83;
|
||||
}
|
||||
|
||||
.dropdown__menu,
|
||||
.theme--dropdown__menu,
|
||||
.modal {
|
||||
--color-bg: #fff8e5;
|
||||
}
|
||||
@ -303,7 +303,7 @@ body {
|
||||
--color-font: #8ea0a2;
|
||||
}
|
||||
|
||||
.dropdown__menu,
|
||||
.theme--dropdown__menu,
|
||||
.modal {
|
||||
--color-bg: #073642;
|
||||
}
|
||||
@ -342,7 +342,7 @@ body {
|
||||
}
|
||||
|
||||
.modal > *,
|
||||
.dropdown__menu {
|
||||
.theme--dropdown__menu {
|
||||
--color-bg: #303c43;
|
||||
--color-font: #dde1e1;
|
||||
}
|
||||
@ -370,7 +370,7 @@ body {
|
||||
.sidebar__item,
|
||||
.btn,
|
||||
.tag,
|
||||
.dropdown__menu,
|
||||
.theme--dropdown__menu,
|
||||
.CodeMirror,
|
||||
.pane__body,
|
||||
.modal__header,
|
||||
@ -424,7 +424,7 @@ body {
|
||||
--color-bg: rgba(238, 231, 213, 0.8);
|
||||
}
|
||||
|
||||
.dropdown__menu,
|
||||
.theme--dropdown__menu,
|
||||
.modal {
|
||||
--color-bg: #fff8e5;
|
||||
--color-font: #657b83;
|
||||
@ -477,7 +477,7 @@ body {
|
||||
--color-font: #e1deda;
|
||||
}
|
||||
|
||||
.dropdown__menu,
|
||||
.theme--dropdown__menu,
|
||||
.modal {
|
||||
--color-bg: #323232;
|
||||
}
|
||||
@ -535,6 +535,10 @@ body {
|
||||
color: var(--color-font) !important;
|
||||
}
|
||||
|
||||
.bg-default {
|
||||
background: var(--color-bg);
|
||||
}
|
||||
|
||||
.bg-success,
|
||||
.bg-http-method-POST {
|
||||
background: var(--color-success) !important;
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* Fonts */
|
||||
@font-size: 13px;
|
||||
@font-size-xxs: round(@font-size * 0.6);
|
||||
@font-size-xs: round(@font-size * 0.8);
|
||||
@font-size-sm: round(@font-size * 0.9);
|
||||
@font-size-md: round(@font-size * 1.0);
|
||||
@ -48,6 +49,10 @@
|
||||
@breakpoint-md: 880px;
|
||||
@breakpoint-sm: 660px;
|
||||
|
||||
.txt-xxs {
|
||||
font-size: @font-size-xxs !important;
|
||||
}
|
||||
|
||||
.txt-xs {
|
||||
font-size: @font-size-xs !important;
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
@import 'components/header-editor';
|
||||
@import 'components/key-value-editor';
|
||||
@import 'components/markdown-editor';
|
||||
@import 'components/markdown-preview';
|
||||
@import 'components/method-dropdown';
|
||||
@import 'components/modal';
|
||||
@import 'components/pane';
|
||||
|
@ -343,7 +343,7 @@ p.notice {
|
||||
}
|
||||
|
||||
/* Make all font awesome icons the same width */
|
||||
i.fa {
|
||||
i.fa:not(.fa--skinny) {
|
||||
min-width: 1.1rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user