mirror of
https://github.com/jambonz/next-static-site.git
synced 2025-12-19 04:47:44 +00:00
Remove Nextra -- Custom docs theme
This commit is contained in:
25
.babelrc
Normal file
25
.babelrc
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"presets": [
|
||||
"next/babel"
|
||||
],
|
||||
"plugins": [
|
||||
[
|
||||
"prismjs",
|
||||
{
|
||||
"languages": [
|
||||
"javascript",
|
||||
"js",
|
||||
"json",
|
||||
"bash",
|
||||
"http"
|
||||
],
|
||||
"plugins": [
|
||||
"line-numbers",
|
||||
"show-language"
|
||||
],
|
||||
"theme": "okaidia",
|
||||
"css": true
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
@@ -37,4 +37,6 @@ We are using static data with [yamljs](https://www.npmjs.com/package/yamljs) and
|
||||
|
||||
## Jambonz developer docs
|
||||
|
||||
The project is using [Nextra.js](https://nextra.vercel.app) which provides a stylized developer docs theme for Next.js. We are loading theme CSS styles with the `styles/_nextra.scss` partial. It is being used to hide the frontend page links from the Nextra sidebar nav as there is currently no way to do this using pure nextra config. There is a [Github issue here](https://github.com/shuding/nextra/issues/59) referring to "Page exclusion from docs".
|
||||
The project is generating developer docs from markdown files using static file JS utilities alongside Next.js static paths/props system. We are leveraging their [catch-all](https://nextjs.org/docs/routing/dynamic-routes#optional-catch-all-routes) dynamic routes logic located at `pages/docs/[[...slug]].js`. The markdown files are in the `pages/docs` directory. The docs structure is controlled in the docs page YAML data located in `data/docs.yaml`. You can create docs markdown files at will in the `pages/docs` directory but they will not render in the sidebar nav until they are also added to the nav structure in this file.
|
||||
|
||||
We are using [remark](https://github.com/remarkjs/remark) & [remark-html](https://github.com/remarkjs/remark-html) as well as [gray-matter](https://github.com/jonschlinkert/gray-matter) for parsing the docs markdown files. Code syntax highlighting is done with [prismjs](https://prismjs.com) and the associative babel config is in the `.babelrc` file. It's important to leave the preset in this file that merges our config with `next/babel` so Next.js works properly.
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { nanoid } from 'nanoid';
|
||||
|
||||
import Link from 'next/link';
|
||||
|
||||
import { Button } from './jambonz-ui';
|
||||
import { homeObj } from '../lib/vars';
|
||||
import { nanoid } from 'nanoid';
|
||||
|
||||
function FooterItem({ obj }) {
|
||||
return (
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import Link from 'next/link';
|
||||
import classNames from 'classnames';
|
||||
import * as Icons from 'react-feather';
|
||||
import { nanoid } from 'nanoid';
|
||||
import { mobileMedia } from '../lib/vars';
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
import Link from 'next/link';
|
||||
|
||||
import { mobileMedia } from '../lib/vars';
|
||||
|
||||
|
||||
// Normalize how we work with the subtext as an array[]
|
||||
export function normalizeSubtext(subtext) {
|
||||
if (!Array.isArray(subtext)) {
|
||||
@@ -93,7 +96,7 @@ export function Hero({ data, subStyle }) {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classNames(classes)}>
|
||||
<section className={classNames(classes)}>
|
||||
<div className="wrap hero__wrap">
|
||||
<div className="hero__headline">
|
||||
<H1>{data.headline}</H1>
|
||||
@@ -109,7 +112,7 @@ export function Hero({ data, subStyle }) {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import Head from 'next/head';
|
||||
|
||||
import Navi from './navi';
|
||||
import Footer from './footer';
|
||||
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useState } from 'react';
|
||||
import { nanoid } from 'nanoid';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/router';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { Button, Icon, useMobileMedia } from './jambonz-ui';
|
||||
import { homeObj } from '../lib/vars';
|
||||
import { nanoid } from 'nanoid';
|
||||
|
||||
function NaviItem({obj}) {
|
||||
const router = useRouter();
|
||||
const classes = {
|
||||
navi__link: true,
|
||||
active: (router.route === obj.link),
|
||||
active: (router.route.replace('/[[...slug]]', '') === obj.link),
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
44
data/docs.yml
Normal file
44
data/docs.yml
Normal file
@@ -0,0 +1,44 @@
|
||||
navi:
|
||||
-
|
||||
path: getting-started
|
||||
title: Getting Started
|
||||
pages:
|
||||
-
|
||||
path: add-carrier
|
||||
title: Add a Carrier
|
||||
-
|
||||
path: add-speech
|
||||
title: Add Speech Credentials
|
||||
-
|
||||
path: add-application
|
||||
title: Add an Application
|
||||
-
|
||||
path: add-phone-numbers
|
||||
title: Add Phone Numbers
|
||||
-
|
||||
path: register-sip-client
|
||||
title: Register SIP clients
|
||||
-
|
||||
path: api
|
||||
title: API Reference
|
||||
pages:
|
||||
-
|
||||
path: webhooks
|
||||
title: Webhooks
|
||||
-
|
||||
path: rest
|
||||
title: REST APIs
|
||||
-
|
||||
path: tutorials
|
||||
title: Tutorials
|
||||
pages:
|
||||
-
|
||||
path: overview
|
||||
title: Overview
|
||||
-
|
||||
path: open-source
|
||||
title: Open Source
|
||||
pages:
|
||||
-
|
||||
path: overview
|
||||
title: Overview
|
||||
130
lib/data.js
130
lib/data.js
@@ -1,17 +1,147 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const yamljs = require('yamljs');
|
||||
const matter = require('gray-matter');
|
||||
const remark = require('remark');
|
||||
const remarkHtml = require('remark-html');
|
||||
const dataDir = path.join(process.cwd(), 'data');
|
||||
const pagesDir = path.join(process.cwd(), 'pages');
|
||||
const docsDir = path.join(pagesDir, 'docs');
|
||||
|
||||
/******************************************************************************
|
||||
* Static page data
|
||||
*******************************************************************************/
|
||||
function _getData(key) {
|
||||
const fullPath = path.join(dataDir, `${key}.yml`);
|
||||
const fileContents = fs.readFileSync(fullPath, 'utf8');
|
||||
return yamljs.parse(fileContents);
|
||||
}
|
||||
|
||||
// Load YAML data to generate the static props for Next.js page components
|
||||
export function getData(key) {
|
||||
return {
|
||||
[key]: _getData(key),
|
||||
site: _getData('site'),
|
||||
};
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Static developer docs data
|
||||
*******************************************************************************/
|
||||
function _getCleanSlug(slug) {
|
||||
return slug
|
||||
.replace(docsDir, '')
|
||||
.replace(/^\/+|\/+$/, '')
|
||||
.split('/');
|
||||
}
|
||||
|
||||
// Load Markdown and YAML front-matter to generate the static props for Next.js docs component
|
||||
async function _getDocs(filePath) {
|
||||
const fileContents = fs.readFileSync(filePath, 'utf8');
|
||||
const fileMatter = matter(fileContents);
|
||||
const frontMatter = fileMatter.data;
|
||||
|
||||
// Use remark to convert markdown into HTML string
|
||||
const processedContent = await remark()
|
||||
.use(remarkHtml)
|
||||
.process(fileMatter.content);
|
||||
const contentHtml = processedContent.toString();
|
||||
|
||||
// Combine the data with the slug and contentHtml
|
||||
return {
|
||||
contentHtml,
|
||||
frontMatter,
|
||||
}
|
||||
}
|
||||
|
||||
// Walk the pages/docs file tree to generate the static paths for Next.js docs pages
|
||||
function _getDocsPaths(dirPath, arrayOfFiles = [{params:{slug:[]}}]) {
|
||||
const files = fs.readdirSync(dirPath);
|
||||
|
||||
files.forEach((file) => {
|
||||
const filePath = `${dirPath}/${file}`;
|
||||
const isDirectory = fs.statSync(filePath).isDirectory();
|
||||
const isMarkdown = /\.md$/.test(file);
|
||||
let slug;
|
||||
|
||||
if (isDirectory) {
|
||||
const indexFile = path.join(filePath, 'index.md');
|
||||
const isIndexFile = fs.existsSync(indexFile);
|
||||
|
||||
if (isIndexFile) {
|
||||
slug = _getCleanSlug(path.join(
|
||||
__dirname,
|
||||
dirPath,
|
||||
'/',
|
||||
file
|
||||
));
|
||||
|
||||
arrayOfFiles.push({
|
||||
params: {
|
||||
slug,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
arrayOfFiles = _getDocsPaths(filePath, arrayOfFiles);
|
||||
|
||||
} else if (isMarkdown) {
|
||||
slug = _getCleanSlug(path.join(
|
||||
__dirname,
|
||||
dirPath,
|
||||
'/',
|
||||
file.replace(/\.md$/, '')
|
||||
));
|
||||
|
||||
arrayOfFiles.push({
|
||||
params: {
|
||||
slug,
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return arrayOfFiles;
|
||||
}
|
||||
|
||||
// Public proxy for _getDocs() to return static props for Next.js docs component
|
||||
export async function getDocs(slug) {
|
||||
let filePath = slug ? path.join(
|
||||
docsDir,
|
||||
slug.join('/')
|
||||
) : path.join(
|
||||
docsDir,
|
||||
'index.md'
|
||||
);
|
||||
const isDirectory = (fs.existsSync(filePath) && fs.statSync(filePath).isDirectory());
|
||||
let isMarkdown = /\.md$/.test(filePath);
|
||||
|
||||
if (isDirectory) {
|
||||
filePath = path.join(
|
||||
docsDir,
|
||||
slug.join('/'),
|
||||
'index.md'
|
||||
);
|
||||
isMarkdown = true;
|
||||
|
||||
} else if (!isMarkdown) {
|
||||
filePath = path.join(
|
||||
docsDir,
|
||||
`${slug.join('/')}.md`
|
||||
);
|
||||
isMarkdown = true;
|
||||
}
|
||||
|
||||
if (isMarkdown && fs.existsSync(filePath)) {
|
||||
return _getDocs(filePath);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Public proxy for _getDocsPaths() to return static paths for Next.js docs pages
|
||||
export function getDocsPaths() {
|
||||
const paths = _getDocsPaths(docsDir);
|
||||
|
||||
return paths;
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
const withNextra = require('nextra')('nextra-theme-docs', './theme.config.js')
|
||||
module.exports = withNextra()
|
||||
17
package.json
17
package.json
@@ -13,19 +13,22 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"classnames": "^2.2.6",
|
||||
"env-cmd": "^10.1.0",
|
||||
"nanoid": "^3.1.22",
|
||||
"next": "^10.0.8-canary.9",
|
||||
"nextra": "^0.4.1",
|
||||
"nextra-theme-docs": "^1.1.2",
|
||||
"prismjs": "^1.23.0",
|
||||
"react": "^17.0.1",
|
||||
"react-dom": "^17.0.1",
|
||||
"react-feather": "^2.0.9",
|
||||
"sass": "^1.32.8",
|
||||
"yamljs": "^0.3.0"
|
||||
"react-feather": "^2.0.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "^2.0.5"
|
||||
"babel-plugin-prismjs": "^2.0.1",
|
||||
"prettier": "^2.0.5",
|
||||
"gray-matter": "^4.0.2",
|
||||
"env-cmd": "^10.1.0",
|
||||
"remark": "^13.0.0",
|
||||
"remark-html": "^13.0.1",
|
||||
"sass": "^1.32.8",
|
||||
"yamljs": "^0.3.0"
|
||||
},
|
||||
"prettier": {
|
||||
"semi": false,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import 'nextra-theme-docs/style.css';
|
||||
import '../styles/global.scss';
|
||||
|
||||
export default function App({Component, pageProps}) {
|
||||
|
||||
112
pages/docs/[[...slug]].js
Normal file
112
pages/docs/[[...slug]].js
Normal file
@@ -0,0 +1,112 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { nanoid } from 'nanoid';
|
||||
import classNames from 'classnames';
|
||||
import Prism from 'prismjs';
|
||||
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/router';
|
||||
|
||||
import Layout from '../../components/layout';
|
||||
import { Icon } from '../../components/jambonz-ui';
|
||||
import { getData, getDocs, getDocsPaths } from '../../lib/data';
|
||||
|
||||
function Sidebar({data}) {
|
||||
const router = useRouter();
|
||||
const [active, setActive] = useState({
|
||||
[data.navi[0].path]: true,
|
||||
});
|
||||
|
||||
const handleToggle = (slug) => {
|
||||
setActive((oldActive) => {
|
||||
const newActive = {};
|
||||
|
||||
for (let i in oldActive) {
|
||||
newActive[i] = oldActive[i];
|
||||
}
|
||||
|
||||
newActive[slug] = newActive[slug] ? false : true;
|
||||
|
||||
return newActive;
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<nav className="bg-pink docs__navi">
|
||||
<ul className="docs__list">
|
||||
{data.navi.map((item) => {
|
||||
const isActiveToggle = (active[item.path] ? true : false);
|
||||
const subClasses = {
|
||||
'docs__sublist': true,
|
||||
'active': isActiveToggle,
|
||||
};
|
||||
|
||||
return (
|
||||
<li key={nanoid()} className="docs__item">
|
||||
<div className="m docs__label" onClick={() => handleToggle(item.path)}>
|
||||
<strong>{item.title}</strong>
|
||||
{isActiveToggle ? <Icon name="ChevronUp" /> : <Icon name="ChevronDown" />}
|
||||
</div>
|
||||
<ul className={classNames(subClasses)}>
|
||||
{item.pages.map((page) => {
|
||||
const isActiveItem = (router.asPath.split('/').pop() === page.path);
|
||||
const itemClasses = {
|
||||
'ms': true,
|
||||
'active': isActiveItem,
|
||||
};
|
||||
|
||||
return (
|
||||
<li key={nanoid()} className="docs__subitem">
|
||||
<Link href={`/docs/${item.path}/${page.path}`}>
|
||||
<a className={classNames(itemClasses)}>{page.title}</a>
|
||||
</Link>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Docs({ data, docs }) {
|
||||
useEffect(() => {
|
||||
setTimeout(() => Prism.highlightAll(), 0);
|
||||
});
|
||||
|
||||
return (
|
||||
<Layout siteData={data.site}>
|
||||
<div className="docs">
|
||||
<div className="wrap docs__wrap">
|
||||
<Sidebar data={data.docs} />
|
||||
<div className="docs__html">
|
||||
<div dangerouslySetInnerHTML={{ __html: docs.contentHtml }} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const paths = getDocsPaths();
|
||||
|
||||
return {
|
||||
paths,
|
||||
fallback: false,
|
||||
};
|
||||
}
|
||||
|
||||
export async function getStaticProps({ params }) {
|
||||
const data = getData('docs');
|
||||
const docs = await getDocs(params.slug);
|
||||
|
||||
return {
|
||||
props: {
|
||||
data,
|
||||
docs,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"code-highlighting": "Code Highlighting"
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
# Anchor Links
|
||||
|
||||
`h2` tags will become anchors in the sidebar automatically.
|
||||
|
||||
## When You Are Old
|
||||
|
||||
When you are old and grey and full of sleep,
|
||||
And nodding by the fire, take down this book,
|
||||
And slowly read, and dream of the soft look
|
||||
Your eyes had once, and of their shadows deep;
|
||||
|
||||
How many loved your moments of glad grace,
|
||||
And loved your beauty with love false or true,
|
||||
But one man loved the pilgrim soul in you,
|
||||
And loved the sorrows of your changing face;
|
||||
|
||||
And bending down beside the glowing bars,
|
||||
Murmur, a little sadly, how Love fled
|
||||
And paced upon the mountains overhead
|
||||
And hid his face amid a crowd of stars.
|
||||
|
||||
## The Young Man's Song
|
||||
|
||||
I whispered, "I am too young,"
|
||||
And then, "I am old enough";
|
||||
Wherefore I threw a penny
|
||||
To find out if I might love.
|
||||
"Go and love, go and love, young man,
|
||||
If the lady be young and fair,"
|
||||
Ah, penny, brown penny, brown penny,
|
||||
I am looped in the loops of her hair.
|
||||
|
||||
Oh, love is the crooked thing,
|
||||
There is nobody wise enough
|
||||
To find out all that is in it,
|
||||
For he would be thinking of love
|
||||
Till the stars had run away,
|
||||
And the shadows eaten the moon.
|
||||
Ah, penny, brown penny, brown penny,
|
||||
One cannot begin it too soon.
|
||||
|
||||
## The Sorrow of Love
|
||||
|
||||
The quarrel of the sparrows in the eaves,
|
||||
The full round moon and the star-laden sky,
|
||||
And the loud song of the ever-singing leaves,
|
||||
Had hid away earth's old and weary cry.
|
||||
|
||||
And then you came with those red mournful lips,
|
||||
And with you came the whole of the world's tears,
|
||||
And all the sorrows of her labouring ships,
|
||||
And all the burden of her myriad years.
|
||||
|
||||
And now the sparrows warring in the eaves,
|
||||
The curd-pale moon, the white stars in the sky,
|
||||
And the loud chaunting of the unquiet leaves
|
||||
Are shaken with earth's old and weary cry.
|
||||
1
pages/docs/api/webhooks.md
Normal file
1
pages/docs/api/webhooks.md
Normal file
@@ -0,0 +1 @@
|
||||
# Webhooks
|
||||
@@ -1,81 +0,0 @@
|
||||
# Built-In Components
|
||||
|
||||
Some helpful built-in components from `nextra-theme-docs`.
|
||||
|
||||
## Callout
|
||||
|
||||
import Callout from 'nextra-theme-docs/callout'
|
||||
|
||||
#### Example
|
||||
|
||||
<Callout>
|
||||
A **callout** is a short piece of text intended to attract attention.
|
||||
</Callout>
|
||||
|
||||
<Callout emoji="🦤">
|
||||
The **dodo** is an extinct flightless bird that was endemic to the island of Mauritius, east of Madagascar in the Indian Ocean.
|
||||
</Callout>
|
||||
|
||||
#### Usage
|
||||
|
||||
```mdx
|
||||
import Callout from 'nextra-theme-docs/callout'
|
||||
|
||||
<Callout emoji="🦤">
|
||||
The **dodo** is an extinct flightless bird.
|
||||
</Callout>
|
||||
```
|
||||
|
||||
## Bleed
|
||||
|
||||
import Bleed from 'nextra-theme-docs/bleed'
|
||||
|
||||
#### Example
|
||||
|
||||
When wrapping your content with `<Bleed>`, it will be slightly wider than the container
|
||||
and will overflow on both sides.
|
||||
|
||||
<Bleed>
|
||||
<div style={{ border: '1px solid #888', padding: '4rem 2.5rem', textAlign: 'center' }}>
|
||||
_There is nothing to writing. All you do is sit down at a typewriter and **bleed**._
|
||||
|
||||
— Ernest Hemingway
|
||||
</div>
|
||||
</Bleed>
|
||||
|
||||
It providers a better reading experience when you want to present some graphical information, which normally
|
||||
looks nicer in a larger size.
|
||||
|
||||
For example you can put text, image, video or any component inside:
|
||||
|
||||
<Bleed>
|
||||
<iframe width="100%" height="430" src="https://www.youtube.com/embed/3hccXiXI0u8" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen/>
|
||||
</Bleed>
|
||||
|
||||
You can even make it full-bleed using `<Bleed full>`:
|
||||
|
||||
<Bleed full>
|
||||

|
||||
</Bleed>
|
||||
|
||||
#### Usage
|
||||
|
||||
```mdx
|
||||
import Bleed from 'nextra-theme-docs/bleed'
|
||||
|
||||
<Bleed>
|
||||
Hey, I can use **Markdown** syntax here.
|
||||
</Bleed>
|
||||
|
||||
<Bleed full>
|
||||

|
||||
</Bleed>
|
||||
|
||||
<Bleed full>
|
||||
<iframe src="https://codesandbox.io/embed/swr-states-4une7"
|
||||
width="100%"
|
||||
height="500px"
|
||||
title="SWR-States"
|
||||
></iframe>
|
||||
</Bleed>
|
||||
```
|
||||
@@ -1,78 +0,0 @@
|
||||
# Get Started
|
||||
|
||||
Create your own Nextra site and deploy to Vercel:
|
||||
|
||||
[](https://vercel.com/import/git?s=https%3A%2F%2Fgithub.com%2Fshuding%2Fnextra&c=1)
|
||||
|
||||
Vercel will create the Nextra repository and deploy the site for you with just a few clicks.
|
||||
Once done, every change in the repository will be deployed automatically.
|
||||
|
||||
---
|
||||
|
||||
### Configurations
|
||||
|
||||
1. Install Next.js and React: `yarn add next react react-dom`
|
||||
|
||||
2. Install Nextra and the docs theme: `yarn add nextra nextra-theme-docs`
|
||||
|
||||
3. Create the following Next.js config and theme config under the root directory:
|
||||
|
||||
```jsx
|
||||
// next.config.js
|
||||
const withNextra = require('nextra')('nextra-theme-docs', './theme.config.js')
|
||||
module.exports = withNextra()
|
||||
```
|
||||
|
||||
```jsx
|
||||
// theme.config.js
|
||||
export default {
|
||||
repository: 'https://github.com/shuding/nextra', // project repo
|
||||
docsRepository: 'https://github.com/shuding/nextra', // docs repo
|
||||
branch: 'master', // branch of docs
|
||||
path: '/', // path of docs
|
||||
titleSuffix: ' – Nextra',
|
||||
nextLinks: true,
|
||||
prevLinks: true,
|
||||
search: true,
|
||||
customSearch: null, // customizable, you can use algolia for example
|
||||
darkMode: true,
|
||||
footer: true,
|
||||
footerText: 'MIT 2020 © Shu Ding.',
|
||||
footerEditOnGitHubLink: true, // will link to the docs repo
|
||||
logo: <>
|
||||
<svg>...</svg>
|
||||
<span>Next.js Static Site Generator</span>
|
||||
</>,
|
||||
head: <>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="description" content="Nextra: the next docs builder" />
|
||||
<meta name="og:title" content="Nextra: the next docs builder" />
|
||||
</>
|
||||
}
|
||||
```
|
||||
|
||||
4. Create `pages/_app.js` and include the theme stylesheet:
|
||||
|
||||
```jsx
|
||||
import 'nextra-theme-docs/style.css'
|
||||
|
||||
export default function Nextra({ Component, pageProps }) {
|
||||
return <Component {...pageProps} />
|
||||
}
|
||||
```
|
||||
|
||||
5. You are good to go!
|
||||
|
||||
---
|
||||
|
||||
import Callout from 'nextra-theme-docs/callout'
|
||||
|
||||
<Callout>
|
||||
Any `.md` or `.mdx` file will turn into a doc page and be displayed in sidebar. You can also create a `meta.json` file to customize the page order and title.
|
||||
|
||||
Check the source code: https://github.com/shuding/nextra for more information.
|
||||
</Callout>
|
||||
|
||||
<Callout>
|
||||
You can also use [`<style jsx>`](https://nextjs.org/docs/basic-features/built-in-css-support#css-in-js) to style elements inside `theme.config.js`.
|
||||
</Callout>
|
||||
3
pages/docs/getting-started/add-application.md
Normal file
3
pages/docs/getting-started/add-application.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Add an Application
|
||||
|
||||
TODO
|
||||
3
pages/docs/getting-started/add-carrier.md
Normal file
3
pages/docs/getting-started/add-carrier.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Add a Carrier
|
||||
|
||||
TODO
|
||||
3
pages/docs/getting-started/add-phone-numbers.md
Normal file
3
pages/docs/getting-started/add-phone-numbers.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Add Phone Numbers
|
||||
|
||||
TODO
|
||||
3
pages/docs/getting-started/add-speech.md
Normal file
3
pages/docs/getting-started/add-speech.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Add Speech Credentials
|
||||
|
||||
TODO
|
||||
3
pages/docs/getting-started/register-sip-client.md
Normal file
3
pages/docs/getting-started/register-sip-client.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Register sip clients
|
||||
|
||||
TODO
|
||||
@@ -1,40 +0,0 @@
|
||||
# I18n
|
||||
|
||||
Nextra supports [Next.js i18n](https://nextjs.org/docs/advanced-features/i18n-routing) out of the box.
|
||||
|
||||
To add multi-language pages to your Nextra application, just need to config `i18n` in `next.config.js`:
|
||||
|
||||
```js
|
||||
// next.config.js
|
||||
const withNextra = require('nextra')('nextra-theme-docs', './theme.config.js')
|
||||
module.exports = withNextra({
|
||||
i18n: {
|
||||
locales: ['en', 'zh', 'de'],
|
||||
defaultLocale: 'en',
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
And then, add the locale to your files as the extension (same for the default locale):
|
||||
|
||||
```
|
||||
/pages
|
||||
index.en.md
|
||||
index.zh.md
|
||||
index.de.md
|
||||
meta.en.json
|
||||
meta.zh.json
|
||||
meta.de.json
|
||||
...
|
||||
```
|
||||
|
||||
Finally, add the `i18n` option to your `theme.config.js` so the theme will show the dropdown menu:
|
||||
|
||||
```jsx
|
||||
i18n: [
|
||||
{ locale: 'en', text: 'English' },
|
||||
{ locale: 'zh', text: '中文' },
|
||||
{ locale: 'de', text: 'Deutsch' },
|
||||
{ locale: 'ar', text: 'العربية', direction: 'rtl' },
|
||||
]
|
||||
```
|
||||
@@ -1,7 +1,13 @@
|
||||
# Nextra
|
||||
# jambonz
|
||||
|
||||
**Nextra** is a [Next.js](https://nextjs.org) based static site generator. 0 lines of code needed.
|
||||
jambonz is a CPaaS that is designed for communications service providers. As an API-driven platform, you will primarily interface with it using [Webhooks]() and [REST APIs]().
|
||||
|
||||
It supports Markdown with React components ([MDX](/docs/mdx)), automatically generated [sidebar and anchor links](/docs/anchors), file-system based routing, built-in syntax highlighting, i18n and more.
|
||||
jambonz is available for use both as cloud APIs, or as an open source platform that you can run on your own infrastructure. Either way, your applications are written in the same fashion, so you can start off by using the cloud APIs and later migrate to running your own platform if you like.
|
||||
|
||||

|
||||
jambonz is also a "Bring Your Own Everything" (BYOE) CPaaS, meaning that you will [plug in your own SIP trunking providers](), and [use your own AWS or Google credentials]() for speech processing.
|
||||
|
||||
Follow the [Getting Started]() pages that follow to get yourself up and running on the cloud platform, or dive into the [API Reference]() or examine [client SDKs]() and [sample applications]() for inspiration.
|
||||
|
||||
```javascript
|
||||
const foo = "bar";
|
||||
```
|
||||
@@ -1,119 +0,0 @@
|
||||
# Markdown and React
|
||||
|
||||
You can write normal `.md` files or the more powerful `.mdx` format.
|
||||
|
||||
Use [MDX](https://mdxjs.com/about) to import and use React components inside your Markdown file:
|
||||
|
||||
```markdown
|
||||
import Callout from 'nextra-theme-docs/callout'
|
||||
|
||||
### Markdown With React Components
|
||||
|
||||
<Callout emoji="✅">
|
||||
**MDX** (the library), at its core, transforms MDX (the syntax) to JSX.
|
||||
It receives an MDX string and outputs a _JSX string_. It does this by parsing
|
||||
the MDX document to a syntax tree and then generates a JSX document from that tree.
|
||||
</Callout>
|
||||
```
|
||||
|
||||
Generates:
|
||||
|
||||
import Callout from 'nextra-theme-docs/callout'
|
||||
|
||||
### Markdown With React Components
|
||||
|
||||
<Callout emoji="✅">
|
||||
**MDX** (the library), at its core, transforms MDX (the syntax) to JSX.
|
||||
It receives an MDX string and outputs a _JSX string_. It does this by parsing
|
||||
the MDX document to a syntax tree and then generates a JSX document from that tree.
|
||||
</Callout>
|
||||
|
||||
## List
|
||||
|
||||
1. one
|
||||
2. two
|
||||
3. three
|
||||
|
||||
- one
|
||||
- two
|
||||
- three
|
||||
|
||||
---
|
||||
|
||||
# **Hello**, This Is a _Title_ Inside `h1`
|
||||
## **Hello**, This Is a _Title_ Inside `h2`
|
||||
### **Hello**, This Is a _Title_ Inside `h3`
|
||||
#### **Hello**, This Is a _Title_ Inside `h4`
|
||||
##### **Hello**, This Is a _Title_ Inside `h5`
|
||||
###### **Hello**, This Is a _Title_ Inside `h6`
|
||||
|
||||
## Code Highlighting
|
||||
|
||||
Code highlighting with focused lines using
|
||||
|
||||
````markdown
|
||||
```jsx highlight=2,3
|
||||
function App() {
|
||||
// these 2 lines will be highlighted
|
||||
return <App>My JSX Code</App>
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
```jsx highlight=4,8
|
||||
import useSWR from 'swr'
|
||||
|
||||
function Profile() {
|
||||
const { data, error } = useSWR('/api/user', fetcher)
|
||||
|
||||
if (error) return <div>failed to load</div>
|
||||
if (!data) return <div>loading...</div>
|
||||
return <div>hello {data.name}!</div>
|
||||
}
|
||||
```
|
||||
|
||||
Inline code: `let x = 1`.
|
||||
Multiple lines: `x += 1`.
|
||||
|
||||
## Blockquote
|
||||
|
||||
> Where some people measure progress in answers-right per test or tests-passed per year, we are more interested in Sistine-Chapel-Ceilings per Lifetime.
|
||||
>
|
||||
> — Alan Kay, A Personal Computer for Children of All Ages
|
||||
|
||||
And nested quotes:
|
||||
|
||||
> > Where some people measure progress in answers-right per test or tests-passed per year, we are more interested in Sistine-Chapel-Ceilings per Lifetime.
|
||||
> >
|
||||
> > — Alan Kay, A Personal Computer for Children of All Ages
|
||||
>
|
||||
> This is **great**.
|
||||
>
|
||||
> — Shu Ding.
|
||||
|
||||
## Table
|
||||
|
||||
| Syntax | Description | Test Text |
|
||||
| :--- | :----: | ---: |
|
||||
| Header | Title | Here's this |
|
||||
| Paragraph | Text | And more |
|
||||
| Strikethrough | | ~~Text~~ |
|
||||
|
||||
With `next/image`:
|
||||
|
||||
import Image from 'next/image'
|
||||
|
||||
| Image |
|
||||
| :--- |
|
||||
| <Image src="/og.png" alt="Nextra" width={1536/2} height={768/2} layout="intrinsic"/> |
|
||||
| `<Image src="/og.png" alt="Nextra" width={1536/2} height={768/2} layout="intrinsic"/>` |
|
||||
|
||||
## Task List
|
||||
|
||||
- [x] Write the press release
|
||||
- [ ] Update the website
|
||||
- [ ] Contact the media
|
||||
|
||||
---
|
||||
|
||||
Click the "Edit this page on GitHub" link below to see the code.
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"get-started": "Get Started",
|
||||
"structure": "Structure",
|
||||
"mdx": "Markdown and React",
|
||||
"built-in-components": "Built-In Components",
|
||||
"ssg": "SSG Support",
|
||||
"anchors": "Anchor Links",
|
||||
"i18n": "I18n",
|
||||
"advanced": "Advanced"
|
||||
}
|
||||
1
pages/docs/open-source/overview.md
Normal file
1
pages/docs/open-source/overview.md
Normal file
@@ -0,0 +1 @@
|
||||
# Overview
|
||||
@@ -1,32 +0,0 @@
|
||||
# Next.js SSG in MDX
|
||||
|
||||
import { useSSG } from 'nextra/ssg'
|
||||
|
||||
export const getStaticProps = ({ params }) => {
|
||||
return fetch('https://api.github.com/repos/shuding/nextra')
|
||||
.then(res => res.json())
|
||||
.then(repo => ({
|
||||
props: {
|
||||
// We return an `ssg` object in the props.
|
||||
ssg: {
|
||||
stars: repo.stargazers_count
|
||||
}
|
||||
},
|
||||
revalidate: 5
|
||||
}))
|
||||
}
|
||||
|
||||
export const StarsRenderer = () => {
|
||||
// And later we can get it inside MDX.
|
||||
const { stars } = useSSG()
|
||||
return <strong>{stars}</strong>
|
||||
}
|
||||
|
||||
The [Nextra repository](https://github.com/shuding/nextra) has <StarsRenderer/> stars!
|
||||
|
||||
---
|
||||
|
||||
The page is prerendered at build time with [`getStaticProps`](https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation)
|
||||
and [Incremental Static Regeneration](https://nextjs.org/docs/basic-features/data-fetching#incremental-static-regeneration).
|
||||
|
||||
Check the source code for more information.
|
||||
@@ -1,7 +0,0 @@
|
||||
# Structure
|
||||
|
||||
Just put all the Markdown files (`.md`, `.mdx`) under the `pages` directory. File system is the best way to organize your documentation:
|
||||
|
||||

|
||||
|
||||
You can also use a `meta.json` file to config the order and displayed name of the page ([example](https://github.com/shuding/nextra/blob/master/pages/meta.json)).
|
||||
1
pages/docs/tutorials/overview.md
Normal file
1
pages/docs/tutorials/overview.md
Normal file
@@ -0,0 +1 @@
|
||||
# Overview
|
||||
@@ -1,13 +1,14 @@
|
||||
import { nanoid } from 'nanoid';
|
||||
import classNames from 'classnames';
|
||||
import { useState, useEffect, useRef } from 'react';
|
||||
|
||||
import Layout from '../components/layout';
|
||||
import { Hero, Icon, Button, H6, H5, H2, P, MS, normalizeSubtext, normalizeSlug, useMobileMedia } from '../components/jambonz-ui';
|
||||
import { getData } from '../lib/data';
|
||||
import { useState, useEffect, useRef } from 'react';
|
||||
|
||||
function Tech({data}) {
|
||||
return (
|
||||
<div className="tech wrap">
|
||||
<section className="tech wrap">
|
||||
<div className="tech__image">
|
||||
<img src={data.image} />
|
||||
</div>
|
||||
@@ -23,7 +24,7 @@ function Tech({data}) {
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -54,7 +55,7 @@ function Dilemma({data}) {
|
||||
}, [mobile, active, setActive, initialRef]);
|
||||
|
||||
return (
|
||||
<div className="bg-grey dilemma pad">
|
||||
<section className="bg-grey dilemma pad">
|
||||
<div className="wrap dilemma__wrap">
|
||||
<div className="dilemma__headline">
|
||||
<H2>{data.headline}</H2>
|
||||
@@ -113,13 +114,13 @@ function Dilemma({data}) {
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
function BYO({data}) {
|
||||
return (
|
||||
<div className="byo pad">
|
||||
<section className="byo pad">
|
||||
<div className="wrap byo__wrap">
|
||||
<div className="byo__headline">
|
||||
<H2>{data.headline}</H2>
|
||||
@@ -142,7 +143,7 @@ function BYO({data}) {
|
||||
<Button href={data.url} subStyle="dark" target="_blank">{data.cta}</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Layout from '../components/layout';
|
||||
import Link from 'next/link';
|
||||
import Image from 'next/image';
|
||||
|
||||
import Layout from '../components/layout';
|
||||
import { P, M, MS, MXS, H1, H2, H3, H4, H5, H6, Button, Icon } from '../components/jambonz-ui';
|
||||
import { getData } from '../lib/data';
|
||||
|
||||
@@ -109,7 +109,7 @@ export default function JambonzUI({ data }) {
|
||||
<MXS>{pageData.text}</MXS>
|
||||
</div>
|
||||
<div className="pad">
|
||||
<Image src="/images/Jambonz_app_screenshot.png" width={1280 / 2} height={842 / 2} />
|
||||
<img src="/images/Jambonz_app_screenshot.png" />
|
||||
</div>
|
||||
<div className="pad">
|
||||
<div className="icons">
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"docs": "Jambonz Docs"
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
import { nanoid } from 'nanoid';
|
||||
|
||||
import Layout from '../components/layout';
|
||||
import Link from 'next/link';
|
||||
import { Hero, Icon, Button, H2, H5, P, M, MS } from '../components/jambonz-ui';
|
||||
import { getData } from '../lib/data';
|
||||
import { nanoid } from 'nanoid';
|
||||
|
||||
function Touts({data}) {
|
||||
return (
|
||||
<div className="bg-pink touts">
|
||||
<section className="bg-pink touts">
|
||||
<div className="wrap touts__wrap">
|
||||
{data.map((tout) => {
|
||||
return (
|
||||
@@ -17,13 +17,13 @@ function Touts({data}) {
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
function Tiers({ data }) {
|
||||
return (
|
||||
<div className="tiers pad">
|
||||
<section className="tiers pad">
|
||||
<div className="wrap tiers__wrap">
|
||||
{data.map((tier) => {
|
||||
return (
|
||||
@@ -52,13 +52,13 @@ function Tiers({ data }) {
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
function Services({data}) {
|
||||
return (
|
||||
<div className="bg-grey services pad">
|
||||
<section className="bg-grey services pad">
|
||||
<div className="wrap services__wrap">
|
||||
<div className="services__headline">
|
||||
<H2>{data.headline}</H2>
|
||||
@@ -85,7 +85,7 @@ function Services({data}) {
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
11
pages/why.js
11
pages/why.js
@@ -1,11 +1,12 @@
|
||||
import { nanoid } from 'nanoid';
|
||||
|
||||
import Layout from '../components/layout';
|
||||
import { Hero, Icon, Button, H5, H2, P } from '../components/jambonz-ui';
|
||||
import { getData } from '../lib/data';
|
||||
import { nanoid } from 'nanoid';
|
||||
|
||||
function Facts({data}) {
|
||||
return (
|
||||
<div className="bg-pink facts">
|
||||
<section className="bg-pink facts">
|
||||
<div className="wrap facts__wrap">
|
||||
<div className="facts__items">
|
||||
{data.map((fact) => {
|
||||
@@ -21,13 +22,13 @@ function Facts({data}) {
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
function OS({data}) {
|
||||
return (
|
||||
<div className="os pad">
|
||||
<section className="os pad">
|
||||
<div className="wrap os__wrap">
|
||||
<div className="os__headline">
|
||||
<H2>
|
||||
@@ -55,7 +56,7 @@ function OS({data}) {
|
||||
<Button href={data.url} subStyle="dark" target="_blank">{data.cta}</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,4 +16,13 @@
|
||||
em {
|
||||
font-family: 'objectivitymedium_slanted';
|
||||
}
|
||||
}
|
||||
|
||||
@mixin p() {
|
||||
font-size: $p-size;
|
||||
line-height: 1.9;
|
||||
|
||||
@media (max-width: $width-tablet-2) {
|
||||
font-size: $m-size;
|
||||
}
|
||||
}
|
||||
@@ -54,7 +54,7 @@
|
||||
cursor: pointer;
|
||||
|
||||
.icon {
|
||||
transform: translateY(-3px);
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
|
||||
@media (max-width: $width-tablet-2) {
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
.nextra-container {
|
||||
.sidebar > ul {
|
||||
> li:not(:first-child) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
77
styles/_reset.scss
Normal file
77
styles/_reset.scss
Normal file
@@ -0,0 +1,77 @@
|
||||
/******************************************************************************
|
||||
* CSS Reset
|
||||
* Add / Remove / Tweak this for your project.
|
||||
* The philosophy behind the CSS Reset is personal application customization.
|
||||
*
|
||||
* This approach is preferred over options like Normalize, which make way
|
||||
* too many assumptions and apply styles on top of the basic property resets.
|
||||
*
|
||||
* Though this CSS Reset is very basic and has not been updated in quite some
|
||||
* time, since 2011, it serves as a great starting point.
|
||||
*
|
||||
* Know what you are resetting and have piloted conrtol of your web app ;-)
|
||||
*
|
||||
*
|
||||
* http://meyerweb.com/eric/tools/css/reset/
|
||||
* v2.0 | 20110126
|
||||
* License: none (public domain)
|
||||
*******************************************************************************/
|
||||
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font: inherit;
|
||||
font-size: 100%;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
html {
|
||||
line-height: 1;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
*,
|
||||
*:before,
|
||||
*:after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
ol, ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
caption, th, td {
|
||||
text-align: left;
|
||||
font-weight: normal;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
q, blockquote {
|
||||
quotes: none;
|
||||
}
|
||||
|
||||
q:before, q:after, blockquote:before, blockquote:after {
|
||||
content: "";
|
||||
content: none;
|
||||
}
|
||||
|
||||
a img {
|
||||
border: none;
|
||||
}
|
||||
|
||||
article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section, summary, main {
|
||||
display: block;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
@@ -67,7 +67,7 @@ em {
|
||||
font-family: 'objectivityitalic';
|
||||
}
|
||||
|
||||
.h1 {
|
||||
.h1, h1 {
|
||||
font-size: $h1-size;
|
||||
line-height: 1.33;
|
||||
letter-spacing: -0.06px;
|
||||
@@ -86,7 +86,7 @@ em {
|
||||
}
|
||||
}
|
||||
|
||||
.h2 {
|
||||
.h2, h2 {
|
||||
font-size: $h2-size;
|
||||
line-height: 1.35;
|
||||
letter-spacing: -0.05px;
|
||||
@@ -105,7 +105,7 @@ em {
|
||||
}
|
||||
}
|
||||
|
||||
.h3 {
|
||||
.h3, h3 {
|
||||
font-size: $h3-size;
|
||||
line-height: 1.33;
|
||||
letter-spacing: -0.05px;
|
||||
@@ -124,7 +124,7 @@ em {
|
||||
}
|
||||
}
|
||||
|
||||
.h4 {
|
||||
.h4, h4 {
|
||||
font-size: $h4-size;
|
||||
line-height: 1.5;
|
||||
letter-spacing: -0.04px;
|
||||
@@ -143,7 +143,7 @@ em {
|
||||
}
|
||||
}
|
||||
|
||||
.h5 {
|
||||
.h5, h5 {
|
||||
font-size: $h5-size;
|
||||
line-height: 1.67;
|
||||
letter-spacing: -0.03px;
|
||||
@@ -167,7 +167,7 @@ em {
|
||||
// }
|
||||
}
|
||||
|
||||
.h6 {
|
||||
.h6, h6 {
|
||||
font-size: $h6-size;
|
||||
line-height: 1.8;
|
||||
letter-spacing: -0.03px;
|
||||
@@ -187,13 +187,8 @@ em {
|
||||
// }
|
||||
}
|
||||
|
||||
.p {
|
||||
font-size: $p-size;
|
||||
line-height: 1.9;
|
||||
|
||||
@media (max-width: $width-tablet-2) {
|
||||
font-size: $m-size;
|
||||
}
|
||||
.p, p {
|
||||
@include p();
|
||||
}
|
||||
|
||||
.m {
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
@import 'vars.scss';
|
||||
@import 'mixins.scss';
|
||||
|
||||
/******************************************************************************
|
||||
* Reset
|
||||
*******************************************************************************/
|
||||
@import 'reset.scss';
|
||||
|
||||
/******************************************************************************
|
||||
* Fonts
|
||||
*******************************************************************************/
|
||||
@@ -50,9 +55,5 @@
|
||||
@import 'pages/home.scss';
|
||||
@import 'pages/why.scss';
|
||||
@import 'pages/pricing.scss';
|
||||
@import 'pages/jambonz-ui.scss';
|
||||
|
||||
/******************************************************************************
|
||||
* Nextra
|
||||
*******************************************************************************/
|
||||
@import 'nextra.scss';
|
||||
@import 'pages/docs.scss';
|
||||
@import 'pages/jambonz-ui.scss';
|
||||
108
styles/pages/_docs.scss
Normal file
108
styles/pages/_docs.scss
Normal file
@@ -0,0 +1,108 @@
|
||||
.docs {
|
||||
padding-top: 64px;
|
||||
padding-bottom: 96px;
|
||||
|
||||
@media (max-width: $width-tablet-1) {
|
||||
padding-top: 16px;
|
||||
padding-bottom: 64px;
|
||||
}
|
||||
|
||||
&__wrap {
|
||||
display: flex;
|
||||
|
||||
@media (max-width: $width-tablet-1) {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
&__navi {
|
||||
max-width: calc(224px + 32px);
|
||||
padding: 16px;
|
||||
width: 100%;
|
||||
border-radius: 8px;
|
||||
border: 2px solid $jambonz;
|
||||
margin-right: 32px;
|
||||
|
||||
@media (max-width: $width-tablet-1) {
|
||||
max-width: 100%;
|
||||
margin: 0 0 32px;
|
||||
}
|
||||
}
|
||||
|
||||
&__html {
|
||||
max-width: $width-tablet-2;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
|
||||
@media (max-width: $width-tablet-1) {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
> div {
|
||||
> h1, > h2, > h3, > h4, > h5, > h6, > p, > div, > ul, > ol {
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
> ol, > ul {
|
||||
padding-left: 64px;
|
||||
|
||||
@media (max-width: $width-tablet-1) {
|
||||
padding-left: 32px;
|
||||
}
|
||||
|
||||
li {
|
||||
list-style-type: disc;
|
||||
@include p();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> div > :first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__item {
|
||||
+ .docs__item {
|
||||
margin-top: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
&__label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
cursor: pointer;
|
||||
color: $jambonz;
|
||||
|
||||
svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
stroke: $jambonz;
|
||||
}
|
||||
}
|
||||
|
||||
&__sublist {
|
||||
padding-left: 16px;
|
||||
display: none;
|
||||
|
||||
&.active {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
&__subitem {
|
||||
a {
|
||||
line-height: 1.5;
|
||||
color: $charcoal;
|
||||
|
||||
&.active {
|
||||
@include font-bold();
|
||||
}
|
||||
}
|
||||
|
||||
+ .docs__subitem {
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
export default {
|
||||
path: 'docs',
|
||||
repository: 'https://github.com/jambonz/next-static-site',
|
||||
docsRepository: 'https://github.com/jambonz/next-static-site',
|
||||
branch: 'main',
|
||||
titleSuffix: ' – Jambonz',
|
||||
logo: (
|
||||
<>
|
||||
<span className="mr-2 font-extrabold hidden md:inline">Jambonz</span>
|
||||
<span className="text-gray-600 font-normal hidden md:inline">
|
||||
Home
|
||||
</span>
|
||||
</>
|
||||
),
|
||||
head: (
|
||||
<>
|
||||
<meta name="msapplication-TileColor" content="#ffffff" />
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta httpEquiv="Content-Language" content="en" />
|
||||
<meta name="description" content="Nextra: the next site builder" />
|
||||
<meta name="og:description" content="Nextra: the next site builder" />
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:image" content="https://jambonz.vercel.app/og.png" />
|
||||
<meta name="twitter:site:domain" content="jambonz.vercel.app" />
|
||||
<meta name="twitter:url" content="https://jambonz.vercel.app" />
|
||||
<meta name="og:title" content="Nextra: Next.js static site generator" />
|
||||
<meta name="og:image" content="https://jambonz.vercel.app/og.png" />
|
||||
<meta name="apple-mobile-web-app-title" content="Jambonz" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png"/>
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="/android-icon-192x192.png"/>
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/>
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png"/>
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/>
|
||||
<meta name="msapplication-TileImage" content="/ms-icon-144x144.png"/>
|
||||
</>
|
||||
),
|
||||
search: true,
|
||||
prevLinks: true,
|
||||
nextLinks: true,
|
||||
footer: true,
|
||||
footerEditOnGitHubLink: true,
|
||||
footerText: <>MIT {new Date().getFullYear()} © Nextra.</>
|
||||
}
|
||||
Reference in New Issue
Block a user