v1.9.0 : add keyboard components

This commit is contained in:
Wildan Nursahidan
2025-05-19 22:20:53 +07:00
parent d66f37085a
commit 209a80d5e8
11 changed files with 302 additions and 3 deletions

23
.vscode/keyboard.code-snippets vendored Normal file
View File

@@ -0,0 +1,23 @@
{
"Keyboard - Mac": {
"prefix": "keymac",
"body": [
"<Kbd show=\"${1:ctrl}\" type=\"mac\" />"
],
"description": "Mac keyboard shortcut."
},
"Keyboard - Windows": {
"prefix": "keywin",
"body": [
"<Kbd show=\"${1:ctrl}\" type=\"windows\" />"
],
"description": "Windows keyboard shortcut."
},
"Keyboard - Custom": {
"prefix": "keycustom",
"body": [
"<Kbd show=\"${1:custom}\">${2:Custom}</Kbd>"
],
"description": "Custom keyboard shortcut."
}
}

View File

@@ -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 ## [1.8.5] - 2025-05-10
> Add sponsor card on single docs page > Add sponsor card on single docs page

View File

@@ -1,4 +1,5 @@
import { Leftbar } from "@/components/leftbar"; import { Leftbar } from "@/components/leftbar";
import { MDXProviderWrapper } from "@/components/markdown/mdx-provider";
export default function DocsLayout({ export default function DocsLayout({
children, children,
@@ -8,7 +9,11 @@ export default function DocsLayout({
return ( return (
<div className="flex items-start gap-8"> <div className="flex items-start gap-8">
<Leftbar key="leftbar" /> <Leftbar key="leftbar" />
<div className="flex-[5.25]">{children}</div> <div className="flex-[5.25]">
<MDXProviderWrapper>
{children}
</MDXProviderWrapper>
</div>
</div> </div>
); );
} }

View File

@@ -25,7 +25,7 @@ export default function Home() {
)} )}
> >
<AnimatedShinyText className="inline-flex items-center justify-center px-4 py-1 transition ease-out hover:text-neutral-100 hover:duration-300 hover:dark:text-neutral-200"> <AnimatedShinyText className="inline-flex items-center justify-center px-4 py-1 transition ease-out hover:text-neutral-100 hover:duration-300 hover:dark:text-neutral-200">
<span>🚀 New Version - Release v1.8.5</span> <span>🚀 New Version - Release v1.9.0</span>
<ArrowRightIcon className="ml-1 size-3 transition-transform duration-300 ease-in-out group-hover:translate-x-0.5" /> <ArrowRightIcon className="ml-1 size-3 transition-transform duration-300 ease-in-out group-hover:translate-x-0.5" />
</AnimatedShinyText> </AnimatedShinyText>
</div> </div>

View File

@@ -0,0 +1,102 @@
import React from 'react';
// Map of special keys to their Mac symbols
const macKeyMap: Record<string, string> = {
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<string, string> = {
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<HTMLElement> {
/** 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<KbdProps> = ({
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 (
<kbd
className="inline-flex items-center justify-center px-2 py-1 mx-0.5 text-xs font-mono font-medium text-gray-800 bg-gray-100 border border-gray-300 rounded-md dark:bg-gray-700 dark:text-gray-200 dark:border-gray-600"
{...props}
>
{renderContent()}
</kbd>
);
};
// Export the component
export const Kbd = KbdComponent;
// Default export for backward compatibility
export default KbdComponent;

View File

@@ -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) => <h1 className="text-2xl font-bold" {...props} />,
};
export default components;

View File

@@ -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<React.HTMLAttributes<HTMLElement>>,
Kbd: components.Kbd as React.ComponentType<React.HTMLAttributes<HTMLElement> & { type?: 'window' | 'mac' }>,
};
export function MDXProviderWrapper({ children }: { children: React.ReactNode }) {
return <MDXProvider components={typedComponents}>{children}</MDXProvider>;
}

View File

@@ -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
<Kbd show="cmd" type="mac" /> + <Kbd show="c" />
```
Renders as:
<Kbd show="cmd" type="mac" /> + <Kbd show="c" />
### Automatic Symbol Rendering
The component automatically renders appropriate symbols based on the platform:
```tsx
{/* Windows style (default) */}
<Kbd show="ctrl" /> + <Kbd show="v" />
{/* Mac style */}
<Kbd show="cmd" type="mac" /> + <Kbd show="v" type="mac" />
```
Renders as:
- Windows: <Kbd show="ctrl" type="window" /> + <Kbd show="v" type="window" />
- Mac: <Kbd show="cmd" type="mac" /> + <Kbd show="v" type="mac" />
### Custom Content
For custom key labels, provide children:
```tsx
<Kbd show="custom">Custom</Kbd>
```
Renders as: <Kbd show="custom">Custom</Kbd>
## 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 */}
<Kbd show="ctrl" /> + <Kbd show="c" />
{/* Paste shortcut */}
<Kbd show="cmd" type="mac" /> + <Kbd show="v" type="mac" />
{/* Save shortcut */}
<Kbd show="ctrl" /> + <Kbd show="s" />
```
### Custom Key Combinations
```tsx
{/* Custom application shortcut */}
<Kbd show="cmd" type="mac" /> + <Kbd show="option" type="mac" /> + <Kbd show="a" type="mac"/>
```
Render as: <Kbd show="cmd" type="mac" /> + <Kbd show="option" type="mac" /> + <Kbd show="a" type="mac"/>
### Arrow Key
```tsx
<Kbd show="up" /> <Kbd show="down" /> <Kbd show="left" /> <Kbd show="right" />
```
Render as: <Kbd show="up" /> <Kbd show="down" /> <Kbd show="left" /> <Kbd show="right" />
## 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 `<kbd>` 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

View File

@@ -81,6 +81,7 @@
{ "title": "Card Group", "href": "/card-group" }, { "title": "Card Group", "href": "/card-group" },
{ "title": "Code Block", "href": "/code-block" }, { "title": "Code Block", "href": "/code-block" },
{ "title": "Image", "href": "/image" }, { "title": "Image", "href": "/image" },
{ "title": "Keyboard", "href": "/keyboard" },
{ "title": "Link", "href": "/link" }, { "title": "Link", "href": "/link" },
{ "title": "Note", "href": "/note" }, { "title": "Note", "href": "/note" },
{ "title": "Release Note", "href": "/release-note" }, { "title": "Release Note", "href": "/release-note" },

View File

@@ -24,6 +24,7 @@ import Card from "@/components/markdown/CardMdx";
import Button from "@/components/markdown/ButtonMdx"; import Button from "@/components/markdown/ButtonMdx";
import Accordion from "@/components/markdown/AccordionMdx"; import Accordion from "@/components/markdown/AccordionMdx";
import CardGroup from "@/components/markdown/CardGroupMdx"; import CardGroup from "@/components/markdown/CardGroupMdx";
import Kbd from "@/components/markdown/KeyboardMdx";
// add custom components // add custom components
const components = { const components = {
@@ -44,6 +45,7 @@ const components = {
Button, Button,
Accordion, Accordion,
CardGroup, CardGroup,
Kbd,
}; };
// can be used for other pages like blogs, Guides etc // can be used for other pages like blogs, Guides etc

View File

@@ -1,6 +1,6 @@
{ {
"name": "docubook", "name": "docubook",
"version": "1.8.5", "version": "1.9.0",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev", "dev": "next dev",
@@ -9,6 +9,7 @@
"lint": "next lint" "lint": "next lint"
}, },
"dependencies": { "dependencies": {
"@mdx-js/react": "^3.1.0",
"@radix-ui/react-accordion": "^1.2.0", "@radix-ui/react-accordion": "^1.2.0",
"@radix-ui/react-avatar": "^1.1.0", "@radix-ui/react-avatar": "^1.1.0",
"@radix-ui/react-collapsible": "^1.1.0", "@radix-ui/react-collapsible": "^1.1.0",