Skip to content

Commit 2e75831

Browse files
committed
✨ Add Kbd component
1 parent b6cc705 commit 2e75831

File tree

9 files changed

+180
-1
lines changed

9 files changed

+180
-1
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ Webcore components use Sass for styling. To use the component library, you must
5858
Depending on your project setup, you'll also need the following packages:
5959

6060
- **For Astro projects**
61-
- [Astro](https://www.npmjs.com/package/astro) - `v4.10` and above
61+
- [Astro](https://www.npmjs.com/package/astro) - `v4.15` and above
6262
- **For Svelte projects**
6363
- [Svelte](https://www.npmjs.com/package/svelte) - `v4.2` and above
6464
- **For React projects**
@@ -221,6 +221,7 @@ import { Accordion } from 'webcoreui/react'
221221
- [Group](https://github.com/Frontendland/webcoreui/tree/main/src/components/Group)
222222
- [Icon](https://github.com/Frontendland/webcoreui/tree/main/src/components/Icon)
223223
- [Input](https://github.com/Frontendland/webcoreui/tree/main/src/components/Input)
224+
- [Kbd](https://github.com/Frontendland/webcoreui/tree/main/src/components/Kbd)
224225
- [List](https://github.com/Frontendland/webcoreui/tree/main/src/components/List)
225226
- [Masonry](https://github.com/Frontendland/webcoreui/tree/main/src/components/Masonry)
226227
- [Menu](https://github.com/Frontendland/webcoreui/tree/main/src/components/Menu)

src/components/Kbd/Kbd.astro

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
import type { KbdProps } from './kbd'
3+
import { keyMap } from './keyMap'
4+
5+
import styles from './kbd.module.scss'
6+
7+
interface Props extends KbdProps {}
8+
9+
const {
10+
keys,
11+
className
12+
} = Astro.props
13+
14+
const classes = [
15+
styles.kbd,
16+
className
17+
]
18+
---
19+
20+
<kbd class:list={classes}>{keys?.map(key => keyMap[key])}<slot /></kbd>

src/components/Kbd/Kbd.svelte

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<script lang="ts">
2+
import type { KbdProps } from './kbd'
3+
import { keyMap } from './keyMap'
4+
5+
import { classNames } from '../../utils/classNames'
6+
7+
import styles from './kbd.module.scss'
8+
9+
export let keys: KbdProps['keys'] = []
10+
export let className: KbdProps['className'] = ''
11+
12+
const classes = classNames([
13+
styles.kbd,
14+
className
15+
])
16+
</script>
17+
18+
<kbd class={classes}>{keys?.map(key => keyMap[key]).join('')}<slot /></kbd>

src/components/Kbd/Kbd.tsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import React from 'react'
2+
import type { ReactKbdProps } from './kbd'
3+
import { keyMap } from './keyMap'
4+
5+
import { classNames } from '../../utils/classNames'
6+
7+
import styles from './kbd.module.scss'
8+
9+
const Kbd = ({
10+
keys,
11+
className,
12+
children
13+
}: ReactKbdProps) => {
14+
const classes = classNames([
15+
styles.kbd,
16+
className
17+
])
18+
19+
return (
20+
<kbd className={classes}>
21+
{keys?.map(key => keyMap[key]).join('')}
22+
{children}
23+
</kbd>
24+
)
25+
}
26+
27+
export default Kbd

src/components/Kbd/kbd.module.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
@import '../../scss/config.scss';
2+
3+
.kbd {
4+
@include background(primary-50);
5+
@include border-radius(md);
6+
@include typography(md, regular);
7+
@include spacing(py-xs, px-xs);
8+
}

src/components/Kbd/kbd.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
export type KbdProps = {
2+
keys?: ('cmd'
3+
| 'shift'
4+
| 'ctrl'
5+
| 'option'
6+
| 'enter'
7+
| 'del'
8+
| 'esc'
9+
| 'tab'
10+
| 'capslock'
11+
| 'up'
12+
| 'down'
13+
| 'left'
14+
| 'right'
15+
| 'pageup'
16+
| 'pagedown'
17+
| 'home'
18+
| 'end'
19+
| 'help'
20+
| 'space')[]
21+
className?: string
22+
}
23+
24+
export type ReactKbdProps = {
25+
children?: React.ReactNode
26+
} & KbdProps

src/components/Kbd/keyMap.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
export const keyMap = {
2+
cmd: '⌘',
3+
shift: '⇧',
4+
ctrl: '⌃',
5+
option: '⌥',
6+
enter: '↵',
7+
del: '⌫',
8+
esc: '⎋',
9+
tab: '⇥',
10+
capslock: '⇪',
11+
up: '↑',
12+
down: '↓',
13+
left: '←',
14+
right: '→',
15+
pageup: '⇞',
16+
pagedown: '⇟',
17+
home: '↖',
18+
end: '↘',
19+
help: '?',
20+
space: '␣'
21+
}

src/pages/components/kbd.astro

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
import ComponentWrapper from '@static/ComponentWrapper.astro'
3+
import Layout from '@static/Layout.astro'
4+
5+
import AstroKbd from '@components/Kbd/Kbd.astro'
6+
import SvelteKbd from '@components/Kbd/Kbd.svelte'
7+
import ReactKbd from '@components/Kbd/Kbd.tsx'
8+
import { keyMap } from '@components/Kbd/keyMap'
9+
10+
import { getSections } from '@helpers'
11+
12+
const sections = getSections({
13+
title: 'kbds',
14+
components: [AstroKbd, SvelteKbd, ReactKbd]
15+
})
16+
---
17+
18+
<Layout>
19+
<h1>Kbd</h1>
20+
<div class="grid md-2 lg-3">
21+
<ComponentWrapper type="Astro">
22+
<AstroKbd keys={['cmd', 'shift']}>A</AstroKbd>
23+
</ComponentWrapper>
24+
25+
<ComponentWrapper type="Svelte">
26+
<SvelteKbd keys={['ctrl', 'space']}>S</SvelteKbd>
27+
</ComponentWrapper>
28+
29+
<ComponentWrapper type="React">
30+
<ReactKbd keys={['up', 'down']}>R</ReactKbd>
31+
</ComponentWrapper>
32+
</div>
33+
34+
{sections.map(section => (
35+
<h1>{section.title}</h1>
36+
<Fragment>
37+
{section.subTitle && <h2 set:html={section.subTitle} />}
38+
</Fragment>
39+
<div class="grid md-2 lg-3">
40+
<ComponentWrapper title="No key">
41+
<section.component>N</section.component>
42+
<section.component keys={['capslock']} />
43+
</ComponentWrapper>
44+
45+
<ComponentWrapper title="One key">
46+
<section.component keys={['cmd']}>O</section.component>
47+
</ComponentWrapper>
48+
49+
<ComponentWrapper title="All keys"s>
50+
<section.component keys={Object.keys(keyMap)}>All</section.component>
51+
</ComponentWrapper>
52+
</div>
53+
))}
54+
</Layout>

src/pages/index.astro

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import Footer from '@components/Footer/Footer.astro'
2020
import Group from '@components/Group/Group.astro'
2121
import Icon from '@components/Icon/Icon.astro'
2222
import Input from '@components/Input/Input.astro'
23+
import Kbd from '@components/Kbd/Kbd.astro'
2324
import List from '@components/List/List.astro'
2425
import Masonry from '@components/Masonry/Masonry.astro'
2526
import Menu from '@components/Menu/Menu.astro'
@@ -203,6 +204,9 @@ const tabItems = [{
203204
<CardWrapper title="Input" href="/components/input">
204205
<Input placeholder="Please enter your email." />
205206
</CardWrapper>
207+
<CardWrapper title="Kbd" href="/components/kbd">
208+
<Kbd keys={['cmd', 'shift']}>K</Kbd>
209+
</CardWrapper>
206210
<CardWrapper title="List" href="/components/list">
207211
<List
208212
itemGroups={listPreview}

0 commit comments

Comments
 (0)