doccupine 0.0.88 → 0.0.90
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -2
- package/dist/index.js +206 -5
- package/dist/lib/layout.js +38 -24
- package/dist/lib/metadata.d.ts +30 -0
- package/dist/lib/metadata.js +98 -1
- package/dist/templates/app/theme.d.ts +1 -1
- package/dist/templates/app/theme.js +84 -19
- package/dist/templates/components/Chat.d.ts +1 -1
- package/dist/templates/components/Chat.js +26 -27
- package/dist/templates/components/SearchModalContent.d.ts +1 -1
- package/dist/templates/components/SearchModalContent.js +12 -6
- package/dist/templates/components/SideBar.d.ts +1 -1
- package/dist/templates/components/SideBar.js +3 -1
- package/dist/templates/components/layout/Accordion.d.ts +1 -1
- package/dist/templates/components/layout/Accordion.js +2 -1
- package/dist/templates/components/layout/ActionBar.d.ts +1 -1
- package/dist/templates/components/layout/ActionBar.js +4 -6
- package/dist/templates/components/layout/Button.d.ts +1 -1
- package/dist/templates/components/layout/Button.js +19 -0
- package/dist/templates/components/layout/Callout.d.ts +1 -1
- package/dist/templates/components/layout/Callout.js +75 -20
- package/dist/templates/components/layout/Card.d.ts +1 -1
- package/dist/templates/components/layout/Card.js +2 -1
- package/dist/templates/components/layout/CherryThemeProvider.d.ts +1 -1
- package/dist/templates/components/layout/CherryThemeProvider.js +6 -12
- package/dist/templates/components/layout/ClientThemeProvider.d.ts +1 -1
- package/dist/templates/components/layout/ClientThemeProvider.js +45 -40
- package/dist/templates/components/layout/Code.d.ts +1 -1
- package/dist/templates/components/layout/Code.js +223 -255
- package/dist/templates/components/layout/ColorSwatch.d.ts +1 -1
- package/dist/templates/components/layout/ColorSwatch.js +2 -2
- package/dist/templates/components/layout/Columns.d.ts +1 -1
- package/dist/templates/components/layout/Columns.js +1 -1
- package/dist/templates/components/layout/DemoTheme.d.ts +1 -1
- package/dist/templates/components/layout/DemoTheme.js +65 -167
- package/dist/templates/components/layout/DocsComponents.d.ts +1 -1
- package/dist/templates/components/layout/DocsComponents.js +13 -19
- package/dist/templates/components/layout/Field.d.ts +1 -1
- package/dist/templates/components/layout/Field.js +6 -4
- package/dist/templates/components/layout/Footer.d.ts +1 -1
- package/dist/templates/components/layout/Footer.js +2 -3
- package/dist/templates/components/layout/GlobalStyles.d.ts +1 -1
- package/dist/templates/components/layout/GlobalStyles.js +63 -10
- package/dist/templates/components/layout/Header.d.ts +1 -1
- package/dist/templates/components/layout/Header.js +14 -11
- package/dist/templates/components/layout/SharedStyles.d.ts +1 -1
- package/dist/templates/components/layout/SharedStyles.js +4 -5
- package/dist/templates/components/layout/StaticLinks.d.ts +1 -1
- package/dist/templates/components/layout/StaticLinks.js +4 -6
- package/dist/templates/components/layout/Steps.d.ts +1 -1
- package/dist/templates/components/layout/Steps.js +3 -3
- package/dist/templates/components/layout/Tabs.d.ts +1 -1
- package/dist/templates/components/layout/Tabs.js +5 -2
- package/dist/templates/components/layout/ThemeToggle.d.ts +1 -1
- package/dist/templates/components/layout/ThemeToggle.js +17 -19
- package/dist/templates/components/layout/Typography.d.ts +1 -1
- package/dist/templates/components/layout/Typography.js +1 -1
- package/dist/templates/components/layout/Update.d.ts +1 -1
- package/dist/templates/components/layout/Update.js +4 -3
- package/dist/templates/llms/llmsFull.d.ts +12 -0
- package/dist/templates/llms/llmsFull.js +59 -0
- package/dist/templates/llms/llmsIndex.d.ts +9 -0
- package/dist/templates/llms/llmsIndex.js +105 -0
- package/dist/templates/llms/llmsPage.d.ts +2 -0
- package/dist/templates/llms/llmsPage.js +20 -0
- package/dist/templates/mdx/accordion.mdx.d.ts +1 -1
- package/dist/templates/mdx/accordion.mdx.js +21 -16
- package/dist/templates/mdx/ai-assistant.mdx.d.ts +1 -1
- package/dist/templates/mdx/ai-assistant.mdx.js +22 -5
- package/dist/templates/mdx/analytics.mdx.d.ts +1 -1
- package/dist/templates/mdx/analytics.mdx.js +15 -4
- package/dist/templates/mdx/buttons.mdx.d.ts +1 -1
- package/dist/templates/mdx/buttons.mdx.js +10 -2
- package/dist/templates/mdx/callouts.mdx.d.ts +1 -1
- package/dist/templates/mdx/callouts.mdx.js +10 -17
- package/dist/templates/mdx/cards.mdx.d.ts +1 -1
- package/dist/templates/mdx/cards.mdx.js +10 -5
- package/dist/templates/mdx/code.mdx.d.ts +1 -1
- package/dist/templates/mdx/code.mdx.js +7 -3
- package/dist/templates/mdx/color-swatches.mdx.d.ts +1 -1
- package/dist/templates/mdx/color-swatches.mdx.js +7 -4
- package/dist/templates/mdx/columns.mdx.d.ts +1 -1
- package/dist/templates/mdx/columns.mdx.js +3 -0
- package/dist/templates/mdx/commands.mdx.d.ts +1 -1
- package/dist/templates/mdx/commands.mdx.js +7 -4
- package/dist/templates/mdx/components.mdx.d.ts +1 -1
- package/dist/templates/mdx/components.mdx.js +1 -0
- package/dist/templates/mdx/deployment-and-hosting.mdx.d.ts +1 -1
- package/dist/templates/mdx/deployment-and-hosting.mdx.js +6 -0
- package/dist/templates/mdx/fields.mdx.d.ts +1 -1
- package/dist/templates/mdx/fields.mdx.js +3 -0
- package/dist/templates/mdx/fonts.mdx.d.ts +1 -1
- package/dist/templates/mdx/fonts.mdx.js +13 -2
- package/dist/templates/mdx/footer-links.mdx.d.ts +1 -1
- package/dist/templates/mdx/footer-links.mdx.js +5 -0
- package/dist/templates/mdx/globals.mdx.d.ts +1 -1
- package/dist/templates/mdx/globals.mdx.js +16 -13
- package/dist/templates/mdx/headers-and-text.mdx.d.ts +1 -1
- package/dist/templates/mdx/headers-and-text.mdx.js +22 -2
- package/dist/templates/mdx/icons.mdx.d.ts +1 -1
- package/dist/templates/mdx/icons.mdx.js +3 -0
- package/dist/templates/mdx/image-and-embeds.mdx.d.ts +1 -1
- package/dist/templates/mdx/image-and-embeds.mdx.js +19 -10
- package/dist/templates/mdx/index.mdx.d.ts +1 -1
- package/dist/templates/mdx/index.mdx.js +2 -2
- package/dist/templates/mdx/lists-and-tables.mdx.d.ts +1 -1
- package/dist/templates/mdx/lists-and-tables.mdx.js +8 -2
- package/dist/templates/mdx/media-and-assets.mdx.d.ts +1 -1
- package/dist/templates/mdx/media-and-assets.mdx.js +14 -5
- package/dist/templates/mdx/model-context-protocol.mdx.d.ts +1 -1
- package/dist/templates/mdx/model-context-protocol.mdx.js +31 -15
- package/dist/templates/mdx/navigation.mdx.d.ts +1 -1
- package/dist/templates/mdx/navigation.mdx.js +9 -0
- package/dist/templates/mdx/platform/ai-assistant.mdx.d.ts +1 -1
- package/dist/templates/mdx/platform/ai-assistant.mdx.js +7 -0
- package/dist/templates/mdx/platform/analytics.mdx.d.ts +1 -1
- package/dist/templates/mdx/platform/analytics.mdx.js +7 -0
- package/dist/templates/mdx/platform/billing.mdx.d.ts +1 -1
- package/dist/templates/mdx/platform/billing.mdx.js +8 -0
- package/dist/templates/mdx/platform/build-and-deploy.mdx.d.ts +1 -1
- package/dist/templates/mdx/platform/build-and-deploy.mdx.js +6 -0
- package/dist/templates/mdx/platform/creating-a-project.mdx.d.ts +1 -1
- package/dist/templates/mdx/platform/creating-a-project.mdx.js +7 -0
- package/dist/templates/mdx/platform/custom-domains.mdx.d.ts +1 -1
- package/dist/templates/mdx/platform/custom-domains.mdx.js +5 -0
- package/dist/templates/mdx/platform/external-links.mdx.d.ts +1 -1
- package/dist/templates/mdx/platform/external-links.mdx.js +5 -0
- package/dist/templates/mdx/platform/file-editor.mdx.d.ts +1 -1
- package/dist/templates/mdx/platform/file-editor.mdx.js +7 -0
- package/dist/templates/mdx/platform/fonts-settings.mdx.d.ts +1 -1
- package/dist/templates/mdx/platform/fonts-settings.mdx.js +5 -0
- package/dist/templates/mdx/platform/index.mdx.d.ts +1 -1
- package/dist/templates/mdx/platform/index.mdx.js +5 -0
- package/dist/templates/mdx/platform/navigation-settings.mdx.d.ts +1 -1
- package/dist/templates/mdx/platform/navigation-settings.mdx.js +20 -4
- package/dist/templates/mdx/platform/project-settings.mdx.d.ts +1 -1
- package/dist/templates/mdx/platform/project-settings.mdx.js +4 -0
- package/dist/templates/mdx/platform/publishing.mdx.d.ts +1 -1
- package/dist/templates/mdx/platform/publishing.mdx.js +6 -0
- package/dist/templates/mdx/platform/site-settings.mdx.d.ts +1 -1
- package/dist/templates/mdx/platform/site-settings.mdx.js +13 -1
- package/dist/templates/mdx/platform/team-members.mdx.d.ts +1 -1
- package/dist/templates/mdx/platform/team-members.mdx.js +8 -0
- package/dist/templates/mdx/platform/theme-settings.mdx.d.ts +1 -1
- package/dist/templates/mdx/platform/theme-settings.mdx.js +7 -0
- package/dist/templates/mdx/sections.mdx.d.ts +1 -1
- package/dist/templates/mdx/sections.mdx.js +22 -1
- package/dist/templates/mdx/steps.mdx.d.ts +1 -1
- package/dist/templates/mdx/steps.mdx.js +7 -5
- package/dist/templates/mdx/tabs.mdx.d.ts +1 -1
- package/dist/templates/mdx/tabs.mdx.js +7 -2
- package/dist/templates/mdx/theme.mdx.d.ts +1 -1
- package/dist/templates/mdx/theme.mdx.js +10 -0
- package/dist/templates/mdx/update.mdx.d.ts +1 -1
- package/dist/templates/mdx/update.mdx.js +17 -14
- package/dist/templates/package.js +14 -15
- package/dist/templates/pnpmWorkspace.d.ts +1 -0
- package/dist/templates/pnpmWorkspace.js +7 -0
- package/dist/templates/proxy.js +14 -20
- package/package.json +6 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const headerTemplate = "\"use client\";\nimport React from \"react\";\nimport { useCallback, useContext, useRef, useState } from \"react\";\nimport styled, { css
|
|
1
|
+
export declare const headerTemplate = "\"use client\";\nimport React from \"react\";\nimport { useCallback, useContext, useRef, useState } from \"react\";\nimport styled, { css } from \"styled-components\";\nimport Link from \"next/link\";\nimport { mq, Theme } from \"@/app/theme\";\nimport { useOnClickOutside } from \"@/components/ClickOutside\";\nimport { Search } from \"lucide-react\";\nimport { Logo } from \"@/components/layout/Pictograms\";\nimport { ChatContext, ChatButtonCTA } from \"@/components/Chat\";\nimport {\n SearchContext,\n SearchKbd,\n StyledSearchButton,\n} from \"@/components/SearchDocs\";\nimport themeJson from \"@/theme.json\";\n\nconst customThemeJson = themeJson as typeof themeJson & {\n logo?: { dark: string; light: string };\n};\n\nconst StyledHeader = styled.header<{ theme: Theme; $hasChildren: boolean }>`\n position: sticky;\n top: 0;\n margin: 0;\n z-index: 1000;\n width: 100%;\n border-bottom: solid 1px ${({ theme }) => theme.colors.grayLight};\n\n ${({ $hasChildren }) =>\n !$hasChildren &&\n css`\n ${mq(\"lg\")} {\n padding-bottom: 16px;\n padding-top: 16px;\n }\n `}\n\n &::before,\n &::after {\n display: block;\n content: \"\";\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n background: ${({ theme }) => theme.colors.light};\n z-index: -2;\n }\n\n &::after {\n background: ${({ theme }) =>\n `color-mix(in srgb, ${theme.colors.primaryLight} 5%, transparent)`};\n z-index: -1;\n }\n\n & .logo {\n display: flex;\n\n & svg,\n & img {\n margin: auto;\n height: auto;\n width: fit-content;\n min-width: fit-content;\n max-width: 182px;\n max-height: 30px;\n\n & path[fill] {\n fill: ${({ theme }) => theme.colors.primary};\n }\n }\n }\n`;\n\nconst StyledHeaderInner = styled.div<{ $hasChildren: boolean }>`\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-wrap: wrap;\n padding: 16px 0 0 20px;\n\n ${({ $hasChildren }) =>\n !$hasChildren &&\n css`\n padding-bottom: 16px;\n `}\n\n ${mq(\"lg\")} {\n flex-wrap: nowrap;\n padding: 0 20px;\n }\n`;\n\nconst StyledLeftWrapper = styled.div`\n display: flex;\n align-items: center;\n gap: 10px;\n min-width: fit-content;\n padding-right: 20px;\n\n ${mq(\"lg\")} {\n padding-right: 0;\n }\n`;\n\ninterface HeaderProps {\n children?: React.ReactNode;\n}\n\nfunction Header({ children }: HeaderProps) {\n const [isOptionActive, setIsOptionActive] = useState(false);\n const [isLangActive, setIsLangActive] = useState(false);\n\n const wrapperRef = useRef<HTMLSpanElement>(null);\n const elmRef = useRef<HTMLDivElement>(null);\n const langRef = useRef<HTMLSpanElement>(null);\n const closeMenu = useCallback(() => {\n setIsOptionActive(false);\n setIsLangActive(false);\n }, []);\n\n useOnClickOutside(\n [elmRef, wrapperRef],\n isOptionActive ? closeMenu : () => {},\n );\n useOnClickOutside([langRef, wrapperRef], isLangActive ? closeMenu : () => {});\n const { isChatActive } = useContext(ChatContext);\n const { openSearch } = useContext(SearchContext);\n\n return (\n <StyledHeader $hasChildren={children ? true : false} id=\"header\">\n <StyledHeaderInner $hasChildren={children ? true : false}>\n <Link href=\"/\" className=\"logo\" aria-label=\"Logo\">\n {customThemeJson.logo ? (\n <>\n {/* Both logos render; .light-only and .dark-only classes in\n GlobalStyles hide the inactive one based on the \"dark\" class\n on <html>. Avoids a JS-driven swap so no flash on first load. */}\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img\n className=\"light-only\"\n src={customThemeJson.logo.light}\n alt=\"Logo\"\n width=\"100\"\n height=\"100\"\n />\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img\n className=\"dark-only\"\n src={customThemeJson.logo.dark}\n alt=\"Logo\"\n width=\"100\"\n height=\"100\"\n />\n </>\n ) : (\n <Logo />\n )}\n </Link>\n {children}\n <StyledLeftWrapper>\n <StyledSearchButton onClick={openSearch} aria-label=\"Search docs\">\n <Search size={14} />\n <SearchKbd>⌘K</SearchKbd>\n </StyledSearchButton>\n {isChatActive && <ChatButtonCTA />}\n </StyledLeftWrapper>\n </StyledHeaderInner>\n </StyledHeader>\n );\n}\n\nexport { Header };\n";
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
export const headerTemplate = `"use client";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import { useCallback, useContext, useRef, useState } from "react";
|
|
4
|
-
import styled, { css
|
|
4
|
+
import styled, { css } from "styled-components";
|
|
5
5
|
import Link from "next/link";
|
|
6
|
-
import { rgba } from "polished";
|
|
7
6
|
import { mq, Theme } from "@/app/theme";
|
|
8
7
|
import { useOnClickOutside } from "@/components/ClickOutside";
|
|
9
8
|
import { Search } from "lucide-react";
|
|
@@ -52,7 +51,8 @@ const StyledHeader = styled.header<{ theme: Theme; $hasChildren: boolean }>\`
|
|
|
52
51
|
}
|
|
53
52
|
|
|
54
53
|
&::after {
|
|
55
|
-
background: \${({ theme }) =>
|
|
54
|
+
background: \${({ theme }) =>
|
|
55
|
+
\`color-mix(in srgb, \${theme.colors.primaryLight} 5%, transparent)\`};
|
|
56
56
|
z-index: -1;
|
|
57
57
|
}
|
|
58
58
|
|
|
@@ -127,7 +127,6 @@ function Header({ children }: HeaderProps) {
|
|
|
127
127
|
isOptionActive ? closeMenu : () => {},
|
|
128
128
|
);
|
|
129
129
|
useOnClickOutside([langRef, wrapperRef], isLangActive ? closeMenu : () => {});
|
|
130
|
-
const theme = useTheme() as Theme;
|
|
131
130
|
const { isChatActive } = useContext(ChatContext);
|
|
132
131
|
const { openSearch } = useContext(SearchContext);
|
|
133
132
|
|
|
@@ -136,23 +135,27 @@ function Header({ children }: HeaderProps) {
|
|
|
136
135
|
<StyledHeaderInner $hasChildren={children ? true : false}>
|
|
137
136
|
<Link href="/" className="logo" aria-label="Logo">
|
|
138
137
|
{customThemeJson.logo ? (
|
|
139
|
-
|
|
140
|
-
|
|
138
|
+
<>
|
|
139
|
+
{/* Both logos render; .light-only and .dark-only classes in
|
|
140
|
+
GlobalStyles hide the inactive one based on the "dark" class
|
|
141
|
+
on <html>. Avoids a JS-driven swap so no flash on first load. */}
|
|
142
|
+
{/* eslint-disable-next-line @next/next/no-img-element */}
|
|
141
143
|
<img
|
|
142
|
-
|
|
144
|
+
className="light-only"
|
|
145
|
+
src={customThemeJson.logo.light}
|
|
143
146
|
alt="Logo"
|
|
144
147
|
width="100"
|
|
145
148
|
height="100"
|
|
146
149
|
/>
|
|
147
|
-
|
|
148
|
-
// eslint-disable-next-line @next/next/no-img-element
|
|
150
|
+
{/* eslint-disable-next-line @next/next/no-img-element */}
|
|
149
151
|
<img
|
|
150
|
-
|
|
152
|
+
className="dark-only"
|
|
153
|
+
src={customThemeJson.logo.dark}
|
|
151
154
|
alt="Logo"
|
|
152
155
|
width="100"
|
|
153
156
|
height="100"
|
|
154
157
|
/>
|
|
155
|
-
|
|
158
|
+
</>
|
|
156
159
|
) : (
|
|
157
160
|
<Logo />
|
|
158
161
|
)}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const sharedStyledTemplate = "\"use client\";\nimport {
|
|
1
|
+
export declare const sharedStyledTemplate = "\"use client\";\nimport { styledSmall, styledText } from \"cherry-styled-components\";\nimport { mq, Theme } from \"@/app/theme\";\nimport styled, { css } from \"styled-components\";\n\nexport const interactiveStyles = css<{ theme: Theme }>`\n transition: all 0.3s ease;\n border: solid 1px transparent;\n box-shadow: 0 0 0 0px ${({ theme }) => theme.colors.primary};\n\n &:hover {\n border-color: ${({ theme }) => theme.colors.primary};\n }\n\n &:focus {\n border-color: ${({ theme }) => theme.colors.primary};\n box-shadow: 0 0 0 4px ${({ theme }) => theme.colors.primaryLight};\n }\n\n &:active {\n box-shadow: 0 0 0 2px ${({ theme }) => theme.colors.primaryLight};\n }\n`;\n\nexport const styledAnchor = css<{ theme: Theme }>`\n & a:not([class]):not(:has(img)) {\n color: inherit;\n transition: all 0.3s ease;\n text-decoration: none;\n box-shadow: 0 2px 0 0 ${({ theme }) => theme.colors.primary};\n\n &:hover {\n color: ${({ theme }) => theme.colors.accent};\n box-shadow: 0 1px 0 0 ${({ theme }) => theme.colors.primary};\n }\n }\n`;\n\nexport const stylesLists = css<{ theme: Theme }>`\n & ul,\n & ol {\n & li {\n & > .code-wrapper {\n margin: 10px 0;\n }\n }\n }\n\n & ul {\n list-style: none;\n padding: 0;\n margin: 0;\n\n & li {\n text-indent: 0;\n display: block;\n position: relative;\n padding: 0 0 0 15px;\n margin: 0;\n ${({ theme }) => styledText(theme)};\n min-height: 23px;\n\n ${mq(\"lg\")} {\n min-height: 27px;\n }\n\n &::before {\n content: \"\";\n display: block;\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: ${({ theme }) => theme.colors.primary};\n position: absolute;\n top: 8px;\n left: 2px;\n\n ${mq(\"lg\")} {\n top: 10px;\n }\n }\n }\n }\n\n & ol {\n padding: 0;\n margin: 0;\n\n & ul {\n padding-left: 15px;\n }\n\n & > li {\n position: relative;\n padding: 0;\n counter-increment: item;\n margin: 0;\n ${({ theme }) => styledText(theme)};\n\n &::before {\n content: counter(item) \".\";\n display: inline-block;\n margin: 0 4px 0 0;\n font-weight: 700;\n color: ${({ theme }) => theme.colors.primary};\n min-width: max-content;\n }\n }\n }\n`;\n\nexport const styledTable = css<{ theme: Theme }>`\n & .table-wrapper {\n overflow-x: auto;\n width: 100%;\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 10px 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\nexport const StyledSmallButton = styled.button<{ theme: Theme }>`\n ${interactiveStyles};\n background: ${({ theme }) => theme.colors.light};\n border: solid 1px ${({ theme }) => theme.colors.grayLight};\n color: ${({ theme }) => theme.colors.accent};\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: inherit;\n }\n`;\n";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export const sharedStyledTemplate = `"use client";
|
|
2
|
-
import {
|
|
2
|
+
import { styledSmall, styledText } from "cherry-styled-components";
|
|
3
|
+
import { mq, Theme } from "@/app/theme";
|
|
3
4
|
import styled, { css } from "styled-components";
|
|
4
5
|
|
|
5
6
|
export const interactiveStyles = css<{ theme: Theme }>\`
|
|
@@ -29,8 +30,7 @@ export const styledAnchor = css<{ theme: Theme }>\`
|
|
|
29
30
|
box-shadow: 0 2px 0 0 \${({ theme }) => theme.colors.primary};
|
|
30
31
|
|
|
31
32
|
&:hover {
|
|
32
|
-
color: \${({ theme }) =>
|
|
33
|
-
theme.isDark ? theme.colors.primaryLight : theme.colors.primaryDark};
|
|
33
|
+
color: \${({ theme }) => theme.colors.accent};
|
|
34
34
|
box-shadow: 0 1px 0 0 \${({ theme }) => theme.colors.primary};
|
|
35
35
|
}
|
|
36
36
|
}
|
|
@@ -148,8 +148,7 @@ export const StyledSmallButton = styled.button<{ theme: Theme }>\`
|
|
|
148
148
|
\${interactiveStyles};
|
|
149
149
|
background: \${({ theme }) => theme.colors.light};
|
|
150
150
|
border: solid 1px \${({ theme }) => theme.colors.grayLight};
|
|
151
|
-
color: \${({ theme }) =>
|
|
152
|
-
theme.isDark ? theme.colors.primaryLight : theme.colors.primaryDark};
|
|
151
|
+
color: \${({ theme }) => theme.colors.accent};
|
|
153
152
|
border-radius: \${({ theme }) => theme.spacing.radius.xs};
|
|
154
153
|
padding: 6px 8px;
|
|
155
154
|
font-size: 12px;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const staticLinksTemplate = "\"use client\";\nimport styled, { css } from \"styled-components\";\nimport {
|
|
1
|
+
export declare const staticLinksTemplate = "\"use client\";\nimport styled, { css } from \"styled-components\";\nimport { useContext } from \"react\";\nimport { ChatContext } from \"@/components/Chat\";\nimport { mq, Theme } from \"@/app/theme\";\nimport { interactiveStyles } from \"@/components/layout/SharedStyled\";\nimport { Icon } from \"@/components/layout/Icon\";\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 StyledStaticLinks = styled.div<{ theme: Theme; $isChatOpen: boolean }>`\n display: flex;\n margin: 0 auto;\n transition: all 0.3s ease;\n padding: 0 20px;\n margin-bottom: 20px;\n\n ${mq(\"lg\")} {\n margin: 0;\n padding: 0 300px 20px 300px;\n\n ${({ $isChatOpen }) =>\n $isChatOpen &&\n css`\n padding: 0 440px 20px 300px;\n `}\n }\n`;\n\nconst StyledStaticLinksContent = styled.div`\n max-width: 640px;\n margin: auto 0;\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n width: 100%;\n margin: 0 auto;\n`;\n\nconst StyledLink = styled.a<{ theme: Theme; $hasIcon?: boolean }>`\n position: relative;\n text-decoration: none;\n font-size: ${({ theme }) => theme.fontSizes.small.lg};\n line-height: 1;\n color: ${({ theme }) => theme.colors.accent};\n padding: 0;\n display: flex;\n gap: 6px;\n transition: all 0.3s ease;\n font-weight: 600;\n white-space: nowrap;\n min-width: fit-content;\n background: ${({ theme }) =>\n `color-mix(in srgb, ${theme.colors.primaryLight} 10%, transparent)`};\n padding: 6px 8px;\n border-radius: ${({ theme }) => theme.spacing.radius.xs};\n ${interactiveStyles};\n\n ${({ $hasIcon }) =>\n $hasIcon &&\n css`\n padding-left: 30px;\n `}\n\n & * {\n margin: auto 0;\n }\n\n & svg {\n position: absolute;\n top: 50%;\n left: 8px;\n transform: translateY(-50%);\n }\n\n &:hover {\n color: ${({ theme }) => theme.colors.accent};\n }\n`;\n\nfunction StaticLinks() {\n const { isOpen } = useContext(ChatContext);\n\n if (links.length === 0) {\n return null;\n }\n\n return (\n <>\n <StyledStaticLinks $isChatOpen={isOpen}>\n <StyledStaticLinksContent>\n {links.map((link, index) => (\n <StyledLink\n key={index}\n href={link.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n $hasIcon={link.icon ? true : false}\n >\n {link.icon && <Icon name={link.icon} size={16} />}\n <span>{link.title}</span>\n </StyledLink>\n ))}\n </StyledStaticLinksContent>\n </StyledStaticLinks>\n </>\n );\n}\n\nexport { StaticLinks };\n";
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { SIDEBAR_WIDTH, CHAT_WIDTH } from "../../app/theme.js";
|
|
2
2
|
export const staticLinksTemplate = `"use client";
|
|
3
3
|
import styled, { css } from "styled-components";
|
|
4
|
-
import { rgba } from "polished";
|
|
5
4
|
import { useContext } from "react";
|
|
6
5
|
import { ChatContext } from "@/components/Chat";
|
|
7
6
|
import { mq, Theme } from "@/app/theme";
|
|
@@ -51,8 +50,7 @@ const StyledLink = styled.a<{ theme: Theme; $hasIcon?: boolean }>\`
|
|
|
51
50
|
text-decoration: none;
|
|
52
51
|
font-size: \${({ theme }) => theme.fontSizes.small.lg};
|
|
53
52
|
line-height: 1;
|
|
54
|
-
color: \${({ theme }) =>
|
|
55
|
-
theme.isDark ? theme.colors.primaryLight : theme.colors.primaryDark};
|
|
53
|
+
color: \${({ theme }) => theme.colors.accent};
|
|
56
54
|
padding: 0;
|
|
57
55
|
display: flex;
|
|
58
56
|
gap: 6px;
|
|
@@ -60,7 +58,8 @@ const StyledLink = styled.a<{ theme: Theme; $hasIcon?: boolean }>\`
|
|
|
60
58
|
font-weight: 600;
|
|
61
59
|
white-space: nowrap;
|
|
62
60
|
min-width: fit-content;
|
|
63
|
-
background: \${({ theme }) =>
|
|
61
|
+
background: \${({ theme }) =>
|
|
62
|
+
\`color-mix(in srgb, \${theme.colors.primaryLight} 10%, transparent)\`};
|
|
64
63
|
padding: 6px 8px;
|
|
65
64
|
border-radius: \${({ theme }) => theme.spacing.radius.xs};
|
|
66
65
|
\${interactiveStyles};
|
|
@@ -83,8 +82,7 @@ const StyledLink = styled.a<{ theme: Theme; $hasIcon?: boolean }>\`
|
|
|
83
82
|
}
|
|
84
83
|
|
|
85
84
|
&:hover {
|
|
86
|
-
color: \${({ theme }) =>
|
|
87
|
-
theme.isDark ? theme.colors.primaryLight : theme.colors.primaryDark};
|
|
85
|
+
color: \${({ theme }) => theme.colors.accent};
|
|
88
86
|
}
|
|
89
87
|
\`;
|
|
90
88
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const stepsTemplate = "\"use client\";\nimport React from \"react\";\nimport styled, { useTheme } from \"styled-components\";\nimport { styledText
|
|
1
|
+
export declare const stepsTemplate = "\"use client\";\nimport React from \"react\";\nimport styled, { useTheme } from \"styled-components\";\nimport { styledText } from \"cherry-styled-components\";\nimport { Theme } from \"@/app/theme\";\nimport { Icon, IconProps } from \"@/components/layout/Icon\";\n\nconst StyledStepsContainer = styled.div<{ theme: Theme }>`\n position: relative;\n width: 100%;\n`;\n\nconst StyledStep = styled.div<{ theme: Theme }>`\n background: ${({ theme }) => theme.colors.light};\n border-radius: ${({ theme }) => theme.spacing.radius.lg};\n padding: 0 0 20px 52px;\n margin: 0;\n position: relative;\n ${({ theme }) => styledText(theme)}\n color: ${({ theme }) => theme.colors.grayDark};\n\n &::after {\n content: \"\";\n position: absolute;\n left: 16px;\n top: 0;\n width: 1px;\n height: 100%;\n background: ${({ theme }) => theme.colors.primary};\n background: linear-gradient(\n 180deg,\n ${({ theme }) => theme.colors.primary},\n transparent\n );\n border-radius: 4px;\n }\n`;\n\nconst StepNumber = styled.div<{ theme: Theme }>`\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: ${({ theme }) => theme.colors.primary};\n color: ${({ theme }) => theme.colors.light};\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 700;\n margin-bottom: 12px;\n ${({ theme }) => styledText(theme)};\n position: absolute;\n left: 0;\n top: 0;\n z-index: 1;\n`;\n\nconst StyledStepTitle = styled.h3<{ theme: Theme }>`\n margin: 0 0 10px 0;\n padding: 2px 0 0 0;\n color: ${({ theme }) => theme.colors.dark};\n ${({ theme }) => styledText(theme)};\n display: flex;\n align-items: center;\n gap: 10px;\n`;\n\nconst StepContent = styled.div<{ theme: Theme }>`\n color: ${({ theme }) => theme.colors.grayDark};\n ${({ theme }) => styledText(theme)};\n\n & > .code-wrapper {\n margin: 10px 0;\n }\n`;\n\ninterface StepProps extends React.HTMLAttributes<HTMLDivElement> {\n title: string;\n children: React.ReactNode;\n icon?: IconProps;\n}\n\nfunction Step(_props: StepProps) {\n return null;\n}\n\ninterface StepsProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n}\n\nfunction Steps({ children }: StepsProps) {\n const theme = useTheme() as Theme;\n\n const steps = React.Children.toArray(children).filter(\n (child): child is React.ReactElement<StepProps> =>\n React.isValidElement(child),\n );\n\n return (\n <StyledStepsContainer theme={theme}>\n {steps.map((step, index) => {\n const { title, children: stepContent, icon } = step.props;\n\n return (\n <StyledStep key={index} theme={theme}>\n <StepNumber theme={theme}>{index + 1}</StepNumber>\n <StyledStepTitle theme={theme}>\n {icon && <Icon name={icon} color={theme.colors.primary} />}\n {title}\n </StyledStepTitle>\n <StepContent theme={theme}>{stepContent}</StepContent>\n </StyledStep>\n );\n })}\n </StyledStepsContainer>\n );\n}\n\nexport { Steps, Step };\n";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export const stepsTemplate = `"use client";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import styled, { useTheme } from "styled-components";
|
|
4
|
-
import { styledText
|
|
5
|
-
import {
|
|
4
|
+
import { styledText } from "cherry-styled-components";
|
|
5
|
+
import { Theme } from "@/app/theme";
|
|
6
6
|
import { Icon, IconProps } from "@/components/layout/Icon";
|
|
7
7
|
|
|
8
8
|
const StyledStepsContainer = styled.div<{ theme: Theme }>\`
|
|
@@ -30,7 +30,7 @@ const StyledStep = styled.div<{ theme: Theme }>\`
|
|
|
30
30
|
background: linear-gradient(
|
|
31
31
|
180deg,
|
|
32
32
|
\${({ theme }) => theme.colors.primary},
|
|
33
|
-
|
|
33
|
+
transparent
|
|
34
34
|
);
|
|
35
35
|
border-radius: 4px;
|
|
36
36
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const tabsTemplate = "\"use client\";\nimport { Theme } from \"@/app/theme\";\nimport { styledText } from \"cherry-styled-components\";\nimport
|
|
1
|
+
export declare const tabsTemplate = "\"use client\";\nimport { Theme } from \"@/app/theme\";\nimport { styledText } from \"cherry-styled-components\";\nimport React, { useState, ReactNode } from \"react\";\nimport styled, { css } from \"styled-components\";\ninterface TabContentProps {\n title: string;\n children: ReactNode;\n}\ninterface TabsProps {\n children: React.ReactElement<TabContentProps>[];\n}\nconst TabsContainer = styled.div`\n width: 100%;\n margin: 0 auto;\n`;\nconst TabsList = styled.div<{ theme: Theme }>`\n display: flex;\n overflow: hidden;\n border-radius: ${({ theme }) => theme.spacing.radius.lg};\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n background-color: ${({ theme }) => theme.colors.light};\n border: solid 1px ${({ theme }) => theme.colors.grayLight};\n overflow-x: auto;\n`;\nconst TabButton = styled.button<{ theme: Theme; $isActive?: boolean }>`\n flex: 1;\n padding: 12px 20px;\n border: none;\n background: ${({ theme }) => theme.colors.light};\n cursor: pointer;\n transition: all 0.2s ease;\n border-bottom: 3px solid transparent;\n min-width: fit-content;\n ${({ theme }) => styledText(theme)};\n color: ${({ theme }) => theme.colors.dark};\n font-weight: 600;\n ${({ theme, $isActive }) =>\n $isActive &&\n css`\n color: ${theme.colors.primary};\n border-bottom: 3px solid ${theme.colors.primary};\n `}\n position: relative;\n &:hover {\n ${({ theme, $isActive }) =>\n !$isActive &&\n css`\n color: ${theme.colors.primary};\n background-color: color-mix(\n in srgb,\n ${theme.colors.primaryLight} 10%,\n transparent\n );\n `}\n }\n &:focus {\n outline: none;\n }\n &:not(:last-child) {\n border-right: 1px solid ${({ theme }) => theme.colors.grayLight};\n }\n`;\nconst TabPanel = styled.div<{ theme: Theme }>`\n background-color: ${({ theme }) => theme.colors.light};\n padding: 20px;\n border-radius: 0 0 ${({ theme }) => theme.spacing.radius.lg}\n ${({ theme }) => theme.spacing.radius.lg};\n color: ${({ theme }) => theme.colors.grayDark};\n ${({ theme }) => styledText(theme)}\n border: solid 1px ${({ theme }) => theme.colors.grayLight};\n border-top: none;\n display: flex;\n flex-direction: column;\n gap: 20px;\n flex-wrap: wrap;\n flex: 1;\n`;\nconst TabContent: React.FC<TabContentProps> = ({ children }) => {\n return <>{children}</>;\n};\nconst Tabs: React.FC<TabsProps> = ({ children }) => {\n const [activeTab, setActiveTab] = useState(0);\n const tabs = React.Children.toArray(children).filter(\n (child): child is React.ReactElement<TabContentProps> =>\n Boolean(\n React.isValidElement(child) &&\n child.props &&\n typeof child.props === \"object\" &&\n \"title\" in child.props &&\n typeof child.props.title === \"string\" &&\n child.props.title.trim() !== \"\",\n ),\n );\n return (\n <TabsContainer>\n <TabsList>\n {tabs.map((tab, index) => (\n <TabButton\n key={index}\n $isActive={activeTab === index}\n onClick={() => setActiveTab(index)}\n type=\"button\"\n >\n {tab.props.title}\n </TabButton>\n ))}\n </TabsList>\n <TabPanel>{tabs[activeTab]?.props.children}</TabPanel>\n </TabsContainer>\n );\n};\nexport { Tabs, TabContent };\n";
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
export const tabsTemplate = `"use client";
|
|
2
2
|
import { Theme } from "@/app/theme";
|
|
3
3
|
import { styledText } from "cherry-styled-components";
|
|
4
|
-
import { rgba } from "polished";
|
|
5
4
|
import React, { useState, ReactNode } from "react";
|
|
6
5
|
import styled, { css } from "styled-components";
|
|
7
6
|
interface TabContentProps {
|
|
@@ -49,7 +48,11 @@ const TabButton = styled.button<{ theme: Theme; $isActive?: boolean }>\`
|
|
|
49
48
|
!$isActive &&
|
|
50
49
|
css\`
|
|
51
50
|
color: \${theme.colors.primary};
|
|
52
|
-
background-color:
|
|
51
|
+
background-color: color-mix(
|
|
52
|
+
in srgb,
|
|
53
|
+
\${theme.colors.primaryLight} 10%,
|
|
54
|
+
transparent
|
|
55
|
+
);
|
|
53
56
|
\`}
|
|
54
57
|
}
|
|
55
58
|
&:focus {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const themeToggleTemplate = "\"use client\";\nimport {
|
|
1
|
+
export declare const themeToggleTemplate = "\"use client\";\nimport { resetButton } from \"cherry-styled-components\";\nimport styled, { css } from \"styled-components\";\nimport { Theme } from \"@/app/theme\";\nimport { Icon } from \"@/components/layout/Icon\";\nimport { useThemeOverride } from \"@/components/layout/ClientThemeProvider\";\n\nconst StyledThemeToggle = styled.button<{ theme: Theme; $hidden?: boolean }>`\n ${resetButton}\n width: 59px;\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 }) =>\n `color-mix(in srgb, ${theme.colors.primaryLight} 20%, transparent)`};\n transition: all 0.3s ease;\n z-index: 1;\n }\n\n /* Knob position depends on the active mode, signaled by the \"dark\" class\n on <html>. Pure CSS \u2014 no JS conditional needed for the visual swap. */\n :root.dark &::after {\n transform: translateX(27px);\n }\n\n ${({ $hidden }) =>\n $hidden &&\n css`\n display: none;\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-sun {\n transform: translateX(1px);\n }\n\n & .lucide-moon-star {\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 }) => theme.colors.accent};\n\n & svg[stroke] {\n stroke: ${({ theme }) => theme.colors.accent};\n }\n }\n\n &:active {\n transform: scale(0.97);\n }\n`;\n\nfunction ToggleTheme({ $hidden }: { $hidden?: boolean }) {\n const { mode, setMode } = useThemeOverride();\n\n return (\n <StyledThemeToggle\n onClick={async () => {\n const next = mode === \"dark\" ? \"light\" : \"dark\";\n setMode(next);\n await fetch(\"/api/theme\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ theme: next }),\n }).catch((err) => console.error(\"Failed to persist theme:\", err));\n }}\n $hidden={$hidden}\n aria-label=\"Toggle Theme\"\n >\n <Icon name=\"Sun\" className=\"light\" />\n <Icon name=\"MoonStar\" className=\"dark\" />\n </StyledThemeToggle>\n );\n}\n\nfunction ToggleThemeLoading() {\n return (\n <StyledThemeToggle $hidden aria-label=\"Toggle Theme\">\n <Icon name=\"MoonStar\" className=\"dark\" />\n <Icon name=\"Sun\" className=\"light\" />\n </StyledThemeToggle>\n );\n}\n\nexport { ToggleTheme, ToggleThemeLoading };\n";
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
export const themeToggleTemplate = `"use client";
|
|
2
|
-
import {
|
|
3
|
-
import styled, { css
|
|
4
|
-
import {
|
|
2
|
+
import { resetButton } from "cherry-styled-components";
|
|
3
|
+
import styled, { css } from "styled-components";
|
|
4
|
+
import { Theme } from "@/app/theme";
|
|
5
5
|
import { Icon } from "@/components/layout/Icon";
|
|
6
|
-
import { theme as themeLight, themeDark } from "@/app/theme";
|
|
7
6
|
import { useThemeOverride } from "@/components/layout/ClientThemeProvider";
|
|
8
7
|
|
|
9
8
|
const StyledThemeToggle = styled.button<{ theme: Theme; $hidden?: boolean }>\`
|
|
@@ -26,14 +25,16 @@ const StyledThemeToggle = styled.button<{ theme: Theme; $hidden?: boolean }>\`
|
|
|
26
25
|
width: 24px;
|
|
27
26
|
height: 24px;
|
|
28
27
|
border-radius: 50%;
|
|
29
|
-
background: \${({ theme }) =>
|
|
28
|
+
background: \${({ theme }) =>
|
|
29
|
+
\`color-mix(in srgb, \${theme.colors.primaryLight} 20%, transparent)\`};
|
|
30
30
|
transition: all 0.3s ease;
|
|
31
31
|
z-index: 1;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/* Knob position depends on the active mode, signaled by the "dark" class
|
|
35
|
+
on <html>. Pure CSS — no JS conditional needed for the visual swap. */
|
|
36
|
+
:root.dark &::after {
|
|
37
|
+
transform: translateX(27px);
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
\${({ $hidden }) =>
|
|
@@ -66,12 +67,10 @@ const StyledThemeToggle = styled.button<{ theme: Theme; $hidden?: boolean }>\`
|
|
|
66
67
|
|
|
67
68
|
&:hover {
|
|
68
69
|
transform: scale(1.05);
|
|
69
|
-
color: \${({ theme }) =>
|
|
70
|
-
theme.isDark ? theme.colors.primaryLight : theme.colors.primaryDark};
|
|
70
|
+
color: \${({ theme }) => theme.colors.accent};
|
|
71
71
|
|
|
72
72
|
& svg[stroke] {
|
|
73
|
-
stroke: \${({ theme }) =>
|
|
74
|
-
theme.isDark ? theme.colors.primaryLight : theme.colors.primaryDark};
|
|
73
|
+
stroke: \${({ theme }) => theme.colors.accent};
|
|
75
74
|
}
|
|
76
75
|
}
|
|
77
76
|
|
|
@@ -81,18 +80,17 @@ const StyledThemeToggle = styled.button<{ theme: Theme; $hidden?: boolean }>\`
|
|
|
81
80
|
\`;
|
|
82
81
|
|
|
83
82
|
function ToggleTheme({ $hidden }: { $hidden?: boolean }) {
|
|
84
|
-
const {
|
|
85
|
-
const theme = useTheme() as Theme;
|
|
83
|
+
const { mode, setMode } = useThemeOverride();
|
|
86
84
|
|
|
87
85
|
return (
|
|
88
86
|
<StyledThemeToggle
|
|
89
87
|
onClick={async () => {
|
|
90
|
-
const
|
|
91
|
-
|
|
88
|
+
const next = mode === "dark" ? "light" : "dark";
|
|
89
|
+
setMode(next);
|
|
92
90
|
await fetch("/api/theme", {
|
|
93
91
|
method: "POST",
|
|
94
92
|
headers: { "Content-Type": "application/json" },
|
|
95
|
-
body: JSON.stringify({ theme:
|
|
93
|
+
body: JSON.stringify({ theme: next }),
|
|
96
94
|
}).catch((err) => console.error("Failed to persist theme:", err));
|
|
97
95
|
}}
|
|
98
96
|
$hidden={$hidden}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const typographyTemplate = "\"use client\";\nimport {\n styledH1,\n styledH2,\n styledH3,\n styledH4,\n styledH5,\n styledH6,\n styledText,\n
|
|
1
|
+
export declare const typographyTemplate = "\"use client\";\nimport {\n styledH1,\n styledH2,\n styledH3,\n styledH4,\n styledH5,\n styledH6,\n styledText,\n} from \"cherry-styled-components\";\nimport styled, { css } from \"styled-components\";\nimport { Theme } from \"@/app/theme\";\n\nconst StyledHeading = css`\n font-weight: 900;\n`;\n\nexport const StyledH1 = styled.h1<{ theme: Theme }>`\n ${StyledHeading};\n ${({ theme }) => styledH1(theme)}\n`;\n\nexport const StyledH2 = styled.h2<{ theme: Theme }>`\n ${StyledHeading};\n ${({ theme }) => styledH2(theme)}\n`;\n\nexport const StyledH3 = styled.h3<{ theme: Theme }>`\n ${StyledHeading};\n ${({ theme }) => styledH3(theme)}\n`;\n\nexport const StyledH4 = styled.h4<{ theme: Theme }>`\n ${StyledHeading};\n ${({ theme }) => styledH4(theme)}\n`;\n\nexport const StyledH5 = styled.h5<{ theme: Theme }>`\n ${StyledHeading};\n ${({ theme }) => styledH5(theme)}\n`;\n\nexport const StyledH6 = styled.h6<{ theme: Theme }>`\n ${StyledHeading};\n ${({ theme }) => styledH6(theme)}\n`;\n\nexport const StyledText = styled.p<{ theme: Theme }>`\n ${({ theme }) => styledText(theme)}\n`;\n";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const updateTemplate = "\"use client\";\nimport styled from \"styled-components\";\nimport {
|
|
1
|
+
export declare const updateTemplate = "\"use client\";\nimport styled from \"styled-components\";\nimport { styledSmall } from \"cherry-styled-components\";\nimport { mq, Theme } from \"@/app/theme\";\n\nconst StyledUpdate = styled.div<{ theme: Theme; $columns?: number }>`\n position: relative;\n display: flex;\n gap: 20px;\n flex-direction: column;\n\n ${mq(\"lg\")} {\n margin: 20px 0;\n flex-direction: row;\n }\n`;\n\nconst StyledUpdateLabel = styled.span<{ theme: Theme }>`\n background: ${({ theme }) =>\n `color-mix(in srgb, ${theme.colors.primaryLight} 20%, transparent)`};\n color: ${({ theme }) => theme.colors.primary};\n padding: 2px 4px;\n border-radius: ${({ theme }) => theme.spacing.radius.xs};\n font-weight: 600;\n ${({ theme }) => styledSmall(theme)};\n`;\n\nconst StyledUpdateDescription = styled.div<{ theme: Theme }>`\n ${({ theme }) => styledSmall(theme)};\n color: ${({ theme }) => theme.colors.gray};\n`;\n\nconst StyledUpdateSidebar = styled.div`\n display: flex;\n flex-direction: column;\n gap: 10px;\n\n ${mq(\"lg\")} {\n min-width: 160px;\n }\n`;\n\nconst StyledUpdateChildren = styled.div`\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 20px;\n`;\n\ninterface UpdateProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n label: string;\n description: string;\n}\n\nfunction Update({ children, label, description }: UpdateProps) {\n return (\n <StyledUpdate>\n <StyledUpdateSidebar>\n <div>\n <StyledUpdateLabel>{label}</StyledUpdateLabel>\n </div>\n <StyledUpdateDescription>{description}</StyledUpdateDescription>\n </StyledUpdateSidebar>\n <StyledUpdateChildren>{children}</StyledUpdateChildren>\n </StyledUpdate>\n );\n}\n\nexport { Update };\n";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export const updateTemplate = `"use client";
|
|
2
2
|
import styled from "styled-components";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { styledSmall } from "cherry-styled-components";
|
|
4
|
+
import { mq, Theme } from "@/app/theme";
|
|
5
5
|
|
|
6
6
|
const StyledUpdate = styled.div<{ theme: Theme; $columns?: number }>\`
|
|
7
7
|
position: relative;
|
|
@@ -16,7 +16,8 @@ const StyledUpdate = styled.div<{ theme: Theme; $columns?: number }>\`
|
|
|
16
16
|
\`;
|
|
17
17
|
|
|
18
18
|
const StyledUpdateLabel = styled.span<{ theme: Theme }>\`
|
|
19
|
-
background: \${({ theme }) =>
|
|
19
|
+
background: \${({ theme }) =>
|
|
20
|
+
\`color-mix(in srgb, \${theme.colors.primaryLight} 20%, transparent)\`};
|
|
20
21
|
color: \${({ theme }) => theme.colors.primary};
|
|
21
22
|
padding: 2px 4px;
|
|
22
23
|
border-radius: \${({ theme }) => theme.spacing.radius.xs};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { PageMeta, SectionConfig } from "../../lib/types.js";
|
|
2
|
+
export interface PageWithBody extends PageMeta {
|
|
3
|
+
body: string;
|
|
4
|
+
}
|
|
5
|
+
export interface LlmsFullArgs {
|
|
6
|
+
siteName: string;
|
|
7
|
+
siteDescription?: string;
|
|
8
|
+
baseUrl: string | null;
|
|
9
|
+
pages: PageWithBody[];
|
|
10
|
+
sectionsConfig: SectionConfig[] | null;
|
|
11
|
+
}
|
|
12
|
+
export declare function llmsFullTemplate(args: LlmsFullArgs): string;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
function pageUrl(slug, baseUrl) {
|
|
2
|
+
if (baseUrl) {
|
|
3
|
+
return slug === "" ? `${baseUrl}/` : `${baseUrl}/${slug}`;
|
|
4
|
+
}
|
|
5
|
+
return slug === "" ? "/" : `/${slug}`;
|
|
6
|
+
}
|
|
7
|
+
function orderedPages(pages, sectionsConfig) {
|
|
8
|
+
const sectionOrderIndex = new Map();
|
|
9
|
+
sectionOrderIndex.set("", 0);
|
|
10
|
+
if (sectionsConfig) {
|
|
11
|
+
sectionsConfig.forEach((section, idx) => {
|
|
12
|
+
sectionOrderIndex.set(section.slug, idx + 1);
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
return [...pages].sort((a, b) => {
|
|
16
|
+
const sa = sectionOrderIndex.get(a.section) ?? 999;
|
|
17
|
+
const sb = sectionOrderIndex.get(b.section) ?? 999;
|
|
18
|
+
if (sa !== sb)
|
|
19
|
+
return sa - sb;
|
|
20
|
+
if (a.categoryOrder !== b.categoryOrder)
|
|
21
|
+
return a.categoryOrder - b.categoryOrder;
|
|
22
|
+
if (a.category !== b.category)
|
|
23
|
+
return a.category.localeCompare(b.category);
|
|
24
|
+
if (a.order !== b.order)
|
|
25
|
+
return a.order - b.order;
|
|
26
|
+
return a.title.localeCompare(b.title);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
export function llmsFullTemplate(args) {
|
|
30
|
+
const { siteName, siteDescription, baseUrl, pages, sectionsConfig } = args;
|
|
31
|
+
const lines = [];
|
|
32
|
+
lines.push(`# ${siteName}`);
|
|
33
|
+
lines.push("");
|
|
34
|
+
lines.push(`> Full documentation for ${siteName}.`);
|
|
35
|
+
if (siteDescription && siteDescription.trim() !== "") {
|
|
36
|
+
lines.push("");
|
|
37
|
+
lines.push(siteDescription.trim());
|
|
38
|
+
}
|
|
39
|
+
lines.push("");
|
|
40
|
+
if (pages.length === 0) {
|
|
41
|
+
return lines.join("\n") + "\n";
|
|
42
|
+
}
|
|
43
|
+
const sorted = orderedPages(pages, sectionsConfig);
|
|
44
|
+
for (const page of sorted) {
|
|
45
|
+
lines.push("---");
|
|
46
|
+
lines.push("");
|
|
47
|
+
lines.push(`# ${page.title}`);
|
|
48
|
+
lines.push("");
|
|
49
|
+
if (page.description && page.description.trim() !== "") {
|
|
50
|
+
lines.push(`> ${page.description.trim()}`);
|
|
51
|
+
lines.push("");
|
|
52
|
+
}
|
|
53
|
+
lines.push(`Source: ${pageUrl(page.slug, baseUrl)}`);
|
|
54
|
+
lines.push("");
|
|
55
|
+
lines.push(page.body.trim());
|
|
56
|
+
lines.push("");
|
|
57
|
+
}
|
|
58
|
+
return lines.join("\n").replace(/\n+$/, "\n");
|
|
59
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { PageMeta, SectionConfig } from "../../lib/types.js";
|
|
2
|
+
export interface LlmsIndexArgs {
|
|
3
|
+
siteName: string;
|
|
4
|
+
siteDescription?: string;
|
|
5
|
+
baseUrl: string | null;
|
|
6
|
+
pages: PageMeta[];
|
|
7
|
+
sectionsConfig: SectionConfig[] | null;
|
|
8
|
+
}
|
|
9
|
+
export declare function llmsIndexTemplate(args: LlmsIndexArgs): string;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
function pageUrl(slug, baseUrl) {
|
|
2
|
+
if (baseUrl) {
|
|
3
|
+
return slug === "" ? `${baseUrl}/` : `${baseUrl}/${slug}`;
|
|
4
|
+
}
|
|
5
|
+
return slug === "" ? "/" : `/${slug}`;
|
|
6
|
+
}
|
|
7
|
+
function comparePages(a, b) {
|
|
8
|
+
if (a.order !== b.order)
|
|
9
|
+
return a.order - b.order;
|
|
10
|
+
return a.title.localeCompare(b.title);
|
|
11
|
+
}
|
|
12
|
+
function buildSectionGroups(pages, sectionsConfig) {
|
|
13
|
+
const sectionOrderIndex = new Map();
|
|
14
|
+
sectionOrderIndex.set("", 0);
|
|
15
|
+
if (sectionsConfig) {
|
|
16
|
+
sectionsConfig.forEach((section, idx) => {
|
|
17
|
+
sectionOrderIndex.set(section.slug, idx + 1);
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
const sectionLabelByslug = new Map();
|
|
21
|
+
if (sectionsConfig) {
|
|
22
|
+
for (const section of sectionsConfig) {
|
|
23
|
+
sectionLabelByslug.set(section.slug, section.label);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const bySection = new Map();
|
|
27
|
+
for (const page of pages) {
|
|
28
|
+
const key = page.section || "";
|
|
29
|
+
const list = bySection.get(key) ?? [];
|
|
30
|
+
list.push(page);
|
|
31
|
+
bySection.set(key, list);
|
|
32
|
+
}
|
|
33
|
+
const groups = [];
|
|
34
|
+
for (const [sectionSlug, sectionPages] of bySection) {
|
|
35
|
+
const byCategory = new Map();
|
|
36
|
+
for (const page of sectionPages) {
|
|
37
|
+
const key = page.category || "";
|
|
38
|
+
const list = byCategory.get(key) ?? [];
|
|
39
|
+
list.push(page);
|
|
40
|
+
byCategory.set(key, list);
|
|
41
|
+
}
|
|
42
|
+
const categories = [];
|
|
43
|
+
for (const [category, catPages] of byCategory) {
|
|
44
|
+
catPages.sort(comparePages);
|
|
45
|
+
const minCategoryOrder = catPages.reduce((min, p) => Math.min(min, p.categoryOrder), Number.POSITIVE_INFINITY);
|
|
46
|
+
categories.push({
|
|
47
|
+
category,
|
|
48
|
+
minCategoryOrder: Number.isFinite(minCategoryOrder)
|
|
49
|
+
? minCategoryOrder
|
|
50
|
+
: 0,
|
|
51
|
+
pages: catPages,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
categories.sort((a, b) => {
|
|
55
|
+
if (a.minCategoryOrder !== b.minCategoryOrder) {
|
|
56
|
+
return a.minCategoryOrder - b.minCategoryOrder;
|
|
57
|
+
}
|
|
58
|
+
return a.category.localeCompare(b.category);
|
|
59
|
+
});
|
|
60
|
+
groups.push({
|
|
61
|
+
sectionSlug,
|
|
62
|
+
sectionLabel: sectionLabelByslug.get(sectionSlug) ??
|
|
63
|
+
(sectionSlug === "" ? "Documentation" : sectionSlug),
|
|
64
|
+
sectionOrder: sectionOrderIndex.get(sectionSlug) ?? 999,
|
|
65
|
+
categories,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
groups.sort((a, b) => a.sectionOrder - b.sectionOrder);
|
|
69
|
+
return groups;
|
|
70
|
+
}
|
|
71
|
+
export function llmsIndexTemplate(args) {
|
|
72
|
+
const { siteName, siteDescription, baseUrl, pages, sectionsConfig } = args;
|
|
73
|
+
const lines = [];
|
|
74
|
+
lines.push(`# ${siteName}`);
|
|
75
|
+
lines.push("");
|
|
76
|
+
if (siteDescription && siteDescription.trim() !== "") {
|
|
77
|
+
lines.push(`> ${siteDescription.trim()}`);
|
|
78
|
+
lines.push("");
|
|
79
|
+
}
|
|
80
|
+
if (pages.length === 0) {
|
|
81
|
+
return lines.join("\n") + "\n";
|
|
82
|
+
}
|
|
83
|
+
const groups = buildSectionGroups(pages, sectionsConfig);
|
|
84
|
+
for (const group of groups) {
|
|
85
|
+
lines.push(`## ${group.sectionLabel}`);
|
|
86
|
+
lines.push("");
|
|
87
|
+
const useCategoryHeadings = group.categories.length > 1 ||
|
|
88
|
+
(group.categories.length === 1 && group.categories[0].category !== "");
|
|
89
|
+
for (const cat of group.categories) {
|
|
90
|
+
if (useCategoryHeadings && cat.category !== "") {
|
|
91
|
+
lines.push(`### ${cat.category}`);
|
|
92
|
+
lines.push("");
|
|
93
|
+
}
|
|
94
|
+
for (const page of cat.pages) {
|
|
95
|
+
const url = pageUrl(page.slug, baseUrl);
|
|
96
|
+
const desc = page.description && page.description.trim() !== ""
|
|
97
|
+
? `: ${page.description.trim()}`
|
|
98
|
+
: "";
|
|
99
|
+
lines.push(`- [${page.title}](${url})${desc}`);
|
|
100
|
+
}
|
|
101
|
+
lines.push("");
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return lines.join("\n").replace(/\n+$/, "\n");
|
|
105
|
+
}
|