diff --git a/.vscode/keyboard.code-snippets b/.vscode/keyboard.code-snippets
new file mode 100644
index 0000000..257bf89
--- /dev/null
+++ b/.vscode/keyboard.code-snippets
@@ -0,0 +1,23 @@
+{
+ "Keyboard - Mac": {
+ "prefix": "keymac",
+ "body": [
+ ""
+ ],
+ "description": "Mac keyboard shortcut."
+ },
+ "Keyboard - Windows": {
+ "prefix": "keywin",
+ "body": [
+ ""
+ ],
+ "description": "Windows keyboard shortcut."
+ },
+ "Keyboard - Custom": {
+ "prefix": "keycustom",
+ "body": [
+ "${2:Custom}"
+ ],
+ "description": "Custom keyboard shortcut."
+ }
+}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3b71425..c340972 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,19 @@
+## [1.9.0] - 2025-05-19
+
+> New Keyboard component to show keyboard shortcut on docs page
+
+### Added
+
+- New Keyboard component with props show, type, children
+- Snippet keyboard component
+
+### Improved
+
+- Support custom content
+- Support platform type (mac or window)
+- Support automatic rendering of platform-specific key symbols
+- Rename lowercase to camelCase for markdown component
+
## [1.8.5] - 2025-05-10
> Add sponsor card on single docs page
diff --git a/app/docs/layout.tsx b/app/docs/layout.tsx
index ef73ca4..aa877c2 100644
--- a/app/docs/layout.tsx
+++ b/app/docs/layout.tsx
@@ -1,4 +1,5 @@
import { Leftbar } from "@/components/leftbar";
+import { MDXProviderWrapper } from "@/components/markdown/mdx-provider";
export default function DocsLayout({
children,
@@ -8,7 +9,11 @@ export default function DocsLayout({
return (
-
{children}
+
+
+ {children}
+
+
);
}
diff --git a/app/page.tsx b/app/page.tsx
index c4c80bd..ce3726d 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -25,7 +25,7 @@ export default function Home() {
)}
>
- 🚀 New Version - Release v1.8.5
+ 🚀 New Version - Release v1.9.0
diff --git a/components/markdown/KeyboardMdx.tsx b/components/markdown/KeyboardMdx.tsx
new file mode 100644
index 0000000..aede1a5
--- /dev/null
+++ b/components/markdown/KeyboardMdx.tsx
@@ -0,0 +1,102 @@
+import React from 'react';
+
+// Map of special keys to their Mac symbols
+const macKeyMap: Record = {
+ command: '⌘',
+ cmd: '⌘',
+ option: '⌥',
+ alt: '⌥',
+ shift: '⇧',
+ ctrl: '⌃',
+ control: '⌃',
+ tab: '⇥',
+ caps: '⇪',
+ enter: '⏎',
+ return: '⏎',
+ delete: '⌫',
+ escape: '⎋',
+ esc: '⎋',
+ up: '↑',
+ down: '↓',
+ left: '←',
+ right: '→',
+ space: '␣',
+};
+
+// Map of special keys to their Windows display text
+const windowsKeyMap: Record = {
+ command: 'Win',
+ cmd: 'Win',
+ option: 'Alt',
+ alt: 'Alt',
+ ctrl: 'Ctrl',
+ control: 'Ctrl',
+ delete: 'Del',
+ escape: 'Esc',
+ esc: 'Esc',
+ enter: 'Enter',
+ return: 'Enter',
+ tab: 'Tab',
+ caps: 'Caps',
+ shift: 'Shift',
+ space: 'Space',
+ up: '↑',
+ down: '↓',
+ left: '←',
+ right: '→',
+};
+
+export interface KbdProps extends React.HTMLAttributes {
+ /** The key to display (e.g., 'cmd', 'ctrl', 'a') */
+ show?: string;
+ /** Platform style - 'window' or 'mac' */
+ type?: 'window' | 'mac';
+ /** Custom content to display (overrides automatic rendering) */
+ children?: React.ReactNode;
+}
+
+const KbdComponent: React.FC = ({
+ show: keyProp,
+ type = 'window',
+ children,
+ ...props
+}) => {
+ // Get the display text based on the key and type
+ const getKeyDisplay = (): React.ReactNode => {
+ if (!keyProp || typeof keyProp !== 'string') return null;
+
+ const lowerKey = keyProp.toLowerCase();
+
+ // For Mac type, return the symbol if it exists
+ if (type === 'mac') {
+ return macKeyMap[lowerKey] || keyProp;
+ }
+
+ // For Windows, return the formatted key if it exists, otherwise capitalize the first letter
+ return windowsKeyMap[lowerKey] || (keyProp.charAt(0).toUpperCase() + keyProp.slice(1));
+ };
+
+ // Determine what to render
+ const renderContent = () => {
+ // If children are provided, always use them
+ if (children !== undefined && children !== null && children !== '') {
+ return children;
+ }
+ // Otherwise use the generated display
+ return getKeyDisplay() || keyProp || '';
+ };
+
+ return (
+
+ {renderContent()}
+
+ );
+};
+
+// Export the component
+export const Kbd = KbdComponent;
+// Default export for backward compatibility
+export default KbdComponent;
diff --git a/components/markdown/mdx-components.tsx b/components/markdown/mdx-components.tsx
new file mode 100644
index 0000000..1993a54
--- /dev/null
+++ b/components/markdown/mdx-components.tsx
@@ -0,0 +1,15 @@
+import { Kbd as KbdComponent } from './KeyboardMdx';
+import type { MDXComponents } from 'mdx/types';
+
+// Export all components that should be available in MDX files
+export const components: MDXComponents = {
+ // Register both Kbd and kbd to handle both cases
+ Kbd: KbdComponent as any, // We'll handle the type in the MDXProvider
+
+ // You can add other MDX components here as needed
+ // They will be available in your MDX files
+ // Example:
+ // h1: (props) => ,
+};
+
+export default components;
diff --git a/components/markdown/mdx-provider.tsx b/components/markdown/mdx-provider.tsx
new file mode 100644
index 0000000..551e60f
--- /dev/null
+++ b/components/markdown/mdx-provider.tsx
@@ -0,0 +1,17 @@
+'use client';
+
+import { MDXProvider } from '@mdx-js/react';
+import { components } from './mdx-components';
+
+// Create a properly typed components object
+const typedComponents = {
+ ...components,
+ // Add any default HTML elements you want to override
+ // or keep their default behavior
+ kbd: components.kbd as React.ComponentType>,
+ Kbd: components.Kbd as React.ComponentType & { type?: 'window' | 'mac' }>,
+};
+
+export function MDXProviderWrapper({ children }: { children: React.ReactNode }) {
+ return {children};
+}
diff --git a/contents/docs/getting-started/components/keyboard/index.mdx b/contents/docs/getting-started/components/keyboard/index.mdx
new file mode 100644
index 0000000..8be50e1
--- /dev/null
+++ b/contents/docs/getting-started/components/keyboard/index.mdx
@@ -0,0 +1,117 @@
+---
+title: Keyboard
+description: Display keyboard keys with platform-specific styling for Windows and macOS.
+date : 19-05-2025
+---
+
+The `Keyboard` component automatically renders platform-appropriate key symbols for macOS and Windows. It's perfect for documenting keyboard shortcuts in your application.
+
+## Usage
+
+### Basic Usage
+
+Simply use the `Kbd` component with a `show` prop:
+
+```tsx
+ +
+```
+
+Renders as:
+ +
+
+### Automatic Symbol Rendering
+
+The component automatically renders appropriate symbols based on the platform:
+
+```tsx
+{/* Windows style (default) */}
+ +
+
+{/* Mac style */}
+ +
+```
+
+Renders as:
+- Windows: +
+- Mac: +
+
+### Custom Content
+
+For custom key labels, provide children:
+
+```tsx
+Custom
+```
+
+Renders as: Custom
+
+## Props
+
+| Prop | Type | Default | Description |
+|-----------|---------------------|------------|-------------|
+| `show` | `string` | (required) | The key identifier (e.g., 'cmd', 'ctrl', 'a') |
+| `type` | `string` | `window` | for device type `mac` or `window` | Platform style or custom content |
+| `children`| `ReactNode` | - | Custom content to display (overrides automatic rendering) |
+
+## Supported Keys
+
+The component includes special handling for common keys:
+
+| Key Name | Windows | macOS |
+|-------------|---------|-------|
+| command/cmd | `Win` | `⌘` |
+| option/alt | `Alt` | `⌥` |
+| shift | `Shift` | `⇧` |
+| ctrl/control| `Ctrl` | `⌃` |
+| tab | `Tab` | `⇥` |
+| enter/return| `Enter` | `⏎` |
+| delete | `Del` | `⌫` |
+| escape/esc | `Esc` | `⎋` |
+| up/down/left/right | `↑` `↓` `←` `→` | `↑` `↓` `←` `→` |
+| space | `Space` | `␣` |
+
+## Examples
+
+### Common Shortcuts
+
+```tsx
+{/* Copy shortcut */}
+ +
+
+{/* Paste shortcut */}
+ +
+
+{/* Save shortcut */}
+ +
+```
+
+### Custom Key Combinations
+
+```tsx
+{/* Custom application shortcut */}
+ + +
+```
+
+Render as: + +
+
+### Arrow Key
+
+```tsx
+
+```
+
+Render as:
+
+## Best Practices
+
+1. **Be Consistent**: Stick to one platform style within the same context
+2. **Use Type Wisely**:
+ - Use `type="mac"` for Mac-specific documentation
+ - Use `type="window"` (default) for Windows/Linux
+3. **Accessibility**: The component uses semantic `` HTML for better accessibility
+
+## Notes
+
+- The component automatically capitalizes single letters (e.g., 'a' becomes 'A')
+- Unrecognized keys are displayed as-is
+- Dark mode is automatically supported through Tailwind's dark mode classes
diff --git a/docu.json b/docu.json
index 59e1b7e..571a0d9 100644
--- a/docu.json
+++ b/docu.json
@@ -81,6 +81,7 @@
{ "title": "Card Group", "href": "/card-group" },
{ "title": "Code Block", "href": "/code-block" },
{ "title": "Image", "href": "/image" },
+ { "title": "Keyboard", "href": "/keyboard" },
{ "title": "Link", "href": "/link" },
{ "title": "Note", "href": "/note" },
{ "title": "Release Note", "href": "/release-note" },
diff --git a/lib/markdown.ts b/lib/markdown.ts
index 327414a..83a4385 100644
--- a/lib/markdown.ts
+++ b/lib/markdown.ts
@@ -24,6 +24,7 @@ import Card from "@/components/markdown/CardMdx";
import Button from "@/components/markdown/ButtonMdx";
import Accordion from "@/components/markdown/AccordionMdx";
import CardGroup from "@/components/markdown/CardGroupMdx";
+import Kbd from "@/components/markdown/KeyboardMdx";
// add custom components
const components = {
@@ -44,6 +45,7 @@ const components = {
Button,
Accordion,
CardGroup,
+ Kbd,
};
// can be used for other pages like blogs, Guides etc
diff --git a/package.json b/package.json
index ec48371..ff2f8c0 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "docubook",
- "version": "1.8.5",
+ "version": "1.9.0",
"private": true,
"scripts": {
"dev": "next dev",
@@ -9,6 +9,7 @@
"lint": "next lint"
},
"dependencies": {
+ "@mdx-js/react": "^3.1.0",
"@radix-ui/react-accordion": "^1.2.0",
"@radix-ui/react-avatar": "^1.1.0",
"@radix-ui/react-collapsible": "^1.1.0",