doccupine 0.0.21 → 0.0.22

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/dist/index.js CHANGED
@@ -749,7 +749,7 @@ export default function Home() {
749
749
  program
750
750
  .name("doccupine")
751
751
  .description("Watch MDX files and generate Next.js documentation pages automatically")
752
- .version("0.0.21");
752
+ .version("0.0.22");
753
753
  program
754
754
  .command("watch", { isDefault: true })
755
755
  .description("Watch a directory for MDX changes and generate Next.js app")
@@ -1,9 +1,6 @@
1
1
  export const layoutTemplate = (pages) => `import type { Metadata } from "next";
2
2
  import { Inter } from "next/font/google";
3
- import {
4
- Container,
5
- StyledComponentsRegistry,
6
- } from "cherry-styled-components/src/lib";
3
+ import { StyledComponentsRegistry } from "cherry-styled-components/src/lib";
7
4
  import { theme, themeDark } from "@/app/theme";
8
5
  import { CherryThemeProvider } from "@/components/layout/CherryThemeProvider";
9
6
  import { Footer } from "@/components/layout/Footer";
@@ -54,15 +51,13 @@ export default async function RootLayout({
54
51
  <StyledComponentsRegistry>
55
52
  <CherryThemeProvider theme={theme} themeDark={themeDark}>
56
53
  <Header />
57
- <Container $padding={20}>
58
- <DocsWrapper>
59
- <SideBar result={result.length ? result : defaultResults} />
60
- {children}
61
- <DocsNavigation
62
- result={result.length ? result : defaultResults}
63
- />
64
- </DocsWrapper>
65
- </Container>
54
+ <DocsWrapper>
55
+ <SideBar result={result.length ? result : defaultResults} />
56
+ {children}
57
+ <DocsNavigation
58
+ result={result.length ? result : defaultResults}
59
+ />
60
+ </DocsWrapper>
66
61
  <Footer />
67
62
  </CherryThemeProvider>
68
63
  </StyledComponentsRegistry>
@@ -1 +1 @@
1
- export declare const actionBarTemplate = "\"use client\";\nimport { useState } from \"react\";\nimport styled, { css } from \"styled-components\";\nimport { Icon } from \"@/components/layout/Icon\";\nimport { mq, Theme } from \"@/app/theme\";\nimport { rgba } from \"polished\";\nimport { resetButton, Textarea } from \"cherry-styled-components/src/lib\";\n\ninterface ActionBarProps {\n children: React.ReactNode;\n content: string;\n}\n\nconst StyledActionBar = styled.div<{ theme: Theme }>`\n position: absolute;\n border-bottom: solid 1px ${({ theme }) => theme.colors.grayLight};\n left: 0;\n padding: 70px 0 20px 0;\n display: flex;\n justify-content: space-between;\n width: 100%;\n\n ${mq(\"lg\")} {\n left: 50%;\n transform: translateX(-50%);\n max-width: calc(100vw - 640px);\n width: 100%;\n padding: 0 20px 20px 20px;\n margin: 0;\n }\n`;\n\nconst StyledActionBarContent = styled.div`\n margin: auto 0;\n`;\n\nconst StyledCopyButton = styled.button<{ theme: Theme; $copied: boolean }>`\n background: transparent;\n border: solid 1px\n ${({ theme, $copied }) =>\n $copied ? theme.colors.success : theme.colors.grayLight};\n color: ${({ theme, $copied }) =>\n $copied ? theme.colors.success : theme.colors.primary};\n border-radius: ${({ theme }) => theme.spacing.radius.xs};\n padding: 6px 8px;\n font-size: 12px;\n font-family: ${({ theme }) => theme.fonts.mono};\n cursor: pointer;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n gap: 4px;\n margin-right: -6px;\n\n & svg.lucide {\n color: ${({ theme, $copied }) =>\n $copied ? theme.colors.success : theme.colors.primary};\n }\n\n &:hover {\n border-color: ${({ theme, $copied }) =>\n $copied ? theme.colors.success : theme.colors.primary};\n }\n\n &:active {\n transform: scale(0.95);\n }\n`;\n\nconst StyledToggle = styled.button<{ theme: Theme; $isActive?: boolean }>`\n ${resetButton}\n width: 56px;\n height: 32px;\n border-radius: 30px;\n display: flex;\n position: relative;\n margin: auto 0;\n transform: scale(1);\n background: ${({ theme }) => theme.colors.light};\n border: solid 1px ${({ theme }) => theme.colors.grayLight};\n\n &::after {\n content: \"\";\n position: absolute;\n top: 3px;\n left: 3px;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n background: ${({ theme }) => rgba(theme.colors.primaryLight, 0.2)};\n transition: all 0.3s ease;\n z-index: 1;\n ${({ $isActive }) =>\n !$isActive &&\n css`\n transform: translateX(24px);\n `}\n }\n\n & svg {\n width: 16px;\n height: 16px;\n object-fit: contain;\n margin: auto;\n transition: all 0.3s ease;\n position: relative;\n z-index: 2;\n }\n\n & .lucide-eye {\n transform: translateX(1px);\n }\n\n & .lucide-code-xml {\n transform: translateX(-1px);\n }\n\n & svg[stroke] {\n stroke: ${({ theme }) => theme.colors.primary};\n }\n\n @media (hover: hover) {\n &:hover {\n transform: scale(1.05);\n color: ${({ theme }) =>\n theme.isDark ? theme.colors.primaryLight : theme.colors.primaryDark};\n Toggle & svg[stroke] {\n stroke: ${({ theme }) =>\n theme.isDark ? theme.colors.primaryLight : theme.colors.primaryDark};\n }\n }\n }\n\n &:active {\n transform: scale(0.97);\n }\n`;\n\nconst StyledContent = styled.div`\n padding-top: 140px;\n\n ${mq(\"lg\")} {\n padding-top: 70px;\n }\n\n & textarea {\n width: 100%;\n height: 100%;\n min-height: calc(100vh - 180px);\n\n ${mq(\"lg\")} {\n min-height: calc(100vh - 110px);\n }\n }\n`;\n\nfunction ActionBar({ children, content }: ActionBarProps) {\n const [isView, setIsView] = useState(true);\n const [copied, setCopied] = useState(false);\n\n const handleCopyContent = async () => {\n try {\n await navigator.clipboard.writeText(content);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch (err) {\n console.error(\"Failed to copy:\", err);\n }\n };\n\n return (\n <>\n <StyledActionBar>\n <StyledCopyButton onClick={handleCopyContent} $copied={copied}>\n {copied ? (\n <>\n <Icon name=\"check\" size={12} />\n <span>Copied!</span>\n </>\n ) : (\n <>\n <Icon name=\"copy\" size={12} />\n <span>Copy Content</span>\n </>\n )}\n </StyledCopyButton>\n <StyledActionBarContent>\n {\" \"}\n <StyledToggle\n onClick={() => setIsView(!isView)}\n aria-label=\"Toggle Theme\"\n $isActive={isView}\n >\n <Icon name=\"Eye\" />\n <Icon name=\"CodeXml\" />\n </StyledToggle>\n </StyledActionBarContent>\n </StyledActionBar>\n {isView && <StyledContent>{children}</StyledContent>}\n {!isView && (\n <StyledContent>\n <Textarea defaultValue={content} $fullWidth />\n </StyledContent>\n )}\n </>\n );\n}\n\nexport { ActionBar };";
1
+ export declare const actionBarTemplate = "\"use client\";\nimport { useState } from \"react\";\nimport styled, { css } from \"styled-components\";\nimport { Icon } from \"@/components/layout/Icon\";\nimport { mq, Theme } from \"@/app/theme\";\nimport { rgba } from \"polished\";\nimport { resetButton, Textarea } from \"cherry-styled-components/src/lib\";\n\ninterface ActionBarProps {\n children: React.ReactNode;\n content: string;\n}\n\nconst StyledActionBar = styled.div<{ theme: Theme }>`\n position: absolute;\n border-bottom: solid 1px ${({ theme }) => theme.colors.grayLight};\n left: 0;\n padding: 70px 20px 20px 20px;\n display: flex;\n justify-content: space-between;\n width: 100%;\n\n ${mq(\"lg\")} {\n left: 50%;\n transform: translateX(-50%);\n max-width: calc(100vw - 640px);\n width: 100%;\n padding: 0 20px 20px 20px;\n margin: 0;\n }\n`;\n\nconst StyledActionBarContent = styled.div`\n margin: auto 0;\n`;\n\nconst StyledCopyButton = styled.button<{ theme: Theme; $copied: boolean }>`\n background: transparent;\n border: solid 1px\n ${({ theme, $copied }) =>\n $copied ? theme.colors.success : theme.colors.grayLight};\n color: ${({ theme, $copied }) =>\n $copied ? theme.colors.success : theme.colors.primary};\n border-radius: ${({ theme }) => theme.spacing.radius.xs};\n padding: 6px 8px;\n font-size: 12px;\n font-family: ${({ theme }) => theme.fonts.mono};\n cursor: pointer;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n gap: 4px;\n margin-right: -6px;\n\n & svg.lucide {\n color: ${({ theme, $copied }) =>\n $copied ? theme.colors.success : theme.colors.primary};\n }\n\n &:hover {\n border-color: ${({ theme, $copied }) =>\n $copied ? theme.colors.success : theme.colors.primary};\n }\n\n &:active {\n transform: scale(0.95);\n }\n`;\n\nconst StyledToggle = styled.button<{ theme: Theme; $isActive?: boolean }>`\n ${resetButton}\n width: 56px;\n height: 32px;\n border-radius: 30px;\n display: flex;\n position: relative;\n margin: auto 0;\n transform: scale(1);\n background: ${({ theme }) => theme.colors.light};\n border: solid 1px ${({ theme }) => theme.colors.grayLight};\n\n &::after {\n content: \"\";\n position: absolute;\n top: 3px;\n left: 3px;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n background: ${({ theme }) => rgba(theme.colors.primaryLight, 0.2)};\n transition: all 0.3s ease;\n z-index: 1;\n ${({ $isActive }) =>\n !$isActive &&\n css`\n transform: translateX(24px);\n `}\n }\n\n & svg {\n width: 16px;\n height: 16px;\n object-fit: contain;\n margin: auto;\n transition: all 0.3s ease;\n position: relative;\n z-index: 2;\n }\n\n & .lucide-eye {\n transform: translateX(1px);\n }\n\n & .lucide-code-xml {\n transform: translateX(-1px);\n }\n\n & svg[stroke] {\n stroke: ${({ theme }) => theme.colors.primary};\n }\n\n @media (hover: hover) {\n &:hover {\n transform: scale(1.05);\n color: ${({ theme }) =>\n theme.isDark ? theme.colors.primaryLight : theme.colors.primaryDark};\n Toggle & svg[stroke] {\n stroke: ${({ theme }) =>\n theme.isDark ? theme.colors.primaryLight : theme.colors.primaryDark};\n }\n }\n }\n\n &:active {\n transform: scale(0.97);\n }\n`;\n\nconst StyledContent = styled.div`\n padding-top: 140px;\n\n ${mq(\"lg\")} {\n padding-top: 70px;\n }\n\n & textarea {\n max-width: 640px;\n margin: auto;\n width: 100%;\n height: 100%;\n min-height: calc(100vh - 180px);\n\n ${mq(\"lg\")} {\n min-height: calc(100vh - 110px);\n }\n }\n`;\n\nfunction ActionBar({ children, content }: ActionBarProps) {\n const [isView, setIsView] = useState(true);\n const [copied, setCopied] = useState(false);\n\n const handleCopyContent = async () => {\n try {\n await navigator.clipboard.writeText(content);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch (err) {\n console.error(\"Failed to copy:\", err);\n }\n };\n\n return (\n <>\n <StyledActionBar>\n <StyledCopyButton onClick={handleCopyContent} $copied={copied}>\n {copied ? (\n <>\n <Icon name=\"check\" size={12} />\n <span>Copied!</span>\n </>\n ) : (\n <>\n <Icon name=\"copy\" size={12} />\n <span>Copy Content</span>\n </>\n )}\n </StyledCopyButton>\n <StyledActionBarContent>\n {\" \"}\n <StyledToggle\n onClick={() => setIsView(!isView)}\n aria-label=\"Toggle Theme\"\n $isActive={isView}\n >\n <Icon name=\"Eye\" />\n <Icon name=\"CodeXml\" />\n </StyledToggle>\n </StyledActionBarContent>\n </StyledActionBar>\n {isView && <StyledContent>{children}</StyledContent>}\n {!isView && (\n <StyledContent>\n <Textarea defaultValue={content} $fullWidth />\n </StyledContent>\n )}\n </>\n );\n}\n\nexport { ActionBar };";
@@ -15,7 +15,7 @@ const StyledActionBar = styled.div<{ theme: Theme }>\`
15
15
  position: absolute;
16
16
  border-bottom: solid 1px \${({ theme }) => theme.colors.grayLight};
17
17
  left: 0;
18
- padding: 70px 0 20px 0;
18
+ padding: 70px 20px 20px 20px;
19
19
  display: flex;
20
20
  justify-content: space-between;
21
21
  width: 100%;
@@ -144,6 +144,8 @@ const StyledContent = styled.div\`
144
144
  }
145
145
 
146
146
  & textarea {
147
+ max-width: 640px;
148
+ margin: auto;
147
149
  width: 100%;
148
150
  height: 100%;
149
151
  min-height: calc(100vh - 180px);
@@ -1 +1 @@
1
- export declare const docsComponentsTemplate = "\"use client\";\nimport { mq, Theme } from \"@/app/theme\";\nimport {\n resetButton,\n styledSmall,\n styledStrong,\n styledText,\n} from \"cherry-styled-components/src/lib\";\nimport Link from \"next/link\";\nimport { darken, lighten, 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 0 100px 0;\n width: 100%;\n ${({ theme }) => styledText(theme)};\n\n ${mq(\"lg\")} {\n padding: 0 320px 80px 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 & .code-wrapper {\n margin: 10px 0;\n }\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 & .code-wrapper {\n margin: 10px 0;\n }\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 & img,\n & video,\n & iframe {\n max-width: 100%;\n border-radius: ${({ theme }) => theme.spacing.radius.lg};\n }\n\n & code:not([class]) {\n background: ${({ theme }) => rgba(theme.colors.primaryLight, 0.2)};\n color: ${({ theme }) => theme.colors.dark};\n padding: 2px 4px;\n border-radius: ${({ theme }) => theme.spacing.radius.xs};\n }\n\n & table {\n margin: 0;\n padding: 0;\n border-collapse: collapse;\n width: 100%;\n text-align: left;\n\n & tr {\n margin: 0;\n padding: 0;\n }\n\n & th {\n border-bottom: solid 1px ${({ theme }) => theme.colors.grayLight};\n padding: 10px 0;\n ${({ theme }) => styledSmall(theme)};\n font-weight: 600;\n color: ${({ theme }) => theme.colors.dark};\n }\n\n & td {\n border-bottom: solid 1px ${({ theme }) => theme.colors.grayLight};\n padding: 10px 10px 10px 0;\n color: ${({ theme }) => theme.colors.grayDark};\n ${({ theme }) => styledSmall(theme)};\n }\n }\n\n & .lucide {\n color: ${({ theme }) => theme.colors.primary};\n }\n\n & .aspect-video {\n aspect-ratio: 16 / 9;\n border-radius: ${({ theme }) => theme.spacing.radius.lg};\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\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`;\n\nexport const StyledIndexSidebarLabel = styled.span<{ theme: Theme }>`\n ${({ theme }) => styledSmall(theme)};\n color: ${({ theme }) => theme.colors.grayDark};\n`;\n\nexport const StyledIndexSidebarLink = styled.a<{\n theme: Theme;\n $isActive: boolean;\n}>`\n ${({ theme }) => styledSmall(theme)};\n color: ${({ theme, $isActive }) =>\n $isActive ? theme.colors.primary : theme.colors.dark};\n font-weight: ${({ $isActive }) => ($isActive ? \"600\" : \"400\")};\n text-decoration: none;\n transition: all 0.3s ease;\n\n &:hover {\n color: ${({ theme }) => theme.colors.primaryDark};\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 color: ${({ theme }) =>\n theme.isDark\n ? lighten(0.1, theme.colors.primaryLight)\n : darken(0.1, theme.colors.primaryDark)};\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.small.lg};\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 @media (hover: hover) {\n &:hover {\n color: ${({ theme }) =>\n theme.isDark ? theme.colors.primaryLight : theme.colors.primaryDark};\n border-color: ${({ theme }) => theme.colors.primary};\n }\n }\n\n ${({ $isActive, theme }) =>\n $isActive &&\n `\n\t\t\tcolor: ${theme.isDark ? lighten(0.1, theme.colors.primaryLight) : darken(0.1, theme.colors.primaryDark)};\n\t\t\tborder-color: ${theme.colors.primary};\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 { darken, lighten, rgba } from \"polished\";\nimport React from \"react\";\nimport styled, { css } from \"styled-components\";\nimport {\n resetButton,\n styledSmall,\n styledStrong,\n styledText,\n} from \"cherry-styled-components/src/lib\";\nimport Link from \"next/link\";\nimport { mq, Theme } from \"@/app/theme\";\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: 20px 20px 100px 20px;\n width: 100%;\n ${({ theme }) => styledText(theme)};\n\n ${mq(\"lg\")} {\n padding: 20px 340px 80px 340px;\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 & .code-wrapper {\n margin: 10px 0;\n }\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 & .code-wrapper {\n margin: 10px 0;\n }\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 & img,\n & video,\n & iframe {\n max-width: 100%;\n border-radius: ${({ theme }) => theme.spacing.radius.lg};\n }\n\n & code:not([class]) {\n background: ${({ theme }) => rgba(theme.colors.primaryLight, 0.2)};\n color: ${({ theme }) => theme.colors.dark};\n padding: 2px 4px;\n border-radius: ${({ theme }) => theme.spacing.radius.xs};\n }\n\n & table {\n margin: 0;\n padding: 0;\n border-collapse: collapse;\n width: 100%;\n text-align: left;\n\n & tr {\n margin: 0;\n padding: 0;\n }\n\n & th {\n border-bottom: solid 1px ${({ theme }) => theme.colors.grayLight};\n padding: 10px 0;\n ${({ theme }) => styledSmall(theme)};\n font-weight: 600;\n color: ${({ theme }) => theme.colors.dark};\n }\n\n & td {\n border-bottom: solid 1px ${({ theme }) => theme.colors.grayLight};\n padding: 10px 10px 10px 0;\n color: ${({ theme }) => theme.colors.grayDark};\n ${({ theme }) => styledSmall(theme)};\n }\n }\n\n & .lucide {\n color: ${({ theme }) => theme.colors.primary};\n }\n\n & .aspect-video {\n aspect-ratio: 16 / 9;\n border-radius: ${({ theme }) => theme.spacing.radius.lg};\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\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`;\n\nexport const StyledIndexSidebarLabel = styled.span<{ theme: Theme }>`\n ${({ theme }) => styledSmall(theme)};\n color: ${({ theme }) => theme.colors.grayDark};\n`;\n\nexport const StyledIndexSidebarLink = styled.a<{\n theme: Theme;\n $isActive: boolean;\n}>`\n ${({ theme }) => styledSmall(theme)};\n color: ${({ theme, $isActive }) =>\n $isActive ? theme.colors.primary : theme.colors.dark};\n font-weight: ${({ $isActive }) => ($isActive ? \"600\" : \"400\")};\n text-decoration: none;\n transition: all 0.3s ease;\n\n &:hover {\n color: ${({ theme }) => theme.colors.primaryDark};\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 color: ${({ theme }) =>\n theme.isDark\n ? lighten(0.1, theme.colors.primaryLight)\n : darken(0.1, theme.colors.primaryDark)};\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.small.lg};\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 @media (hover: hover) {\n &:hover {\n color: ${({ theme }) =>\n theme.isDark ? theme.colors.primaryLight : theme.colors.primaryDark};\n border-color: ${({ theme }) => theme.colors.primary};\n }\n }\n\n ${({ $isActive, theme }) =>\n $isActive &&\n `\n\t\t\tcolor: ${theme.isDark ? lighten(0.1, theme.colors.primaryLight) : darken(0.1, theme.colors.primaryDark)};\n\t\t\tborder-color: ${theme.colors.primary};\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: 20px;\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\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 };";
@@ -1,5 +1,7 @@
1
1
  export const docsComponentsTemplate = `"use client";
2
- import { mq, Theme } from "@/app/theme";
2
+ import { darken, lighten, rgba } from "polished";
3
+ import React from "react";
4
+ import styled, { css } from "styled-components";
3
5
  import {
4
6
  resetButton,
5
7
  styledSmall,
@@ -7,10 +9,7 @@ import {
7
9
  styledText,
8
10
  } from "cherry-styled-components/src/lib";
9
11
  import Link from "next/link";
10
- import { darken, lighten, rgba } from "polished";
11
- import React from "react";
12
- import styled, { css } from "styled-components";
13
- import { interactiveStyles } from "./SharedStyled";
12
+ import { mq, Theme } from "@/app/theme";
14
13
 
15
14
  interface DocsProps {
16
15
  children: React.ReactNode;
@@ -26,12 +25,12 @@ const StyledDocsSidebar = styled.div<{ theme: Theme }>\`
26
25
 
27
26
  const StyledDocsContainer = styled.div<{ theme: Theme }>\`
28
27
  position: relative;
29
- padding: 0 0 100px 0;
28
+ padding: 20px 20px 100px 20px;
30
29
  width: 100%;
31
30
  \${({ theme }) => styledText(theme)};
32
31
 
33
32
  \${mq("lg")} {
34
- padding: 0 320px 80px 320px;
33
+ padding: 20px 340px 80px 340px;
35
34
  }
36
35
 
37
36
  & p {
@@ -325,7 +324,7 @@ export const StyleMobileBar = styled.button<Props>\`
325
324
  theme.isDark ? theme.colors.dark : theme.colors.primary};
326
325
  backdrop-filter: blur(10px);
327
326
  -webkit-backdrop-filter: blur(10px);
328
- padding: 30px;
327
+ padding: 20px;
329
328
  border-radius: 100px;
330
329
  margin: 0 0 20px 0;
331
330
  font-weight: 600;
@@ -337,7 +336,7 @@ export const StyleMobileBar = styled.button<Props>\`
337
336
  display: none;
338
337
  }
339
338
 
340
- \${({ $isActive }) => $isActive && \`position: fixed; \`};
339
+ \${({ $isActive }) => $isActive && \`position: fixed;\`};
341
340
  \`;
342
341
 
343
342
  export const StyledMobileBurger = styled.span<Props>\`
@@ -384,147 +383,6 @@ export const StyledMobileBurger = styled.span<Props>\`
384
383
  \`};
385
384
  \`;
386
385
 
387
- export const StyledInlineButton = styled.button<{ theme: Theme }>\`
388
- \${resetButton};
389
- \${interactiveStyles};
390
- color: \${({ theme }) => theme.colors.primary};
391
- vertical-align: middle;
392
- border: solid 1px \${({ theme }) => theme.colors.grayLight};
393
- border-radius: \${({ theme }) => theme.spacing.radius.xs};
394
- padding: 0;
395
- width: 18px;
396
- height: 18px;
397
- display: flex;
398
- margin: auto 0;
399
- transition: all 0.3s ease;
400
-
401
- @media (hover: hover) {
402
- &:hover {
403
- color: \${({ theme }) => theme.colors.light};
404
- background: \${({ theme }) => theme.colors.primary};
405
- border-color: \${({ theme }) => theme.colors.primary};
406
- }
407
- }
408
-
409
- & svg {
410
- vertical-align: middle;
411
- width: 12px;
412
- height: 12px;
413
- margin: auto;
414
- }
415
- \`;
416
-
417
- export const StyledPlusButton = styled.button<{ theme: Theme }>\`
418
- \${resetButton};
419
- color: \${({ theme }) => theme.colors.primary};
420
- vertical-align: middle;
421
- padding: 0;
422
- width: 100%;
423
- height: 18px;
424
- display: flex;
425
- margin: auto 0;
426
- transition: all 0.3s ease;
427
- position: relative;
428
- margin: 20px 0 0 0;
429
-
430
- &::before {
431
- content: "";
432
- display: block;
433
- position: absolute;
434
- top: 50%;
435
- transform: translateY(-50%);
436
- width: 100%;
437
- height: 1px;
438
- border-radius: 3px;
439
- background: \${({ theme }) => theme.colors.grayLight};
440
- transition: all 0.3s ease;
441
- z-index: -1;
442
- }
443
-
444
- &::after {
445
- content: "";
446
- display: block;
447
- position: absolute;
448
- left: 50%;
449
- top: 50%;
450
- transform: translate(-50%, -50%);
451
- width: 18px;
452
- height: 18px;
453
- border: solid 1px \${({ theme }) => theme.colors.grayLight};
454
- border-radius: \${({ theme }) => theme.spacing.radius.xs};
455
- background: \${({ theme }) => theme.colors.light};
456
- transition: all 0.3s ease;
457
- z-index: -1;
458
- }
459
-
460
- box-shadow: 0 0 0 0px \${({ theme }) => theme.colors.primary};
461
-
462
- @media (hover: hover) {
463
- &:hover {
464
- &::after {
465
- border-color: \${({ theme }) => theme.colors.primary};
466
- }
467
- }
468
- }
469
-
470
- &:focus {
471
- &::after {
472
- border-color: \${({ theme }) => theme.colors.primary};
473
- box-shadow: 0 0 0 4px \${({ theme }) => theme.colors.primaryLight};
474
- }
475
- }
476
-
477
- &:active {
478
- &::after {
479
- box-shadow: 0 0 0 2px \${({ theme }) => theme.colors.primaryLight};
480
- }
481
- }
482
-
483
- @media (hover: hover) {
484
- &:hover {
485
- color: \${({ theme }) => theme.colors.light};
486
-
487
- &::after {
488
- background: \${({ theme }) => theme.colors.primary};
489
- border-color: \${({ theme }) => theme.colors.primary};
490
- }
491
- }
492
- }
493
-
494
- & svg {
495
- vertical-align: middle;
496
- width: 14px;
497
- height: 14px;
498
- margin: auto;
499
- }
500
- \`;
501
-
502
- export const StyledFullHeightInput = styled.div\`
503
- height: 100%;
504
- width: 100%;
505
- display: flex;
506
- flex-direction: column;
507
- gap: 20px;
508
- flex: 1;
509
-
510
- & > span {
511
- height: 100%;
512
- width: 100%;
513
- }
514
-
515
- & textarea {
516
- height: 100%;
517
- }
518
- \`;
519
-
520
- export const StyledEditorWrapper = styled.div\`
521
- flex: 1;
522
-
523
- &:empty {
524
- display: none;
525
- }
526
- \`;
527
-
528
386
  function DocsWrapper({ children }: DocsProps) {
529
387
  return <StyledDocsWrapper>{children}</StyledDocsWrapper>;
530
388
  }
@@ -537,5 +395,4 @@ function DocsContainer({ children }: DocsProps) {
537
395
  return <StyledDocsContainer>{children}</StyledDocsContainer>;
538
396
  }
539
397
 
540
- export { DocsWrapper, DocsSidebar, DocsContainer };
541
- `;
398
+ export { DocsWrapper, DocsSidebar, DocsContainer };`;
@@ -1 +1 @@
1
- export declare const docsNavigationTemplate = "\"use client\";\nimport { usePathname } from \"next/navigation\";\nimport Link from \"next/link\";\nimport styled from \"styled-components\";\nimport { Icon } from \"@/components/layout/Icon\";\nimport { mq, Theme } from \"@/app/theme\";\nimport { interactiveStyles } from \"@/components/layout/SharedStyled\";\n\nconst NavigationWrapper = styled.div`\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 20px;\n padding: 0 0 100px 0;\n\n ${mq(\"lg\")} {\n padding: 0 320px 80px 320px;\n }\n`;\n\nconst NavButton = styled(Link)<{ theme: Theme }>`\n ${interactiveStyles};\n display: flex;\n flex-direction: column;\n text-decoration: none;\n padding: 20px;\n flex: 50%;\n max-width: 50%;\n border-radius: ${({ theme }) => theme.spacing.radius.lg};\n border: solid 1px ${({ theme }) => theme.colors.grayLight};\n color: ${({ theme }) => theme.colors.dark};\n\n &:hover {\n border-color: ${({ theme }) => theme.colors.primary};\n }\n\n &[data-direction=\"prev\"] {\n align-items: flex-start;\n }\n\n &[data-direction=\"next\"] {\n align-items: flex-end;\n margin-left: auto;\n text-align: right;\n }\n`;\n\nconst NavLabel = styled.span<{ theme: Theme }>`\n color: ${({ theme }) => theme.colors.gray};\n display: flex;\n flex-direction: row;\n gap: 4px;\n\n & svg {\n margin: auto 0;\n }\n`;\n\nconst NavTitle = styled.span<{ theme: Theme }>`\n color: ${({ theme }) => theme.colors.dark};\n font-weight: 600;\n margin: 0 0 4px 0;\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n`;\n\nconst Spacer = styled.div`\n flex: 1;\n`;\n\ninterface Page {\n slug: string;\n title: string;\n category?: string;\n [key: string]: any;\n}\n\ninterface NavigationItem {\n category?: string;\n slug?: string;\n title?: string;\n links?: Page[];\n items?: Page[];\n [key: string]: any;\n}\n\ninterface DocsNavigationProps {\n result: NavigationItem[];\n}\n\nfunction DocsNavigation({ result }: DocsNavigationProps) {\n const pathname = usePathname();\n\n const allPages: Page[] = result.flatMap((item) => {\n if (item.links && Array.isArray(item.links)) {\n return item.links;\n }\n if (item.items && Array.isArray(item.items)) {\n return item.items;\n }\n if (item.slug !== undefined) {\n return [item as Page];\n }\n return [];\n });\n\n const currentSlug = pathname.replace(/^\\//, \"\").replace(/\\/$/, \"\");\n\n const currentIndex = allPages.findIndex((page) => page.slug === currentSlug);\n\n const prevPage = currentIndex > 0 ? allPages[currentIndex - 1] : null;\n const nextPage =\n currentIndex < allPages.length - 1 ? allPages[currentIndex + 1] : null;\n\n if (currentIndex === -1 || allPages.length === 0) {\n return null;\n }\n\n if (!prevPage && !nextPage) {\n return null;\n }\n\n return (\n <NavigationWrapper>\n {prevPage ? (\n <NavButton href={`/${prevPage.slug}`} data-direction=\"prev\">\n <NavTitle>{prevPage.title}</NavTitle>\n <NavLabel>\n <Icon name=\"arrow-left\" size={16} /> Previous\n </NavLabel>\n </NavButton>\n ) : (\n <Spacer />\n )}\n\n {nextPage && (\n <NavButton href={`/${nextPage.slug}`} data-direction=\"next\">\n <NavTitle>{nextPage.title}</NavTitle>\n <NavLabel>\n Next <Icon name=\"arrow-right\" size={16} />\n </NavLabel>\n </NavButton>\n )}\n </NavigationWrapper>\n );\n}\n\nexport { DocsNavigation };";
1
+ export declare const docsNavigationTemplate = "\"use client\";\nimport { usePathname } from \"next/navigation\";\nimport Link from \"next/link\";\nimport styled from \"styled-components\";\nimport { Icon } from \"@/components/layout/Icon\";\nimport { mq, Theme } from \"@/app/theme\";\nimport { interactiveStyles } from \"@/components/layout/SharedStyled\";\n\nconst StyledNavigationWrapper = styled.div`\n padding: 0 20px 100px 20px;\n\n ${mq(\"lg\")} {\n padding: 0 340px 80px 340px;\n }\n`;\n\nconst StyledNavigationInner = styled.div`\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 20px;\n max-width: 640px;\n margin: auto;\n`;\n\nconst StyledNavButton = styled(Link)<{ theme: Theme }>`\n ${interactiveStyles};\n display: flex;\n flex-direction: column;\n text-decoration: none;\n padding: 20px;\n flex: 50%;\n max-width: 50%;\n border-radius: ${({ theme }) => theme.spacing.radius.lg};\n border: solid 1px ${({ theme }) => theme.colors.grayLight};\n color: ${({ theme }) => theme.colors.dark};\n\n &:hover {\n border-color: ${({ theme }) => theme.colors.primary};\n }\n\n &[data-direction=\"prev\"] {\n align-items: flex-start;\n }\n\n &[data-direction=\"next\"] {\n align-items: flex-end;\n margin-left: auto;\n text-align: right;\n }\n`;\n\nconst StyledNavLabel = styled.span<{ theme: Theme }>`\n color: ${({ theme }) => theme.colors.gray};\n display: flex;\n flex-direction: row;\n gap: 4px;\n\n & svg {\n margin: auto 0;\n }\n`;\n\nconst StyledNavTitle = styled.span<{ theme: Theme }>`\n color: ${({ theme }) => theme.colors.dark};\n font-weight: 600;\n margin: 0 0 4px 0;\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n`;\n\nconst StyledSpacer = styled.div`\n flex: 1;\n`;\n\ninterface Page {\n slug: string;\n title: string;\n category?: string;\n [key: string]: any;\n}\n\ninterface NavigationItem {\n category?: string;\n slug?: string;\n title?: string;\n links?: Page[];\n items?: Page[];\n [key: string]: any;\n}\n\ninterface DocsNavigationProps {\n result: NavigationItem[];\n}\n\nfunction DocsNavigation({ result }: DocsNavigationProps) {\n const pathname = usePathname();\n\n const allPages: Page[] = result.flatMap((item) => {\n if (item.links && Array.isArray(item.links)) {\n return item.links;\n }\n if (item.items && Array.isArray(item.items)) {\n return item.items;\n }\n if (item.slug !== undefined) {\n return [item as Page];\n }\n return [];\n });\n\n const currentSlug = pathname.replace(/^\\//, \"\").replace(/\\/$/, \"\");\n\n const currentIndex = allPages.findIndex((page) => page.slug === currentSlug);\n\n const prevPage = currentIndex > 0 ? allPages[currentIndex - 1] : null;\n const nextPage =\n currentIndex < allPages.length - 1 ? allPages[currentIndex + 1] : null;\n\n if (currentIndex === -1 || allPages.length === 0) {\n return null;\n }\n\n if (!prevPage && !nextPage) {\n return null;\n }\n\n return (\n <StyledNavigationWrapper>\n <StyledNavigationInner>\n {prevPage ? (\n <StyledNavButton href={`/${prevPage.slug}`} data-direction=\"prev\">\n <StyledNavTitle>{prevPage.title}</StyledNavTitle>\n <StyledNavLabel>\n <Icon name=\"arrow-left\" size={16} /> Previous\n </StyledNavLabel>\n </StyledNavButton>\n ) : (\n <StyledSpacer />\n )}\n\n {nextPage && (\n <StyledNavButton href={`/${nextPage.slug}`} data-direction=\"next\">\n <StyledNavTitle>{nextPage.title}</StyledNavTitle>\n <StyledNavLabel>\n Next <Icon name=\"arrow-right\" size={16} />\n </StyledNavLabel>\n </StyledNavButton>\n )}\n </StyledNavigationInner>\n </StyledNavigationWrapper>\n );\n}\n\nexport { DocsNavigation };";
@@ -6,19 +6,24 @@ import { Icon } from "@/components/layout/Icon";
6
6
  import { mq, Theme } from "@/app/theme";
7
7
  import { interactiveStyles } from "@/components/layout/SharedStyled";
8
8
 
9
- const NavigationWrapper = styled.div\`
9
+ const StyledNavigationWrapper = styled.div\`
10
+ padding: 0 20px 100px 20px;
11
+
12
+ \${mq("lg")} {
13
+ padding: 0 340px 80px 340px;
14
+ }
15
+ \`;
16
+
17
+ const StyledNavigationInner = styled.div\`
10
18
  display: flex;
11
19
  justify-content: space-between;
12
20
  align-items: center;
13
21
  gap: 20px;
14
- padding: 0 0 100px 0;
15
-
16
- \${mq("lg")} {
17
- padding: 0 320px 80px 320px;
18
- }
22
+ max-width: 640px;
23
+ margin: auto;
19
24
  \`;
20
25
 
21
- const NavButton = styled(Link)<{ theme: Theme }>\`
26
+ const StyledNavButton = styled(Link)<{ theme: Theme }>\`
22
27
  \${interactiveStyles};
23
28
  display: flex;
24
29
  flex-direction: column;
@@ -45,7 +50,7 @@ const NavButton = styled(Link)<{ theme: Theme }>\`
45
50
  }
46
51
  \`;
47
52
 
48
- const NavLabel = styled.span<{ theme: Theme }>\`
53
+ const StyledNavLabel = styled.span<{ theme: Theme }>\`
49
54
  color: \${({ theme }) => theme.colors.gray};
50
55
  display: flex;
51
56
  flex-direction: row;
@@ -56,7 +61,7 @@ const NavLabel = styled.span<{ theme: Theme }>\`
56
61
  }
57
62
  \`;
58
63
 
59
- const NavTitle = styled.span<{ theme: Theme }>\`
64
+ const StyledNavTitle = styled.span<{ theme: Theme }>\`
60
65
  color: \${({ theme }) => theme.colors.dark};
61
66
  font-weight: 600;
62
67
  margin: 0 0 4px 0;
@@ -65,7 +70,7 @@ const NavTitle = styled.span<{ theme: Theme }>\`
65
70
  overflow: hidden;
66
71
  \`;
67
72
 
68
- const Spacer = styled.div\`
73
+ const StyledSpacer = styled.div\`
69
74
  flex: 1;
70
75
  \`;
71
76
 
@@ -122,27 +127,29 @@ function DocsNavigation({ result }: DocsNavigationProps) {
122
127
  }
123
128
 
124
129
  return (
125
- <NavigationWrapper>
126
- {prevPage ? (
127
- <NavButton href={\`/\${prevPage.slug}\`} data-direction="prev">
128
- <NavTitle>{prevPage.title}</NavTitle>
129
- <NavLabel>
130
- <Icon name="arrow-left" size={16} /> Previous
131
- </NavLabel>
132
- </NavButton>
133
- ) : (
134
- <Spacer />
135
- )}
136
-
137
- {nextPage && (
138
- <NavButton href={\`/\${nextPage.slug}\`} data-direction="next">
139
- <NavTitle>{nextPage.title}</NavTitle>
140
- <NavLabel>
141
- Next <Icon name="arrow-right" size={16} />
142
- </NavLabel>
143
- </NavButton>
144
- )}
145
- </NavigationWrapper>
130
+ <StyledNavigationWrapper>
131
+ <StyledNavigationInner>
132
+ {prevPage ? (
133
+ <StyledNavButton href={\`/\${prevPage.slug}\`} data-direction="prev">
134
+ <StyledNavTitle>{prevPage.title}</StyledNavTitle>
135
+ <StyledNavLabel>
136
+ <Icon name="arrow-left" size={16} /> Previous
137
+ </StyledNavLabel>
138
+ </StyledNavButton>
139
+ ) : (
140
+ <StyledSpacer />
141
+ )}
142
+
143
+ {nextPage && (
144
+ <StyledNavButton href={\`/\${nextPage.slug}\`} data-direction="next">
145
+ <StyledNavTitle>{nextPage.title}</StyledNavTitle>
146
+ <StyledNavLabel>
147
+ Next <Icon name="arrow-right" size={16} />
148
+ </StyledNavLabel>
149
+ </StyledNavButton>
150
+ )}
151
+ </StyledNavigationInner>
152
+ </StyledNavigationWrapper>
146
153
  );
147
154
  }
148
155
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "doccupine",
3
- "version": "0.0.21",
3
+ "version": "0.0.22",
4
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": {