Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: code block tab #1063

Merged
merged 8 commits into from
Jan 24, 2019
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions v1/lib/core/CodeTabsMarkdownBlock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import _ from 'lodash';

const React = require('react');
const Remarkable = require('./Remarkable');

/**
* The MarkdownBlock component is used to parse markdown and render to HTML.
*/
class MarkdownBlock extends React.Component {
render() {
const groupId = _.uniqueId();

const tabs = this.props.children.map(({title, content}) => ({
id: _.uniqueId(),
groupId: groupId,
label: title,
lang: title,
panelContent: <Remarkable source={content} />,
}));

return (
<div className="tabs">
<div className="nav-tabs">
{tabs.map((t, i) => (
<div
className={`nav-link${i === 0 ? ' active' : ''}`}
id={`${t.id}-tab`}
data-group={`group_${t.groupId}`}
data-tab={`tabpanel_${t.id}`}>
{t.label}
</div>
))}
</div>
<div className="tab-content">
{tabs.map((t, i) => (
<div
className={`tab-pane${i === 0 ? ' active' : ''}`}
data-group={`group_${t.groupId}`}
tabIndex="-1"
id={`tabpanel_${t.id}`}>
{t.panelContent}
</div>
))}
</div>
</div>
);
}
}

module.exports = MarkdownBlock;
45 changes: 42 additions & 3 deletions v1/lib/core/Doc.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

const React = require('react');
const MarkdownBlock = require('./MarkdownBlock.js');
const CodeTabsMarkdownBlock = require('./CodeTabsMarkdownBlock.js');

const translate = require('../server/translate.js').translate;

Expand All @@ -17,8 +18,46 @@ const translateThisDoc = translate(
'Translate this Doc|recruitment message asking to translate the docs',
);

const splitTabsToTitleAndContent = content => {
const tabs = content.match(/TAB_TITLE(.*?)END_TAB/gms);
const titleAndContentRegex = /^TAB_TITLE=([^\n]+)(.*?)END_TAB$/s;
if (tabs && tabs.length) {
return tabs.map(tab => {
const temp = tab.match(titleAndContentRegex);
return {title: temp[1], content: temp[2]};
});
}
return null;
};
// inner doc component for article itself
class Doc extends React.Component {
renderContent() {
const {content} = this.props;
let inCodeTabs = false;
const contents = content.split(
/(DOCUSAURUS_CODE_TABS\n)(.*?)(\nEND_DOCUSAURUS_CODE_TABS)/gms,
);
const renderResult = contents.map(c => {
if (c === 'DOCUSAURUS_CODE_TABS\n') {
inCodeTabs = true;
return null;
}
if (c === '\nEND_DOCUSAURUS_CODE_TABS') {
inCodeTabs = false;
return null;
}
if (inCodeTabs) {
return (
<CodeTabsMarkdownBlock>
{splitTabsToTitleAndContent(c)}
</CodeTabsMarkdownBlock>
);
}
return <MarkdownBlock>{c}</MarkdownBlock>;
});
return renderResult;
}

render() {
let docSource = this.props.source;

Expand Down Expand Up @@ -59,6 +98,8 @@ class Doc extends React.Component {
);
}

// const a = this.props.content.split(/(DOCUSAURUS_CODE_TABS)(.*?)(END_DOCUSAURUS_CODE_TABS)/gms)
// console.log(a.length, a);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove these.

return (
<div className="post">
<header className="postHeader">
Expand All @@ -67,9 +108,7 @@ class Doc extends React.Component {
<h1 className="postHeaderTitle">{this.props.title}</h1>
)}
</header>
<article>
<MarkdownBlock>{this.props.content}</MarkdownBlock>
</article>
<article>{this.renderContent()}</article>
</div>
);
}
Expand Down
54 changes: 54 additions & 0 deletions v1/lib/static/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -2354,3 +2354,57 @@ input::placeholder {
padding: 5px 0;
}
/* End of Footer */


.tabs {
border-top: 1px solid #cfcfcf;
}

.nav-tabs {
display: flex;
border-bottom: 4px solid #e0e0e0;
width: 100%;
padding: 0;
overflow-x: auto;
white-space: nowrap;
max-height: 100%;
}

.nav-tabs::-webkit-scrollbar {
display: none;
}

.tabs .tab-pane:focus {
outline: none;
}

.tabs .nav-tabs > div {
font-size: 14px;
line-height: 1.14286;
padding: 12px 16px;
text-decoration: none;
display: block;
cursor: pointer;
}

