docs: make widget docs editable (#1782)
* make widget docs editable * update widget doc frontmatter keys * improve docs preview * fix formatting * fix preview * add prism highlighting for previews * fix formatting * restore cms branch
This commit is contained in:
@ -1,16 +1,45 @@
|
||||
import React from 'react';
|
||||
import CMS from 'netlify-cms';
|
||||
import dayjs from 'dayjs';
|
||||
import Prism from 'prismjs';
|
||||
import { BlogPostTemplate } from '../templates/blog-post';
|
||||
import { DocsTemplate } from '../templates/doc-page';
|
||||
import WidgetDoc from '../components/widget-doc';
|
||||
import Release from '../components/release';
|
||||
import WhatsNew from '../components/whats-new';
|
||||
import Notification from '../components/notification';
|
||||
import '../css/lib/prism.css';
|
||||
import '../css/imports/docs.css';
|
||||
import '../css/imports/whatsnew.css';
|
||||
import '../css/imports/header.css';
|
||||
|
||||
const withHighlight = WrappedComponent =>
|
||||
class Highlight extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.ref = React.createRef();
|
||||
}
|
||||
|
||||
highlight() {
|
||||
Prism.highlightAllUnder(this.ref.current);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.highlight();
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.highlight();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="language-markup" ref={this.ref}>
|
||||
<WrappedComponent {...this.props} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const BlogPostPreview = ({ entry, widgetFor }) => {
|
||||
const data = entry.get('data');
|
||||
return (
|
||||
@ -27,6 +56,10 @@ const DocsPreview = ({ entry, widgetFor }) => (
|
||||
<DocsTemplate title={entry.getIn(['data', 'title'])} body={widgetFor('body')} />
|
||||
);
|
||||
|
||||
const WidgetDocPreview = ({ entry, widgetFor }) => (
|
||||
<WidgetDoc visible={true} label={entry.get('label')} body={widgetFor('body')} />
|
||||
);
|
||||
|
||||
const ReleasePreview = ({ entry }) => (
|
||||
<WhatsNew>
|
||||
{entry.getIn(['data', 'updates']).map((release, idx) => (
|
||||
@ -50,7 +83,8 @@ const NotificationPreview = ({ entry }) =>
|
||||
</Notification>
|
||||
));
|
||||
|
||||
CMS.registerPreviewTemplate('blog', BlogPostPreview);
|
||||
CMS.registerPreviewTemplate('docs', DocsPreview);
|
||||
CMS.registerPreviewTemplate('blog', withHighlight(BlogPostPreview));
|
||||
CMS.registerPreviewTemplate('docs', withHighlight(DocsPreview));
|
||||
CMS.registerPreviewTemplate('widget_docs', withHighlight(WidgetDocPreview));
|
||||
CMS.registerPreviewTemplate('releases', ReleasePreview);
|
||||
CMS.registerPreviewTemplate('notifications', NotificationPreview);
|
||||
|
11
website/src/components/widget-doc.js
Normal file
11
website/src/components/widget-doc.js
Normal file
@ -0,0 +1,11 @@
|
||||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
|
||||
const WidgetDoc = ({ visible, label, body, html }) => (
|
||||
<div className={classnames('widget', { widget_open: visible })}>
|
||||
<h3>{label}</h3>
|
||||
{body ? body : <div dangerouslySetInnerHTML={{ __html: html }} />}
|
||||
</div>
|
||||
);
|
||||
|
||||
export default WidgetDoc;
|
@ -1,5 +1,6 @@
|
||||
import React, { Component } from 'react';
|
||||
import classnames from 'classnames';
|
||||
import WidgetDoc from './widget-doc';
|
||||
|
||||
import '../css/imports/widgets.css';
|
||||
|
||||
@ -13,7 +14,7 @@ class Widgets extends Component {
|
||||
|
||||
const hash = window.location.hash ? window.location.hash.replace('#', '') : '';
|
||||
|
||||
const widgetsContainHash = widgets.edges.some(w => w.node.frontmatter.target === hash);
|
||||
const widgetsContainHash = widgets.edges.some(w => w.node.frontmatter.title === hash);
|
||||
|
||||
if (widgetsContainHash) {
|
||||
return this.setState({
|
||||
@ -22,18 +23,18 @@ class Widgets extends Component {
|
||||
}
|
||||
|
||||
this.setState({
|
||||
currentWidget: widgets.edges[0].node.frontmatter.target,
|
||||
currentWidget: widgets.edges[0].node.frontmatter.title,
|
||||
});
|
||||
}
|
||||
|
||||
handleWidgetChange = (event, target) => {
|
||||
handleWidgetChange = (event, title) => {
|
||||
event.preventDefault();
|
||||
this.setState(
|
||||
{
|
||||
currentWidget: target,
|
||||
currentWidget: title,
|
||||
},
|
||||
() => {
|
||||
window.history.pushState(null, null, `#${target}`);
|
||||
window.history.pushState(null, null, `#${title}`);
|
||||
},
|
||||
);
|
||||
};
|
||||
@ -47,14 +48,14 @@ class Widgets extends Component {
|
||||
<section className="widgets">
|
||||
<div className="widgets__cloud">
|
||||
{widgets.edges.map(({ node }) => {
|
||||
const { label, target } = node.frontmatter;
|
||||
const { label, title } = node.frontmatter;
|
||||
return (
|
||||
<button
|
||||
key={target}
|
||||
key={title}
|
||||
className={classnames('widgets__item', {
|
||||
widgets__item_active: currentWidget === target,
|
||||
widgets__item_active: currentWidget === title,
|
||||
})}
|
||||
onClick={event => this.handleWidgetChange(event, target)}
|
||||
onClick={event => this.handleWidgetChange(event, title)}
|
||||
>
|
||||
{label}
|
||||
</button>
|
||||
@ -63,18 +64,10 @@ class Widgets extends Component {
|
||||
</div>
|
||||
<div className="widgets__container">
|
||||
{widgets.edges.map(({ node }) => {
|
||||
const { label, target } = node.frontmatter;
|
||||
return (
|
||||
<div
|
||||
key={label}
|
||||
className={classnames('widget', {
|
||||
widget_open: currentWidget === target,
|
||||
})}
|
||||
>
|
||||
<h3>{label}</h3>
|
||||
<div dangerouslySetInnerHTML={{ __html: node.html }} />
|
||||
</div>
|
||||
);
|
||||
const { frontmatter, html } = node;
|
||||
const { title, label } = frontmatter;
|
||||
const isVisible = currentWidget === title;
|
||||
return <WidgetDoc key={label} visible={isVisible} label={label} html={html} />;
|
||||
})}
|
||||
</div>
|
||||
</section>
|
||||
|
@ -1,120 +0,0 @@
|
||||
/**
|
||||
* prism.js tomorrow night eighties for JavaScript, CoffeeScript, CSS and HTML
|
||||
* Based on https://github.com/chriskempson/tomorrow-theme
|
||||
* @author Rose Pritchard
|
||||
*/
|
||||
|
||||
code[class*='language-'],
|
||||
pre[class*='language-'] {
|
||||
color: #ccc;
|
||||
background: none;
|
||||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-break: normal;
|
||||
word-wrap: normal;
|
||||
line-height: 1.5;
|
||||
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
pre[class*='language-'] {
|
||||
padding: 1em;
|
||||
margin: 0.5em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
:not(pre) > code[class*='language-'],
|
||||
pre[class*='language-'] {
|
||||
background: #2d2d2d;
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
:not(pre) > code[class*='language-'] {
|
||||
padding: 0.1em;
|
||||
border-radius: 0.3em;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.token.comment,
|
||||
.token.block-comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.token.punctuation {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.token.tag,
|
||||
.token.attr-name,
|
||||
.token.namespace,
|
||||
.token.deleted {
|
||||
color: #e2777a;
|
||||
}
|
||||
|
||||
.token.function-name {
|
||||
color: #6196cc;
|
||||
}
|
||||
|
||||
.token.boolean,
|
||||
.token.number,
|
||||
.token.function {
|
||||
color: #f08d49;
|
||||
}
|
||||
|
||||
.token.property,
|
||||
.token.class-name,
|
||||
.token.constant,
|
||||
.token.symbol {
|
||||
color: #f8c555;
|
||||
}
|
||||
|
||||
.token.selector,
|
||||
.token.important,
|
||||
.token.atrule,
|
||||
.token.keyword,
|
||||
.token.builtin {
|
||||
color: #cc99cd;
|
||||
}
|
||||
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.attr-value,
|
||||
.token.regex,
|
||||
.token.variable {
|
||||
color: #7ec699;
|
||||
}
|
||||
|
||||
.token.operator,
|
||||
.token.entity,
|
||||
.token.url {
|
||||
color: #67cdcc;
|
||||
}
|
||||
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
.token.inserted {
|
||||
color: green;
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import Helmet from 'react-helmet';
|
||||
import { graphql } from 'gatsby';
|
||||
import 'prismjs/themes/prism-tomorrow.css';
|
||||
|
||||
import Layout from '../components/layout';
|
||||
import EditLink from '../components/edit-link';
|
||||
@ -8,7 +9,6 @@ import Widgets from '../components/widgets';
|
||||
import DocsNav from '../components/docs-nav';
|
||||
import MobileNav from '../components/mobile-nav';
|
||||
|
||||
import '../css/lib/prism.css';
|
||||
import '../css/imports/docs.css';
|
||||
|
||||
const toMenu = (menu, nav) =>
|
||||
@ -124,8 +124,8 @@ export const pageQuery = graphql`
|
||||
edges {
|
||||
node {
|
||||
frontmatter {
|
||||
title
|
||||
label
|
||||
target
|
||||
}
|
||||
html
|
||||
}
|
||||
|
Reference in New Issue
Block a user