From 209a80d5e8068f4b4cd327e442cbcacd629fab4a Mon Sep 17 00:00:00 2001 From: Wildan Nursahidan <> Date: Mon, 19 May 2025 22:20:53 +0700 Subject: [PATCH] v1.9.0 : add keyboard components --- .vscode/keyboard.code-snippets | 23 ++++ CHANGELOG.md | 16 +++ app/docs/layout.tsx | 7 +- app/page.tsx | 2 +- components/markdown/KeyboardMdx.tsx | 102 +++++++++++++++ components/markdown/mdx-components.tsx | 15 +++ components/markdown/mdx-provider.tsx | 17 +++ .../components/keyboard/index.mdx | 117 ++++++++++++++++++ docu.json | 1 + lib/markdown.ts | 2 + package.json | 3 +- 11 files changed, 302 insertions(+), 3 deletions(-) create mode 100644 .vscode/keyboard.code-snippets create mode 100644 components/markdown/KeyboardMdx.tsx create mode 100644 components/markdown/mdx-components.tsx create mode 100644 components/markdown/mdx-provider.tsx create mode 100644 contents/docs/getting-started/components/keyboard/index.mdx 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",