diff --git a/docs/package.json b/docs/package.json index 81898ab..0287ffb 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "akiradocs", - "version": "1.0.47", + "version": "1.0.52", "private": true, "scripts": { "translate": "npm run compile && node scripts/translate.js", diff --git a/docs/public/context/en_docs.txt b/docs/public/context/en_docs.txt index 8078524..762054a 100644 --- a/docs/public/context/en_docs.txt +++ b/docs/public/context/en_docs.txt @@ -358,55 +358,6 @@ Context-aware translations Technical term preservation Format maintenance ------------- -[Document: docs/guides/analytics.json] -Title: Analytics Integration -Learn how to add analytics tracking to your documentation -AkiraDocs supports Google Analytics 4 (GA4) out of the box. This guide will help you set up analytics tracking for your documentation. -Setting up Google Analytics -1. Create a Google Analytics 4 property in your [Google Analytics account](https://analytics.google.com/) -2. Get your Measurement ID (starts with "G-") -3. Add the ID to your `akiradocs.config.json`: -Code example: -{ -"analytics": { -"google": { -"measurementId": "G-XXXXXXXXXX", -"enabled": true -}, -"debug": false -} -} -What's Tracked Automatically -Page views -Navigation between pages -Time on page -User language preferences -Device and browser information -Custom Event Tracking -You can track custom events using the `useAnalytics` hook: -Code example: -import { useAnalytics } from '@/hooks/useAnalytics' -function MyComponent() { - const { track } = useAnalytics() - const handleClick = () => { - track('doc_rating', { - rating: 5, - page: 'getting-started', - helpful: true - }) - } - return -} -Debug Mode -Enable debug mode to see analytics events in the console during development: -Code example: -{ -"analytics": { -"debug": true -} -} -This provides a complete analytics integration that's easy for users to set up and extend as needed. -------------- [Document: docs/installation/troubleshooting.json] Title: Troubleshooting Guide Common issues and their solutions when setting up AkiraDocs. @@ -630,6 +581,55 @@ Code example: }, } ------------- +[Document: docs/guides/analytics.json] +Title: Analytics Integration +Learn how to add analytics tracking to your documentation +AkiraDocs supports Google Analytics 4 (GA4) out of the box. This guide will help you set up analytics tracking for your documentation. +Setting up Google Analytics +1. Create a Google Analytics 4 property in your [Google Analytics account](https://analytics.google.com/) +2. Get your Measurement ID (starts with "G-") +3. Add the ID to your `akiradocs.config.json`: +Code example: +{ +"analytics": { +"google": { +"measurementId": "G-XXXXXXXXXX", +"enabled": true +}, +"debug": false +} +} +What's Tracked Automatically +Page views +Navigation between pages +Time on page +User language preferences +Device and browser information +Custom Event Tracking +You can track custom events using the `useAnalytics` hook: +Code example: +import { useAnalytics } from '@/hooks/useAnalytics' +function MyComponent() { + const { track } = useAnalytics() + const handleClick = () => { + track('doc_rating', { + rating: 5, + page: 'getting-started', + helpful: true + }) + } + return +} +Debug Mode +Enable debug mode to see analytics events in the console during development: +Code example: +{ +"analytics": { +"debug": true +} +} +This provides a complete analytics integration that's easy for users to set up and extend as needed. +------------- [Document: docs/getting-started/requirements.json] Title: System Requirements Before installing AkiraDocs, ensure your environment meets the following requirements. diff --git a/docs/public/sitemap.xml b/docs/public/sitemap.xml index 14340cc..7e8d931 100644 --- a/docs/public/sitemap.xml +++ b/docs/public/sitemap.xml @@ -1,6 +1,10 @@ + + https://docs.akiradocs.com/manifest + + https://docs.akiradocs.com/fr/docs/introduction @@ -9,16 +13,92 @@ https://docs.akiradocs.com/fr/docs/_meta + + https://docs.akiradocs.com/fr/docs/seo-and-performance/sitemap-generation + + + + https://docs.akiradocs.com/fr/docs/seo-and-performance/robot-txt + + + + https://docs.akiradocs.com/fr/docs/internationalization/setup + + + + https://docs.akiradocs.com/fr/docs/internationalization/managing-translation + + + + https://docs.akiradocs.com/fr/docs/internationalization/ai-translation + + + + https://docs.akiradocs.com/fr/docs/installation/troubleshooting + + + + https://docs.akiradocs.com/fr/docs/installation/setup + + + + https://docs.akiradocs.com/fr/docs/installation/configuration + + + + https://docs.akiradocs.com/fr/docs/guides/analytics + + + + https://docs.akiradocs.com/fr/docs/getting-started/requirements + + https://docs.akiradocs.com/fr/docs/getting-started/quickstart - https://docs.akiradocs.com/fr/articles/welcome + https://docs.akiradocs.com/fr/docs/getting-started/features - https://docs.akiradocs.com/fr/articles/template + https://docs.akiradocs.com/fr/docs/editor/overview + + + + https://docs.akiradocs.com/fr/docs/editor/getting-started + + + + https://docs.akiradocs.com/fr/docs/editor/features + + + + https://docs.akiradocs.com/fr/docs/editor/blocks + + + + https://docs.akiradocs.com/fr/docs/editor/ai-features + + + + https://docs.akiradocs.com/fr/docs/contributing/how-to-contribute + + + + https://docs.akiradocs.com/fr/docs/contributing/code-of-conduct + + + + https://docs.akiradocs.com/fr/docs/content-management/creating-pages + + + + https://docs.akiradocs.com/fr/docs/api-reference/usage-guide + + + + https://docs.akiradocs.com/fr/articles/welcome @@ -41,16 +121,92 @@ https://docs.akiradocs.com/es/docs/_meta + + https://docs.akiradocs.com/es/docs/seo-and-performance/sitemap-generation + + + + https://docs.akiradocs.com/es/docs/seo-and-performance/robot-txt + + + + https://docs.akiradocs.com/es/docs/internationalization/setup + + + + https://docs.akiradocs.com/es/docs/internationalization/managing-translation + + + + https://docs.akiradocs.com/es/docs/internationalization/ai-translation + + + + https://docs.akiradocs.com/es/docs/installation/troubleshooting + + + + https://docs.akiradocs.com/es/docs/installation/setup + + + + https://docs.akiradocs.com/es/docs/installation/configuration + + + + https://docs.akiradocs.com/es/docs/guides/analytics + + + + https://docs.akiradocs.com/es/docs/getting-started/requirements + + https://docs.akiradocs.com/es/docs/getting-started/quickstart - https://docs.akiradocs.com/es/articles/welcome + https://docs.akiradocs.com/es/docs/getting-started/features + + + + https://docs.akiradocs.com/es/docs/editor/overview + + + + https://docs.akiradocs.com/es/docs/editor/getting-started - https://docs.akiradocs.com/es/articles/template + https://docs.akiradocs.com/es/docs/editor/features + + + + https://docs.akiradocs.com/es/docs/editor/blocks + + + + https://docs.akiradocs.com/es/docs/editor/ai-features + + + + https://docs.akiradocs.com/es/docs/contributing/how-to-contribute + + + + https://docs.akiradocs.com/es/docs/contributing/code-of-conduct + + + + https://docs.akiradocs.com/es/docs/content-management/creating-pages + + + + https://docs.akiradocs.com/es/docs/api-reference/usage-guide + + + + https://docs.akiradocs.com/es/articles/welcome @@ -73,20 +229,132 @@ https://docs.akiradocs.com/en/docs/_meta + + https://docs.akiradocs.com/en/docs/seo-and-performance/sitemap-generation + + + + https://docs.akiradocs.com/en/docs/seo-and-performance/robot-txt + + + + https://docs.akiradocs.com/en/docs/seo-and-performance/_meta + + + + https://docs.akiradocs.com/en/docs/internationalization/setup + + + + https://docs.akiradocs.com/en/docs/internationalization/managing-translation + + + + https://docs.akiradocs.com/en/docs/internationalization/ai-translation + + + + https://docs.akiradocs.com/en/docs/internationalization/_meta + + + + https://docs.akiradocs.com/en/docs/installation/troubleshooting + + + + https://docs.akiradocs.com/en/docs/installation/setup + + + + https://docs.akiradocs.com/en/docs/installation/configuration + + + + https://docs.akiradocs.com/en/docs/installation/_meta + + https://docs.akiradocs.com/en/docs/guides/analytics + + https://docs.akiradocs.com/en/docs/guides/_meta + + + + https://docs.akiradocs.com/en/docs/getting-started/requirements + + https://docs.akiradocs.com/en/docs/getting-started/quickstart + + https://docs.akiradocs.com/en/docs/getting-started/features + + + + https://docs.akiradocs.com/en/docs/getting-started/_meta + + + + https://docs.akiradocs.com/en/docs/editor/overview + + + + https://docs.akiradocs.com/en/docs/editor/getting-started + + + + https://docs.akiradocs.com/en/docs/editor/features + + + + https://docs.akiradocs.com/en/docs/editor/blocks + + + + https://docs.akiradocs.com/en/docs/editor/ai-features + + + + https://docs.akiradocs.com/en/docs/editor/_meta + + + + https://docs.akiradocs.com/en/docs/contributing/how-to-contribute + + + + https://docs.akiradocs.com/en/docs/contributing/code-of-conduct + + + + https://docs.akiradocs.com/en/docs/contributing/_meta + + + + https://docs.akiradocs.com/en/docs/content-management/creating-pages + + + + https://docs.akiradocs.com/en/docs/content-management/_meta + + + + https://docs.akiradocs.com/en/docs/api-reference/usage-guide + + + + https://docs.akiradocs.com/en/docs/api-reference/_meta + + https://docs.akiradocs.com/en/articles/welcome - https://docs.akiradocs.com/en/articles/template + https://docs.akiradocs.com/en/articles/importance_of_documentation @@ -109,16 +377,92 @@ https://docs.akiradocs.com/de/docs/_meta + + https://docs.akiradocs.com/de/docs/seo-and-performance/sitemap-generation + + + + https://docs.akiradocs.com/de/docs/seo-and-performance/robot-txt + + + + https://docs.akiradocs.com/de/docs/internationalization/setup + + + + https://docs.akiradocs.com/de/docs/internationalization/managing-translation + + + + https://docs.akiradocs.com/de/docs/internationalization/ai-translation + + + + https://docs.akiradocs.com/de/docs/installation/troubleshooting + + + + https://docs.akiradocs.com/de/docs/installation/setup + + + + https://docs.akiradocs.com/de/docs/installation/configuration + + + + https://docs.akiradocs.com/de/docs/guides/analytics + + + + https://docs.akiradocs.com/de/docs/getting-started/requirements + + https://docs.akiradocs.com/de/docs/getting-started/quickstart - https://docs.akiradocs.com/de/articles/welcome + https://docs.akiradocs.com/de/docs/getting-started/features + + + + https://docs.akiradocs.com/de/docs/editor/overview + + + + https://docs.akiradocs.com/de/docs/editor/getting-started + + + + https://docs.akiradocs.com/de/docs/editor/features + + + + https://docs.akiradocs.com/de/docs/editor/blocks - https://docs.akiradocs.com/de/articles/template + https://docs.akiradocs.com/de/docs/editor/ai-features + + + + https://docs.akiradocs.com/de/docs/contributing/how-to-contribute + + + + https://docs.akiradocs.com/de/docs/contributing/code-of-conduct + + + + https://docs.akiradocs.com/de/docs/content-management/creating-pages + + + + https://docs.akiradocs.com/de/docs/api-reference/usage-guide + + + + https://docs.akiradocs.com/de/articles/welcome diff --git a/docs/src/app/[locale]/[type]/[...slug]/page.tsx b/docs/src/app/[locale]/[type]/[...slug]/page.tsx index 4111dac..bfea903 100644 --- a/docs/src/app/[locale]/[type]/[...slug]/page.tsx +++ b/docs/src/app/[locale]/[type]/[...slug]/page.tsx @@ -113,7 +113,7 @@ export default async function ContentPage({ params }: Props) { description={pageDescription} canonical={canonicalUrl} /> -
+
diff --git a/docs/src/app/[locale]/[type]/page.tsx b/docs/src/app/[locale]/[type]/page.tsx index 0b15df0..210b161 100644 --- a/docs/src/app/[locale]/[type]/page.tsx +++ b/docs/src/app/[locale]/[type]/page.tsx @@ -75,7 +75,7 @@ export default async function Page({ params }: Props) { } // Fallback redirect if no content found - console.log("redirecting to", `/${locale}`); + // console.log("redirecting to", `/${locale}`); redirect(`/${locale}`); } diff --git a/docs/src/app/aiSearch/page.tsx b/docs/src/app/aiSearch/page.tsx index a620cdf..5e849e3 100644 --- a/docs/src/app/aiSearch/page.tsx +++ b/docs/src/app/aiSearch/page.tsx @@ -15,6 +15,8 @@ import { getAkiradocsConfig } from '@/lib/getAkiradocsConfig' import { ChatCompletionMessageParam, CreateMLCEngine } from "@mlc-ai/web-llm"; import { Source } from '@/types/Source' import AILoader from '@/components/aiSearch/AILoader' +import { getHeaderConfig } from '@/lib/headerConfig' +import { Header } from '@/components/layout/Header' export default function Home() { const [query, setQuery] = useState('') @@ -23,6 +25,7 @@ export default function Home() { const [error, setError] = useState(null) const recommendedArticles = getRecommendedArticles() const searchConfig = getSearchConfig() + const headerConfig = getHeaderConfig() const config = getAkiradocsConfig() const [sources, setSources] = useState([]) @@ -160,7 +163,10 @@ export default function Home() { } return ( +
+
+
+
) } diff --git a/docs/src/app/apiReference/page.tsx b/docs/src/app/apiReference/page.tsx index e36f59c..d1c34ff 100644 --- a/docs/src/app/apiReference/page.tsx +++ b/docs/src/app/apiReference/page.tsx @@ -312,7 +312,7 @@ export default function Page() { }>
-
+
diff --git a/docs/src/components/blocks/ButtonBlock.tsx b/docs/src/components/blocks/ButtonBlock.tsx new file mode 100644 index 0000000..a54e8b1 --- /dev/null +++ b/docs/src/components/blocks/ButtonBlock.tsx @@ -0,0 +1,103 @@ +import { cn } from "@/lib/utils" +import { Button, buttonVariants } from "@/components/ui/button" +import { useState } from "react" + +interface ButtonBlockProps { + content: string + metadata?: { + buttonUrl?: string + buttonStyle?: { + variant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link' + size?: 'default' | 'sm' | 'lg' + radius?: 'none' | 'sm' | 'md' | 'lg' | 'full' + } + } + isEditing?: boolean + onUpdate?: (content: string) => void + align?: 'left' | 'center' | 'right' +} + +export function ButtonBlock({ + content, + metadata, + isEditing, + onUpdate, + align = 'left' +}: ButtonBlockProps) { + const [isFocused, setIsFocused] = useState(false); + const buttonStyle = metadata?.buttonStyle || {} + const url = metadata?.buttonUrl || '#' + + const buttonClasses = cn( + "relative", + { + 'rounded-none': buttonStyle.radius === 'none', + 'rounded-sm': buttonStyle.radius === 'sm', + 'rounded-md': buttonStyle.radius === 'md', + 'rounded-lg': buttonStyle.radius === 'lg', + 'rounded-full': buttonStyle.radius === 'full', + 'w-full': buttonStyle.size === 'lg', + 'w-24': buttonStyle.size === 'sm', + 'w-auto': buttonStyle.size === 'default' + } + ) + + const wrapperClasses = cn( + 'w-full', + { + 'text-left': align === 'left', + 'text-center': align === 'center', + 'text-right': align === 'right' + } + ) + + if (isEditing) { + return ( +
+
+ + onUpdate?.(e.target.value)} + onFocus={() => setIsFocused(true)} + onBlur={() => setIsFocused(false)} + className={cn( + buttonVariants({ + variant: buttonStyle.variant || 'default', + size: buttonStyle.size || 'default' + }), + buttonClasses, + "absolute inset-0 border-0 outline-none", + !isFocused && "opacity-0" + )} + placeholder="Button text..." + /> +
+
+ ) + } + + return ( +
+ +
+ ) +} \ No newline at end of file diff --git a/docs/src/components/blocks/SortableBlock.tsx b/docs/src/components/blocks/SortableBlock.tsx index 9afa175..020e810 100644 --- a/docs/src/components/blocks/SortableBlock.tsx +++ b/docs/src/components/blocks/SortableBlock.tsx @@ -35,6 +35,12 @@ interface SortableBlockProps { align?: 'left' | 'center' | 'right' type?: 'info' | 'warning' | 'success' | 'error' title?: string + buttonUrl?: string + buttonStyle?: { + variant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link' + size?: 'default' | 'sm' | 'lg' + radius?: 'none' | 'sm' | 'md' | 'lg' | 'full' + } } } updateBlock: (id: string, content: string) => void @@ -514,6 +520,21 @@ export function SortableBlock({ updateBlock(block.id, JSON.stringify(updatedContent)); } }} + showButtonControls={block.type === 'button'} + buttonMetadata={{ + url: block.metadata?.buttonUrl, + style: block.metadata?.buttonStyle + }} + onButtonMetadataChange={(metadata) => { + updateBlockMetadata(block.id, { + ...block.metadata, + buttonUrl: metadata.buttonUrl, + buttonStyle: { + ...block.metadata?.buttonStyle, + ...metadata.buttonStyle + } + }) + }} /> )} void +} + +const spacingSizes = { + small: 'h-4', + medium: 'h-8', + large: 'h-16', + xlarge: 'h-24' +} + +export function SpacerBlock({ size = 'medium', isEditing, onUpdate }: SpacerBlockProps) { + const [isFocused, setIsFocused] = useState(false) + + if (!isEditing) { + return
+ } + + return ( +
setIsFocused(true)} + onBlur={(e) => { + if (!e.currentTarget.contains(e.relatedTarget)) { + setIsFocused(false) + } + }} + > +
+ {isFocused && ( + + )} +
+ ) +} \ No newline at end of file diff --git a/docs/src/components/editor/AIRewriteButton.tsx b/docs/src/components/editor/AIRewriteButton.tsx index eb1c654..589ef86 100644 --- a/docs/src/components/editor/AIRewriteButton.tsx +++ b/docs/src/components/editor/AIRewriteButton.tsx @@ -193,6 +193,25 @@ const blockStyles = { label: 'Descriptive', prompt: 'Rewrite the API reference to be more descriptive and engaging.' } + ], + button: [ + { + value: 'descriptive', + label: 'Descriptive', + prompt: 'Rewrite the button text to be more descriptive and engaging.' + }, + { + value: 'concise', + label: 'Concise', + prompt: 'Rewrite the button text to be more concise and clear.' + } + ], + spacer: [ + { + value: 'default', + label: 'Default', + prompt: 'No rewriting options available for spacer' + } ] } as const; @@ -213,6 +232,10 @@ export function AIRewriteButton({ onRewrite, blockType, isRewriting }: AIRewrite }; const handleRewrite = async () => { + if (blockType === 'spacer') { + return; + } + try { await onRewrite(style) } catch (error) { @@ -224,6 +247,10 @@ export function AIRewriteButton({ onRewrite, blockType, isRewriting }: AIRewrite } } + if (blockType === 'spacer') { + return null; + } + return ( diff --git a/docs/src/components/editor/AddBlockButton.tsx b/docs/src/components/editor/AddBlockButton.tsx index 00a1770..ec5998f 100644 --- a/docs/src/components/editor/AddBlockButton.tsx +++ b/docs/src/components/editor/AddBlockButton.tsx @@ -16,19 +16,14 @@ import { Minus, Table, Quote, - // ToggleLeft, - // CheckSquare, - // Video, - // Music, - // File, - // Smile, AlertCircle, Plus, - // Search, Video, Music, File, CheckSquare, + ArrowUpDown, + Link2, } from 'lucide-react' interface AddBlockButtonProps { @@ -83,6 +78,8 @@ export const AddBlockButton = forwardRef< { type: 'audio', icon: , label: 'Audio', description: 'Embed audio content.', group: 'Media' }, { type: 'file', icon: , label: 'File', description: 'Upload or link to a file.', group: 'Media' }, { type: 'checkList', icon: , label: 'To-do list', description: 'Track tasks with a to-do list.', group: 'Basic' }, + { type: 'spacer', icon: , label: 'Spacing', description: 'Add vertical space between blocks.', group: 'Basic' }, + { type: 'button', icon: , label: 'Button', description: 'Add a clickable button with link.', group: 'Basic' }, ] const filteredOptions = blockOptions.filter((option) => diff --git a/docs/src/components/editor/BlockFormatToolbar.tsx b/docs/src/components/editor/BlockFormatToolbar.tsx index 8a70ee5..e575d98 100644 --- a/docs/src/components/editor/BlockFormatToolbar.tsx +++ b/docs/src/components/editor/BlockFormatToolbar.tsx @@ -76,6 +76,23 @@ interface BlockFormatToolbarProps { caption: string; alignment: 'left' | 'center' | 'right'; }>) => void; + showButtonControls?: boolean; + buttonMetadata?: { + url?: string; + style?: { + variant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link'; + size?: 'default' | 'sm' | 'lg'; + radius?: 'none' | 'sm' | 'md' | 'lg' | 'full'; + }; + }; + onButtonMetadataChange?: (metadata: Partial<{ + buttonUrl: string; + buttonStyle: { + variant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link'; + size?: 'default' | 'sm' | 'lg'; + radius?: 'none' | 'sm' | 'md' | 'lg' | 'full'; + }; + }>) => void; } export function BlockFormatToolbar({ @@ -119,8 +136,11 @@ export function BlockFormatToolbar({ showAudioControls = false, audioContent, onAudioMetadataChange, + showButtonControls = false, + buttonMetadata, + onButtonMetadataChange, }: BlockFormatToolbarProps) { - if (blockType === 'file') { + if (blockType === 'file' || blockType === 'spacer') { return null; } @@ -133,7 +153,7 @@ export function BlockFormatToolbar({ "bg-popover border shadow-md rounded-md", className )}> - {!showImageControls && !showCodeControls && !showVideoControls && !showAudioControls && blockType !== 'table' && ( + {!showImageControls && !showCodeControls && !showVideoControls && !showAudioControls && !showButtonControls && blockType !== 'table' && ( <> )} + {showButtonControls && ( + <> + + + onButtonMetadataChange?.({ buttonUrl: e.target.value })} + placeholder="URL" + className="h-7 w-32 text-xs" + /> + + + + + + + + )} + {!showImageControls && !showVideoControls && !showAudioControls && ( <> {!showCalloutControls && blockType !== 'table' && } diff --git a/docs/src/components/layout/Header.tsx b/docs/src/components/layout/Header.tsx index 56a363a..ba1bc04 100644 --- a/docs/src/components/layout/Header.tsx +++ b/docs/src/components/layout/Header.tsx @@ -34,7 +34,8 @@ export const Header = memo(function Header({ navItems, socialLinks, languages, - currentLocale = 'en' + currentLocale = 'en', + currentType = 'docs' }: HeaderConfig) { const [isMounted, setIsMounted] = useState(false) const { theme, setTheme } = useTheme() @@ -104,31 +105,36 @@ export const Header = memo(function Header({ // Memoize the navigation items const navigationItems = useMemo(() => { - return navItems?.filter((item) => item.show).map((item, index) => ( - - item.show).map((item, index) => { + // Check if the current nav item matches the page type + const isActive = currentType ? item.href.includes(`/${currentType}`) : pathname === item.href; + + return ( + - {t(item.label as string)} - - - - )) - }, [navItems, pathname]) + + {t(item.label as string)} + + + + ); + }); + }, [navItems, pathname, currentType]); return ( (defaultValue: T, locale: string, t try { const navigationFile = `${locale}/${type}/_meta.json` const navigation = await getJsonContent(navigationFile) - console.log(navigation) + // console.log(navigation) return navigation } catch (error) { console.warn(`Failed to read ${type} _meta.json file. Using default value.`) @@ -131,7 +131,7 @@ interface ApiNavItem { export async function getApiNavigation(): Promise { try { const apiSpec = await get_api_spec(); - console.log("apiSpec", apiSpec) + // console.log("apiSpec", apiSpec) if (!apiSpec || !apiSpec.paths) { return []; } diff --git a/docs/src/lib/renderers/BlockRenderer.tsx b/docs/src/lib/renderers/BlockRenderer.tsx index b640646..6247349 100644 --- a/docs/src/lib/renderers/BlockRenderer.tsx +++ b/docs/src/lib/renderers/BlockRenderer.tsx @@ -6,22 +6,15 @@ import { List } from "@/components/blocks/ListBlock" import { Blockquote } from "@/components/blocks/BlockquoteBlock" import { Divider } from "@/components/blocks/DividerBlock" import { CodeBlock } from "@/components/blocks/CodeBlock" -// import { Image } from '../blocks/Image' -// import { Table } from '../blocks/Table' -// import { ToggleList } from '../blocks/ToggleList' import { CheckList } from "@/components/blocks/CheckListBlock" -// import { Video } from '../blocks/Video' -// import { Audio } from '../blocks/Audio' -// import { File } from '../blocks/File' -// import { Emoji } from '../blocks/Emoji' import { Callout } from "@/components/blocks/CalloutBlock" -import { cn } from '@/lib/utils' -import { ErrorBoundary } from 'react-error-boundary' import { ImageBlock } from "@/components/blocks/ImageBlock" import { Table } from '@/components/blocks/TableBlock' import { VideoBlock } from "@/components/blocks/VideoBlock" import { AudioBlock } from "@/components/blocks/AudioBlock" import { FileBlock } from "@/components/blocks/FileBlock" +import { SpacerBlock } from "@/components/blocks/SpacerBlock" +import { ButtonBlock } from "@/components/blocks/ButtonBlock" interface ImageBlockContent { url: string; @@ -64,20 +57,16 @@ export function BlockRenderer({ block, isEditing, onUpdate }: BlockRendererProps ); case 'heading': - const hasStrong = block.content.includes(''); return ( onUpdate?.(block.id, content)} > - {hasStrong ? block.content.replace(/<\/?strong>/g, '') : block.content} + {block.content} ); case 'list': @@ -234,6 +223,24 @@ export function BlockRenderer({ block, isEditing, onUpdate }: BlockRendererProps onUpdate={(content) => onUpdate?.(block.id, content)} /> ); + case 'spacer': + return ( + onUpdate?.(block.id, size)} + /> + ); + case 'button': + return ( + onUpdate?.(block.id, content)} + align={block.metadata?.align} + /> + ); default: return null } diff --git a/docs/src/types/Block.ts b/docs/src/types/Block.ts index 61f1b7a..044cc58 100644 --- a/docs/src/types/Block.ts +++ b/docs/src/types/Block.ts @@ -12,9 +12,10 @@ export type BlockType = | 'video' | 'audio' | 'file' - // | 'emoji' | 'callout' - | 'apiReference'; + | 'spacer' + | 'apiReference' + | 'button'; export interface Block { id: string; @@ -44,6 +45,12 @@ export interface Block { align?: 'left' | 'center' | 'right'; // For alignment type?: 'info' | 'warning' | 'success' | 'error'; // For callouts title?: string; // For callouts + buttonUrl?: string; + buttonStyle?: { + variant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link'; + size?: 'default' | 'sm' | 'lg'; + radius?: 'none' | 'sm' | 'md' | 'lg' | 'full'; + }; }; } diff --git a/docs/src/types/config.ts b/docs/src/types/config.ts index ddf0804..5aaa68f 100644 --- a/docs/src/types/config.ts +++ b/docs/src/types/config.ts @@ -39,6 +39,7 @@ interface NavItem { }[]; }; currentLocale?: string; + currentType?: string; } export interface FooterConfig { diff --git a/docs/wrangler.toml b/docs/wrangler.toml new file mode 100644 index 0000000..7188cd4 --- /dev/null +++ b/docs/wrangler.toml @@ -0,0 +1,16 @@ +name = "akiradocs" + +pages_build_output_dir = ".next" + +[build] +command = "npx @cloudflare/next-on-pages@1" + + +[vars] +NODE_VERSION = "18.8.0" + +compatibility_flags = ["nodejs_compat"] + + +[env.production] +NODE_ENV = "production" \ No newline at end of file