Added anchors for document headings

This commit is contained in:
Jori Lallo
2016-05-29 15:22:33 -07:00
parent 249c67011a
commit 4f630aadc8
5 changed files with 57 additions and 2 deletions

View File

@ -1,14 +1,27 @@
import slug from 'slug';
import truncate from 'truncate-html';
import marked, { Renderer } from 'marked';
import highlight from 'highlight.js';
slug.defaults.mode ='rfc3986';
const renderer = new Renderer();
renderer.code = (code, language) => {
const validLang = !!(language && highlight.getLanguage(language));
const highlighted = validLang ? highlight.highlight(language, code).value : code;
return `<pre><code class="hljs ${language}">${highlighted}</code></pre>`;
};
renderer.heading = (text, level) => {
const headingSlug = slug(text);
return `
<h${level}>
<a name="${headingSlug}" class="anchor" href="#${headingSlug}">
<span class="header-link">&nbsp;</span>
</a>
${text}
</h${level}>
`;
},
marked.setOptions({
renderer: renderer,

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 100 125" enable-background="new 0 0 100 100" xml:space="preserve"><path d="M82.641,40.452L69.984,53.109c-1.164,1.164-3.054,1.164-4.218,0s-1.164-3.054,0-4.218l12.657-12.657 c3.489-3.489,3.489-9.165,0-12.657s-9.165-3.489-12.657,0L48.891,40.452c-1.035,1.059-5.955,6.702,0,12.657 c1.164,1.164,1.164,3.054,0,4.218s-3.054,1.164-4.218,0c-8.343-8.343-3.648-17.445,0-21.093l16.875-16.875 c5.814-5.814,15.279-5.814,21.093,0C88.455,25.173,88.452,34.638,82.641,40.452z M57.327,44.673c-1.164-1.164-3.054-1.164-4.218,0 c-1.164,1.164-1.164,3.054,0,4.218c5.955,5.955,1.035,11.595,0,12.657L36.234,78.423c-3.489,3.489-9.165,3.489-12.657,0 c-3.492-3.489-3.489-9.165,0-12.657l12.657-12.657c1.164-1.164,1.164-3.054,0-4.218s-3.054-1.164-4.218,0L19.359,61.548 c-5.814,5.814-5.814,15.279,0,21.093c5.814,5.814,15.279,5.814,21.093,0l16.875-16.875C60.975,62.118,65.67,53.013,57.327,44.673z"/></svg>

After

Width:  |  Height:  |  Size: 1003 B

View File

@ -20,7 +20,10 @@ class Document extends React.Component {
name={ this.props.document.user.name }
timestamp={ this.props.document.createdAt }
/>
<div dangerouslySetInnerHTML={{ __html: this.props.document.html }} />
<div
className={ styles.document }
dangerouslySetInnerHTML={{ __html: this.props.document.html }}
/>
</div>
);
}

View File

@ -2,3 +2,28 @@
width: 100%;
padding: 20px;
}
.document {
h1, h2, h3, h4, h5, h6 {
:global {
.anchor {
visibility: hidden;
background-image: url('../../assets/icons/anchor.svg');
background-repeat: no-repeat;
background-size: 100%;
background-position: 0 center;
margin-left: -26px;
width: 20px;
display: inline-block;
}
}
&:hover {
:global {
.anchor {
visibility: visible;
}
}
}
}
}

View File

@ -17,6 +17,19 @@ class DocumentScene extends React.Component {
this.props.fetchDocumentAsync(documentId);
}
componentWillReceiveProps = (nextProps) => {
// Scroll to anchor after loading
const hash = this.props.location.hash;
if (nextProps.document && hash) {
const name = hash.split('#')[1];
setTimeout(() => {
const element = document.getElementsByName(name)[0];
if (element) element.scrollIntoView()
}, 0);
}
}
render() {
const document = this.props.document;
let title;