.tabs .nav-tabs > div.active {
border-bottom: 4px solid $primaryColor;
}

.tab-pane {
display: none;
}

.tab-pane.active {
display: block;
}

.tab-pane > pre {
white-space: pre-wrap;
}

.tab-pane > pre > code {
margin-top: 0;
border-radius: 0;
box-shadow: none;
}
21 changes: 21 additions & 0 deletions v1/website/static/js/code-blocks-buttons.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,25 @@ window.addEventListener('load', function() {
textEl.textContent = 'Copy';
}, 2000);
});

// add event listener for all tab
document.querySelectorAll('.nav-link').forEach(function(el) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will need to make sure that this is installed as part of the Docusaurus install process -- e.g., docusaurus-init

el.addEventListener('click', function(e) {
const groupId = e.target.getAttribute('data-group');
document
.querySelectorAll(`.nav-link[data-group=${groupId}]`)
.forEach(function(el) {
el.classList.remove('active');
});
document
.querySelectorAll(`.tab-pane[data-group=${groupId}]`)
.forEach(function(el) {
el.classList.remove('active');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldnt be placed here because not every docusaurus user has this file

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@endiliey I suggested that we add it as part of docusaurus-init. But you might be right, since that is more of a custom file. Could put it in v1/lib/static maybe?

Copy link
Contributor Author

@fiennyangeln fiennyangeln Oct 26, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm yeah I'm confused where to put it actually 😯 I put it there to mimic the code blocks

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I make something like this? https://gist.github.com/yangshun/55db997ed0f8f4e6527571fc3bee4675 and put all the related css outside of the lib?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

put it in v1/lib/static and modify the Head.js to always include it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@endiliey @JoelMarcey made the changes:D please review!

});
e.target.classList.add('active');
document
.querySelector(`#${e.target.getAttribute('data-tab')}`)
.classList.add('active');
});
});
});
96 changes: 96 additions & 0 deletions v1/website/versioned_docs/version-1.0.15/guides-custom-pages.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,108 @@ root-of-repo
│ └── static
```


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

## Codeblocks in multiple languages

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add some wording about what is going on here.

DOCUSAURUS_CODE_TABS
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a clever way to do this.

TAB_TITLE=Javascript
```js
const a = 33 + 4;
console.log(a);
```
END_TAB
TAB_TITLE=Python
```py
a = 33 + 4
print(a)
```
END_TAB
END_DOCUSAURUS_CODE_TABS

Of course, you are also free to write your own pages. It is strongly suggested that you at least have an index page, but none of the pages provided are mandatory to include in your site. More information on how to use the provided components or include your own can be found [here](api-pages.md). Information on how to link to your different pages in the header navigation bar can be found [here](guides-navigation.md).

> If you want your page to show up in your navigation header, you will need to update `siteConfig.js` to add to the `headerLinks` element. e.g., `{ page: 'about-slash', label: 'About/' }`,

## Adding Static Pages

DOCUSAURUS_CODE_TABS
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure you need this all this example here if you add the documentation to https://github.com/facebook/Docusaurus/blob/master/docs/api-doc-markdown.md

TAB_TITLE=Javascript
```js
const a = 33 + 4;
```
END_TAB
TAB_TITLE=Python
```py
a = 33 + 4;
```
END_TAB
TAB_TITLE=React
```jsx
const React = require('react');

class HelloWorld extends React.Component {
render() {
return <p>Hello, World!</p>;
}
}
```
END_TAB
TAB_TITLE=Java
```java
public class Main {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
```
END_TAB
TAB_TITLE=C++
```java
public class Main {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
```
END_TAB
TAB_TITLE=C
```java
public class Main {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
```
END_TAB
TAB_TITLE=C#
```java
public class Main {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
```
END_TAB
TAB_TITLE=LongName
```java
public class Main {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
```
END_TAB
TAB_TITLE=Long name
```java
public class Main {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
```
END_TAB
END_DOCUSAURUS_CODE_TABS

Static `.html` files can also be used, but they will not include Docusaurus' header, footer, or styles by default. These can be added to the `static` folder in the same way as other [static assets](api-pages.md#using-static-assets). Alternatively, they can be placed in the `pages` folder and would be served as-is instead of being rendered from React.

If you wish to use Docusaurus' stylesheet, you can access it at `${baseUrl}css/main.css`. If you wish to use separate css for these static pages, you can exclude them from being concatenated to Docusaurus' styles by adding them into the `siteConfig.separateCss` field in `siteConfig.js`.
Expand Down