@umami/shiso 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +11 -0
- package/.prettierrc.json +7 -0
- package/LICENSE +21 -0
- package/README.md +7 -0
- package/dist/index.css +158 -0
- package/dist/index.d.ts +95 -0
- package/dist/index.js +335 -0
- package/dist/index.mjs +302 -0
- package/dts.mjs +8 -0
- package/esbuild.mjs +36 -0
- package/next.config.ts +15 -0
- package/package.json +83 -0
- package/public/leaf.png +0 -0
- package/public/leaf.svg +1 -0
- package/src/app/Footer.tsx +14 -0
- package/src/app/Header.tsx +14 -0
- package/src/app/blog/[[...id]]/page.tsx +8 -0
- package/src/app/docs/[[...id]]/page.tsx +8 -0
- package/src/app/layout.tsx +41 -0
- package/src/app/page.tsx +25 -0
- package/src/assets/leaf.svg +1 -0
- package/src/components/Footer.module.css +0 -0
- package/src/components/Footer.tsx +1 -0
- package/src/components/Header.module.css +0 -0
- package/src/components/Header.tsx +0 -0
- package/src/components/Markdown.tsx +21 -0
- package/src/components/Shiso.tsx +19 -0
- package/src/components/blog/Blog.module.css +0 -0
- package/src/components/blog/Blog.tsx +21 -0
- package/src/components/docs/Callout.module.css +6 -0
- package/src/components/docs/Callout.tsx +18 -0
- package/src/components/docs/CodeBlock.module.css +37 -0
- package/src/components/docs/CodeBlock.tsx +30 -0
- package/src/components/docs/ContentArea.module.css +63 -0
- package/src/components/docs/ContentArea.tsx +27 -0
- package/src/components/docs/Docs.tsx +50 -0
- package/src/components/docs/Note.tsx +5 -0
- package/src/components/docs/PageLinks.module.css +49 -0
- package/src/components/docs/PageLinks.tsx +49 -0
- package/src/components/docs/SideNav.module.css +32 -0
- package/src/components/docs/SideNav.tsx +46 -0
- package/src/components/docs/TopNav.tsx +25 -0
- package/src/components/icons/Leaf.tsx +15 -0
- package/src/components/icons/index.ts +1 -0
- package/src/components/index.ts +8 -0
- package/src/content/blog/index.mdx +5 -0
- package/src/content/docs/components/index.mdx +1 -0
- package/src/content/docs/components.mdx +5 -0
- package/src/content/docs/configuration.mdx +81 -0
- package/src/content/docs/index.mdx +11 -0
- package/src/content/docs/installation.mdx +38 -0
- package/src/content/docs/writing-content.mdx +95 -0
- package/src/declarations.d.ts +3 -0
- package/src/index.ts +5 -0
- package/src/lib/content.ts +61 -0
- package/src/lib/next.tsx +46 -0
- package/src/lib/types.ts +10 -0
- package/src/shiso.config.json +59 -0
- package/tsconfig.build.json +24 -0
- package/tsconfig.json +41 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import classNames from 'classnames';
|
|
3
|
+
import styles from './Callout.module.css';
|
|
4
|
+
|
|
5
|
+
export interface CalloutProps {
|
|
6
|
+
variant: 'note' | 'warning' | 'info' | 'tip';
|
|
7
|
+
icon?: ReactNode;
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default function Callout({ variant = 'note', icon, children }: CalloutProps) {
|
|
12
|
+
return (
|
|
13
|
+
<div className={classNames(styles[variant])}>
|
|
14
|
+
{icon}
|
|
15
|
+
{children}
|
|
16
|
+
</div>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
.container {
|
|
2
|
+
position: relative;
|
|
3
|
+
background: var(--base-color-900);
|
|
4
|
+
padding: var(--spacing-5);
|
|
5
|
+
border-radius: 6px;
|
|
6
|
+
white-space: pre-wrap;
|
|
7
|
+
word-wrap: break-word;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
pre.container code {
|
|
11
|
+
font-family: var(--font-family-code);
|
|
12
|
+
color: var(--base-color-300);
|
|
13
|
+
padding: 0;
|
|
14
|
+
border: 0;
|
|
15
|
+
background: transparent;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.button {
|
|
19
|
+
border: 0;
|
|
20
|
+
position: absolute;
|
|
21
|
+
right: var(--spacing-5);
|
|
22
|
+
top: var(--spacing-5);
|
|
23
|
+
cursor: pointer;
|
|
24
|
+
background: transparent;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.copy {
|
|
28
|
+
color: var(--base-color-300);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.copy:hover {
|
|
32
|
+
color: var(--base-color-50);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.check {
|
|
36
|
+
color: var(--success-color);
|
|
37
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useState, useRef } from 'react';
|
|
3
|
+
import { Icon, Icons } from '@umami/react-zen';
|
|
4
|
+
import styles from './CodeBlock.module.css';
|
|
5
|
+
|
|
6
|
+
export function CodeBlock(props: any) {
|
|
7
|
+
const textInput = useRef<any>(null);
|
|
8
|
+
const [copied, setCopied] = useState(false);
|
|
9
|
+
|
|
10
|
+
const handleCopy = () => {
|
|
11
|
+
setCopied(true);
|
|
12
|
+
|
|
13
|
+
navigator?.clipboard?.writeText(textInput?.current?.textContent);
|
|
14
|
+
|
|
15
|
+
setTimeout(() => {
|
|
16
|
+
setCopied(false);
|
|
17
|
+
}, 1000);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<pre ref={textInput} className={styles.container}>
|
|
22
|
+
{props.children}
|
|
23
|
+
<button aria-label="Copy code" className={styles.button} onClick={handleCopy}>
|
|
24
|
+
<Icon size="sm" className={copied ? styles.check : styles.copy}>
|
|
25
|
+
{copied ? <Icons.Check /> : <Icons.Copy />}
|
|
26
|
+
</Icon>
|
|
27
|
+
</button>
|
|
28
|
+
</pre>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
.content {
|
|
2
|
+
font-size: 16px;
|
|
3
|
+
margin-bottom: 60px;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.content > p {
|
|
7
|
+
color: var(--font-muted-color);
|
|
8
|
+
line-height: 1.8;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.content a {
|
|
12
|
+
color: var(--font-color);
|
|
13
|
+
font-weight: 600;
|
|
14
|
+
text-decoration: underline var(--font-faded-color);
|
|
15
|
+
text-underline-offset: 4px;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.content a:hover {
|
|
19
|
+
text-decoration: underline var(--font-color);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.content h1 {
|
|
23
|
+
font-size: var(--font-size-8);
|
|
24
|
+
letter-spacing: var(--letter-spacing-1);
|
|
25
|
+
margin: 0 0 var(--spacing-4) 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.content h2 {
|
|
29
|
+
font-size: var(--font-size-6);
|
|
30
|
+
letter-spacing: var(--letter-spacing-1);
|
|
31
|
+
margin: var(--spacing-8) 0 var(--spacing-4) 0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.content h3 {
|
|
35
|
+
font-size: var(--font-size-5);
|
|
36
|
+
letter-spacing: var(--letter-spacing-1);
|
|
37
|
+
margin: var(--spacing-7) 0 var(--spacing-4) 0;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.content ul {
|
|
41
|
+
list-style: disc;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.content ol {
|
|
45
|
+
list-style: decimal;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.content pre {
|
|
49
|
+
margin: var(--spacing-5) 0;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.content code {
|
|
53
|
+
font-size: 14px;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.content code:not([class]) {
|
|
57
|
+
font-family: var(--font-family-code);
|
|
58
|
+
color: var(--font-color);
|
|
59
|
+
padding: var(--spacing-1);
|
|
60
|
+
border-radius: var(--border-radius);
|
|
61
|
+
background: var(--base-color-50);
|
|
62
|
+
font-weight: var(--font-weight-bold);
|
|
63
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Heading, Box, Text } from '@umami/react-zen';
|
|
2
|
+
import Markdown from '@/components/Markdown';
|
|
3
|
+
import styles from './ContentArea.module.css';
|
|
4
|
+
|
|
5
|
+
export interface ContentAreaProps {
|
|
6
|
+
title: string;
|
|
7
|
+
body: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
group?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function ContentArea({ title, description, group, body }: ContentAreaProps) {
|
|
13
|
+
return (
|
|
14
|
+
<Box flexGrow={1}>
|
|
15
|
+
<Text color="primary" weight="bold">
|
|
16
|
+
{group}
|
|
17
|
+
</Text>
|
|
18
|
+
<Heading size="8" as="h1">
|
|
19
|
+
{title}
|
|
20
|
+
</Heading>
|
|
21
|
+
<Text type="muted">{description}</Text>
|
|
22
|
+
<Box className={styles.content}>
|
|
23
|
+
<Markdown>{body}</Markdown>
|
|
24
|
+
</Box>
|
|
25
|
+
</Box>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Grid, Box, Heading } from '@umami/react-zen';
|
|
2
|
+
import PageLinks from './PageLinks';
|
|
3
|
+
import SideNav from './SideNav';
|
|
4
|
+
import TopNav from './TopNav';
|
|
5
|
+
import { ContentArea } from './ContentArea';
|
|
6
|
+
import { ShisoConfig } from '../Shiso';
|
|
7
|
+
|
|
8
|
+
export interface contentsProps {
|
|
9
|
+
config: ShisoConfig;
|
|
10
|
+
content: any;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function Docs({ content, config }: contentsProps) {
|
|
14
|
+
if (!content) {
|
|
15
|
+
return <Heading size="6">Page not found</Heading>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const { tabs, navigation } = config?.docs || {};
|
|
19
|
+
|
|
20
|
+
content.group = Object.keys(navigation).reduce((name, key) => {
|
|
21
|
+
if (!name) {
|
|
22
|
+
return navigation[key]?.find((section: { pages: any[] }) => {
|
|
23
|
+
return section.pages.find(
|
|
24
|
+
page =>
|
|
25
|
+
page.url === `/docs/${content.id}` || (page.url === `/docs` && content.id === 'index'),
|
|
26
|
+
);
|
|
27
|
+
})?.group;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return name;
|
|
31
|
+
}, null);
|
|
32
|
+
|
|
33
|
+
console.log({ config, tabs, content });
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<Box flexGrow="1">
|
|
37
|
+
{tabs && <TopNav tabs={tabs} />}
|
|
38
|
+
<Grid gap="6" columns="240px 1fr 240px">
|
|
39
|
+
<SideNav tabs={tabs} navigation={navigation} />
|
|
40
|
+
<ContentArea
|
|
41
|
+
title={content?.meta?.title}
|
|
42
|
+
body={content?.body}
|
|
43
|
+
group={content?.group}
|
|
44
|
+
description={content?.meta?.description}
|
|
45
|
+
/>
|
|
46
|
+
<PageLinks items={content?.anchors} offset={150} />
|
|
47
|
+
</Grid>
|
|
48
|
+
</Box>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
.title {
|
|
2
|
+
position: sticky;
|
|
3
|
+
top: 0;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.links {
|
|
7
|
+
position: sticky;
|
|
8
|
+
top: 30px;
|
|
9
|
+
height: max-content;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.links a {
|
|
13
|
+
display: block;
|
|
14
|
+
color: var(--font-muted-color);
|
|
15
|
+
text-wrap: nowrap;
|
|
16
|
+
text-decoration: none;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.links a:hover {
|
|
20
|
+
color: var(--primary-color);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.indent-1 {
|
|
24
|
+
margin-left: 0;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.indent-2 {
|
|
28
|
+
margin-left: 0;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.indent-3 {
|
|
32
|
+
margin-left: 10px;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.indent-4 {
|
|
36
|
+
margin-left: 20px;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.indent-5 {
|
|
40
|
+
margin-left: 30px;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.indent-6 {
|
|
44
|
+
margin-left: 40px;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
a.selected {
|
|
48
|
+
color: var(--primary-color);
|
|
49
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { Column, Text } from '@umami/react-zen';
|
|
4
|
+
import classNames from 'classnames';
|
|
5
|
+
import styles from './PageLinks.module.css';
|
|
6
|
+
|
|
7
|
+
export default function PageLinks({ items, offset = 0 }) {
|
|
8
|
+
const [hash, setHash] = useState(items?.[0]?.id);
|
|
9
|
+
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
const callback = () => {
|
|
12
|
+
const x = [...items].reverse().find(({ id }) => {
|
|
13
|
+
const rect = document.getElementById(id)?.getBoundingClientRect();
|
|
14
|
+
return rect && rect.top <= offset;
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
if (x) setHash(x.id);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
window.addEventListener('scroll', callback, false);
|
|
21
|
+
|
|
22
|
+
return () => {
|
|
23
|
+
window.removeEventListener('scroll', callback, false);
|
|
24
|
+
};
|
|
25
|
+
}, []);
|
|
26
|
+
|
|
27
|
+
if (!items?.length) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<Column gap="3" minWidth="240px" className={styles.links}>
|
|
33
|
+
<Text size="2" weight="bold">
|
|
34
|
+
On this page
|
|
35
|
+
</Text>
|
|
36
|
+
{items.map(({ name, id, size }) => {
|
|
37
|
+
return (
|
|
38
|
+
<a
|
|
39
|
+
key={id}
|
|
40
|
+
href={`#${id}`}
|
|
41
|
+
className={classNames(styles[`indent-${size}`], { [styles.selected]: hash === id })}
|
|
42
|
+
>
|
|
43
|
+
{name}
|
|
44
|
+
</a>
|
|
45
|
+
);
|
|
46
|
+
})}
|
|
47
|
+
</Column>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
.nav {
|
|
2
|
+
position: sticky;
|
|
3
|
+
top: 30px;
|
|
4
|
+
height: max-content;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.item {
|
|
8
|
+
color: var(--font-muted-color);
|
|
9
|
+
padding: 0;
|
|
10
|
+
border-radius: 0;
|
|
11
|
+
border-left: var(--border-size-1) solid var(--border-color);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.item a {
|
|
15
|
+
color: currentColor;
|
|
16
|
+
width: 100%;
|
|
17
|
+
padding: var(--padding-y) var(--padding-x);
|
|
18
|
+
text-decoration: none;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.item a:hover {
|
|
22
|
+
color: var(--primary-color);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.item.selected {
|
|
26
|
+
color: var(--font-color);
|
|
27
|
+
border-color: var(--primary-color);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.items header {
|
|
31
|
+
padding: var(--padding-y) 0;
|
|
32
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Box, List, ListItem, ListSection } from '@umami/react-zen';
|
|
4
|
+
import classNames from 'classnames';
|
|
5
|
+
import { usePathname } from 'next/navigation';
|
|
6
|
+
import Link from 'next/link';
|
|
7
|
+
import styles from './SideNav.module.css';
|
|
8
|
+
|
|
9
|
+
export interface SideNavProps {
|
|
10
|
+
tabs: any;
|
|
11
|
+
navigation: any;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default function SideNav({ tabs, navigation }: SideNavProps) {
|
|
15
|
+
const pathname = usePathname();
|
|
16
|
+
|
|
17
|
+
const tab = tabs.find(({ url, id }) => (id !== 'docs' ? pathname.startsWith(url) : false));
|
|
18
|
+
const menu = navigation[tab?.id || 'docs'];
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<Box className={styles.nav}>
|
|
22
|
+
<List items={navigation}>
|
|
23
|
+
{menu.map(({ group, pages }) => {
|
|
24
|
+
return (
|
|
25
|
+
<ListSection title={group} key={group} className={styles.items}>
|
|
26
|
+
{pages.map(({ label: text, url }, index: number) => {
|
|
27
|
+
return (
|
|
28
|
+
<ListItem
|
|
29
|
+
key={index}
|
|
30
|
+
className={classNames(styles.item, {
|
|
31
|
+
[styles.selected]: url === pathname,
|
|
32
|
+
})}
|
|
33
|
+
>
|
|
34
|
+
<Link href={url} prefetch={false}>
|
|
35
|
+
{text}
|
|
36
|
+
</Link>
|
|
37
|
+
</ListItem>
|
|
38
|
+
);
|
|
39
|
+
})}
|
|
40
|
+
</ListSection>
|
|
41
|
+
);
|
|
42
|
+
})}
|
|
43
|
+
</List>
|
|
44
|
+
</Box>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import Link from 'next/link';
|
|
3
|
+
import { usePathname } from 'next/navigation';
|
|
4
|
+
import { Tabs, TabList, Tab } from '@umami/react-zen';
|
|
5
|
+
|
|
6
|
+
export default function TopNav({ tabs }) {
|
|
7
|
+
const pathname = usePathname();
|
|
8
|
+
|
|
9
|
+
const tab = tabs.find(({ id, url }) => (id !== 'docs' ? pathname.startsWith(url) : false));
|
|
10
|
+
const selected = tab?.id || 'docs';
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<Tabs selectedKey={selected}>
|
|
14
|
+
<TabList items={tabs}>
|
|
15
|
+
{({ id, label, url }) => {
|
|
16
|
+
return (
|
|
17
|
+
<Tab id={id}>
|
|
18
|
+
<Link href={url}>{label}</Link>
|
|
19
|
+
</Tab>
|
|
20
|
+
);
|
|
21
|
+
}}
|
|
22
|
+
</TabList>
|
|
23
|
+
</Tabs>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { SVGProps } from 'react';
|
|
3
|
+
const SvgLeaf = (props: SVGProps<SVGSVGElement>) => (
|
|
4
|
+
<svg
|
|
5
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
6
|
+
width={512}
|
|
7
|
+
height={512}
|
|
8
|
+
data-name="Glyph Icon"
|
|
9
|
+
viewBox="0 0 64 64"
|
|
10
|
+
{...props}
|
|
11
|
+
>
|
|
12
|
+
<path d="M55.221 10.79a1.31 1.31 0 0 0-1.564.39c-4.738 5.882-18.607 6.77-22.746 6.903a18.3 18.3 0 0 0-3.067.366C7.277 22.636 7.589 37.763 8.173 42.299c.097.75.601 1.362 1.315 1.599a1.91 1.91 0 0 0 1.988-.492c2.403-2.49 7.671-6.969 15.952-8.985 3.422-.833 6.668-2.36 9.557-4.111-3.375 2.564-7.731 5.332-13.243 7.92-5.526 2.596-9.586 7.096-11.075 8.909a1.94 1.94 0 0 0-.423 1.483c.072.536.368 1.023.812 1.338 1.414 1.004 3.099 1.813 5.006 2.408 2.053.638 4.168.954 6.286.954 4.28 0 8.564-1.287 12.329-3.782 14.464-9.588 18.439-31.031 19.312-37.373a1.29 1.29 0 0 0-.768-1.377" />
|
|
13
|
+
</svg>
|
|
14
|
+
);
|
|
15
|
+
export default SvgLeaf;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Leaf } from './Leaf';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Components
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Configuration
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Config file
|
|
6
|
+
|
|
7
|
+
The `shiso.config.json` file contains the configuration options for your project.
|
|
8
|
+
|
|
9
|
+
The file has the following schema:
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{
|
|
13
|
+
"docs": {},
|
|
14
|
+
"blog": {}
|
|
15
|
+
}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
At the root level, the properties represent the different content sections of your project.
|
|
19
|
+
Shiso currently supports `docs` and `blog` content.
|
|
20
|
+
|
|
21
|
+
## Docs options
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"docs": {
|
|
26
|
+
"tabs": [
|
|
27
|
+
{
|
|
28
|
+
"id": "docs",
|
|
29
|
+
"label": "Documentation",
|
|
30
|
+
"url": "/docs"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"id": "components",
|
|
34
|
+
"label": "Components",
|
|
35
|
+
"url": "/docs/components"
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
"navigation": {
|
|
39
|
+
"docs": [
|
|
40
|
+
{
|
|
41
|
+
"group": "Getting started",
|
|
42
|
+
"pages": [
|
|
43
|
+
{
|
|
44
|
+
"label": "Overview",
|
|
45
|
+
"url": "/docs"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"label": "Installation",
|
|
49
|
+
"url": "/docs/installation"
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"group": "Basics",
|
|
55
|
+
"pages": [
|
|
56
|
+
{
|
|
57
|
+
"label": "Writing content",
|
|
58
|
+
"url": "/docs/writing-content"
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
],
|
|
63
|
+
"components": [
|
|
64
|
+
{
|
|
65
|
+
"group": "Components",
|
|
66
|
+
"pages": [
|
|
67
|
+
{
|
|
68
|
+
"label": "Overview",
|
|
69
|
+
"url": "/docs/components"
|
|
70
|
+
}
|
|
71
|
+
]
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Blog options
|
|
80
|
+
|
|
81
|
+
...
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Overview
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## What is Shiso?
|
|
6
|
+
|
|
7
|
+
Shiso lets you quickly build websites by focusing on writing content. Shiso takes care of the
|
|
8
|
+
design, layout and functionality while you provide the content through Markdown files. You can also
|
|
9
|
+
embed React components into your content with MDX.
|
|
10
|
+
|
|
11
|
+
Out of the box, Shiso provides templates for docs and blogs and works with [Next.js](/docs/).
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Installation
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
These instructions show how to set up Shiso in a Next.js project.
|
|
6
|
+
|
|
7
|
+
## 1. Install the package
|
|
8
|
+
|
|
9
|
+
```shell
|
|
10
|
+
npm install @umami/shiso
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## 2. Create page
|
|
14
|
+
|
|
15
|
+
In your `app` folder, create a folder for the content section you wish to add.
|
|
16
|
+
|
|
17
|
+
```text
|
|
18
|
+
src
|
|
19
|
+
├── app
|
|
20
|
+
│ └── docs
|
|
21
|
+
│ └── [[...id]]
|
|
22
|
+
│ └── page.jsx
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
In this case we are creating a section for `docs`.
|
|
26
|
+
|
|
27
|
+
In the `page.jsx` file, add the following code:
|
|
28
|
+
|
|
29
|
+
```javascript
|
|
30
|
+
import shiso from '@umami/shiso/next';
|
|
31
|
+
import config from '@/shiso.config.json';
|
|
32
|
+
|
|
33
|
+
const { getMetadata, renderPage } = shiso(config);
|
|
34
|
+
|
|
35
|
+
export const generateMetadata = getMetadata('SHISO');
|
|
36
|
+
|
|
37
|
+
export default renderPage('docs');
|
|
38
|
+
```
|