doccupine 0.0.63 → 0.0.64

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.
Files changed (86) hide show
  1. package/README.md +4 -3
  2. package/dist/lib/structures.js +2 -0
  3. package/dist/templates/app/theme.d.ts +3 -1
  4. package/dist/templates/app/theme.js +17 -15
  5. package/dist/templates/components/Chat.d.ts +1 -1
  6. package/dist/templates/components/Chat.js +251 -158
  7. package/dist/templates/components/DocsSideBar.d.ts +1 -1
  8. package/dist/templates/components/DocsSideBar.js +34 -11
  9. package/dist/templates/components/SideBar.d.ts +1 -1
  10. package/dist/templates/components/SideBar.js +12 -2
  11. package/dist/templates/components/layout/Accordion.d.ts +1 -1
  12. package/dist/templates/components/layout/Accordion.js +1 -1
  13. package/dist/templates/components/layout/ActionBar.d.ts +1 -1
  14. package/dist/templates/components/layout/ActionBar.js +15 -60
  15. package/dist/templates/components/layout/Callout.d.ts +1 -1
  16. package/dist/templates/components/layout/Callout.js +1 -1
  17. package/dist/templates/components/layout/Card.d.ts +1 -1
  18. package/dist/templates/components/layout/Card.js +26 -7
  19. package/dist/templates/components/layout/Columns.d.ts +1 -1
  20. package/dist/templates/components/layout/Columns.js +1 -1
  21. package/dist/templates/components/layout/DocsComponents.d.ts +1 -1
  22. package/dist/templates/components/layout/DocsComponents.js +37 -11
  23. package/dist/templates/components/layout/DocsNavigation.d.ts +1 -1
  24. package/dist/templates/components/layout/DocsNavigation.js +3 -2
  25. package/dist/templates/components/layout/Field.d.ts +1 -1
  26. package/dist/templates/components/layout/Field.js +1 -1
  27. package/dist/templates/components/layout/Footer.d.ts +1 -1
  28. package/dist/templates/components/layout/Footer.js +28 -6
  29. package/dist/templates/components/layout/Header.d.ts +1 -1
  30. package/dist/templates/components/layout/Header.js +10 -12
  31. package/dist/templates/components/layout/SharedStyles.d.ts +1 -1
  32. package/dist/templates/components/layout/SharedStyles.js +26 -2
  33. package/dist/templates/components/layout/StaticLinks.d.ts +1 -1
  34. package/dist/templates/components/layout/StaticLinks.js +7 -3
  35. package/dist/templates/components/layout/Steps.d.ts +1 -1
  36. package/dist/templates/components/layout/Steps.js +7 -2
  37. package/dist/templates/components/layout/Tabs.d.ts +1 -1
  38. package/dist/templates/components/layout/Tabs.js +2 -2
  39. package/dist/templates/components/layout/Update.d.ts +1 -1
  40. package/dist/templates/components/layout/Update.js +1 -1
  41. package/dist/templates/mdx/ai-assistant.mdx.d.ts +1 -1
  42. package/dist/templates/mdx/ai-assistant.mdx.js +8 -0
  43. package/dist/templates/mdx/callouts.mdx.d.ts +1 -1
  44. package/dist/templates/mdx/callouts.mdx.js +6 -2
  45. package/dist/templates/mdx/cards.mdx.d.ts +1 -1
  46. package/dist/templates/mdx/cards.mdx.js +19 -3
  47. package/dist/templates/mdx/columns.mdx.d.ts +1 -1
  48. package/dist/templates/mdx/columns.mdx.js +2 -2
  49. package/dist/templates/mdx/commands.mdx.d.ts +1 -1
  50. package/dist/templates/mdx/commands.mdx.js +10 -2
  51. package/dist/templates/mdx/components.mdx.d.ts +1 -0
  52. package/dist/templates/mdx/components.mdx.js +56 -0
  53. package/dist/templates/mdx/deployment.mdx.d.ts +1 -1
  54. package/dist/templates/mdx/deployment.mdx.js +1 -1
  55. package/dist/templates/mdx/globals.mdx.d.ts +1 -1
  56. package/dist/templates/mdx/globals.mdx.js +5 -0
  57. package/dist/templates/mdx/index.mdx.d.ts +1 -1
  58. package/dist/templates/mdx/index.mdx.js +5 -5
  59. package/dist/templates/mdx/model-context-protocol.mdx.d.ts +1 -1
  60. package/dist/templates/mdx/model-context-protocol.mdx.js +2 -2
  61. package/dist/templates/mdx/navigation.mdx.d.ts +1 -1
  62. package/dist/templates/mdx/navigation.mdx.js +1 -1
  63. package/dist/templates/mdx/platform/external-links.mdx.d.ts +1 -1
  64. package/dist/templates/mdx/platform/external-links.mdx.js +2 -0
  65. package/dist/templates/mdx/platform/fonts-settings.mdx.d.ts +1 -1
  66. package/dist/templates/mdx/platform/fonts-settings.mdx.js +8 -5
  67. package/dist/templates/mdx/platform/index.mdx.d.ts +1 -1
  68. package/dist/templates/mdx/platform/index.mdx.js +10 -1
  69. package/dist/templates/mdx/platform/site-settings.mdx.d.ts +1 -1
  70. package/dist/templates/mdx/platform/site-settings.mdx.js +4 -4
  71. package/dist/templates/mdx/sections.mdx.d.ts +1 -1
  72. package/dist/templates/mdx/sections.mdx.js +2 -2
  73. package/dist/templates/mdx/steps.mdx.d.ts +1 -1
  74. package/dist/templates/mdx/steps.mdx.js +4 -0
  75. package/dist/templates/mdx/tabs.mdx.d.ts +1 -1
  76. package/dist/templates/mdx/tabs.mdx.js +1 -1
  77. package/dist/templates/package.js +4 -4
  78. package/dist/templates/services/llm/types.d.ts +1 -1
  79. package/dist/templates/services/llm/types.js +1 -1
  80. package/dist/templates/services/mcp/server.d.ts +1 -1
  81. package/dist/templates/services/mcp/server.js +1 -1
  82. package/dist/templates/services/mcp/tools.d.ts +1 -1
  83. package/dist/templates/services/mcp/tools.js +1 -5
  84. package/dist/templates/utils/config.d.ts +1 -1
  85. package/dist/templates/utils/config.js +1 -1
  86. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  export const sideBarTemplate = `"use client";
2
- import { useContext, useState } from "react";
2
+ import { useContext, useState, Suspense } from "react";
3
3
  import { usePathname } from "next/navigation";
4
- import { Space } from "cherry-styled-components";
4
+ import { Flex, Space } from "cherry-styled-components";
5
5
  import {
6
6
  DocsSidebar,
7
7
  SectionBarContext,
@@ -13,6 +13,10 @@ import {
13
13
  StyleMobileBar,
14
14
  StyledMobileBurger,
15
15
  } from "@/components/layout/DocsComponents";
16
+ import {
17
+ ToggleTheme,
18
+ ToggleThemeLoading,
19
+ } from "@/components/layout/ThemeToggle";
16
20
 
17
21
  type NavItem = {
18
22
  label: string;
@@ -74,6 +78,12 @@ function SideBar({ result }: SideBarProps) {
74
78
  </StyledSidebarList>
75
79
  );
76
80
  })}
81
+ <Space $xs={40} $lg={20} />
82
+ <Flex $xsJustifyContent="flex-start" $lgJustifyContent="flex-end">
83
+ <Suspense fallback={<ToggleThemeLoading />}>
84
+ <ToggleTheme />
85
+ </Suspense>
86
+ </Flex>
77
87
  </StyledSidebar>
78
88
  </DocsSidebar>
79
89
  );
@@ -1 +1 @@
1
- export declare const accordionTemplate = "\"use client\";\nimport { useState } from \"react\";\nimport styled, { css } from \"styled-components\";\nimport { styledText, Theme } from \"cherry-styled-components\";\nimport { Icon } from \"@/components/layout/Icon\";\n\nconst StyledAccordion = styled.div<{ theme: Theme }>`\n background: ${({ theme }) => theme.colors.light};\n border: solid 1px ${({ theme }) => theme.colors.grayLight};\n border-radius: ${({ theme }) => theme.spacing.radius.lg};\n padding: 20px;\n margin: 0;\n ${({ theme }) => styledText(theme)};\n width: 100%;\n`;\n\nconst StyledAccordionTitle = styled.h3<{ theme: Theme; $isOpen: boolean }>`\n cursor: pointer;\n margin: 0;\n padding: 0 40px 0 0;\n ${({ theme }) => styledText(theme)};\n color: ${({ theme }) => theme.colors.primary};\n transition: color 0.3s ease;\n position: relative;\n\n &:hover {\n color: ${({ theme }) => theme.colors.primaryDark};\n }\n\n & .lucide-chevron-down {\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n right: 0;\n transition: transform 0.3s ease;\n\n ${({ $isOpen }) =>\n $isOpen &&\n css`\n transform: translateY(-50%) rotate(180deg);\n `}\n }\n`;\n\nconst StyledAccordionContent = styled.div<{ theme: Theme; $isOpen: boolean }>`\n ${({ theme }) => styledText(theme)};\n color: ${({ theme }) => theme.colors.grayDark};\n height: 0;\n overflow: clip;\n transition: all 0.3s ease;\n display: flex;\n flex-direction: column;\n gap: 20px;\n flex-wrap: wrap;\n flex: 1;\n\n ${({ $isOpen }) =>\n $isOpen &&\n css`\n margin: 20px 0 0;\n height: auto;\n `}\n`;\n\nexport interface AccordionProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n title: string;\n}\n\nfunction Accordion({ children, title }: AccordionProps) {\n const [isOpen, setIsOpen] = useState(false);\n\n return (\n <StyledAccordion>\n <StyledAccordionTitle\n onClick={() => setIsOpen(!isOpen)}\n $isOpen={isOpen}\n role=\"button\"\n aria-expanded={isOpen}\n >\n {title} <Icon name=\"ChevronDown\" />\n </StyledAccordionTitle>\n <StyledAccordionContent $isOpen={isOpen}>\n {children}\n </StyledAccordionContent>\n </StyledAccordion>\n );\n}\n\nexport { Accordion };\n";
1
+ export declare const accordionTemplate = "\"use client\";\nimport { useState } from \"react\";\nimport styled, { css } from \"styled-components\";\nimport { styledText, Theme } from \"cherry-styled-components\";\nimport { Icon } from \"@/components/layout/Icon\";\n\nconst StyledAccordion = styled.div<{ theme: Theme }>`\n background: ${({ theme }) => theme.colors.light};\n border: solid 1px ${({ theme }) => theme.colors.grayLight};\n border-radius: ${({ theme }) => theme.spacing.radius.lg};\n padding: 20px;\n margin: 0;\n ${({ theme }) => styledText(theme)};\n width: 100%;\n`;\n\nconst StyledAccordionTitle = styled.h3<{ theme: Theme; $isOpen: boolean }>`\n cursor: pointer;\n margin: 0;\n padding: 0 40px 0 0;\n ${({ theme }) => styledText(theme)};\n color: ${({ theme }) => theme.colors.primary};\n transition: color 0.3s ease;\n position: relative;\n\n &:hover {\n color: ${({ theme }) => theme.colors.primaryDark};\n }\n\n & .lucide-chevron-down {\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n right: 0;\n transition: transform 0.3s ease;\n\n ${({ $isOpen }) =>\n $isOpen &&\n css`\n transform: translateY(-50%) rotate(180deg);\n `}\n }\n`;\n\nconst StyledAccordionContent = styled.div<{ theme: Theme; $isOpen: boolean }>`\n ${({ theme }) => styledText(theme)};\n color: ${({ theme }) => theme.colors.grayDark};\n height: 0;\n overflow: clip;\n transition: all 0.3s ease;\n display: flex;\n flex-direction: column;\n gap: 20px;\n flex-wrap: wrap;\n flex: 1;\n\n ${({ $isOpen }) =>\n $isOpen &&\n css`\n margin: 20px 0 0;\n height: auto;\n `}\n`;\n\ninterface AccordionProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n title: string;\n}\n\nfunction Accordion({ children, title }: AccordionProps) {\n const [isOpen, setIsOpen] = useState(false);\n\n return (\n <StyledAccordion>\n <StyledAccordionTitle\n onClick={() => setIsOpen(!isOpen)}\n $isOpen={isOpen}\n role=\"button\"\n aria-expanded={isOpen}\n >\n {title} <Icon name=\"ChevronDown\" />\n </StyledAccordionTitle>\n <StyledAccordionContent $isOpen={isOpen}>\n {children}\n </StyledAccordionContent>\n </StyledAccordion>\n );\n}\n\nexport { Accordion };\n";
@@ -62,7 +62,7 @@ const StyledAccordionContent = styled.div<{ theme: Theme; $isOpen: boolean }>\`
62
62
  \`}
63
63
  \`;
64
64
 
65
- export interface AccordionProps extends React.HTMLAttributes<HTMLDivElement> {
65
+ interface AccordionProps extends React.HTMLAttributes<HTMLDivElement> {
66
66
  children: React.ReactNode;
67
67
  title: string;
68
68
  }
@@ -1 +1 @@
1
- export declare const actionBarTemplate = "\"use client\";\nimport { useContext, 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\";\nimport { ChatContext } from \"@/components/Chat\";\nimport { SectionBarContext } from \"@/components/layout/DocsComponents\";\n\ninterface ActionBarProps {\n children: React.ReactNode;\n content: string;\n}\n\nconst StyledActionBar = styled.div<{\n theme: Theme;\n $isChatOpen?: boolean;\n}>`\n position: absolute;\n border-bottom: solid 1px ${({ theme }) => theme.colors.grayLight};\n left: 0;\n padding: 0 20px 20px;\n display: flex;\n justify-content: space-between;\n width: 100%;\n transition: all 0.3s ease;\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;\n margin: 0;\n\n ${({ $isChatOpen }) =>\n $isChatOpen &&\n css`\n padding: 0 120px 20px 20px;\n `}\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: inherit;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n gap: 6px;\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 &:hover {\n transform: scale(1.05);\n color: ${({ theme }) =>\n theme.isDark ? theme.colors.primaryLight : theme.colors.primaryDark};\n\n & svg[stroke] {\n stroke: ${({ theme }) =>\n theme.isDark ? theme.colors.primaryLight : theme.colors.primaryDark};\n }\n }\n\n &:active {\n transform: scale(0.97);\n }\n`;\n\nconst StyledContent = styled.div<{\n theme: Theme;\n $isChatActive?: boolean;\n $isChatOpen?: boolean;\n $hasSectionBar?: boolean;\n}>`\n padding-top: 74px;\n transition: all 0.3s ease;\n\n ${mq(\"lg\")} {\n ${({ $isChatActive }) =>\n $isChatActive &&\n css`\n padding-top: 140px;\n `}\n\n ${({ $isChatOpen, $isChatActive }) =>\n $isChatOpen &&\n $isChatActive &&\n css`\n padding-top: 70px;\n `}\n }\n\n & textarea {\n max-width: 640px;\n margin: auto;\n width: 100%;\n height: 100%;\n min-height: calc(\n 100vh - ${({ $hasSectionBar }) => ($hasSectionBar ? 219 : 178)}px\n );\n\n ${({ $isChatOpen, $isChatActive, $hasSectionBar }) =>\n !$isChatOpen &&\n $isChatActive &&\n css`\n min-height: calc(100vh - ${$hasSectionBar ? 288 : 246}px);\n `}\n\n ${mq(\"lg\")} {\n min-height: calc(100vh - 176px);\n\n ${({ $isChatOpen, $isChatActive }) =>\n !$isChatOpen &&\n $isChatActive &&\n css`\n min-height: calc(100vh - 242px);\n `}\n }\n }\n`;\n\nfunction ActionBar({ children, content }: ActionBarProps) {\n const [isView, setIsView] = useState(true);\n const [copied, setCopied] = useState(false);\n const { isOpen, isChatActive } = useContext(ChatContext);\n const hasSectionBar = useContext(SectionBarContext);\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 $isChatOpen={isOpen}>\n <StyledCopyButton onClick={handleCopyContent} $copied={copied}>\n {copied ? (\n <>\n <Icon name=\"check\" size={16} />\n <span>Copied!</span>\n </>\n ) : (\n <>\n <Icon name=\"copy\" size={16} />\n <span>Copy Content</span>\n </>\n )}\n </StyledCopyButton>\n <StyledActionBarContent>\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 && (\n <StyledContent\n $isChatActive={isChatActive}\n $isChatOpen={isOpen}\n $hasSectionBar={hasSectionBar}\n >\n {children}\n </StyledContent>\n )}\n {!isView && (\n <StyledContent\n $isChatActive={isChatActive}\n $isChatOpen={isOpen}\n $hasSectionBar={hasSectionBar}\n >\n <Textarea defaultValue={content} $fullWidth />\n </StyledContent>\n )}\n </>\n );\n}\n\nexport { ActionBar };\n";
1
+ export declare const actionBarTemplate = "\"use client\";\nimport { useContext, 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\";\nimport { ChatContext } from \"@/components/Chat\";\nimport { SectionBarContext } from \"@/components/layout/DocsComponents\";\nimport { StyledSmallButton } from \"@/components/layout/SharedStyled\";\n\ninterface ActionBarProps {\n children: React.ReactNode;\n content: string;\n}\n\nconst StyledActionBar = styled.div<{\n theme: Theme;\n $isChatOpen?: boolean;\n}>`\n position: absolute;\n border-bottom: solid 1px ${({ theme }) => theme.colors.grayLight};\n left: 0;\n padding: 12px 20px;\n display: flex;\n justify-content: space-between;\n width: 100%;\n transition: all 0.3s ease;\n\n ${mq(\"lg\")} {\n left: 50%;\n transform: translateX(-50%);\n max-width: calc(100vw - 560px);\n width: 100%;\n padding: 12px;\n margin: 0;\n\n ${({ $isChatOpen }) =>\n $isChatOpen &&\n css`\n padding-right: 152px;\n `}\n }\n`;\n\nconst StyledActionBarContent = styled.div`\n margin: auto 0;\n`;\n\nconst StyledCopyButton = styled(StyledSmallButton)<{\n theme: Theme;\n $copied: boolean;\n}>`\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\n & svg.lucide {\n color: ${({ theme, $copied }) =>\n $copied ? theme.colors.success : theme.colors.primary};\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 &:hover {\n transform: scale(1.05);\n color: ${({ theme }) =>\n theme.isDark ? theme.colors.primaryLight : theme.colors.primaryDark};\n\n & svg[stroke] {\n stroke: ${({ theme }) =>\n theme.isDark ? theme.colors.primaryLight : theme.colors.primaryDark};\n }\n }\n\n &:active {\n transform: scale(0.97);\n }\n`;\n\nconst StyledContent = styled.div<{\n theme: Theme;\n $isChatActive?: boolean;\n $isChatOpen?: boolean;\n $hasSectionBar?: boolean;\n}>`\n padding-top: 77px;\n transition: all 0.3s ease;\n\n & textarea {\n max-width: 640px;\n margin: auto;\n width: 100%;\n height: 100%;\n min-height: calc(\n 100vh - ${({ $hasSectionBar }) => ($hasSectionBar ? 202 : 160)}px\n );\n\n ${mq(\"lg\")} {\n min-height: calc(100vh - 159px);\n }\n }\n`;\n\nfunction ActionBar({ children, content }: ActionBarProps) {\n const [isView, setIsView] = useState(true);\n const [copied, setCopied] = useState(false);\n const { isOpen, isChatActive } = useContext(ChatContext);\n const hasSectionBar = useContext(SectionBarContext);\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 $isChatOpen={isOpen}>\n <StyledCopyButton onClick={handleCopyContent} $copied={copied}>\n {copied ? (\n <>\n <Icon name=\"check\" size={16} />\n Copied!\n </>\n ) : (\n <>\n <Icon name=\"copy\" size={16} />\n Copy Content\n </>\n )}\n </StyledCopyButton>\n <StyledActionBarContent>\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 && (\n <StyledContent\n $isChatActive={isChatActive}\n $isChatOpen={isOpen}\n $hasSectionBar={hasSectionBar}\n >\n {children}\n </StyledContent>\n )}\n {!isView && (\n <StyledContent\n $isChatActive={isChatActive}\n $isChatOpen={isOpen}\n $hasSectionBar={hasSectionBar}\n >\n <Textarea defaultValue={content} $fullWidth />\n </StyledContent>\n )}\n </>\n );\n}\n\nexport { ActionBar };\n";
@@ -1,3 +1,4 @@
1
+ import { SIDEBAR_WIDTH } from "../../app/theme.js";
1
2
  export const actionBarTemplate = `"use client";
2
3
  import { useContext, useState } from "react";
3
4
  import styled, { css } from "styled-components";
@@ -7,6 +8,7 @@ import { rgba } from "polished";
7
8
  import { resetButton, Textarea } from "cherry-styled-components";
8
9
  import { ChatContext } from "@/components/Chat";
9
10
  import { SectionBarContext } from "@/components/layout/DocsComponents";
11
+ import { StyledSmallButton } from "@/components/layout/SharedStyled";
10
12
 
11
13
  interface ActionBarProps {
12
14
  children: React.ReactNode;
@@ -20,7 +22,7 @@ const StyledActionBar = styled.div<{
20
22
  position: absolute;
21
23
  border-bottom: solid 1px \${({ theme }) => theme.colors.grayLight};
22
24
  left: 0;
23
- padding: 0 20px 20px;
25
+ padding: 12px 20px;
24
26
  display: flex;
25
27
  justify-content: space-between;
26
28
  width: 100%;
@@ -29,15 +31,15 @@ const StyledActionBar = styled.div<{
29
31
  \${mq("lg")} {
30
32
  left: 50%;
31
33
  transform: translateX(-50%);
32
- max-width: calc(100vw - 640px);
34
+ max-width: calc(100vw - ${SIDEBAR_WIDTH * 2}px);
33
35
  width: 100%;
34
- padding: 0 20px 20px;
36
+ padding: 12px;
35
37
  margin: 0;
36
38
 
37
39
  \${({ $isChatOpen }) =>
38
40
  $isChatOpen &&
39
41
  css\`
40
- padding: 0 120px 20px 20px;
42
+ padding-right: 152px;
41
43
  \`}
42
44
  }
43
45
  \`;
@@ -46,38 +48,20 @@ const StyledActionBarContent = styled.div\`
46
48
  margin: auto 0;
47
49
  \`;
48
50
 
49
- const StyledCopyButton = styled.button<{ theme: Theme; $copied: boolean }>\`
50
- background: transparent;
51
+ const StyledCopyButton = styled(StyledSmallButton)<{
52
+ theme: Theme;
53
+ $copied: boolean;
54
+ }>\`
51
55
  border: solid 1px
52
56
  \${({ theme, $copied }) =>
53
57
  $copied ? theme.colors.success : theme.colors.grayLight};
54
58
  color: \${({ theme, $copied }) =>
55
59
  $copied ? theme.colors.success : theme.colors.primary};
56
- border-radius: \${({ theme }) => theme.spacing.radius.xs};
57
- padding: 6px 8px;
58
- font-size: 12px;
59
- font-family: inherit;
60
- font-weight: 600;
61
- cursor: pointer;
62
- transition: all 0.2s ease;
63
- display: flex;
64
- align-items: center;
65
- gap: 6px;
66
- margin-right: -6px;
67
60
 
68
61
  & svg.lucide {
69
62
  color: \${({ theme, $copied }) =>
70
63
  $copied ? theme.colors.success : theme.colors.primary};
71
64
  }
72
-
73
- &:hover {
74
- border-color: \${({ theme, $copied }) =>
75
- $copied ? theme.colors.success : theme.colors.primary};
76
- }
77
-
78
- &:active {
79
- transform: scale(0.95);
80
- }
81
65
  \`;
82
66
 
83
67
  const StyledToggle = styled.button<{ theme: Theme; $isActive?: boolean }>\`
@@ -154,49 +138,20 @@ const StyledContent = styled.div<{
154
138
  $isChatOpen?: boolean;
155
139
  $hasSectionBar?: boolean;
156
140
  }>\`
157
- padding-top: 74px;
141
+ padding-top: 77px;
158
142
  transition: all 0.3s ease;
159
143
 
160
- \${mq("lg")} {
161
- \${({ $isChatActive }) =>
162
- $isChatActive &&
163
- css\`
164
- padding-top: 140px;
165
- \`}
166
-
167
- \${({ $isChatOpen, $isChatActive }) =>
168
- $isChatOpen &&
169
- $isChatActive &&
170
- css\`
171
- padding-top: 70px;
172
- \`}
173
- }
174
-
175
144
  & textarea {
176
145
  max-width: 640px;
177
146
  margin: auto;
178
147
  width: 100%;
179
148
  height: 100%;
180
149
  min-height: calc(
181
- 100vh - \${({ $hasSectionBar }) => ($hasSectionBar ? 219 : 178)}px
150
+ 100vh - \${({ $hasSectionBar }) => ($hasSectionBar ? 202 : 160)}px
182
151
  );
183
152
 
184
- \${({ $isChatOpen, $isChatActive, $hasSectionBar }) =>
185
- !$isChatOpen &&
186
- $isChatActive &&
187
- css\`
188
- min-height: calc(100vh - \${$hasSectionBar ? 288 : 246}px);
189
- \`}
190
-
191
153
  \${mq("lg")} {
192
- min-height: calc(100vh - 176px);
193
-
194
- \${({ $isChatOpen, $isChatActive }) =>
195
- !$isChatOpen &&
196
- $isChatActive &&
197
- css\`
198
- min-height: calc(100vh - 242px);
199
- \`}
154
+ min-height: calc(100vh - 159px);
200
155
  }
201
156
  }
202
157
  \`;
@@ -224,12 +179,12 @@ function ActionBar({ children, content }: ActionBarProps) {
224
179
  {copied ? (
225
180
  <>
226
181
  <Icon name="check" size={16} />
227
- <span>Copied!</span>
182
+ Copied!
228
183
  </>
229
184
  ) : (
230
185
  <>
231
186
  <Icon name="copy" size={16} />
232
- <span>Copy Content</span>
187
+ Copy Content
233
188
  </>
234
189
  )}
235
190
  </StyledCopyButton>
@@ -1 +1 @@
1
- export declare const calloutTemplate = "\"use client\";\nimport { Theme } from \"@/app/theme\";\nimport { styledSmall } from \"cherry-styled-components\";\nimport styled, { css } from \"styled-components\";\nimport { Icon, IconProps } from \"@/components/layout/Icon\";\n\ntype CalloutType = \"note\" | \"info\" | \"warning\" | \"danger\" | \"success\";\n\nconst StyledCallout = styled.div<{ theme: Theme; $type?: CalloutType }>`\n background: ${({ theme }) => theme.colors.light};\n border: solid 1px ${({ theme }) => theme.colors.grayLight};\n border-radius: ${({ theme }) => theme.spacing.radius.lg};\n padding: 20px;\n margin: 0;\n ${({ theme }) => styledSmall(theme)}\n color: ${({ theme }) => theme.colors.grayDark};\n display: flex;\n\n & svg {\n vertical-align: middle;\n min-width: min-content;\n margin: 3px 10px 0 0;\n }\n\n ${({ theme, $type }) =>\n $type === \"note\" &&\n css`\n border-color: ${theme.isDark ? \"#0ea5e94d\" : \"#0ea5e933\"};\n background: ${theme.isDark ? \"#0ea5e91a\" : \"#f0f9ff80\"};\n\n & svg.lucide,\n & p {\n color: ${theme.isDark ? \"#bae6fd\" : \"#0c4a6e\"};\n }\n `}\n\n ${({ theme, $type }) =>\n $type === \"info\" &&\n css`\n border-color: ${theme.isDark ? \"#71717a4d\" : \"#71717a33\"};\n background: ${theme.isDark ? \"#71717a1a\" : \"#fafafa80\"};\n\n & svg.lucide,\n & .lucide,\n & p {\n color: ${theme.isDark ? \"#e4e4e7\" : \"#18181b\"};\n }\n `}\n\n ${({ theme, $type }) =>\n $type === \"warning\" &&\n css`\n border-color: ${theme.isDark ? \"#f59e0b4d\" : \"#f59e0b33\"};\n background: ${theme.isDark ? \"#f59e0b1a\" : \"#fffbeb80\"};\n\n & svg.lucide,\n & p {\n color: ${theme.isDark ? \"#fde68a\" : \"#78350f\"};\n }\n `}\n\n ${({ theme, $type }) =>\n $type === \"danger\" &&\n css`\n border-color: ${theme.isDark ? \"#ef44444d\" : \"#ef444433\"};\n background: ${theme.isDark ? \"#ef44441a\" : \"#fef2f280\"};\n\n & svg.lucide,\n & p {\n color: ${theme.isDark ? \"#fecaca\" : \"#7f1d1d\"};\n }\n `}\n\n ${({ theme, $type }) =>\n $type === \"success\" &&\n css`\n border-color: ${theme.isDark ? \"#10b9814d\" : \"#10b98133\"};\n background: ${theme.isDark ? \"#10b9811a\" : \"#ecfdf580\"};\n\n & svg.lucide,\n & p {\n color: ${theme.isDark ? \"#a7f3d0\" : \"#064e3b\"};\n }\n `}\n`;\n\nexport interface CalloutProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n icon?: IconProps;\n type?: CalloutType;\n}\n\nfunction Callout({ children, type, icon }: CalloutProps) {\n const iconType =\n type === \"note\"\n ? \"CircleAlert\"\n : type === \"info\"\n ? \"Info\"\n : type === \"warning\"\n ? \"TriangleAlert\"\n : type === \"danger\"\n ? \"OctagonAlert\"\n : type === \"success\"\n ? \"Check\"\n : (icon as IconProps);\n return (\n <StyledCallout $type={type}>\n <Icon name={iconType} size={16} />\n {children}\n </StyledCallout>\n );\n}\n\nexport { Callout };\n";
1
+ export declare const calloutTemplate = "\"use client\";\nimport { Theme } from \"@/app/theme\";\nimport { styledSmall } from \"cherry-styled-components\";\nimport styled, { css } from \"styled-components\";\nimport { Icon, IconProps } from \"@/components/layout/Icon\";\n\ntype CalloutType = \"note\" | \"info\" | \"warning\" | \"danger\" | \"success\";\n\nconst StyledCallout = styled.div<{ theme: Theme; $type?: CalloutType }>`\n background: ${({ theme }) => theme.colors.light};\n border: solid 1px ${({ theme }) => theme.colors.grayLight};\n border-radius: ${({ theme }) => theme.spacing.radius.lg};\n padding: 20px;\n margin: 0;\n ${({ theme }) => styledSmall(theme)}\n color: ${({ theme }) => theme.colors.grayDark};\n display: flex;\n\n & svg {\n vertical-align: middle;\n min-width: min-content;\n margin: 3px 10px 0 0;\n }\n\n ${({ theme, $type }) =>\n $type === \"note\" &&\n css`\n border-color: ${theme.isDark ? \"#0ea5e94d\" : \"#0ea5e933\"};\n background: ${theme.isDark ? \"#0ea5e91a\" : \"#f0f9ff80\"};\n\n & svg.lucide,\n & p {\n color: ${theme.isDark ? \"#bae6fd\" : \"#0c4a6e\"};\n }\n `}\n\n ${({ theme, $type }) =>\n $type === \"info\" &&\n css`\n border-color: ${theme.isDark ? \"#71717a4d\" : \"#71717a33\"};\n background: ${theme.isDark ? \"#71717a1a\" : \"#fafafa80\"};\n\n & svg.lucide,\n & .lucide,\n & p {\n color: ${theme.isDark ? \"#e4e4e7\" : \"#18181b\"};\n }\n `}\n\n ${({ theme, $type }) =>\n $type === \"warning\" &&\n css`\n border-color: ${theme.isDark ? \"#f59e0b4d\" : \"#f59e0b33\"};\n background: ${theme.isDark ? \"#f59e0b1a\" : \"#fffbeb80\"};\n\n & svg.lucide,\n & p {\n color: ${theme.isDark ? \"#fde68a\" : \"#78350f\"};\n }\n `}\n\n ${({ theme, $type }) =>\n $type === \"danger\" &&\n css`\n border-color: ${theme.isDark ? \"#ef44444d\" : \"#ef444433\"};\n background: ${theme.isDark ? \"#ef44441a\" : \"#fef2f280\"};\n\n & svg.lucide,\n & p {\n color: ${theme.isDark ? \"#fecaca\" : \"#7f1d1d\"};\n }\n `}\n\n ${({ theme, $type }) =>\n $type === \"success\" &&\n css`\n border-color: ${theme.isDark ? \"#10b9814d\" : \"#10b98133\"};\n background: ${theme.isDark ? \"#10b9811a\" : \"#ecfdf580\"};\n\n & svg.lucide,\n & p {\n color: ${theme.isDark ? \"#a7f3d0\" : \"#064e3b\"};\n }\n `}\n`;\n\ninterface CalloutProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n icon?: IconProps;\n type?: CalloutType;\n}\n\nfunction Callout({ children, type, icon }: CalloutProps) {\n const iconType =\n type === \"note\"\n ? \"CircleAlert\"\n : type === \"info\"\n ? \"Info\"\n : type === \"warning\"\n ? \"TriangleAlert\"\n : type === \"danger\"\n ? \"OctagonAlert\"\n : type === \"success\"\n ? \"Check\"\n : (icon as IconProps);\n return (\n <StyledCallout $type={type}>\n <Icon name={iconType} size={16} />\n {children}\n </StyledCallout>\n );\n}\n\nexport { Callout };\n";
@@ -84,7 +84,7 @@ const StyledCallout = styled.div<{ theme: Theme; $type?: CalloutType }>\`
84
84
  \`}
85
85
  \`;
86
86
 
87
- export interface CalloutProps extends React.HTMLAttributes<HTMLDivElement> {
87
+ interface CalloutProps extends React.HTMLAttributes<HTMLDivElement> {
88
88
  children: React.ReactNode;
89
89
  icon?: IconProps;
90
90
  type?: CalloutType;
@@ -1 +1 @@
1
- export declare const cardTemplate = "\"use client\";\nimport styled, { useTheme } from \"styled-components\";\nimport { styledText, Theme } from \"cherry-styled-components\";\nimport { Icon, IconProps } from \"@/components/layout/Icon\";\n\nconst StyledCard = styled.div<{ theme: Theme }>`\n background: ${({ theme }) => theme.colors.light};\n border: solid 1px ${({ theme }) => theme.colors.grayLight};\n border-radius: ${({ theme }) => theme.spacing.radius.lg};\n padding: 20px;\n margin: 0;\n ${({ theme }) => styledText(theme)}\n color: ${({ theme }) => theme.colors.grayDark};\n`;\n\nconst StyledCardTitle = styled.h3<{ theme: Theme }>`\n margin: 5px 0;\n color: ${({ theme }) => theme.colors.dark};\n ${({ theme }) => styledText(theme)};\n`;\n\nexport interface CardProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n title: string;\n icon?: IconProps;\n}\n\nfunction Card({ children, title, icon }: CardProps) {\n const theme = useTheme() as Theme;\n\n return (\n <StyledCard>\n {icon && <Icon name={icon} color={theme.colors.primary} />}\n <StyledCardTitle>{title}</StyledCardTitle>\n {children}\n </StyledCard>\n );\n}\n\nexport { Card };\n";
1
+ export declare const cardTemplate = "\"use client\";\nimport Link from \"next/link\";\nimport styled, { css, useTheme } from \"styled-components\";\nimport { styledText, Theme } from \"cherry-styled-components\";\nimport { Icon, IconProps } from \"@/components/layout/Icon\";\nimport { interactiveStyles } from \"@/components/layout/SharedStyled\";\n\nconst cardStyles = css<{ theme: Theme }>`\n background: ${({ theme }) => theme.colors.light};\n border: solid 1px ${({ theme }) => theme.colors.grayLight};\n border-radius: ${({ theme }) => theme.spacing.radius.lg};\n padding: 20px;\n margin: 0;\n ${({ theme }) => styledText(theme)}\n color: ${({ theme }) => theme.colors.grayDark};\n`;\n\nconst StyledCard = styled.div<{ theme: Theme }>`\n ${cardStyles}\n`;\n\nconst StyledCardLink = styled(Link)<{ theme: Theme }>`\n ${interactiveStyles};\n ${cardStyles}\n text-decoration: none;\n`;\n\nconst StyledCardTitle = styled.h3<{ theme: Theme }>`\n margin: 5px 0;\n color: ${({ theme }) => theme.colors.dark};\n ${({ theme }) => styledText(theme)};\n`;\n\ninterface CardProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n title: string;\n icon?: IconProps;\n href?: string;\n}\n\nfunction Card({ children, title, icon, href }: CardProps) {\n const theme = useTheme() as Theme;\n\n const content = (\n <>\n {icon && <Icon name={icon} color={theme.colors.primary} />}\n <StyledCardTitle>{title}</StyledCardTitle>\n {children}\n </>\n );\n\n if (href) {\n return <StyledCardLink href={href}>{content}</StyledCardLink>;\n }\n\n return <StyledCard>{content}</StyledCard>;\n}\n\nexport { Card };\n";
@@ -1,9 +1,11 @@
1
1
  export const cardTemplate = `"use client";
2
- import styled, { useTheme } from "styled-components";
2
+ import Link from "next/link";
3
+ import styled, { css, useTheme } from "styled-components";
3
4
  import { styledText, Theme } from "cherry-styled-components";
4
5
  import { Icon, IconProps } from "@/components/layout/Icon";
6
+ import { interactiveStyles } from "@/components/layout/SharedStyled";
5
7
 
6
- const StyledCard = styled.div<{ theme: Theme }>\`
8
+ const cardStyles = css<{ theme: Theme }>\`
7
9
  background: \${({ theme }) => theme.colors.light};
8
10
  border: solid 1px \${({ theme }) => theme.colors.grayLight};
9
11
  border-radius: \${({ theme }) => theme.spacing.radius.lg};
@@ -13,28 +15,45 @@ const StyledCard = styled.div<{ theme: Theme }>\`
13
15
  color: \${({ theme }) => theme.colors.grayDark};
14
16
  \`;
15
17
 
18
+ const StyledCard = styled.div<{ theme: Theme }>\`
19
+ \${cardStyles}
20
+ \`;
21
+
22
+ const StyledCardLink = styled(Link)<{ theme: Theme }>\`
23
+ \${interactiveStyles};
24
+ \${cardStyles}
25
+ text-decoration: none;
26
+ \`;
27
+
16
28
  const StyledCardTitle = styled.h3<{ theme: Theme }>\`
17
29
  margin: 5px 0;
18
30
  color: \${({ theme }) => theme.colors.dark};
19
31
  \${({ theme }) => styledText(theme)};
20
32
  \`;
21
33
 
22
- export interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
34
+ interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
23
35
  children: React.ReactNode;
24
36
  title: string;
25
37
  icon?: IconProps;
38
+ href?: string;
26
39
  }
27
40
 
28
- function Card({ children, title, icon }: CardProps) {
41
+ function Card({ children, title, icon, href }: CardProps) {
29
42
  const theme = useTheme() as Theme;
30
43
 
31
- return (
32
- <StyledCard>
44
+ const content = (
45
+ <>
33
46
  {icon && <Icon name={icon} color={theme.colors.primary} />}
34
47
  <StyledCardTitle>{title}</StyledCardTitle>
35
48
  {children}
36
- </StyledCard>
49
+ </>
37
50
  );
51
+
52
+ if (href) {
53
+ return <StyledCardLink href={href}>{content}</StyledCardLink>;
54
+ }
55
+
56
+ return <StyledCard>{content}</StyledCard>;
38
57
  }
39
58
 
40
59
  export { Card };
@@ -1 +1 @@
1
- export declare const columnsTemplate = "\"use client\";\nimport styled from \"styled-components\";\nimport { mq, Theme } from \"cherry-styled-components\";\n\nconst StyledColumns = styled.div<{ theme: Theme; $columns?: number }>`\n display: flex;\n flex-direction: column;\n gap: 20px;\n\n ${mq(\"lg\")} {\n display: grid;\n grid-template-columns: repeat(${({ $columns }) => $columns ?? 1}, 1fr);\n }\n`;\n\nexport interface ColumnsProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n cols?: number;\n}\n\nfunction Columns({ children, cols }: ColumnsProps) {\n return <StyledColumns $columns={cols}>{children}</StyledColumns>;\n}\n\nexport { Columns };\n";
1
+ export declare const columnsTemplate = "\"use client\";\nimport styled from \"styled-components\";\nimport { mq, Theme } from \"cherry-styled-components\";\n\nconst StyledColumns = styled.div<{ theme: Theme; $columns?: number }>`\n display: flex;\n flex-direction: column;\n gap: 20px;\n\n ${mq(\"lg\")} {\n display: grid;\n grid-template-columns: repeat(${({ $columns }) => $columns ?? 1}, 1fr);\n }\n`;\n\ninterface ColumnsProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n cols?: number;\n}\n\nfunction Columns({ children, cols }: ColumnsProps) {\n return <StyledColumns $columns={cols}>{children}</StyledColumns>;\n}\n\nexport { Columns };\n";
@@ -13,7 +13,7 @@ const StyledColumns = styled.div<{ theme: Theme; $columns?: number }>\`
13
13
  }
14
14
  \`;
15
15
 
16
- export interface ColumnsProps extends React.HTMLAttributes<HTMLDivElement> {
16
+ interface ColumnsProps extends React.HTMLAttributes<HTMLDivElement> {
17
17
  children: React.ReactNode;
18
18
  cols?: number;
19
19
  }
@@ -1 +1 @@
1
- export declare const docsComponentsTemplate = "\"use client\";\nimport { darken, lighten, rgba } from \"polished\";\nimport React, { createContext, useContext } from \"react\";\nimport styled, { css } from \"styled-components\";\nimport {\n resetButton,\n styledSmall,\n styledStrong,\n styledText,\n} from \"cherry-styled-components\";\nimport Link from \"next/link\";\nimport { mq, Theme } from \"@/app/theme\";\nimport {\n styledAnchor,\n styledTable,\n stylesLists,\n} from \"@/components/layout/SharedStyled\";\nimport { ChatContext } from \"@/components/Chat\";\n\nconst SectionBarContext = createContext(false);\n\nfunction SectionBarProvider({\n hasSectionBar,\n children,\n}: {\n hasSectionBar: boolean;\n children: React.ReactNode;\n}) {\n return (\n <SectionBarContext.Provider value={hasSectionBar}>\n {children}\n </SectionBarContext.Provider>\n );\n}\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; $isChatOpen?: boolean }>`\n position: relative;\n padding: 20px 20px 100px 20px;\n width: 100%;\n ${({ theme }) => styledText(theme)};\n transition: all 0.3s ease;\n\n ${mq(\"lg\")} {\n padding: 20px 340px 80px 340px;\n\n ${({ $isChatOpen }) =>\n $isChatOpen &&\n css`\n padding: 20px 440px 80px 340px;\n `}\n }\n\n & p {\n color: ${({ theme }) => theme.colors.grayDark};\n }\n\n & pre {\n max-width: 100%;\n }\n\n ${styledAnchor};\n ${stylesLists};\n ${styledTable};\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 white-space: pre;\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 $hasSectionBar?: boolean;\n}\n\nexport const StyledSidebar = styled.nav<Props>`\n position: fixed;\n overflow-y: auto;\n max-height: calc(\n 100svh - ${({ $hasSectionBar }) => ($hasSectionBar ? 105 : 63)}px\n );\n width: 100%;\n z-index: 99;\n top: ${({ $hasSectionBar }) => ($hasSectionBar ? 105 : 63)}px;\n height: 100%;\n padding: 20px 20px 80px 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 border-right: solid 1px ${({ theme }) => theme.colors.grayLight};\n -webkit-overflow-scrolling: touch;\n\n &::-webkit-scrollbar {\n display: none;\n }\n\n ${mq(\"lg\")} {\n transition: none;\n max-height: calc(100svh - 62px);\n width: 220px;\n background: transparent;\n padding: 25px 40px 40px;\n opacity: 1;\n pointer-events: all;\n transform: translateY(0);\n background: ${({ theme }) => rgba(theme.colors.primaryLight, 0.05)};\n top: 62px;\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: 61px;\n right: 0;\n width: 320px;\n height: calc(100vh - 61px);\n overflow-y: auto;\n z-index: 1;\n padding: 27px 40px 40px;\n background: ${({ theme }) => theme.colors.light};\n border-left: solid 1px ${({ theme }) => theme.colors.grayLight};\n -webkit-overflow-scrolling: touch;\n\n &::-webkit-scrollbar {\n display: none;\n }\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.primary};\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 &:hover {\n color: ${({ theme }) =>\n theme.isDark ? theme.colors.primaryLight : theme.colors.primaryDark};\n border-color: ${({ theme }) => theme.colors.primary};\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: 999;\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\ninterface DocsWrapperProps {\n children: React.ReactNode;\n}\n\nfunction DocsWrapper({ children }: DocsWrapperProps) {\n return <StyledDocsWrapper>{children}</StyledDocsWrapper>;\n}\n\nfunction DocsSidebar({ children }: DocsProps) {\n return <StyledDocsSidebar>{children}</StyledDocsSidebar>;\n}\n\nfunction DocsContainer({ children }: DocsProps) {\n const { isOpen } = useContext(ChatContext);\n\n return (\n <StyledDocsContainer $isChatOpen={isOpen}>{children}</StyledDocsContainer>\n );\n}\n\nexport {\n DocsWrapper,\n DocsSidebar,\n DocsContainer,\n SectionBarContext,\n SectionBarProvider,\n};\n";
1
+ export declare const docsComponentsTemplate = "\"use client\";\nimport { darken, lighten, rgba } from \"polished\";\nimport React, { createContext, useContext } from \"react\";\nimport styled, { css } from \"styled-components\";\nimport {\n resetButton,\n styledSmall,\n styledStrong,\n styledText,\n} from \"cherry-styled-components\";\nimport Link from \"next/link\";\nimport { mq, Theme } from \"@/app/theme\";\nimport {\n styledAnchor,\n styledTable,\n stylesLists,\n} from \"@/components/layout/SharedStyled\";\nimport { ChatContext } from \"@/components/Chat\";\n\nconst SectionBarContext = createContext(false);\n\nfunction SectionBarProvider({\n hasSectionBar,\n children,\n}: {\n hasSectionBar: boolean;\n children: React.ReactNode;\n}) {\n return (\n <SectionBarContext.Provider value={hasSectionBar}>\n {children}\n </SectionBarContext.Provider>\n );\n}\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; $isChatOpen?: boolean }>`\n position: relative;\n padding: 0 20px 100px 20px;\n width: 100%;\n ${({ theme }) => styledText(theme)};\n transition: all 0.3s ease;\n\n ${mq(\"lg\")} {\n padding: 0 300px 80px 300px;\n\n ${({ $isChatOpen }) =>\n $isChatOpen &&\n css`\n padding: 0 440px 80px 300px;\n `}\n }\n\n & p {\n color: ${({ theme }) => theme.colors.grayDark};\n hyphens: auto;\n }\n\n & pre {\n max-width: 100%;\n }\n\n ${styledAnchor};\n ${stylesLists};\n ${styledTable};\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 white-space: pre;\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 $hasSectionBar?: boolean;\n}\n\nexport const StyledSidebar = styled.nav<Props>`\n position: fixed;\n overflow-y: auto;\n max-height: calc(\n 100svh - ${({ $hasSectionBar }) => ($hasSectionBar ? 105 : 63)}px\n );\n width: 100%;\n z-index: 99;\n top: ${({ $hasSectionBar }) => ($hasSectionBar ? 105 : 63)}px;\n height: 100%;\n padding: 20px 20px 80px 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 border-right: solid 1px ${({ theme }) => theme.colors.grayLight};\n -webkit-overflow-scrolling: touch;\n\n &::-webkit-scrollbar {\n display: none;\n }\n\n ${mq(\"lg\")} {\n transition: none;\n max-height: 100svh;\n width: 220px;\n background: transparent;\n padding: 82px 20px 20px 20px;\n opacity: 1;\n pointer-events: all;\n transform: translateY(0);\n background: ${({ theme }) => rgba(theme.colors.primaryLight, 0.05)};\n top: 0;\n width: 280px;\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: 280px;\n height: 100svh;\n overflow-y: auto;\n z-index: 1;\n padding: 82px 20px 20px 20px;\n background: ${({ theme }) => theme.colors.light};\n border-left: solid 1px ${({ theme }) => theme.colors.grayLight};\n -webkit-overflow-scrolling: touch;\n\n &::-webkit-scrollbar {\n display: none;\n }\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 StyledIndexSidebarLi = styled.li<{\n theme: Theme;\n $isActive: boolean;\n}>`\n &::before {\n content: \"\";\n display: block;\n position: absolute;\n left: 0;\n height: 20px;\n width: 1px;\n background: transparent;\n transition: all 0.3s ease;\n }\n\n ${({ $isActive, theme }) =>\n $isActive &&\n css`\n &::before {\n background: ${theme.colors.primary};\n }\n `}\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.primary};\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 &:hover {\n color: ${({ theme }) =>\n theme.isDark ? theme.colors.primaryLight : theme.colors.primaryDark};\n border-color: ${({ theme }) => theme.colors.primary};\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: 999;\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\ninterface DocsWrapperProps {\n children: React.ReactNode;\n}\n\nfunction DocsWrapper({ children }: DocsWrapperProps) {\n return <StyledDocsWrapper>{children}</StyledDocsWrapper>;\n}\n\nfunction DocsSidebar({ children }: DocsProps) {\n return <StyledDocsSidebar>{children}</StyledDocsSidebar>;\n}\n\nfunction DocsContainer({ children }: DocsProps) {\n const { isOpen } = useContext(ChatContext);\n\n return (\n <StyledDocsContainer $isChatOpen={isOpen}>{children}</StyledDocsContainer>\n );\n}\n\nexport {\n DocsWrapper,\n DocsSidebar,\n DocsContainer,\n SectionBarContext,\n SectionBarProvider,\n};\n";
@@ -1,3 +1,4 @@
1
+ import { SIDEBAR_WIDTH, CHAT_WIDTH } from "../../app/theme.js";
1
2
  export const docsComponentsTemplate = `"use client";
2
3
  import { darken, lighten, rgba } from "polished";
3
4
  import React, { createContext, useContext } from "react";
@@ -47,23 +48,24 @@ const StyledDocsSidebar = styled.div<{ theme: Theme }>\`
47
48
 
48
49
  const StyledDocsContainer = styled.div<{ theme: Theme; $isChatOpen?: boolean }>\`
49
50
  position: relative;
50
- padding: 20px 20px 100px 20px;
51
+ padding: 0 20px 100px 20px;
51
52
  width: 100%;
52
53
  \${({ theme }) => styledText(theme)};
53
54
  transition: all 0.3s ease;
54
55
 
55
56
  \${mq("lg")} {
56
- padding: 20px 340px 80px 340px;
57
+ padding: 0 ${SIDEBAR_WIDTH + 20}px 80px ${SIDEBAR_WIDTH + 20}px;
57
58
 
58
59
  \${({ $isChatOpen }) =>
59
60
  $isChatOpen &&
60
61
  css\`
61
- padding: 20px 440px 80px 340px;
62
+ padding: 0 ${CHAT_WIDTH + 20}px 80px ${SIDEBAR_WIDTH + 20}px;
62
63
  \`}
63
64
  }
64
65
 
65
66
  & p {
66
67
  color: \${({ theme }) => theme.colors.grayDark};
68
+ hyphens: auto;
67
69
  }
68
70
 
69
71
  & pre {
@@ -141,16 +143,16 @@ export const StyledSidebar = styled.nav<Props>\`
141
143
 
142
144
  \${mq("lg")} {
143
145
  transition: none;
144
- max-height: calc(100svh - 62px);
146
+ max-height: 100svh;
145
147
  width: 220px;
146
148
  background: transparent;
147
- padding: 25px 40px 40px;
149
+ padding: 82px 20px 20px 20px;
148
150
  opacity: 1;
149
151
  pointer-events: all;
150
152
  transform: translateY(0);
151
153
  background: \${({ theme }) => rgba(theme.colors.primaryLight, 0.05)};
152
- top: 62px;
153
- width: 320px;
154
+ top: 0;
155
+ width: ${SIDEBAR_WIDTH}px;
154
156
  }
155
157
 
156
158
  \${({ $isActive }) =>
@@ -168,13 +170,13 @@ export const StyledIndexSidebar = styled.ul<{ theme: Theme }>\`
168
170
  margin: 0;
169
171
  padding: 0;
170
172
  position: fixed;
171
- top: 61px;
173
+ top: 0;
172
174
  right: 0;
173
- width: 320px;
174
- height: calc(100vh - 61px);
175
+ width: 280px;
176
+ height: 100svh;
175
177
  overflow-y: auto;
176
178
  z-index: 1;
177
- padding: 27px 40px 40px;
179
+ padding: 82px 20px 20px 20px;
178
180
  background: \${({ theme }) => theme.colors.light};
179
181
  border-left: solid 1px \${({ theme }) => theme.colors.grayLight};
180
182
  -webkit-overflow-scrolling: touch;
@@ -197,6 +199,30 @@ export const StyledIndexSidebarLabel = styled.span<{ theme: Theme }>\`
197
199
  color: \${({ theme }) => theme.colors.grayDark};
198
200
  \`;
199
201
 
202
+ export const StyledIndexSidebarLi = styled.li<{
203
+ theme: Theme;
204
+ $isActive: boolean;
205
+ }>\`
206
+ &::before {
207
+ content: "";
208
+ display: block;
209
+ position: absolute;
210
+ left: 0;
211
+ height: 20px;
212
+ width: 1px;
213
+ background: transparent;
214
+ transition: all 0.3s ease;
215
+ }
216
+
217
+ \${({ $isActive, theme }) =>
218
+ $isActive &&
219
+ css\`
220
+ &::before {
221
+ background: \${theme.colors.primary};
222
+ }
223
+ \`}
224
+ \`;
225
+
200
226
  export const StyledIndexSidebarLink = styled.a<{
201
227
  theme: Theme;
202
228
  $isActive: boolean;
@@ -1 +1 @@
1
- export declare const docsNavigationTemplate = "\"use client\";\nimport { useContext } from \"react\";\nimport { usePathname } from \"next/navigation\";\nimport Link from \"next/link\";\nimport styled, { css } from \"styled-components\";\nimport { Icon } from \"@/components/layout/Icon\";\nimport { mq, Theme } from \"@/app/theme\";\nimport { interactiveStyles } from \"@/components/layout/SharedStyled\";\nimport { ChatContext } from \"@/components/Chat\";\n\nconst StyledNavigationWrapper = styled.div<{\n $isChatOpen?: boolean;\n}>`\n transition: all 0.3s ease;\n padding: 0 20px 100px 20px;\n ${mq(\"lg\")} {\n padding: 0 340px 80px 340px;\n ${({ $isChatOpen }) =>\n $isChatOpen &&\n css`\n padding: 0 440px 80px 340px;\n `}\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 max-width: 100%;\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]: unknown;\n}\n\ninterface NavigationItem {\n category?: string;\n slug?: string;\n title?: string;\n links?: Page[];\n items?: Page[];\n [key: string]: unknown;\n}\n\ninterface DocsNavigationProps {\n result: NavigationItem[];\n}\n\nfunction DocsNavigation({ result }: DocsNavigationProps) {\n const { isOpen } = useContext(ChatContext);\n const pathname = usePathname();\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 const currentSlug = pathname.replace(/^\\//, \"\").replace(/\\/$/, \"\");\n const currentIndex = allPages.findIndex((page) => page.slug === currentSlug);\n const prevPage = currentIndex > 0 ? allPages[currentIndex - 1] : null;\n const nextPage =\n currentIndex < allPages.length - 1 ? allPages[currentIndex + 1] : null;\n if (currentIndex === -1 || allPages.length === 0) {\n return null;\n }\n if (!prevPage && !nextPage) {\n return null;\n }\n return (\n <StyledNavigationWrapper $isChatOpen={isOpen}>\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 {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 };\n";
1
+ export declare const docsNavigationTemplate = "\"use client\";\nimport { useContext } from \"react\";\nimport { usePathname } from \"next/navigation\";\nimport Link from \"next/link\";\nimport styled, { css } from \"styled-components\";\nimport { Icon } from \"@/components/layout/Icon\";\nimport { mq, Theme } from \"@/app/theme\";\nimport { interactiveStyles } from \"@/components/layout/SharedStyled\";\nimport { ChatContext } from \"@/components/Chat\";\n\nconst StyledNavigationWrapper = styled.div<{\n $isChatOpen?: boolean;\n}>`\n transition: all 0.3s ease;\n padding: 0 20px 100px 20px;\n ${mq(\"lg\")} {\n padding: 0 300px 80px 300px;\n ${({ $isChatOpen }) =>\n $isChatOpen &&\n css`\n padding: 0 440px 80px 300px;\n `}\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 max-width: 100%;\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]: unknown;\n}\n\ninterface NavigationItem {\n category?: string;\n slug?: string;\n title?: string;\n links?: Page[];\n items?: Page[];\n [key: string]: unknown;\n}\n\ninterface DocsNavigationProps {\n result: NavigationItem[];\n}\n\nfunction DocsNavigation({ result }: DocsNavigationProps) {\n const { isOpen } = useContext(ChatContext);\n const pathname = usePathname();\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 const currentSlug = pathname.replace(/^\\//, \"\").replace(/\\/$/, \"\");\n const currentIndex = allPages.findIndex((page) => page.slug === currentSlug);\n const prevPage = currentIndex > 0 ? allPages[currentIndex - 1] : null;\n const nextPage =\n currentIndex < allPages.length - 1 ? allPages[currentIndex + 1] : null;\n if (currentIndex === -1 || allPages.length === 0) {\n return null;\n }\n if (!prevPage && !nextPage) {\n return null;\n }\n return (\n <StyledNavigationWrapper $isChatOpen={isOpen}>\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 {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 };\n";
@@ -1,3 +1,4 @@
1
+ import { SIDEBAR_WIDTH, CHAT_WIDTH } from "../../app/theme.js";
1
2
  export const docsNavigationTemplate = `"use client";
2
3
  import { useContext } from "react";
3
4
  import { usePathname } from "next/navigation";
@@ -14,11 +15,11 @@ const StyledNavigationWrapper = styled.div<{
14
15
  transition: all 0.3s ease;
15
16
  padding: 0 20px 100px 20px;
16
17
  \${mq("lg")} {
17
- padding: 0 340px 80px 340px;
18
+ padding: 0 ${SIDEBAR_WIDTH + 20}px 80px ${SIDEBAR_WIDTH + 20}px;
18
19
  \${({ $isChatOpen }) =>
19
20
  $isChatOpen &&
20
21
  css\`
21
- padding: 0 440px 80px 340px;
22
+ padding: 0 ${CHAT_WIDTH + 20}px 80px ${SIDEBAR_WIDTH + 20}px;
22
23
  \`}
23
24
  }
24
25
  \`;
@@ -1 +1 @@
1
- export declare const fieldTemplate = "\"use client\";\nimport styled from \"styled-components\";\nimport { styledSmall, Theme } from \"cherry-styled-components\";\nimport { rgba } from \"polished\";\n\nconst StyledField = styled.div<{ theme: Theme; $columns?: number }>`\n border-bottom: solid 1px ${({ theme }) => theme.colors.grayLight};\n padding: 0 0 20px 0;\n`;\n\nconst StyledFieldFlex = styled.div<{ theme: Theme }>`\n display: flex;\n flex-wrap: wrap;\n gap: 10px;\n ${({ theme }) => styledSmall(theme)};\n padding: 0 0 15px 0;\n`;\n\nconst StyledFieldValue = styled.span<{ theme: Theme }>`\n color: ${({ theme }) => theme.colors.primary};\n font-family: ${({ theme }) => theme.fonts.mono};\n font-weight: 600;\n`;\n\nconst StyledFieldType = styled.span<{ theme: Theme }>`\n background: ${({ theme }) => rgba(theme.colors.primaryLight, 0.2)};\n color: ${({ theme }) => theme.colors.dark};\n padding: 0 4px;\n font-family: ${({ theme }) => theme.fonts.mono};\n border-radius: ${({ theme }) => theme.spacing.radius.xs};\n`;\n\nconst StyledFieldRequired = styled.span<{ theme: Theme }>`\n background: ${({ theme }) => rgba(theme.colors.error, 0.2)};\n color: ${({ theme }) => theme.colors.error};\n padding: 0 4px;\n font-family: ${({ theme }) => theme.fonts.mono};\n border-radius: ${({ theme }) => theme.spacing.radius.xs};\n`;\n\nexport interface FieldProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n value: string;\n type: string;\n required?: boolean;\n}\n\nfunction Field({ children, value, type, required }: FieldProps) {\n return (\n <StyledField>\n <StyledFieldFlex>\n <StyledFieldValue>{value}</StyledFieldValue>\n <StyledFieldType>{type}</StyledFieldType>\n {required && <StyledFieldRequired>required</StyledFieldRequired>}\n </StyledFieldFlex>\n {children}\n </StyledField>\n );\n}\n\nexport { Field };\n";
1
+ export declare const fieldTemplate = "\"use client\";\nimport styled from \"styled-components\";\nimport { styledSmall, Theme } from \"cherry-styled-components\";\nimport { rgba } from \"polished\";\n\nconst StyledField = styled.div<{ theme: Theme; $columns?: number }>`\n border-bottom: solid 1px ${({ theme }) => theme.colors.grayLight};\n padding: 0 0 20px 0;\n`;\n\nconst StyledFieldFlex = styled.div<{ theme: Theme }>`\n display: flex;\n flex-wrap: wrap;\n gap: 10px;\n ${({ theme }) => styledSmall(theme)};\n padding: 0 0 15px 0;\n`;\n\nconst StyledFieldValue = styled.span<{ theme: Theme }>`\n color: ${({ theme }) => theme.colors.primary};\n font-family: ${({ theme }) => theme.fonts.mono};\n font-weight: 600;\n`;\n\nconst StyledFieldType = styled.span<{ theme: Theme }>`\n background: ${({ theme }) => rgba(theme.colors.primaryLight, 0.2)};\n color: ${({ theme }) => theme.colors.dark};\n padding: 0 4px;\n font-family: ${({ theme }) => theme.fonts.mono};\n border-radius: ${({ theme }) => theme.spacing.radius.xs};\n`;\n\nconst StyledFieldRequired = styled.span<{ theme: Theme }>`\n background: ${({ theme }) => rgba(theme.colors.error, 0.2)};\n color: ${({ theme }) => theme.colors.error};\n padding: 0 4px;\n font-family: ${({ theme }) => theme.fonts.mono};\n border-radius: ${({ theme }) => theme.spacing.radius.xs};\n`;\n\ninterface FieldProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n value: string;\n type: string;\n required?: boolean;\n}\n\nfunction Field({ children, value, type, required }: FieldProps) {\n return (\n <StyledField>\n <StyledFieldFlex>\n <StyledFieldValue>{value}</StyledFieldValue>\n <StyledFieldType>{type}</StyledFieldType>\n {required && <StyledFieldRequired>required</StyledFieldRequired>}\n </StyledFieldFlex>\n {children}\n </StyledField>\n );\n}\n\nexport { Field };\n";
@@ -38,7 +38,7 @@ const StyledFieldRequired = styled.span<{ theme: Theme }>\`
38
38
  border-radius: \${({ theme }) => theme.spacing.radius.xs};
39
39
  \`;
40
40
 
41
- export interface FieldProps extends React.HTMLAttributes<HTMLDivElement> {
41
+ interface FieldProps extends React.HTMLAttributes<HTMLDivElement> {
42
42
  children: React.ReactNode;
43
43
  value: string;
44
44
  type: string;
@@ -1 +1 @@
1
- export declare const footerTemplate = "\"use client\";\nimport { useContext } from \"react\";\nimport styled, { css } from \"styled-components\";\nimport { Space, styledSmall } from \"cherry-styled-components\";\nimport { ChatContext } from \"@/components/Chat\";\nimport { mq, Theme } from \"@/app/theme\";\nimport { GitHubLogo } from \"@/components/layout/Pictograms\";\n\nconst StyledFooter = styled.footer<{ theme: Theme; $isChatOpen?: boolean }>`\n padding: 20px;\n transition: all 0.3s ease;\n\n ${mq(\"lg\")} {\n padding: 0 340px 0 340px;\n ${({ $isChatOpen }) =>\n $isChatOpen &&\n css`\n padding: 0 440px 0 340px;\n `}\n }\n`;\n\nconst StyledFooterInner = styled.div<{ theme: Theme }>`\n border-top: solid 1px ${({ theme }) => theme.colors.grayLight};\n max-width: 640px;\n margin: 0 auto;\n padding: 33px 0 90px 0;\n color: ${({ theme }) => theme.colors.gray};\n ${({ theme }) => styledSmall(theme)};\n\n ${mq(\"lg\")} {\n padding: 32px 0;\n }\n\n & a {\n font-weight: 700;\n color: ${({ theme }) => theme.colors.primary};\n text-decoration: none;\n transition: all 0.3s ease;\n\n &:hover {\n color: ${({ theme }) => theme.colors.primaryDark};\n }\n\n & svg {\n width: 18px;\n height: 18px;\n }\n }\n`;\n\nconst StyledFooterFlex = styled.div`\n display: flex;\n justify-content: space-between;\n align-items: center;\n`;\n\nfunction Footer({ hideBranding }: { hideBranding?: boolean }) {\n const { isOpen } = useContext(ChatContext);\n\n if (hideBranding) return <Space $xs={70} $lg=\"none\" />;\n\n return (\n <StyledFooter $isChatOpen={isOpen}>\n <StyledFooterInner>\n <StyledFooterFlex>\n <span>\n Powered by <a href=\"https://doccupine.com\">Doccupine</a>\n </span>\n <a href=\"https://github.com/doccupine/cli\" target=\"_blank\">\n <GitHubLogo />\n </a>\n </StyledFooterFlex>\n </StyledFooterInner>\n </StyledFooter>\n );\n}\n\nexport { Footer };\n";
1
+ export declare const footerTemplate = "\"use client\";\nimport { useContext } from \"react\";\nimport styled, { css } from \"styled-components\";\nimport { Space, styledSmall } from \"cherry-styled-components\";\nimport { ChatContext } from \"@/components/Chat\";\nimport { mq, Theme } from \"@/app/theme\";\nimport { GitHubLogo } from \"@/components/layout/Pictograms\";\nimport linksData from \"@/links.json\";\n\ninterface LinkProps {\n title: string;\n url: string;\n icon?: string;\n}\n\nconst links = linksData as LinkProps[];\n\nconst StyledFooter = styled.footer<{\n theme: Theme;\n $isChatOpen?: boolean;\n $hasLinks?: boolean;\n}>`\n padding: 0 20px 20px 20px;\n transition: all 0.3s ease;\n\n ${({ $hasLinks }) =>\n $hasLinks &&\n css`\n margin-top: 20px;\n `}\n\n ${mq(\"lg\")} {\n margin: 0;\n padding: 0 300px 0 300px;\n\n ${({ $isChatOpen }) =>\n $isChatOpen &&\n css`\n padding: 0 440px 0 300px;\n `}\n }\n`;\n\nconst StyledFooterInner = styled.div<{ theme: Theme }>`\n border-top: solid 1px ${({ theme }) => theme.colors.grayLight};\n max-width: 640px;\n margin: 0 auto;\n padding: 33px 0 90px 0;\n color: ${({ theme }) => theme.colors.gray};\n ${({ theme }) => styledSmall(theme)};\n\n ${mq(\"lg\")} {\n padding: 32px 0;\n }\n\n & a {\n font-weight: 700;\n color: ${({ theme }) => theme.colors.primary};\n text-decoration: none;\n transition: all 0.3s ease;\n\n &:hover {\n color: ${({ theme }) => theme.colors.primaryDark};\n }\n\n & svg {\n width: 18px;\n height: 18px;\n }\n }\n`;\n\nconst StyledFooterFlex = styled.div`\n display: flex;\n justify-content: space-between;\n align-items: center;\n`;\n\nfunction Footer({ hideBranding }: { hideBranding?: boolean }) {\n const { isOpen } = useContext(ChatContext);\n\n if (hideBranding) return <Space $xs={80} $lg=\"none\" />;\n\n return (\n <StyledFooter $isChatOpen={isOpen} $hasLinks={links.length > 0}>\n <StyledFooterInner>\n <StyledFooterFlex>\n <span>\n Powered by <a href=\"https://doccupine.com\">Doccupine</a>\n </span>\n <a href=\"https://github.com/doccupine/cli\" target=\"_blank\">\n <GitHubLogo />\n </a>\n </StyledFooterFlex>\n </StyledFooterInner>\n </StyledFooter>\n );\n}\n\nexport { Footer };\n";