Remove Nextra -- Custom docs theme

This commit is contained in:
kitajchuk
2021-04-06 17:52:42 -07:00
parent 10960dd69f
commit 51b270cb80
45 changed files with 785 additions and 1520 deletions

25
.babelrc Normal file
View 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
}
]
]
}

View File

@@ -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.

View File

@@ -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 (

View File

@@ -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>
);
}

View File

@@ -1,4 +1,5 @@
import Head from 'next/head';
import Navi from './navi';
import Footer from './footer';

View File

@@ -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
View 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

View File

@@ -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;
}

View File

@@ -1,2 +0,0 @@
const withNextra = require('nextra')('nextra-theme-docs', './theme.config.js')
module.exports = withNextra()

View File

@@ -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,

View File

@@ -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
View 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,
},
};
}

View File

@@ -1,3 +0,0 @@
{
"code-highlighting": "Code Highlighting"
}

View File

@@ -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.

View File

@@ -0,0 +1 @@
# Webhooks

View File

@@ -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>
![Landscape](https://source.unsplash.com/eaxwP9J_V6s/1600x398)
</Bleed>
#### Usage
```mdx
import Bleed from 'nextra-theme-docs/bleed'
<Bleed>
Hey, I can use **Markdown** syntax here.
</Bleed>
<Bleed full>
![Landscape](https://source.unsplash.com/eaxwP9J_V6s/1600x398)
</Bleed>
<Bleed full>
<iframe src="https://codesandbox.io/embed/swr-states-4une7"
width="100%"
height="500px"
title="SWR-States"
></iframe>
</Bleed>
```

View File

@@ -1,78 +0,0 @@
# Get Started
Create your own Nextra site and deploy to Vercel:
[![](https://vercel.com/button)](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>

View File

@@ -0,0 +1,3 @@
# Add an Application
TODO

View File

@@ -0,0 +1,3 @@
# Add a Carrier
TODO

View File

@@ -0,0 +1,3 @@
# Add Phone Numbers
TODO

View File

@@ -0,0 +1,3 @@
# Add Speech Credentials
TODO

View File

@@ -0,0 +1,3 @@
# Register sip clients
TODO

View File

@@ -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' },
]
```

View File

@@ -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.
![](/demo.png)
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";
```

View File

@@ -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.

View File

@@ -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"
}

View File

@@ -0,0 +1 @@
# Overview

View File

@@ -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.

View File

@@ -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:
![](/demo.png)
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)).

View File

@@ -0,0 +1 @@
# Overview

View File

@@ -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>
);
}

View File

@@ -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">

View File

@@ -1,3 +0,0 @@
{
"docs": "Jambonz Docs"
}

View File

@@ -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>
);
}

View File

@@ -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>
);
}

View File

@@ -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;
}
}

View File

@@ -54,7 +54,7 @@
cursor: pointer;
.icon {
transform: translateY(-3px);
transform: translateY(-5px);
}
@media (max-width: $width-tablet-2) {

View File

@@ -1,7 +0,0 @@
.nextra-container {
.sidebar > ul {
> li:not(:first-child) {
display: none;
}
}
}

77
styles/_reset.scss Normal file
View 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%;
}

View File

@@ -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 {

View File

@@ -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
View 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;
}
}
}

View File

@@ -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.</>
}

1153
yarn.lock

File diff suppressed because it is too large Load Diff