doccupine 0.0.123 → 0.0.125
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/templates/components/MDXComponents.d.ts +1 -1
- package/dist/templates/components/MDXComponents.js +4 -2
- package/dist/templates/components/layout/Card.d.ts +1 -1
- package/dist/templates/components/layout/Card.js +2 -2
- package/dist/templates/components/layout/Slug.d.ts +1 -1
- package/dist/templates/components/layout/Slug.js +1 -1
- package/dist/templates/components/layout/Steps.d.ts +1 -1
- package/dist/templates/components/layout/Steps.js +7 -5
- package/dist/templates/components/layout/Update.d.ts +1 -1
- package/dist/templates/components/layout/Update.js +8 -3
- package/dist/templates/mdx/cards.mdx.d.ts +1 -1
- package/dist/templates/mdx/cards.mdx.js +2 -2
- package/dist/templates/mdx/steps.mdx.d.ts +1 -1
- package/dist/templates/mdx/steps.mdx.js +2 -2
- package/dist/templates/mdx/update.mdx.d.ts +1 -1
- package/dist/templates/mdx/update.mdx.js +2 -2
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const mdxComponentsTemplate = "import React from \"react\";\nimport Link from \"next/link\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype MDXComponents = Record<string, React.ComponentType<any>>;\nimport { Space } from \"cherry-styled-components\";\nimport { Code as CodeBlock, CodeTabs } from \"@/components/layout/Code\";\nimport { Card } from \"@/components/layout/Card\";\nimport { Accordion } from \"@/components/layout/Accordion\";\nimport { Tabs, TabContent } from \"@/components/layout/Tabs\";\nimport { Callout } from \"@/components/layout/Callout\";\nimport { Icon } from \"@/components/layout/Icon\";\nimport { Columns } from \"@/components/layout/Columns\";\nimport { Field } from \"@/components/layout/Field\";\nimport { Update } from \"@/components/layout/Update\";\nimport { Steps, Step } from \"@/components/layout/Steps\";\nimport { Button } from \"@/components/layout/Button\";\nimport { ColorSwatch, ColorSwatchGroup } from \"@/components/layout/ColorSwatch\";\nimport { DemoTheme } from \"@/components/layout/DemoTheme\";\nimport { createSlugger } from \"@/components/layout/Slug\";\n\ninterface HeadingProps extends React.HTMLAttributes<HTMLHeadingElement> {\n children?: React.ReactNode;\n}\n\ninterface PreProps extends React.HTMLAttributes<HTMLPreElement> {\n children?: React.ReactNode;\n}\n\nfunction extractAllTextFromChildren(children: React.ReactNode): string {\n if (children == null) return \"\";\n if (typeof children === \"string\") return children;\n if (typeof children === \"number\") return String(children);\n if (typeof children === \"boolean\") return \"\";\n if (Array.isArray(children))\n return children.map(extractAllTextFromChildren).join(\"\");\n if (React.isValidElement(children)) {\n const element = children as React.ReactElement<{\n children?: React.ReactNode;\n }>;\n return extractAllTextFromChildren(element.props.children);\n }\n return \"\";\n}\n\n// Map <pre><code class=\"language-xyz\"> to our <Code /> component\nfunction Pre(props: PreProps) {\n const child = React.Children.only(props.children) as React.ReactElement<{\n className?: string;\n children?: React.ReactNode;\n }> | null;\n if (child && child.type === \"code\") {\n const className = child.props.className || \"\";\n const match = /language-(\\w+)/.exec(className);\n const language = match ? match[1] : undefined;\n const code = extractAllTextFromChildren(child.props.children).replace(\n /\\n$/,\n \"\",\n );\n if (language) {\n return (\n <CodeBlock className={className} code={code} language={language} />\n );\n }\n }\n return <pre {...props} />;\n}\n\nexport function useMDXComponents(components: MDXComponents): MDXComponents {\n // One slugger per render so repeated heading text (and <Update> labels)\n // resolve to unique, document-order ids that match the index sidebar built\n // in components/Docs.tsx.\n const slug = createSlugger();\n return {\n // Headings with auto-generated ids for TOC and deep links\n h1: ({ children, ...props }: HeadingProps) => {\n const id = slug(extractAllTextFromChildren(children));\n return (\n <h1 id={id} {...props}>\n {children}\n </h1>\n );\n },\n h2: ({ children, ...props }: HeadingProps) => {\n const id = slug(extractAllTextFromChildren(children));\n return (\n <h2 id={id} {...props}>\n {children}\n </h2>\n );\n },\n h3: ({ children, ...props }: HeadingProps) => {\n const id = slug(extractAllTextFromChildren(children));\n return (\n <h3 id={id} {...props}>\n {children}\n </h3>\n );\n },\n h4: ({ children, ...props }: HeadingProps) => {\n const id = slug(extractAllTextFromChildren(children));\n return (\n <h4 id={id} {...props}>\n {children}\n </h4>\n );\n },\n h5: ({ children, ...props }: HeadingProps) => {\n const id = slug(extractAllTextFromChildren(children));\n return (\n <h5 id={id} {...props}>\n {children}\n </h5>\n );\n },\n h6: ({ children, ...props }: HeadingProps) => {\n const id = slug(extractAllTextFromChildren(children));\n return (\n <h6 id={id} {...props}>\n {children}\n </h6>\n );\n },\n\n // Links - use Next.js Link for internal paths\n a: ({\n href,\n children,\n ...props\n }: React.AnchorHTMLAttributes<HTMLAnchorElement>) => {\n if (href && href.startsWith(\"/\")) {\n return (\n <Link href={href} {...props}>\n {children}\n </Link>\n );\n }\n return (\n <a href={href} target=\"_blank\" rel=\"noopener noreferrer\" {...props}>\n {children}\n </a>\n );\n },\n\n // Tables - wrap in a div for responsive overflow\n table: (props: React.TableHTMLAttributes<HTMLTableElement>) => (\n <div className=\"table-wrapper\">\n <table {...props} />\n </div>\n ),\n\n // Code blocks\n pre: Pre,\n\n // Expose your custom components for MDX usage\n Code: CodeBlock,\n CodeTabs,\n Card,\n Accordion,\n Tabs,\n TabContent,\n Callout,\n Icon,\n Columns,\n Field,\n // Share the heading slugger so an <Update> label anchor stays unique and\n // in document order alongside the surrounding headings.\n Update: (props: React.ComponentProps<typeof Update>) => (\n <Update {...props} id={slug(props.label)} />\n ),\n Steps,\n Step,\n Button,\n ColorSwatch,\n ColorSwatchGroup,\n DemoTheme,\n Space,\n ...components,\n };\n}\n";
|
|
1
|
+
export declare const mdxComponentsTemplate = "import React from \"react\";\nimport Link from \"next/link\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype MDXComponents = Record<string, React.ComponentType<any>>;\nimport { Space } from \"cherry-styled-components\";\nimport { Code as CodeBlock, CodeTabs } from \"@/components/layout/Code\";\nimport { Card } from \"@/components/layout/Card\";\nimport { Accordion } from \"@/components/layout/Accordion\";\nimport { Tabs, TabContent } from \"@/components/layout/Tabs\";\nimport { Callout } from \"@/components/layout/Callout\";\nimport { Icon } from \"@/components/layout/Icon\";\nimport { Columns } from \"@/components/layout/Columns\";\nimport { Field } from \"@/components/layout/Field\";\nimport { Update } from \"@/components/layout/Update\";\nimport { Steps, Step } from \"@/components/layout/Steps\";\nimport { Button } from \"@/components/layout/Button\";\nimport { ColorSwatch, ColorSwatchGroup } from \"@/components/layout/ColorSwatch\";\nimport { DemoTheme } from \"@/components/layout/DemoTheme\";\nimport { createSlugger } from \"@/components/layout/Slug\";\n\ninterface HeadingProps extends React.HTMLAttributes<HTMLHeadingElement> {\n children?: React.ReactNode;\n}\n\ninterface PreProps extends React.HTMLAttributes<HTMLPreElement> {\n children?: React.ReactNode;\n}\n\nfunction extractAllTextFromChildren(children: React.ReactNode): string {\n if (children == null) return \"\";\n if (typeof children === \"string\") return children;\n if (typeof children === \"number\") return String(children);\n if (typeof children === \"boolean\") return \"\";\n if (Array.isArray(children))\n return children.map(extractAllTextFromChildren).join(\"\");\n if (React.isValidElement(children)) {\n const element = children as React.ReactElement<{\n children?: React.ReactNode;\n }>;\n return extractAllTextFromChildren(element.props.children);\n }\n return \"\";\n}\n\n// Map <pre><code class=\"language-xyz\"> to our <Code /> component\nfunction Pre(props: PreProps) {\n const child = React.Children.only(props.children) as React.ReactElement<{\n className?: string;\n children?: React.ReactNode;\n }> | null;\n if (child && child.type === \"code\") {\n const className = child.props.className || \"\";\n const match = /language-(\\w+)/.exec(className);\n const language = match ? match[1] : undefined;\n const code = extractAllTextFromChildren(child.props.children).replace(\n /\\n$/,\n \"\",\n );\n if (language) {\n return (\n <CodeBlock className={className} code={code} language={language} />\n );\n }\n }\n return <pre {...props} />;\n}\n\nexport function useMDXComponents(components: MDXComponents): MDXComponents {\n // One slugger per render so repeated heading text (and <Update> labels)\n // resolve to unique, document-order ids that match the index sidebar built\n // in components/Docs.tsx.\n const slug = createSlugger();\n return {\n // Headings with auto-generated ids for TOC and deep links\n h1: ({ children, ...props }: HeadingProps) => {\n const id = slug(extractAllTextFromChildren(children));\n return (\n <h1 id={id} {...props}>\n {children}\n </h1>\n );\n },\n h2: ({ children, ...props }: HeadingProps) => {\n const id = slug(extractAllTextFromChildren(children));\n return (\n <h2 id={id} {...props}>\n {children}\n </h2>\n );\n },\n h3: ({ children, ...props }: HeadingProps) => {\n const id = slug(extractAllTextFromChildren(children));\n return (\n <h3 id={id} {...props}>\n {children}\n </h3>\n );\n },\n h4: ({ children, ...props }: HeadingProps) => {\n const id = slug(extractAllTextFromChildren(children));\n return (\n <h4 id={id} {...props}>\n {children}\n </h4>\n );\n },\n h5: ({ children, ...props }: HeadingProps) => {\n const id = slug(extractAllTextFromChildren(children));\n return (\n <h5 id={id} {...props}>\n {children}\n </h5>\n );\n },\n h6: ({ children, ...props }: HeadingProps) => {\n const id = slug(extractAllTextFromChildren(children));\n return (\n <h6 id={id} {...props}>\n {children}\n </h6>\n );\n },\n\n // Links - use Next.js Link for internal paths\n a: ({\n href,\n children,\n ...props\n }: React.AnchorHTMLAttributes<HTMLAnchorElement>) => {\n if (href && href.startsWith(\"/\")) {\n return (\n <Link href={href} {...props}>\n {children}\n </Link>\n );\n }\n return (\n <a href={href} target=\"_blank\" rel=\"noopener noreferrer\" {...props}>\n {children}\n </a>\n );\n },\n\n // Tables - wrap in a div for responsive overflow\n table: (props: React.TableHTMLAttributes<HTMLTableElement>) => (\n <div className=\"table-wrapper\">\n <table {...props} />\n </div>\n ),\n\n // Code blocks\n pre: Pre,\n\n // Expose your custom components for MDX usage\n Code: CodeBlock,\n CodeTabs,\n Card,\n Accordion,\n Tabs,\n TabContent,\n Callout,\n Icon,\n Columns,\n Field,\n // Share the heading slugger so an <Update> label anchor stays unique and\n // in document order alongside the surrounding headings. Only consume a\n // slug when a label is present so a label-less <Update> does not crash the\n // slugger (Update itself renders gracefully without a label anchor).\n Update: (props: React.ComponentProps<typeof Update>) => (\n <Update {...props} id={props.label ? slug(props.label) : undefined} />\n ),\n Steps,\n Step,\n Button,\n ColorSwatch,\n ColorSwatchGroup,\n DemoTheme,\n Space,\n ...components,\n };\n}\n";
|
|
@@ -164,9 +164,11 @@ export function useMDXComponents(components: MDXComponents): MDXComponents {
|
|
|
164
164
|
Columns,
|
|
165
165
|
Field,
|
|
166
166
|
// Share the heading slugger so an <Update> label anchor stays unique and
|
|
167
|
-
// in document order alongside the surrounding headings.
|
|
167
|
+
// in document order alongside the surrounding headings. Only consume a
|
|
168
|
+
// slug when a label is present so a label-less <Update> does not crash the
|
|
169
|
+
// slugger (Update itself renders gracefully without a label anchor).
|
|
168
170
|
Update: (props: React.ComponentProps<typeof Update>) => (
|
|
169
|
-
<Update {...props} id={slug(props.label)} />
|
|
171
|
+
<Update {...props} id={props.label ? slug(props.label) : undefined} />
|
|
170
172
|
),
|
|
171
173
|
Steps,
|
|
172
174
|
Step,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const cardTemplate = "\"use client\";\nimport Link from \"next/link\";\nimport styled, { css, useTheme } from \"styled-components\";\nimport { styledText } from \"cherry-styled-components\";\nimport { Theme } from \"@/app/theme\";\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.p<{ theme: Theme }>`\n font-weight: bold;\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
|
|
1
|
+
export declare const cardTemplate = "\"use client\";\nimport Link from \"next/link\";\nimport styled, { css, useTheme } from \"styled-components\";\nimport { styledText } from \"cherry-styled-components\";\nimport { Theme } from \"@/app/theme\";\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.p<{ theme: Theme }>`\n font-weight: bold;\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 {title && <StyledCardTitle>{title}</StyledCardTitle>}\n {children}\n </>\n );\n\n if (href) {\n const isExternal = /^(https?:)?\\/\\//i.test(href);\n return (\n <StyledCardLink\n href={href}\n target={isExternal ? \"_blank\" : undefined}\n rel={isExternal ? \"noopener noreferrer\" : undefined}\n >\n {content}\n </StyledCardLink>\n );\n }\n\n return <StyledCard>{content}</StyledCard>;\n}\n\nexport { Card };\n";
|
|
@@ -35,7 +35,7 @@ const StyledCardTitle = styled.p<{ theme: Theme }>\`
|
|
|
35
35
|
|
|
36
36
|
interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
37
37
|
children: React.ReactNode;
|
|
38
|
-
title
|
|
38
|
+
title?: string;
|
|
39
39
|
icon?: IconProps;
|
|
40
40
|
href?: string;
|
|
41
41
|
}
|
|
@@ -46,7 +46,7 @@ function Card({ children, title, icon, href }: CardProps) {
|
|
|
46
46
|
const content = (
|
|
47
47
|
<>
|
|
48
48
|
{icon && <Icon name={icon} color={theme.colors.primary} />}
|
|
49
|
-
<StyledCardTitle>{title}</StyledCardTitle>
|
|
49
|
+
{title && <StyledCardTitle>{title}</StyledCardTitle>}
|
|
50
50
|
{children}
|
|
51
51
|
</>
|
|
52
52
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const slugTemplate = "// Shared heading/anchor id helpers.\n//\n// `slugify` turns heading text into a URL-safe base slug. `createSlugger`\n// wraps it with occurrence-based de-duplication so repeated heading text\n// yields stable, unique ids (\"setup\", \"setup-1\", \"setup-2\", ...) matching\n// the scheme used by GitHub and rehype-slug.\n//\n// The index sidebar (components/Docs.tsx) and the rendered headings\n// (components/MDXComponents.tsx, components/layout/Update.tsx) must walk the\n// document in the same order with a shared slugger so every sidebar link\n// resolves to exactly one heading.\n\nexport function slugify(text: string): string {\n return text\n .toLowerCase()\n .replace(/[^\\w\\s-]/g, \"\")\n .replace(/\\s+/g, \"-\")\n .trim();\n}\n\nexport type Slugger = (text: string) => string;\n\nexport function createSlugger(): Slugger {\n const seen = new Map<string, number>();\n return (text: string) => {\n const base = slugify(text);\n const count = seen.get(base) ?? 0;\n seen.set(base, count + 1);\n return count === 0 ? base : `${base}-${count}`;\n };\n}\n";
|
|
1
|
+
export declare const slugTemplate = "// Shared heading/anchor id helpers.\n//\n// `slugify` turns heading text into a URL-safe base slug. `createSlugger`\n// wraps it with occurrence-based de-duplication so repeated heading text\n// yields stable, unique ids (\"setup\", \"setup-1\", \"setup-2\", ...) matching\n// the scheme used by GitHub and rehype-slug.\n//\n// The index sidebar (components/Docs.tsx) and the rendered headings\n// (components/MDXComponents.tsx, components/layout/Update.tsx) must walk the\n// document in the same order with a shared slugger so every sidebar link\n// resolves to exactly one heading.\n\nexport function slugify(text: string): string {\n return (text ?? \"\")\n .toLowerCase()\n .replace(/[^\\w\\s-]/g, \"\")\n .replace(/\\s+/g, \"-\")\n .trim();\n}\n\nexport type Slugger = (text: string) => string;\n\nexport function createSlugger(): Slugger {\n const seen = new Map<string, number>();\n return (text: string) => {\n const base = slugify(text);\n const count = seen.get(base) ?? 0;\n seen.set(base, count + 1);\n return count === 0 ? base : `${base}-${count}`;\n };\n}\n";
|
|
@@ -11,7 +11,7 @@ export const slugTemplate = `// Shared heading/anchor id helpers.
|
|
|
11
11
|
// resolves to exactly one heading.
|
|
12
12
|
|
|
13
13
|
export function slugify(text: string): string {
|
|
14
|
-
return text
|
|
14
|
+
return (text ?? "")
|
|
15
15
|
.toLowerCase()
|
|
16
16
|
.replace(/[^\\w\\s-]/g, "")
|
|
17
17
|
.replace(/\\s+/g, "-")
|
|
@@ -1 +1 @@
|
|
|
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.div<{ 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 font-weight: 700;\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
|
|
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.div<{ 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 font-weight: 700;\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 {(title || icon) && (\n <StyledStepTitle theme={theme}>\n {icon && <Icon name={icon} color={theme.colors.primary} />}\n {title}\n </StyledStepTitle>\n )}\n <StepContent theme={theme}>{stepContent}</StepContent>\n </StyledStep>\n );\n })}\n </StyledStepsContainer>\n );\n}\n\nexport { Steps, Step };\n";
|
|
@@ -75,7 +75,7 @@ const StepContent = styled.div<{ theme: Theme }>\`
|
|
|
75
75
|
\`;
|
|
76
76
|
|
|
77
77
|
interface StepProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
78
|
-
title
|
|
78
|
+
title?: string;
|
|
79
79
|
children: React.ReactNode;
|
|
80
80
|
icon?: IconProps;
|
|
81
81
|
}
|
|
@@ -104,10 +104,12 @@ function Steps({ children }: StepsProps) {
|
|
|
104
104
|
return (
|
|
105
105
|
<StyledStep key={index} theme={theme}>
|
|
106
106
|
<StepNumber theme={theme}>{index + 1}</StepNumber>
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
107
|
+
{(title || icon) && (
|
|
108
|
+
<StyledStepTitle theme={theme}>
|
|
109
|
+
{icon && <Icon name={icon} color={theme.colors.primary} />}
|
|
110
|
+
{title}
|
|
111
|
+
</StyledStepTitle>
|
|
112
|
+
)}
|
|
111
113
|
<StepContent theme={theme}>{stepContent}</StepContent>
|
|
112
114
|
</StyledStep>
|
|
113
115
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const updateTemplate = "\"use client\";\nimport styled from \"styled-components\";\nimport { styledSmall } from \"cherry-styled-components\";\nimport { mq, Theme } from \"@/app/theme\";\nimport { slugify } from \"@/components/layout/Slug\";\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.a<{ theme: Theme }>`\n display: inline-block;\n width: fit-content;\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 text-decoration: none;\n ${({ theme }) => styledSmall(theme)};\n\n &:hover {\n background: ${({ theme }) =>\n `color-mix(in srgb, ${theme.colors.primaryLight} 35%, transparent)`};\n }\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
|
|
1
|
+
export declare const updateTemplate = "\"use client\";\nimport styled from \"styled-components\";\nimport { styledSmall } from \"cherry-styled-components\";\nimport { mq, Theme } from \"@/app/theme\";\nimport { slugify } from \"@/components/layout/Slug\";\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.a<{ theme: Theme }>`\n display: inline-block;\n width: fit-content;\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 text-decoration: none;\n ${({ theme }) => styledSmall(theme)};\n\n &:hover {\n background: ${({ theme }) =>\n `color-mix(in srgb, ${theme.colors.primaryLight} 35%, transparent)`};\n }\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 position: sticky;\n top: 80px;\n align-self: flex-start;\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 = \"Label\", description, id }: UpdateProps) {\n // MDXComponents injects a de-duplicated id from the shared slugger so the\n // index sidebar anchor resolves here; fall back to a plain slug when used\n // outside the MDX pipeline. The label doubles as an anchor so readers can\n // right-click to copy the deep link (native #anchor jump is offset by the\n // global scroll-padding-top).\n const anchor = id ?? slugify(label);\n return (\n <StyledUpdate id={anchor}>\n <StyledUpdateSidebar>\n <div>\n <StyledUpdateLabel href={`#${anchor}`}>{label}</StyledUpdateLabel>\n </div>\n {description && (\n <StyledUpdateDescription>{description}</StyledUpdateDescription>\n )}\n </StyledUpdateSidebar>\n <StyledUpdateChildren>{children}</StyledUpdateChildren>\n </StyledUpdate>\n );\n}\n\nexport { Update };\n";
|
|
@@ -45,6 +45,9 @@ const StyledUpdateSidebar = styled.div\`
|
|
|
45
45
|
gap: 10px;
|
|
46
46
|
|
|
47
47
|
\${mq("lg")} {
|
|
48
|
+
position: sticky;
|
|
49
|
+
top: 80px;
|
|
50
|
+
align-self: flex-start;
|
|
48
51
|
min-width: 160px;
|
|
49
52
|
}
|
|
50
53
|
\`;
|
|
@@ -59,10 +62,10 @@ const StyledUpdateChildren = styled.div\`
|
|
|
59
62
|
interface UpdateProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
60
63
|
children: React.ReactNode;
|
|
61
64
|
label: string;
|
|
62
|
-
description
|
|
65
|
+
description?: string;
|
|
63
66
|
}
|
|
64
67
|
|
|
65
|
-
function Update({ children, label, description, id }: UpdateProps) {
|
|
68
|
+
function Update({ children, label = "Label", description, id }: UpdateProps) {
|
|
66
69
|
// MDXComponents injects a de-duplicated id from the shared slugger so the
|
|
67
70
|
// index sidebar anchor resolves here; fall back to a plain slug when used
|
|
68
71
|
// outside the MDX pipeline. The label doubles as an anchor so readers can
|
|
@@ -75,7 +78,9 @@ function Update({ children, label, description, id }: UpdateProps) {
|
|
|
75
78
|
<div>
|
|
76
79
|
<StyledUpdateLabel href={\`#\${anchor}\`}>{label}</StyledUpdateLabel>
|
|
77
80
|
</div>
|
|
78
|
-
|
|
81
|
+
{description && (
|
|
82
|
+
<StyledUpdateDescription>{description}</StyledUpdateDescription>
|
|
83
|
+
)}
|
|
79
84
|
</StyledUpdateSidebar>
|
|
80
85
|
<StyledUpdateChildren>{children}</StyledUpdateChildren>
|
|
81
86
|
</StyledUpdate>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const cardsMdxTemplate = "---\ntitle: \"Cards\"\ndescription: \"Cards act as visual containers for your content, giving you flexibility to combine text, icons, images, and links in a clean and organized way.\"\ndate: \"2026-02-19\"\ncategory: \"Components\"\ncategoryOrder: 1\norder: 6\n---\n\n# Cards\n\nDuplicate a page or section with ease, then emphasize important information or links using customizable layouts and icons.\n\nCards act as visual containers for your content, giving you flexibility to combine text, icons, images, and links in a clean and organized way.\n\n## Cards Usage\n\nYou can use the Cards component directly within your MDX files without any import. The following example shows a basic usage:\n\n```html\n<Card title=\"Note\" icon=\"badge-info\">\n Doccupine CLI is a command-line tool that helps you create and manage your\n Doccupine project. It provides a simple and intuitive interface for creating\n and configuring your project.\n</Card>\n```\n\n<Card title=\"Note\" icon=\"badge-info\">\n Doccupine CLI is a command-line tool that helps you create and manage your Doccupine project. It provides a simple and intuitive interface for creating and configuring your project.\n</Card>\n\n## Link Card\n\nPass a `href` prop to turn the card into a clickable link. The card will display interactive hover and focus styles automatically.\n\n```html\n<Card title=\"Getting Started\" icon=\"rocket\" href=\"/cards\">\n Learn how to set up Doccupine and create your first documentation site.\n</Card>\n```\n\n<Card title=\"Getting Started\" icon=\"rocket\" href=\"/cards\">\n Learn how to set up Doccupine and create your first documentation site.\n</Card>\n\n## Properties\n\n<Field value=\"title\" type=\"string\"
|
|
1
|
+
export declare const cardsMdxTemplate = "---\ntitle: \"Cards\"\ndescription: \"Cards act as visual containers for your content, giving you flexibility to combine text, icons, images, and links in a clean and organized way.\"\ndate: \"2026-02-19\"\ncategory: \"Components\"\ncategoryOrder: 1\norder: 6\n---\n\n# Cards\n\nDuplicate a page or section with ease, then emphasize important information or links using customizable layouts and icons.\n\nCards act as visual containers for your content, giving you flexibility to combine text, icons, images, and links in a clean and organized way.\n\n## Cards Usage\n\nYou can use the Cards component directly within your MDX files without any import. The following example shows a basic usage:\n\n```html\n<Card title=\"Note\" icon=\"badge-info\">\n Doccupine CLI is a command-line tool that helps you create and manage your\n Doccupine project. It provides a simple and intuitive interface for creating\n and configuring your project.\n</Card>\n```\n\n<Card title=\"Note\" icon=\"badge-info\">\n Doccupine CLI is a command-line tool that helps you create and manage your Doccupine project. It provides a simple and intuitive interface for creating and configuring your project.\n</Card>\n\n## Link Card\n\nPass a `href` prop to turn the card into a clickable link. The card will display interactive hover and focus styles automatically.\n\n```html\n<Card title=\"Getting Started\" icon=\"rocket\" href=\"/cards\">\n Learn how to set up Doccupine and create your first documentation site.\n</Card>\n```\n\n<Card title=\"Getting Started\" icon=\"rocket\" href=\"/cards\">\n Learn how to set up Doccupine and create your first documentation site.\n</Card>\n\n## Properties\n\n<Field value=\"title\" type=\"string\">\n An optional title for the card. When omitted, the card renders without a title.\n</Field>\n\n<Field value=\"icon\" type=\"string\">\n The [Lucide](https://lucide.dev/icons) icon name to display in the card.\n</Field>\n\n<Field value=\"href\" type=\"string\">\n A URL or path to link to. When provided, the card becomes a clickable link with interactive styles.\n</Field>\n\n<Field value=\"children\" type=\"node\" required>\n The content of the card.\n</Field>";
|
|
@@ -45,8 +45,8 @@ Pass a \`href\` prop to turn the card into a clickable link. The card will displ
|
|
|
45
45
|
|
|
46
46
|
## Properties
|
|
47
47
|
|
|
48
|
-
<Field value="title" type="string"
|
|
49
|
-
|
|
48
|
+
<Field value="title" type="string">
|
|
49
|
+
An optional title for the card. When omitted, the card renders without a title.
|
|
50
50
|
</Field>
|
|
51
51
|
|
|
52
52
|
<Field value="icon" type="string">
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const stepsMdxTemplate = "---\ntitle: \"Steps\"\ndescription: \"Guide readers step-by-step using the Steps component.\"\ndate: \"2026-02-19\"\ncategory: \"Components\"\ncategoryOrder: 1\norder: 14\n---\n\n# Steps\n\nGuide readers step-by-step using the Steps component.\n\nThe Steps component is perfect for organizing procedures or workflows in a clear sequence. Include as many individual steps as necessary to outline your process.\n\n## Steps Usage\n\nYou can use the `Steps` component to create a step-by-step guide. Each step is represented by a `Step` component, which includes a title and content.\n\n```html\n<Steps>\n <Step title=\"Step 1\">\n Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n </Step>\n <Step title=\"Step 2\">\n Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n </Step>\n <Step title=\"Step 3\">\n Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n </Step>\n</Steps>\n```\n\n<Steps>\n <Step title=\"Step 1\">\n Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n </Step>\n <Step title=\"Step 2\">\n Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n </Step>\n <Step title=\"Step 3\">\n Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n </Step>\n</Steps>\n\n## Properties\n\n<Field value=\"title\" type=\"string\"
|
|
1
|
+
export declare const stepsMdxTemplate = "---\ntitle: \"Steps\"\ndescription: \"Guide readers step-by-step using the Steps component.\"\ndate: \"2026-02-19\"\ncategory: \"Components\"\ncategoryOrder: 1\norder: 14\n---\n\n# Steps\n\nGuide readers step-by-step using the Steps component.\n\nThe Steps component is perfect for organizing procedures or workflows in a clear sequence. Include as many individual steps as necessary to outline your process.\n\n## Steps Usage\n\nYou can use the `Steps` component to create a step-by-step guide. Each step is represented by a `Step` component, which includes a title and content.\n\n```html\n<Steps>\n <Step title=\"Step 1\">\n Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n </Step>\n <Step title=\"Step 2\">\n Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n </Step>\n <Step title=\"Step 3\">\n Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n </Step>\n</Steps>\n```\n\n<Steps>\n <Step title=\"Step 1\">\n Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n </Step>\n <Step title=\"Step 2\">\n Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n </Step>\n <Step title=\"Step 3\">\n Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n </Step>\n</Steps>\n\n## Properties\n\n<Field value=\"title\" type=\"string\">\n An optional title for the step. When omitted, the step renders without a title row.\n</Field>\n\n<Field value=\"icon\" type=\"string\">\n A [Lucide](https://lucide.dev/icons) icon name shown next to the step title.\n</Field>\n\n<Field value=\"children\" type=\"node\" required>\n The content of the step.\n</Field>";
|
|
@@ -45,8 +45,8 @@ You can use the \`Steps\` component to create a step-by-step guide. Each step is
|
|
|
45
45
|
|
|
46
46
|
## Properties
|
|
47
47
|
|
|
48
|
-
<Field value="title" type="string"
|
|
49
|
-
|
|
48
|
+
<Field value="title" type="string">
|
|
49
|
+
An optional title for the step. When omitted, the step renders without a title row.
|
|
50
50
|
</Field>
|
|
51
51
|
|
|
52
52
|
<Field value="icon" type="string">
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const updateMdxTemplate = "---\ntitle: \"Update\"\ndescription: \"Easily manage and present change history.\"\ndate: \"2026-02-19\"\ncategory: \"Components\"\ncategoryOrder: 1\norder: 12\n---\n\n# Update\n\nEasily manage and present change history.\n\nThe `Update` component helps you display release notes, version details, and changelogs in a standardized format.\n\nEach `Update` label is added to the \"On this page\" sidebar and gets its own anchor, so you can link directly to a specific entry.\n\n<Update label=\"v0.0.1\" description=\"Example\">\n ## Example entry\n\n You can include anything here - images, code snippets, or a bullet list of modifications.\n\n \n\n ### Key additions\n\n - Fully responsive layout\n - Individual anchor for each update\n - Automatic RSS feed entry generation\n</Update>\n\n## Update Usage\n\nYou can combine multiple `Update` components to build complete changelogs.\n\n```html\n<Update label=\"v0.0.1\" description=\"Example\">\n ## Example entry\n\n You can include anything here - images, code snippets, or a bullet list of modifications.\n\n \n\n ### Key additions\n\n - Fully responsive layout\n - Individual anchor for each update\n - Automatic RSS feed entry generation\n</Update>\n```\n\n## Properties\n\n<Field value=\"label\" type=\"string\" required>\n The label of the update. It also appears in the page's \"On this page\"\n navigation and acts as a deep-link anchor to this entry.\n</Field>\n\n<Field value=\"description\" type=\"string\"
|
|
1
|
+
export declare const updateMdxTemplate = "---\ntitle: \"Update\"\ndescription: \"Easily manage and present change history.\"\ndate: \"2026-02-19\"\ncategory: \"Components\"\ncategoryOrder: 1\norder: 12\n---\n\n# Update\n\nEasily manage and present change history.\n\nThe `Update` component helps you display release notes, version details, and changelogs in a standardized format.\n\nEach `Update` label is added to the \"On this page\" sidebar and gets its own anchor, so you can link directly to a specific entry.\n\n<Update label=\"v0.0.1\" description=\"Example\">\n ## Example entry\n\n You can include anything here - images, code snippets, or a bullet list of modifications.\n\n \n\n ### Key additions\n\n - Fully responsive layout\n - Individual anchor for each update\n - Automatic RSS feed entry generation\n</Update>\n\n## Update Usage\n\nYou can combine multiple `Update` components to build complete changelogs.\n\n```html\n<Update label=\"v0.0.1\" description=\"Example\">\n ## Example entry\n\n You can include anything here - images, code snippets, or a bullet list of modifications.\n\n \n\n ### Key additions\n\n - Fully responsive layout\n - Individual anchor for each update\n - Automatic RSS feed entry generation\n</Update>\n```\n\n## Properties\n\n<Field value=\"label\" type=\"string\" required>\n The label of the update. It also appears in the page's \"On this page\"\n navigation and acts as a deep-link anchor to this entry.\n</Field>\n\n<Field value=\"description\" type=\"string\">\n An optional description for the update. When omitted, no description is shown.\n</Field>\n\n<Field value=\"children\" type=\"node\" required>\n The content of the update.\n</Field>";
|
|
@@ -56,8 +56,8 @@ You can combine multiple \`Update\` components to build complete changelogs.
|
|
|
56
56
|
navigation and acts as a deep-link anchor to this entry.
|
|
57
57
|
</Field>
|
|
58
58
|
|
|
59
|
-
<Field value="description" type="string"
|
|
60
|
-
|
|
59
|
+
<Field value="description" type="string">
|
|
60
|
+
An optional description for the update. When omitted, no description is shown.
|
|
61
61
|
</Field>
|
|
62
62
|
|
|
63
63
|
<Field value="children" type="node" required>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "doccupine",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.125",
|
|
4
4
|
"description": "Free and open-source documentation platform. Write MDX, get a production-ready site with AI chat, built-in components, and an MCP server - in one command.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|