doccupine 0.0.6 → 0.0.8
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/README.md +1 -1
- package/dist/index.js +1 -1
- package/dist/templates/components/Docs.d.ts +1 -1
- package/dist/templates/components/Docs.js +143 -31
- package/dist/templates/components/layout/DocsComponents.d.ts +1 -1
- package/dist/templates/components/layout/DocsComponents.js +60 -27
- package/dist/templates/components/layout/Header.d.ts +1 -1
- package/dist/templates/components/layout/Header.js +13 -192
- package/package.json +9 -5
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Welcome to Doccupine
|
|
2
2
|
|
|
3
|
-
Doccupine is a free and open-source document management system that allows you to store, organize, and share your documentation with ease. Using Doccupine, you simply create your documentation in MDX files with traditional Markdown syntax, Doccupine monitors your changes automatically generating a beautiful, modern documentation website.
|
|
3
|
+
[Doccupine](https://doccupine.com) is a free and open-source document management system that allows you to store, organize, and share your documentation with ease. Using Doccupine, you simply create your documentation in MDX files with traditional Markdown syntax, Doccupine monitors your changes automatically generating a beautiful, modern documentation website.
|
|
4
4
|
|
|
5
5
|
## Open Source and Extensible
|
|
6
6
|
|
package/dist/index.js
CHANGED
|
@@ -469,7 +469,7 @@ export default function Home() {
|
|
|
469
469
|
program
|
|
470
470
|
.name("doccupine")
|
|
471
471
|
.description("Watch MDX files and generate Next.js documentation pages automatically")
|
|
472
|
-
.version("0.0.
|
|
472
|
+
.version("0.0.8");
|
|
473
473
|
program
|
|
474
474
|
.command("watch", { isDefault: true })
|
|
475
475
|
.description("Watch a directory for MDX changes and generate Next.js app")
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const docsTemplate = "\"use client\";\nimport { Flex } from \"cherry-styled-components/src/lib\";\nimport Markdown from \"react-markdown\";\nimport remarkGfm from \"remark-gfm\";\nimport { Code } from \"@/components/layout/Code\";\nimport { \n DocsContainer,\n StyledMarkdownContainer,\n} from \"@/components/layout/DocsComponents\";\n\ninterface DocsProps {\n content: string;\n}\n \nfunction Docs({ content }: DocsProps) {\n return (\n <DocsContainer>\n
|
|
1
|
+
export declare const docsTemplate = "\"use client\";\nimport { useEffect, useState } from \"react\";\nimport { Flex, Space } from \"cherry-styled-components/src/lib\";\nimport Markdown from \"react-markdown\";\nimport remarkGfm from \"remark-gfm\";\nimport { Code } from \"@/components/layout/Code\";\nimport { \n DocsContainer,\n StyledMarkdownContainer,\n StyledIndexSidebar,\n} from \"@/components/layout/DocsComponents\";\nimport { StyledText } from \"@/components/layout/Typography\";\n\ninterface DocsProps {\n content: string;\n}\n\n\ninterface Heading {\n id: string;\n text: string;\n level: number;\n}\n\nfunction generateId(text: string): string {\n return text\n .toLowerCase()\n .replace(/[^\\w\\s-]/g, \"\")\n .replace(/\\s+/g, \"-\")\n .trim();\n}\n\nfunction extractHeadings(content: string): Heading[] {\n const headingRegex = /^(#{1,6})\\s+(.+)$/gm;\n const headings: Heading[] = [];\n let match;\n\n while ((match = headingRegex.exec(content)) !== null) {\n const level = match[1].length;\n const text = match[2].trim();\n const id = generateId(text);\n headings.push({ id, text, level });\n }\n\n return headings;\n}\n \nfunction Docs({ content }: DocsProps) {\n const [headings, setHeadings] = useState<Heading[]>([]);\n\n useEffect(() => {\n if (content) {\n const extractedHeadings = extractHeadings(content);\n setHeadings(extractedHeadings);\n }\n }, [content]);\n\n return (\n <>\n <DocsContainer>\n <Flex $gap={20}>\n <StyledMarkdownContainer>\n {content && (\n <Markdown\n remarkPlugins={[remarkGfm]}\n components={{\n code(props) {\n const { children, className, node, ...rest } = props;\n const match = /language-(\\w+)/.exec(className || \"\");\n return match ? (\n <Code\n {...rest}\n className={className}\n code={String(children).replace(/\\n$/, \"\")}\n language={match[1]}\n />\n ) : (\n <code {...rest} className={className}>\n {children}\n </code>\n );\n },\n h1: ({ children, ...props }) => {\n const id = generateId(String(children));\n return (\n <h1 id={id} {...props}>\n {children}\n </h1>\n );\n },\n h2: ({ children, ...props }) => {\n const id = generateId(String(children));\n return (\n <h2 id={id} {...props}>\n {children}\n </h2>\n );\n },\n h3: ({ children, ...props }) => {\n const id = generateId(String(children));\n return (\n <h3 id={id} {...props}>\n {children}\n </h3>\n );\n },\n h4: ({ children, ...props }) => {\n const id = generateId(String(children));\n return (\n <h4 id={id} {...props}>\n {children}\n </h4>\n );\n },\n h5: ({ children, ...props }) => {\n const id = generateId(String(children));\n return (\n <h5 id={id} {...props}>\n {children}\n </h5>\n );\n },\n h6: ({ children, ...props }) => {\n const id = generateId(String(children));\n return (\n <h6 id={id} {...props}>\n {children}\n </h6>\n );\n },\n }}\n >\n {content}\n </Markdown>\n )}\n </StyledMarkdownContainer>\n </Flex>\n </DocsContainer>\n <StyledIndexSidebar>\n {headings?.length > 0 && (\n <>\n <StyledText>On this page</StyledText>\n <Space $size={20} />\n </>\n )}\n {headings.map((heading, index) => (\n <li\n key={index}\n style={\n {\n // paddingLeft: `${(heading.level - 1) * 16}px`,\n }\n }\n >\n <a href={`#${heading.id}`}>{heading.text}</a>\n </li>\n ))}\n </StyledIndexSidebar>\n </>\n );\n}\n\nexport { Docs };\n";
|
|
@@ -1,50 +1,162 @@
|
|
|
1
1
|
export const docsTemplate = `"use client";
|
|
2
|
-
import {
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import { Flex, Space } from "cherry-styled-components/src/lib";
|
|
3
4
|
import Markdown from "react-markdown";
|
|
4
5
|
import remarkGfm from "remark-gfm";
|
|
5
6
|
import { Code } from "@/components/layout/Code";
|
|
6
7
|
import {
|
|
7
8
|
DocsContainer,
|
|
8
9
|
StyledMarkdownContainer,
|
|
10
|
+
StyledIndexSidebar,
|
|
9
11
|
} from "@/components/layout/DocsComponents";
|
|
12
|
+
import { StyledText } from "@/components/layout/Typography";
|
|
10
13
|
|
|
11
14
|
interface DocsProps {
|
|
12
15
|
content: string;
|
|
13
16
|
}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
interface Heading {
|
|
20
|
+
id: string;
|
|
21
|
+
text: string;
|
|
22
|
+
level: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function generateId(text: string): string {
|
|
26
|
+
return text
|
|
27
|
+
.toLowerCase()
|
|
28
|
+
.replace(/[^\\w\\s-]/g, "")
|
|
29
|
+
.replace(/\\s+/g, "-")
|
|
30
|
+
.trim();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function extractHeadings(content: string): Heading[] {
|
|
34
|
+
const headingRegex = /^(#{1,6})\\s+(.+)$/gm;
|
|
35
|
+
const headings: Heading[] = [];
|
|
36
|
+
let match;
|
|
37
|
+
|
|
38
|
+
while ((match = headingRegex.exec(content)) !== null) {
|
|
39
|
+
const level = match[1].length;
|
|
40
|
+
const text = match[2].trim();
|
|
41
|
+
const id = generateId(text);
|
|
42
|
+
headings.push({ id, text, level });
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return headings;
|
|
46
|
+
}
|
|
14
47
|
|
|
15
48
|
function Docs({ content }: DocsProps) {
|
|
49
|
+
const [headings, setHeadings] = useState<Heading[]>([]);
|
|
50
|
+
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
if (content) {
|
|
53
|
+
const extractedHeadings = extractHeadings(content);
|
|
54
|
+
setHeadings(extractedHeadings);
|
|
55
|
+
}
|
|
56
|
+
}, [content]);
|
|
57
|
+
|
|
16
58
|
return (
|
|
17
|
-
|
|
18
|
-
<
|
|
19
|
-
<
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
{
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
59
|
+
<>
|
|
60
|
+
<DocsContainer>
|
|
61
|
+
<Flex $gap={20}>
|
|
62
|
+
<StyledMarkdownContainer>
|
|
63
|
+
{content && (
|
|
64
|
+
<Markdown
|
|
65
|
+
remarkPlugins={[remarkGfm]}
|
|
66
|
+
components={{
|
|
67
|
+
code(props) {
|
|
68
|
+
const { children, className, node, ...rest } = props;
|
|
69
|
+
const match = /language-(\\w+)/.exec(className || "");
|
|
70
|
+
return match ? (
|
|
71
|
+
<Code
|
|
72
|
+
{...rest}
|
|
73
|
+
className={className}
|
|
74
|
+
code={String(children).replace(/\\n\$/, "")}
|
|
75
|
+
language={match[1]}
|
|
76
|
+
/>
|
|
77
|
+
) : (
|
|
78
|
+
<code {...rest} className={className}>
|
|
79
|
+
{children}
|
|
80
|
+
</code>
|
|
81
|
+
);
|
|
82
|
+
},
|
|
83
|
+
h1: ({ children, ...props }) => {
|
|
84
|
+
const id = generateId(String(children));
|
|
85
|
+
return (
|
|
86
|
+
<h1 id={id} {...props}>
|
|
87
|
+
{children}
|
|
88
|
+
</h1>
|
|
89
|
+
);
|
|
90
|
+
},
|
|
91
|
+
h2: ({ children, ...props }) => {
|
|
92
|
+
const id = generateId(String(children));
|
|
93
|
+
return (
|
|
94
|
+
<h2 id={id} {...props}>
|
|
95
|
+
{children}
|
|
96
|
+
</h2>
|
|
97
|
+
);
|
|
98
|
+
},
|
|
99
|
+
h3: ({ children, ...props }) => {
|
|
100
|
+
const id = generateId(String(children));
|
|
101
|
+
return (
|
|
102
|
+
<h3 id={id} {...props}>
|
|
103
|
+
{children}
|
|
104
|
+
</h3>
|
|
105
|
+
);
|
|
106
|
+
},
|
|
107
|
+
h4: ({ children, ...props }) => {
|
|
108
|
+
const id = generateId(String(children));
|
|
109
|
+
return (
|
|
110
|
+
<h4 id={id} {...props}>
|
|
111
|
+
{children}
|
|
112
|
+
</h4>
|
|
113
|
+
);
|
|
114
|
+
},
|
|
115
|
+
h5: ({ children, ...props }) => {
|
|
116
|
+
const id = generateId(String(children));
|
|
117
|
+
return (
|
|
118
|
+
<h5 id={id} {...props}>
|
|
119
|
+
{children}
|
|
120
|
+
</h5>
|
|
121
|
+
);
|
|
122
|
+
},
|
|
123
|
+
h6: ({ children, ...props }) => {
|
|
124
|
+
const id = generateId(String(children));
|
|
125
|
+
return (
|
|
126
|
+
<h6 id={id} {...props}>
|
|
127
|
+
{children}
|
|
128
|
+
</h6>
|
|
129
|
+
);
|
|
130
|
+
},
|
|
131
|
+
}}
|
|
132
|
+
>
|
|
133
|
+
{content}
|
|
134
|
+
</Markdown>
|
|
135
|
+
)}
|
|
136
|
+
</StyledMarkdownContainer>
|
|
137
|
+
</Flex>
|
|
138
|
+
</DocsContainer>
|
|
139
|
+
<StyledIndexSidebar>
|
|
140
|
+
{headings?.length > 0 && (
|
|
141
|
+
<>
|
|
142
|
+
<StyledText>On this page</StyledText>
|
|
143
|
+
<Space $size={20} />
|
|
144
|
+
</>
|
|
145
|
+
)}
|
|
146
|
+
{headings.map((heading, index) => (
|
|
147
|
+
<li
|
|
148
|
+
key={index}
|
|
149
|
+
style={
|
|
150
|
+
{
|
|
151
|
+
// paddingLeft: \`\${(heading.level - 1) * 16}px\`,
|
|
152
|
+
}
|
|
153
|
+
}
|
|
41
154
|
>
|
|
42
|
-
{
|
|
43
|
-
</
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
</DocsContainer>
|
|
155
|
+
<a href={\`#\${heading.id}\`}>{heading.text}</a>
|
|
156
|
+
</li>
|
|
157
|
+
))}
|
|
158
|
+
</StyledIndexSidebar>
|
|
159
|
+
</>
|
|
48
160
|
);
|
|
49
161
|
}
|
|
50
162
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const docsComponentsTemplate = "\"use client\";\nimport { mq, Theme } from \"@/app/theme\";\nimport {\n resetButton,\n styledStrong,\n styledText,\n} from \"cherry-styled-components/src/lib\";\nimport Link from \"next/link\";\nimport { rgba } from \"polished\";\nimport React from \"react\";\nimport styled, { css } from \"styled-components\";\nimport { interactiveStyles } from \"./SharedStyled\";\n\ninterface DocsProps {\n children: React.ReactNode;\n}\n\nconst StyledDocsWrapper = styled.div<{ theme: Theme }>`\n position: relative;\n`;\n\nconst StyledDocsSidebar = styled.div<{ theme: Theme }>`\n position: sticky;\n top: 90px;\n min-width: 200px;\n float: left;\n z-index: 999;\n\n ${mq(\"lg\")} {\n z-index: 2;\n }\n`;\n\nconst StyledDocsContainer = styled.div<{ theme: Theme }>`\n position: relative;\n padding: 0;\n width: 100%;\n\n & pre {\n max-width: 100%;\n }\n\n ${mq(\"lg\")} {\n padding-left: 230px;\n }\n\n & ul {\n list-style: none;\n padding: 0;\n margin: 0;\n\n & li {\n text-indent: 0;\n display: block;\n position: relative;\n padding: 0 0 0 15px;\n margin: 0;\n ${({ theme }) => styledText(theme)};\n min-height: 23px;\n\n $mq: \"lg\" {\n min-height: 27px;\n }\n\n &::before {\n content: \"\";\n display: block;\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: ${({ theme }) => theme.colors.primary};\n position: absolute;\n top: 8px;\n left: 2px;\n\n ${mq(\"lg\")} {\n top: 10px;\n }\n }\n }\n }\n\n & ol {\n padding: 0;\n margin: 0;\n\n & > li {\n position: relative;\n padding: 0;\n counter-increment: item;\n padding: 0;\n margin: 0;\n ${({ theme }) => styledText(theme)};\n\n &::before {\n content: counter(item) \".\";\n display: inline-block;\n margin: 0 4px 0 0;\n font-weight: 700;\n color: ${({ theme }) => theme.colors.primary};\n min-width: max-content;\n }\n }\n }\n`;\n\nexport const StyledMarkdownContainer = styled.div`\n display: flex;\n flex-direction: column;\n gap: 20px;\n flex-wrap: wrap;\n flex: 1;\n`;\n\ninterface Props {\n theme?: Theme;\n $isActive?: boolean;\n}\n\nexport const StyledSidebar = styled.nav<Props>`\n position: fixed;\n overflow-y: auto;\n max-height: calc(100svh - 70px);\n width: 100%;\n background: ${({ theme }) => theme.colors.light};\n z-index: 99;\n top: 70px;\n height: 100%;\n padding: 20px;\n opacity: 0;\n pointer-events: none;\n transition: all 0.3s ease;\n transform: translateY(30px);\n left: 0;\n\n ${mq(\"lg\")} {\n width: 220px;\n left: 20px;\n background: transparent;\n padding: 20px 20px 20px 0;\n opacity: 1;\n pointer-events: all;\n transform: translateY(0);\n }\n\n ${mq(\"xl\")} {\n width: 220px;\n left: calc(50% - 610px);\n }\n\n ${mq(\"xxl\")} {\n width: 220px;\n left: calc(50% - 690px);\n }\n\n ${({ $isActive }) =>\n $isActive &&\n css`\n transform: translateY(0);\n opacity: 1;\n pointer-events: all;\n `}\n`;\n\nexport const StyledSidebarList = styled.ul`\n list-style: none;\n margin: 0;\n padding: 0;\n`;\n\nexport const StyledStrong = styled.strong<{ theme: Theme }>`\n font-weight: 600;\n ${({ theme }) => styledStrong(theme)};\n`;\n\nexport const StyledSidebarListItem = styled.li`\n display: flex;\n gap: 10px;\n clear: both;\n`;\n\nexport const StyledSidebarListItemLink = styled(Link)<Props>`\n text-decoration: none;\n font-size: ${({ theme }) => theme.fontSizes.strong.xs};\n line-height: 1.6;\n color: ${({ theme }) =>\n theme.isDark ? theme.colors.grayDark : theme.colors.primary};\n padding: 5px 0 5px 20px;\n display: flex;\n transition: all 0.3s ease;\n border-left: solid 1px ${({ theme }) => theme.colors.grayLight};\n\n ${mq(\"lg\")} {\n font-size: ${({ theme }) => theme.fontSizes.strong.lg};\n }\n\n @media (hover: hover) {\n &:hover {\n color: ${({ theme }) =>\n theme.isDark ? theme.colors.primaryLight : theme.colors.primaryDark};\n border-color: ${({ theme }) => theme.colors.info};\n }\n }\n\n ${({ $isActive, theme }) =>\n $isActive &&\n `\n\t\t\tcolor: ${theme.colors.dark};\n\t\t\tborder-color: ${theme.colors.info};\n\t\t\tfont-weight: 600;\n\t`};\n`;\n\nexport const StyleMobileBar = styled.button<Props>`\n ${resetButton};\n position: fixed;\n z-index: 1000;\n bottom: 0;\n right: 20px;\n font-size: ${({ theme }) => theme.fontSizes.strong.lg};\n line-height: ${({ theme }) => theme.fontSizes.strong.lg};\n box-shadow: ${({ theme }) => theme.shadows.sm};\n background: ${({ theme }) =>\n theme.isDark\n ? rgba(theme.colors.grayLight, 0.7)\n : rgba(theme.colors.light, 0.7)};\n color: ${({ theme }) =>\n theme.isDark ? theme.colors.dark : theme.colors.primary};\n backdrop-filter: blur(10px);\n -webkit-backdrop-filter: blur(10px);\n padding: 30px;\n border-radius: 100px;\n margin: 0 0 20px 0;\n font-weight: 600;\n display: flex;\n justify-content: flex-start;\n width: auto;\n\n ${mq(\"lg\")} {\n display: none;\n }\n\n ${({ $isActive }) => $isActive && `position: fixed; `};\n`;\n\nexport const StyledMobileBurger = styled.span<Props>`\n display: block;\n margin: auto 0;\n width: 18px;\n height: 18px;\n position: relative;\n overflow: hidden;\n background: transparent;\n position: relative;\n\n &::before,\n &::after {\n content: \"\";\n display: block;\n position: absolute;\n width: 18px;\n height: 3px;\n border-radius: 3px;\n background: ${({ theme }) =>\n theme.isDark ? theme.colors.dark : theme.colors.primary};\n transition: all 0.3s ease;\n }\n\n &::before {\n top: 3px;\n }\n\n &::after {\n bottom: 3px;\n }\n\n ${({ $isActive }) =>\n $isActive &&\n css`\n &::before {\n transform: translateY(5px) rotate(45deg);\n }\n\n &::after {\n transform: translateY(-4px) rotate(-45deg);\n }\n `};\n`;\n\nexport const StyledInlineButton = styled.button<{ theme: Theme }>`\n ${resetButton};\n ${interactiveStyles};\n color: ${({ theme }) => theme.colors.primary};\n vertical-align: middle;\n border: solid 1px ${({ theme }) => theme.colors.grayLight};\n border-radius: ${({ theme }) => theme.spacing.radius.xs};\n padding: 0;\n width: 18px;\n height: 18px;\n display: flex;\n margin: auto 0;\n transition: all 0.3s ease;\n\n @media (hover: hover) {\n &:hover {\n color: ${({ theme }) => theme.colors.light};\n background: ${({ theme }) => theme.colors.primary};\n border-color: ${({ theme }) => theme.colors.primary};\n }\n }\n\n & svg {\n vertical-align: middle;\n width: 12px;\n height: 12px;\n margin: auto;\n }\n`;\n\nexport const StyledPlusButton = styled.button<{ theme: Theme }>`\n ${resetButton};\n color: ${({ theme }) => theme.colors.primary};\n vertical-align: middle;\n padding: 0;\n width: 100%;\n height: 18px;\n display: flex;\n margin: auto 0;\n transition: all 0.3s ease;\n position: relative;\n margin: 20px 0 0 0;\n\n &::before {\n content: \"\";\n display: block;\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n width: 100%;\n height: 1px;\n border-radius: 3px;\n background: ${({ theme }) => theme.colors.grayLight};\n transition: all 0.3s ease;\n z-index: -1;\n }\n\n &::after {\n content: \"\";\n display: block;\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n width: 18px;\n height: 18px;\n border: solid 1px ${({ theme }) => theme.colors.grayLight};\n border-radius: ${({ theme }) => theme.spacing.radius.xs};\n background: ${({ theme }) => theme.colors.light};\n transition: all 0.3s ease;\n z-index: -1;\n }\n\n box-shadow: 0 0 0 0px ${({ theme }) => theme.colors.primary};\n\n @media (hover: hover) {\n &:hover {\n &::after {\n border-color: ${({ theme }) => theme.colors.primary};\n }\n }\n }\n\n &:focus {\n &::after {\n border-color: ${({ theme }) => theme.colors.primary};\n box-shadow: 0 0 0 4px ${({ theme }) => theme.colors.primaryLight};\n }\n }\n\n &:active {\n &::after {\n box-shadow: 0 0 0 2px ${({ theme }) => theme.colors.primaryLight};\n }\n }\n\n @media (hover: hover) {\n &:hover {\n color: ${({ theme }) => theme.colors.light};\n\n &::after {\n background: ${({ theme }) => theme.colors.primary};\n border-color: ${({ theme }) => theme.colors.primary};\n }\n }\n }\n\n & svg {\n vertical-align: middle;\n width: 14px;\n height: 14px;\n margin: auto;\n }\n`;\n\nexport const StyledFullHeightInput = styled.div`\n height: 100%;\n width: 100%;\n display: flex;\n flex-direction: column;\n gap: 20px;\n flex: 1;\n\n & > span {\n height: 100%;\n width: 100%;\n }\n\n & textarea {\n height: 100%;\n }\n`;\n\nexport const StyledEditorWrapper = styled.div`\n flex: 1;\n\n &:empty {\n display: none;\n }\n`;\n\nfunction DocsWrapper({ children }: DocsProps) {\n return <StyledDocsWrapper>{children}</StyledDocsWrapper>;\n}\n\nfunction DocsSidebar({ children }: DocsProps) {\n return <StyledDocsSidebar>{children}</StyledDocsSidebar>;\n}\n\nfunction DocsContainer({ children }: DocsProps) {\n return <StyledDocsContainer>{children}</StyledDocsContainer>;\n}\n\nexport { DocsWrapper, DocsSidebar, DocsContainer };\n";
|
|
1
|
+
export declare const docsComponentsTemplate = "\"use client\";\nimport { mq, Theme } from \"@/app/theme\";\nimport {\n resetButton,\n styledStrong,\n styledText,\n} from \"cherry-styled-components/src/lib\";\nimport Link from \"next/link\";\nimport { rgba } from \"polished\";\nimport React from \"react\";\nimport styled, { css } from \"styled-components\";\nimport { interactiveStyles } from \"./SharedStyled\";\n\ninterface DocsProps {\n children: React.ReactNode;\n}\n\nconst StyledDocsWrapper = styled.div<{ theme: Theme }>`\n position: relative;\n`;\n\nconst StyledDocsSidebar = styled.div<{ theme: Theme }>`\n clear: both;\n`;\n\nconst StyledDocsContainer = styled.div<{ theme: Theme }>`\n position: relative;\n padding: 0;\n width: 100%;\n ${({ theme }) => styledText(theme)};\n\n ${mq(\"lg\")} {\n padding-left: 320px;\n padding-right: 320px;\n }\n\n & p {\n color: ${({ theme }) => theme.colors.grayDark};\n }\n\n & pre {\n max-width: 100%;\n }\n\n & ul {\n list-style: none;\n padding: 0;\n margin: 0;\n\n & li {\n text-indent: 0;\n display: block;\n position: relative;\n padding: 0 0 0 15px;\n margin: 0;\n ${({ theme }) => styledText(theme)};\n min-height: 23px;\n\n $mq: \"lg\" {\n min-height: 27px;\n }\n\n &::before {\n content: \"\";\n display: block;\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: ${({ theme }) => theme.colors.primary};\n position: absolute;\n top: 8px;\n left: 2px;\n\n ${mq(\"lg\")} {\n top: 10px;\n }\n }\n }\n }\n\n & ol {\n padding: 0;\n margin: 0;\n\n & > li {\n position: relative;\n padding: 0;\n counter-increment: item;\n margin: 0;\n ${({ theme }) => styledText(theme)};\n\n &::before {\n content: counter(item) \".\";\n display: inline-block;\n margin: 0 4px 0 0;\n font-weight: 700;\n color: ${({ theme }) => theme.colors.primary};\n min-width: max-content;\n }\n }\n }\n`;\n\nexport const StyledMarkdownContainer = styled.div`\n display: flex;\n flex-direction: column;\n gap: 20px;\n flex-wrap: wrap;\n flex: 1;\n max-width: 640px;\n margin: auto;\n\n ${mq(\"lg\")} {\n padding-bottom: 110px;\n }\n`;\n\ninterface Props {\n theme?: Theme;\n $isActive?: boolean;\n}\n\nexport const StyledSidebar = styled.nav<Props>`\n position: fixed;\n overflow-y: auto;\n max-height: calc(100svh - 70px);\n width: 100%;\n z-index: 99;\n top: 70px;\n height: 100%;\n padding: 20px;\n opacity: 0;\n pointer-events: none;\n transition: all 0.3s ease;\n transform: translateY(30px);\n left: 0;\n background: ${({ theme }) => theme.colors.light};\n\n ${mq(\"lg\")} {\n max-height: 100svh;\n width: 220px;\n background: transparent;\n padding: 90px 40px 40px;\n opacity: 1;\n pointer-events: all;\n transform: translateY(0);\n background: ${({ theme }) => rgba(theme.colors.primaryLight, 0.1)};\n top: 0;\n width: 320px;\n }\n\n ${({ $isActive }) =>\n $isActive &&\n css`\n transform: translateY(0);\n opacity: 1;\n pointer-events: all;\n `}\n`;\n\nexport const StyledIndexSidebar = styled.ul<{ theme: Theme }>`\n display: none;\n list-style: none;\n margin: 0;\n padding: 0;\n position: fixed;\n top: 0;\n right: 0;\n width: 320px;\n height: 100vh;\n overflow-y: auto;\n z-index: 1;\n padding: 40px;\n background: ${({ theme }) => theme.colors.light};\n border-left: solid 1px ${({ theme }) => theme.colors.grayLight};\n\n ${mq(\"lg\")} {\n display: block;\n }\n\n & li {\n padding: 5px 0;\n\n & a {\n ${({ theme }) => styledText(theme)};\n color: ${({ theme }) => theme.colors.primary};\n font-weight: 600;\n text-decoration: none;\n transition: all 0.3s ease;\n\n &:hover {\n color: ${({ theme }) => theme.colors.primaryDark};\n }\n }\n }\n`;\n\nexport const StyledSidebarList = styled.ul`\n list-style: none;\n margin: 0;\n padding: 0;\n`;\n\nexport const StyledStrong = styled.strong<{ theme: Theme }>`\n font-weight: 600;\n ${({ theme }) => styledStrong(theme)};\n`;\n\nexport const StyledSidebarListItem = styled.li`\n display: flex;\n gap: 10px;\n clear: both;\n`;\n\nexport const StyledSidebarListItemLink = styled(Link)<Props>`\n text-decoration: none;\n font-size: ${({ theme }) => theme.fontSizes.strong.xs};\n line-height: 1.6;\n color: ${({ theme }) =>\n theme.isDark ? theme.colors.grayDark : theme.colors.primary};\n padding: 5px 0 5px 20px;\n display: flex;\n transition: all 0.3s ease;\n border-left: solid 1px ${({ theme }) => theme.colors.grayLight};\n\n ${mq(\"lg\")} {\n font-size: ${({ theme }) => theme.fontSizes.strong.lg};\n }\n\n @media (hover: hover) {\n &:hover {\n color: ${({ theme }) =>\n theme.isDark ? theme.colors.primaryLight : theme.colors.primaryDark};\n border-color: ${({ theme }) => theme.colors.info};\n }\n }\n\n ${({ $isActive, theme }) =>\n $isActive &&\n `\n\t\t\tcolor: ${theme.colors.dark};\n\t\t\tborder-color: ${theme.colors.info};\n\t\t\tfont-weight: 600;\n\t`};\n`;\n\nexport const StyleMobileBar = styled.button<Props>`\n ${resetButton};\n position: fixed;\n z-index: 1000;\n bottom: 0;\n right: 20px;\n font-size: ${({ theme }) => theme.fontSizes.strong.lg};\n line-height: ${({ theme }) => theme.fontSizes.strong.lg};\n box-shadow: ${({ theme }) => theme.shadows.sm};\n background: ${({ theme }) =>\n theme.isDark\n ? rgba(theme.colors.grayLight, 0.7)\n : rgba(theme.colors.light, 0.7)};\n color: ${({ theme }) =>\n theme.isDark ? theme.colors.dark : theme.colors.primary};\n backdrop-filter: blur(10px);\n -webkit-backdrop-filter: blur(10px);\n padding: 30px;\n border-radius: 100px;\n margin: 0 0 20px 0;\n font-weight: 600;\n display: flex;\n justify-content: flex-start;\n width: auto;\n\n ${mq(\"lg\")} {\n display: none;\n }\n\n ${({ $isActive }) => $isActive && `position: fixed; `};\n`;\n\nexport const StyledMobileBurger = styled.span<Props>`\n display: block;\n margin: auto 0;\n width: 18px;\n height: 18px;\n position: relative;\n overflow: hidden;\n background: transparent;\n position: relative;\n\n &::before,\n &::after {\n content: \"\";\n display: block;\n position: absolute;\n width: 18px;\n height: 3px;\n border-radius: 3px;\n background: ${({ theme }) =>\n theme.isDark ? theme.colors.dark : theme.colors.primary};\n transition: all 0.3s ease;\n }\n\n &::before {\n top: 3px;\n }\n\n &::after {\n bottom: 3px;\n }\n\n ${({ $isActive }) =>\n $isActive &&\n css`\n &::before {\n transform: translateY(5px) rotate(45deg);\n }\n\n &::after {\n transform: translateY(-4px) rotate(-45deg);\n }\n `};\n`;\n\nexport const StyledInlineButton = styled.button<{ theme: Theme }>`\n ${resetButton};\n ${interactiveStyles};\n color: ${({ theme }) => theme.colors.primary};\n vertical-align: middle;\n border: solid 1px ${({ theme }) => theme.colors.grayLight};\n border-radius: ${({ theme }) => theme.spacing.radius.xs};\n padding: 0;\n width: 18px;\n height: 18px;\n display: flex;\n margin: auto 0;\n transition: all 0.3s ease;\n\n @media (hover: hover) {\n &:hover {\n color: ${({ theme }) => theme.colors.light};\n background: ${({ theme }) => theme.colors.primary};\n border-color: ${({ theme }) => theme.colors.primary};\n }\n }\n\n & svg {\n vertical-align: middle;\n width: 12px;\n height: 12px;\n margin: auto;\n }\n`;\n\nexport const StyledPlusButton = styled.button<{ theme: Theme }>`\n ${resetButton};\n color: ${({ theme }) => theme.colors.primary};\n vertical-align: middle;\n padding: 0;\n width: 100%;\n height: 18px;\n display: flex;\n margin: auto 0;\n transition: all 0.3s ease;\n position: relative;\n margin: 20px 0 0 0;\n\n &::before {\n content: \"\";\n display: block;\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n width: 100%;\n height: 1px;\n border-radius: 3px;\n background: ${({ theme }) => theme.colors.grayLight};\n transition: all 0.3s ease;\n z-index: -1;\n }\n\n &::after {\n content: \"\";\n display: block;\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n width: 18px;\n height: 18px;\n border: solid 1px ${({ theme }) => theme.colors.grayLight};\n border-radius: ${({ theme }) => theme.spacing.radius.xs};\n background: ${({ theme }) => theme.colors.light};\n transition: all 0.3s ease;\n z-index: -1;\n }\n\n box-shadow: 0 0 0 0px ${({ theme }) => theme.colors.primary};\n\n @media (hover: hover) {\n &:hover {\n &::after {\n border-color: ${({ theme }) => theme.colors.primary};\n }\n }\n }\n\n &:focus {\n &::after {\n border-color: ${({ theme }) => theme.colors.primary};\n box-shadow: 0 0 0 4px ${({ theme }) => theme.colors.primaryLight};\n }\n }\n\n &:active {\n &::after {\n box-shadow: 0 0 0 2px ${({ theme }) => theme.colors.primaryLight};\n }\n }\n\n @media (hover: hover) {\n &:hover {\n color: ${({ theme }) => theme.colors.light};\n\n &::after {\n background: ${({ theme }) => theme.colors.primary};\n border-color: ${({ theme }) => theme.colors.primary};\n }\n }\n }\n\n & svg {\n vertical-align: middle;\n width: 14px;\n height: 14px;\n margin: auto;\n }\n`;\n\nexport const StyledFullHeightInput = styled.div`\n height: 100%;\n width: 100%;\n display: flex;\n flex-direction: column;\n gap: 20px;\n flex: 1;\n\n & > span {\n height: 100%;\n width: 100%;\n }\n\n & textarea {\n height: 100%;\n }\n`;\n\nexport const StyledEditorWrapper = styled.div`\n flex: 1;\n\n &:empty {\n display: none;\n }\n`;\n\nfunction DocsWrapper({ children }: DocsProps) {\n return <StyledDocsWrapper>{children}</StyledDocsWrapper>;\n}\n\nfunction DocsSidebar({ children }: DocsProps) {\n return <StyledDocsSidebar>{children}</StyledDocsSidebar>;\n}\n\nfunction DocsContainer({ children }: DocsProps) {\n return <StyledDocsContainer>{children}</StyledDocsContainer>;\n}\n\nexport { DocsWrapper, DocsSidebar, DocsContainer };\n";
|
|
@@ -20,28 +20,26 @@ const StyledDocsWrapper = styled.div<{ theme: Theme }>\`
|
|
|
20
20
|
\`;
|
|
21
21
|
|
|
22
22
|
const StyledDocsSidebar = styled.div<{ theme: Theme }>\`
|
|
23
|
-
|
|
24
|
-
top: 90px;
|
|
25
|
-
min-width: 200px;
|
|
26
|
-
float: left;
|
|
27
|
-
z-index: 999;
|
|
28
|
-
|
|
29
|
-
\${mq("lg")} {
|
|
30
|
-
z-index: 2;
|
|
31
|
-
}
|
|
23
|
+
clear: both;
|
|
32
24
|
\`;
|
|
33
25
|
|
|
34
26
|
const StyledDocsContainer = styled.div<{ theme: Theme }>\`
|
|
35
27
|
position: relative;
|
|
36
28
|
padding: 0;
|
|
37
29
|
width: 100%;
|
|
30
|
+
\${({ theme }) => styledText(theme)};
|
|
38
31
|
|
|
39
|
-
|
|
40
|
-
|
|
32
|
+
\${mq("lg")} {
|
|
33
|
+
padding-left: 320px;
|
|
34
|
+
padding-right: 320px;
|
|
41
35
|
}
|
|
42
36
|
|
|
43
|
-
|
|
44
|
-
|
|
37
|
+
& p {
|
|
38
|
+
color: \${({ theme }) => theme.colors.grayDark};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
& pre {
|
|
42
|
+
max-width: 100%;
|
|
45
43
|
}
|
|
46
44
|
|
|
47
45
|
& ul {
|
|
@@ -88,7 +86,6 @@ const StyledDocsContainer = styled.div<{ theme: Theme }>\`
|
|
|
88
86
|
position: relative;
|
|
89
87
|
padding: 0;
|
|
90
88
|
counter-increment: item;
|
|
91
|
-
padding: 0;
|
|
92
89
|
margin: 0;
|
|
93
90
|
\${({ theme }) => styledText(theme)};
|
|
94
91
|
|
|
@@ -110,6 +107,12 @@ export const StyledMarkdownContainer = styled.div\`
|
|
|
110
107
|
gap: 20px;
|
|
111
108
|
flex-wrap: wrap;
|
|
112
109
|
flex: 1;
|
|
110
|
+
max-width: 640px;
|
|
111
|
+
margin: auto;
|
|
112
|
+
|
|
113
|
+
\${mq("lg")} {
|
|
114
|
+
padding-bottom: 110px;
|
|
115
|
+
}
|
|
113
116
|
\`;
|
|
114
117
|
|
|
115
118
|
interface Props {
|
|
@@ -122,7 +125,6 @@ export const StyledSidebar = styled.nav<Props>\`
|
|
|
122
125
|
overflow-y: auto;
|
|
123
126
|
max-height: calc(100svh - 70px);
|
|
124
127
|
width: 100%;
|
|
125
|
-
background: \${({ theme }) => theme.colors.light};
|
|
126
128
|
z-index: 99;
|
|
127
129
|
top: 70px;
|
|
128
130
|
height: 100%;
|
|
@@ -132,25 +134,19 @@ export const StyledSidebar = styled.nav<Props>\`
|
|
|
132
134
|
transition: all 0.3s ease;
|
|
133
135
|
transform: translateY(30px);
|
|
134
136
|
left: 0;
|
|
137
|
+
background: \${({ theme }) => theme.colors.light};
|
|
135
138
|
|
|
136
139
|
\${mq("lg")} {
|
|
140
|
+
max-height: 100svh;
|
|
137
141
|
width: 220px;
|
|
138
|
-
left: 20px;
|
|
139
142
|
background: transparent;
|
|
140
|
-
padding:
|
|
143
|
+
padding: 90px 40px 40px;
|
|
141
144
|
opacity: 1;
|
|
142
145
|
pointer-events: all;
|
|
143
146
|
transform: translateY(0);
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
width: 220px;
|
|
148
|
-
left: calc(50% - 610px);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
\${mq("xxl")} {
|
|
152
|
-
width: 220px;
|
|
153
|
-
left: calc(50% - 690px);
|
|
147
|
+
background: \${({ theme }) => rgba(theme.colors.primaryLight, 0.1)};
|
|
148
|
+
top: 0;
|
|
149
|
+
width: 320px;
|
|
154
150
|
}
|
|
155
151
|
|
|
156
152
|
\${({ $isActive }) =>
|
|
@@ -162,6 +158,43 @@ export const StyledSidebar = styled.nav<Props>\`
|
|
|
162
158
|
\`}
|
|
163
159
|
\`;
|
|
164
160
|
|
|
161
|
+
export const StyledIndexSidebar = styled.ul<{ theme: Theme }>\`
|
|
162
|
+
display: none;
|
|
163
|
+
list-style: none;
|
|
164
|
+
margin: 0;
|
|
165
|
+
padding: 0;
|
|
166
|
+
position: fixed;
|
|
167
|
+
top: 0;
|
|
168
|
+
right: 0;
|
|
169
|
+
width: 320px;
|
|
170
|
+
height: 100vh;
|
|
171
|
+
overflow-y: auto;
|
|
172
|
+
z-index: 1;
|
|
173
|
+
padding: 40px;
|
|
174
|
+
background: \${({ theme }) => theme.colors.light};
|
|
175
|
+
border-left: solid 1px \${({ theme }) => theme.colors.grayLight};
|
|
176
|
+
|
|
177
|
+
\${mq("lg")} {
|
|
178
|
+
display: block;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
& li {
|
|
182
|
+
padding: 5px 0;
|
|
183
|
+
|
|
184
|
+
& a {
|
|
185
|
+
\${({ theme }) => styledText(theme)};
|
|
186
|
+
color: \${({ theme }) => theme.colors.primary};
|
|
187
|
+
font-weight: 600;
|
|
188
|
+
text-decoration: none;
|
|
189
|
+
transition: all 0.3s ease;
|
|
190
|
+
|
|
191
|
+
&:hover {
|
|
192
|
+
color: \${({ theme }) => theme.colors.primaryDark};
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
\`;
|
|
197
|
+
|
|
165
198
|
export const StyledSidebarList = styled.ul\`
|
|
166
199
|
list-style: none;
|
|
167
200
|
margin: 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const headerTemplate = "\"use client\";\nimport {
|
|
1
|
+
export declare const headerTemplate = "\"use client\";\nimport { Flex, MaxWidth, resetButton } from \"cherry-styled-components/src/lib\";\nimport React, { useCallback, useRef, useState, Suspense } from \"react\";\nimport styled, { css } from \"styled-components\";\nimport Link from \"next/link\";\nimport { rgba } from \"polished\";\nimport { mq, Theme } from \"@/app/theme\";\nimport { \n ToggleTheme,\n ToggleThemeLoading\n} from \"@/components/layout/ThemeToggle\";\nimport {\n StyledTinyDesktopOnly,\n StyledTinyMobileOnly,\n} from \"@/components/layout/SharedStyled\";\nimport { useOnClickOutside } from \"@/components/ClickOutside\";\nimport { Logo } from \"@/components/layout/Pictograms\";\n\nconst StyledHeader = styled.header<{ theme: Theme }>`\n position: sticky;\n top: 0;\n padding: 20px;\n margin: 0;\n z-index: 1000;\n\n ${mq(\"lg\")} {\n width: 320px;\n }\n\n &::before,\n &::after {\n display: block;\n content: \"\";\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n background: ${({ theme }) => theme.colors.light};\n z-index: -2;\n }\n\n &::after {\n background: ${({ theme }) => rgba(theme.colors.primaryLight, 0.1)};\n z-index: -1;\n }\n\n & .logo {\n display: flex;\n\n & svg {\n margin: auto;\n }\n }\n`;\n\nfunction Header() {\n const [isOptionActive, setIsOptionActive] = useState(false);\n const [isLangActive, setIsLangActive] = useState(false);\n const [isMobileMenuActive, setIsMobileMenuActive] = useState(false);\n\n const wrapperRef = useRef<HTMLSpanElement>(null);\n const elmRef = useRef<HTMLDivElement>(null);\n const langRef = useRef<HTMLSpanElement>(null);\n const closeMenu = useCallback(() => {\n setIsOptionActive(false);\n setIsLangActive(false);\n }, []);\n\n useOnClickOutside(\n [elmRef, wrapperRef],\n isOptionActive ? closeMenu : () => {},\n );\n useOnClickOutside([langRef, wrapperRef], isLangActive ? closeMenu : () => {});\n\n return (\n <>\n <StyledHeader>\n <MaxWidth $size={1000}>\n <Flex $justifyContent=\"space-between\" $wrap=\"nowrap\">\n <Link href=\"/\" className=\"logo\" aria-label=\"Logo\">\n <StyledTinyDesktopOnly>\n <Logo />\n </StyledTinyDesktopOnly>\n <StyledTinyMobileOnly>\n <Logo />\n </StyledTinyMobileOnly>\n </Link>\n <Suspense fallback={<ToggleThemeLoading />}>\n <ToggleTheme />\n </Suspense>\n </Flex>\n </MaxWidth>\n </StyledHeader>\n </>\n );\n}\n\nexport { Header };\n";
|
|
@@ -1,22 +1,14 @@
|
|
|
1
1
|
export const headerTemplate = `"use client";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
MaxWidth,
|
|
5
|
-
resetButton,
|
|
6
|
-
styledText,
|
|
7
|
-
} from "cherry-styled-components/src/lib";
|
|
8
|
-
import React, {
|
|
9
|
-
useCallback,
|
|
10
|
-
useContext,
|
|
11
|
-
useRef,
|
|
12
|
-
useState,
|
|
13
|
-
Suspense
|
|
14
|
-
} from "react";
|
|
2
|
+
import { Flex, MaxWidth, resetButton } from "cherry-styled-components/src/lib";
|
|
3
|
+
import React, { useCallback, useRef, useState, Suspense } from "react";
|
|
15
4
|
import styled, { css } from "styled-components";
|
|
16
5
|
import Link from "next/link";
|
|
17
6
|
import { rgba } from "polished";
|
|
18
7
|
import { mq, Theme } from "@/app/theme";
|
|
19
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
ToggleTheme,
|
|
10
|
+
ToggleThemeLoading
|
|
11
|
+
} from "@/components/layout/ThemeToggle";
|
|
20
12
|
import {
|
|
21
13
|
StyledTinyDesktopOnly,
|
|
22
14
|
StyledTinyMobileOnly,
|
|
@@ -31,6 +23,10 @@ const StyledHeader = styled.header<{ theme: Theme }>\`
|
|
|
31
23
|
margin: 0;
|
|
32
24
|
z-index: 1000;
|
|
33
25
|
|
|
26
|
+
\${mq("lg")} {
|
|
27
|
+
width: 320px;
|
|
28
|
+
}
|
|
29
|
+
|
|
34
30
|
&::before,
|
|
35
31
|
&::after {
|
|
36
32
|
display: block;
|
|
@@ -59,158 +55,6 @@ const StyledHeader = styled.header<{ theme: Theme }>\`
|
|
|
59
55
|
}
|
|
60
56
|
\`;
|
|
61
57
|
|
|
62
|
-
const StyledLink = styled(Link)<{ theme: Theme }>\`
|
|
63
|
-
text-decoration: none;
|
|
64
|
-
margin: auto 0;
|
|
65
|
-
color: \${({ theme }) => theme.colors.primary};
|
|
66
|
-
font-weight: 500;
|
|
67
|
-
|
|
68
|
-
@media (hover: hover) {
|
|
69
|
-
&:hover {
|
|
70
|
-
color: \${({ theme }) => theme.colors.primaryDark};
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
\`;
|
|
74
|
-
|
|
75
|
-
export const StyledMobileBurger = styled.button<{
|
|
76
|
-
theme: Theme;
|
|
77
|
-
$isActive: boolean;
|
|
78
|
-
}>\`
|
|
79
|
-
\${resetButton};
|
|
80
|
-
display: block;
|
|
81
|
-
margin: auto 0;
|
|
82
|
-
width: 18px;
|
|
83
|
-
height: 18px;
|
|
84
|
-
position: relative;
|
|
85
|
-
overflow: hidden;
|
|
86
|
-
background: transparent;
|
|
87
|
-
position: relative;
|
|
88
|
-
|
|
89
|
-
\${mq("lg")} {
|
|
90
|
-
display: none;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
&::before,
|
|
94
|
-
&::after {
|
|
95
|
-
content: "";
|
|
96
|
-
display: block;
|
|
97
|
-
position: absolute;
|
|
98
|
-
width: 18px;
|
|
99
|
-
height: 2px;
|
|
100
|
-
border-radius: 3px;
|
|
101
|
-
background: \${({ theme }) => theme.colors.primary};
|
|
102
|
-
transition: all 0.3s ease;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
&::before {
|
|
106
|
-
top: 4px;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
&::after {
|
|
110
|
-
bottom: 4px;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
\${({ $isActive }) =>
|
|
114
|
-
$isActive &&
|
|
115
|
-
css\`
|
|
116
|
-
&::before {
|
|
117
|
-
transform: translateY(4px) rotate(45deg);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
&::after {
|
|
121
|
-
transform: translateY(-4px) rotate(-45deg);
|
|
122
|
-
}
|
|
123
|
-
\`};
|
|
124
|
-
\`;
|
|
125
|
-
|
|
126
|
-
const StyledMobileMenu = styled.ul<{ theme: Theme; $isActive: boolean }>\`
|
|
127
|
-
list-style: none;
|
|
128
|
-
padding: 70px 0 0 0;
|
|
129
|
-
margin: 0;
|
|
130
|
-
position: fixed;
|
|
131
|
-
top: 0;
|
|
132
|
-
left: 0;
|
|
133
|
-
background: \${({ theme }) => theme.colors.light};
|
|
134
|
-
pointer-events: none;
|
|
135
|
-
opacity: 0;
|
|
136
|
-
width: 100%;
|
|
137
|
-
height: 100dvh;
|
|
138
|
-
transition: all 0.3s ease;
|
|
139
|
-
z-index: 800;
|
|
140
|
-
transform: translateY(40px) scale(1.2);
|
|
141
|
-
display: block;
|
|
142
|
-
|
|
143
|
-
\${({ $isActive }) =>
|
|
144
|
-
$isActive &&
|
|
145
|
-
css\`
|
|
146
|
-
pointer-events: all;
|
|
147
|
-
opacity: 1;
|
|
148
|
-
transform: translateY(0) scale(1);
|
|
149
|
-
\`};
|
|
150
|
-
|
|
151
|
-
& li {
|
|
152
|
-
display: block;
|
|
153
|
-
width: 100%;
|
|
154
|
-
padding: 0;
|
|
155
|
-
margin: 0;
|
|
156
|
-
border-bottom: solid 1px \${({ theme }) => theme.colors.grayLight};
|
|
157
|
-
|
|
158
|
-
&.languages {
|
|
159
|
-
display: flex;
|
|
160
|
-
justify-content: center;
|
|
161
|
-
gap: 10px;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
& a,
|
|
165
|
-
& button {
|
|
166
|
-
\${({ theme }) => styledText(theme)};
|
|
167
|
-
font-family: \${({ theme }) => theme.fonts.text};
|
|
168
|
-
font-weight: 500;
|
|
169
|
-
appearance: none;
|
|
170
|
-
background: transparent;
|
|
171
|
-
border: none;
|
|
172
|
-
color: \${({ theme }) => theme.colors.dark};
|
|
173
|
-
display: flex;
|
|
174
|
-
margin: 0;
|
|
175
|
-
padding: 20px;
|
|
176
|
-
font-weight: 500;
|
|
177
|
-
text-decoration: none;
|
|
178
|
-
cursor: pointer;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
& button {
|
|
182
|
-
flex: 1;
|
|
183
|
-
border-right: solid 1px \${({ theme }) => theme.colors.grayLight};
|
|
184
|
-
text-align: center;
|
|
185
|
-
justify-content: center;
|
|
186
|
-
|
|
187
|
-
&:last-of-type {
|
|
188
|
-
border-right: none;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
\`;
|
|
193
|
-
|
|
194
|
-
const StyledMenu = styled.div<{ theme: Theme }>\`
|
|
195
|
-
display: none;
|
|
196
|
-
|
|
197
|
-
\${mq("lg")} {
|
|
198
|
-
display: flex;
|
|
199
|
-
gap: 20px;
|
|
200
|
-
}
|
|
201
|
-
\`;
|
|
202
|
-
|
|
203
|
-
const StyledDivider = styled.div<{ theme: Theme }>\`
|
|
204
|
-
width: 1px;
|
|
205
|
-
height: calc(100% - 10px);
|
|
206
|
-
margin: auto 0;
|
|
207
|
-
background: \${({ theme }) => theme.colors.grayLight};
|
|
208
|
-
\`;
|
|
209
|
-
|
|
210
|
-
const StyledWrapper = styled.div<{ theme: Theme }>\`
|
|
211
|
-
margin: auto 0;
|
|
212
|
-
\`;
|
|
213
|
-
|
|
214
58
|
function Header() {
|
|
215
59
|
const [isOptionActive, setIsOptionActive] = useState(false);
|
|
216
60
|
const [isLangActive, setIsLangActive] = useState(false);
|
|
@@ -243,35 +87,12 @@ function Header() {
|
|
|
243
87
|
<Logo />
|
|
244
88
|
</StyledTinyMobileOnly>
|
|
245
89
|
</Link>
|
|
246
|
-
<
|
|
247
|
-
<
|
|
248
|
-
|
|
249
|
-
<StyledMenu>
|
|
250
|
-
<StyledLink href="https://doccupine.com" target="_blank">
|
|
251
|
-
Doccupine
|
|
252
|
-
</StyledLink>
|
|
253
|
-
</StyledMenu>
|
|
254
|
-
<Suspense fallback={<ToggleThemeLoading />}>
|
|
255
|
-
<ToggleTheme />
|
|
256
|
-
</Suspense>
|
|
257
|
-
<StyledMobileBurger
|
|
258
|
-
$isActive={isMobileMenuActive}
|
|
259
|
-
onClick={() => setIsMobileMenuActive(!isMobileMenuActive)}
|
|
260
|
-
aria-label="Burger Menu"
|
|
261
|
-
/>
|
|
262
|
-
</Flex>
|
|
263
|
-
</span>
|
|
264
|
-
</StyledWrapper>
|
|
90
|
+
<Suspense fallback={<ToggleThemeLoading />}>
|
|
91
|
+
<ToggleTheme />
|
|
92
|
+
</Suspense>
|
|
265
93
|
</Flex>
|
|
266
94
|
</MaxWidth>
|
|
267
95
|
</StyledHeader>
|
|
268
|
-
<StyledMobileMenu $isActive={isMobileMenuActive}>
|
|
269
|
-
<li onClick={() => setIsMobileMenuActive(false)}>
|
|
270
|
-
<a href="https://doccupine.com" target="_blank">
|
|
271
|
-
Doccupine
|
|
272
|
-
</a>
|
|
273
|
-
</li>
|
|
274
|
-
</StyledMobileMenu>
|
|
275
96
|
</>
|
|
276
97
|
);
|
|
277
98
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "doccupine",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.0.8",
|
|
4
|
+
"description": "Generate beautiful, ready-to-use documentation with just one CLI command – fast, simple, and open source.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"doccupine": "dist/index.js"
|
|
@@ -16,18 +16,22 @@
|
|
|
16
16
|
"keywords": [
|
|
17
17
|
"doccupine",
|
|
18
18
|
"documentation",
|
|
19
|
+
"docs",
|
|
19
20
|
"mdx",
|
|
20
21
|
"nextjs",
|
|
21
22
|
"cli",
|
|
23
|
+
"generator",
|
|
22
24
|
"file-watcher",
|
|
23
25
|
"static-site-generator"
|
|
24
26
|
],
|
|
27
|
+
"homepage": "https://doccupine.com",
|
|
28
|
+
"repository": "https://github.com/thethemefoundry/doccupine-cli",
|
|
25
29
|
"author": "Luan Gjokaj",
|
|
26
30
|
"license": "MIT",
|
|
27
31
|
"dependencies": {
|
|
28
|
-
"chalk": "^5.6.
|
|
32
|
+
"chalk": "^5.6.2",
|
|
29
33
|
"chokidar": "^4.0.3",
|
|
30
|
-
"commander": "^14.0.
|
|
34
|
+
"commander": "^14.0.1",
|
|
31
35
|
"fs-extra": "^11.3.1",
|
|
32
36
|
"gray-matter": "^4.0.3",
|
|
33
37
|
"prompts": "^2.4.2"
|
|
@@ -35,7 +39,7 @@
|
|
|
35
39
|
"devDependencies": {
|
|
36
40
|
"@types/chokidar": "^2.1.7",
|
|
37
41
|
"@types/fs-extra": "^11.0.4",
|
|
38
|
-
"@types/node": "^24.
|
|
42
|
+
"@types/node": "^24.4.0",
|
|
39
43
|
"@types/prompts": "^2.4.9",
|
|
40
44
|
"typescript": "^5.9.2"
|
|
41
45
|
},
|