-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(HotkeysPanel): add component (#53)
* fix(CompositeBar): fix for listItems * feat(HotkeysPanel): add component * fix(HotkeysPanel): fix usage in readme * fix(HotkeysPanel): fix double scroll
- Loading branch information
Showing
13 changed files
with
430 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
@use '../variables'; | ||
@import '../../../styles/mixins'; | ||
|
||
$block: '.#{variables.$ns}hotkeys-panel'; | ||
|
||
#{$block} { | ||
position: fixed; | ||
top: 0; | ||
left: 0; | ||
right: 0; | ||
bottom: 0; | ||
|
||
--hotkeys-panel-width: 400px; | ||
--hotkeys-panel-vertical-padding: 18px; | ||
--hotkeys-panel-horizontal-padding: 24px; | ||
|
||
&__drawer-item { | ||
width: var(--hotkeys-panel-width); | ||
padding: var(--hotkeys-panel-vertical-padding) 0; | ||
box-sizing: border-box; | ||
display: flex; | ||
flex-direction: column; | ||
} | ||
|
||
&__title { | ||
margin: 0 var(--hotkeys-panel-horizontal-padding) 16px | ||
var(--hotkeys-panel-horizontal-padding); | ||
} | ||
|
||
&__search { | ||
padding: 0 var(--hotkeys-panel-horizontal-padding); | ||
margin-bottom: 14px; | ||
} | ||
|
||
&__list { | ||
flex: 1; | ||
overflow-y: auto; | ||
} | ||
|
||
&__item { | ||
height: auto; | ||
padding: 8px var(--hotkeys-panel-horizontal-padding); | ||
|
||
&.yc-list__item_active { | ||
background: inherit; | ||
} | ||
} | ||
|
||
&__item-content { | ||
display: flex; | ||
align-items: baseline; | ||
justify-content: space-between; | ||
|
||
width: 100%; | ||
|
||
font-size: var(--yc-text-body-1-font-size); | ||
line-height: var(--yc-text-body-1-line-height); | ||
|
||
color: var(--yc-color-text-primary); | ||
|
||
&_group { | ||
font-size: var(--yc-text-body-2-font-size); | ||
font-weight: 500; | ||
line-height: var(--yc-text-body-2-line-height); | ||
} | ||
} | ||
|
||
&__hotkey { | ||
color: var(--yc-color-text-complementary); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import React, {useMemo, useCallback, useState} from 'react'; | ||
import type {ReactNode} from 'react'; | ||
|
||
import {Hotkey, List, TextInput} from '@gravity-ui/uikit'; | ||
import type {ListProps} from '@gravity-ui/uikit'; | ||
|
||
import {Drawer, DrawerItem} from '../Drawer/Drawer'; | ||
import type {DrawerProps} from '../Drawer/Drawer'; | ||
import {block} from '../utils/cn'; | ||
|
||
import {flattenHotkeyGroups} from './utils/flattenHotkeyGroups'; | ||
import {filterHotkeys} from './utils/filterHotkeys'; | ||
import type {HotkeysListItem, HotkeysGroup} from './types'; | ||
import './HotkeysPanel.scss'; | ||
|
||
const b = block('hotkeys-panel'); | ||
|
||
export type HotkeysPanelProps<T> = { | ||
hotkeys: HotkeysGroup<T>[]; | ||
title?: ReactNode; | ||
filterPlaceholder?: string; | ||
emptyState?: ReactNode; | ||
visible: boolean; | ||
onClose?: () => void; | ||
className?: string; | ||
leftOffset?: number | string; | ||
topOffset?: number | string; | ||
preventScrollBody?: DrawerProps['preventScrollBody']; | ||
} & Omit<ListProps<HotkeysListItem>, 'items' | 'emptyPlaceholder'>; | ||
|
||
export function HotkeysPanel<T = {}>({ | ||
visible, | ||
onClose, | ||
leftOffset, | ||
topOffset, | ||
className, | ||
preventScrollBody, | ||
hotkeys, | ||
itemClassName, | ||
filterPlaceholder, | ||
title, | ||
emptyState, | ||
...listProps | ||
}: HotkeysPanelProps<T>) { | ||
const [filter, setFilter] = useState(''); | ||
|
||
const hotkeysList = useMemo(() => { | ||
const filteredHotkeys = filterHotkeys(hotkeys, filter); | ||
return flattenHotkeyGroups(filteredHotkeys); | ||
}, [hotkeys, filter]); | ||
|
||
const renderItem = useCallback( | ||
(item: HotkeysListItem) => ( | ||
<div className={b('item-content', {group: item.group})} key={item.title}> | ||
{item.title} | ||
{item.value && <Hotkey className={b('hotkey')} value={item.value} />} | ||
</div> | ||
), | ||
[], | ||
); | ||
|
||
const drawerItemContent = ( | ||
<React.Fragment> | ||
<h2 className={b('title')}>{title}</h2> | ||
<TextInput | ||
value={filter} | ||
onUpdate={setFilter} | ||
placeholder={filterPlaceholder} | ||
autoFocus | ||
className={b('search')} | ||
/> | ||
<List<HotkeysListItem> | ||
className={b('list')} | ||
virtualized={false} | ||
filterable={false} | ||
items={hotkeysList} | ||
renderItem={renderItem} | ||
itemClassName={b('item', itemClassName)} | ||
emptyPlaceholder={emptyState as string} | ||
{...listProps} | ||
/> | ||
</React.Fragment> | ||
); | ||
|
||
return ( | ||
<Drawer | ||
className={b(null, className)} | ||
onVeilClick={onClose} | ||
onEscape={onClose} | ||
preventScrollBody={preventScrollBody} | ||
style={{ | ||
left: leftOffset, | ||
top: topOffset, | ||
}} | ||
> | ||
<DrawerItem | ||
id="hotkeys" | ||
visible={visible} | ||
className={b('drawer-item')} | ||
content={drawerItemContent} | ||
/> | ||
</Drawer> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
## HotkeysPanel | ||
|
||
A panel for hotkeys documentation | ||
|
||
### PropTypes | ||
|
||
| Property | Type | Required | Default | Description | | ||
| :---------------- | :-------------- | :------: | :------ | :------------------------------- | | ||
| className | `String` | | | Drawer class | | ||
| visible | `Boolean` | yes | | Whether drawer visible or not | | ||
| onClose | `Function` | | | close drawer handler | | ||
| leftOffset | `Number/String` | | 0 | drawer left offset | | ||
| topOffset | `Number/String` | | 0 | drawer top offset | | ||
| preventScrollBody | `Boolean` | | true | Disable body scroll when visible | | ||
| hotkeys | `Array` | yes | | List of hotkey groups | | ||
|
||
And all the `List` PropTypes, but not `items` (you can find them [here](https://github.com/gravity-ui/uikit/blob/main/src/components/List/README.md)) | ||
|
||
### Usage | ||
|
||
See storybook example `src/components/HotkeysPanel/__stories__/HotkeysPanelShowcase`. |
13 changes: 13 additions & 0 deletions
13
src/components/HotkeysPanel/__stories__/HotkeysPanel.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import React from 'react'; | ||
import {Meta, Story} from '@storybook/react/types-6-0'; | ||
|
||
import {HotkeysPanel} from '..'; | ||
import {HotkeysPanelShowcase} from './HotkeysPanelShowcase'; | ||
|
||
export default { | ||
title: 'components/HotkeysPanel', | ||
component: HotkeysPanel, | ||
} as Meta; | ||
|
||
const ShowcaseTemplate: Story = () => <HotkeysPanelShowcase />; | ||
export const Showcase = ShowcaseTemplate.bind({}); |
41 changes: 41 additions & 0 deletions
41
src/components/HotkeysPanel/__stories__/HotkeysPanelShowcase.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
@import '../../../../styles/mixins'; | ||
|
||
.hotkeys-panel-showcase { | ||
display: flex; | ||
flex-direction: column; | ||
position: relative; | ||
box-sizing: border-box; | ||
|
||
*, | ||
*::before, | ||
*::after { | ||
box-sizing: inherit; | ||
} | ||
|
||
&__header { | ||
width: 100%; | ||
padding: 20px; | ||
border-bottom: 1px solid var(--yc-color-line-generic); | ||
} | ||
|
||
&__title { | ||
display: flex; | ||
gap: 8px; | ||
align-items: baseline; | ||
} | ||
|
||
&__body { | ||
position: absolute; | ||
top: 77px; | ||
background-color: var(--yc-color-base-generic); | ||
height: 100vh; | ||
width: 100%; | ||
} | ||
|
||
&__empty { | ||
margin: 48px auto 0; | ||
font-size: var(--yc-text-header-1-font-size); | ||
line-height: var(--yc-text-header-1-line-height); | ||
color: var(--yc-color-text-primary); | ||
} | ||
} |
44 changes: 44 additions & 0 deletions
44
src/components/HotkeysPanel/__stories__/HotkeysPanelShowcase.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import React from 'react'; | ||
import block from 'bem-cn-lite'; | ||
|
||
import {Button, Hotkey} from '@gravity-ui/uikit'; | ||
|
||
import {HotkeysPanel} from '../../../components/HotkeysPanel'; | ||
|
||
import {hotkeys} from './moc'; | ||
import './HotkeysPanelShowcase.scss'; | ||
|
||
const b = block('hotkeys-panel-showcase'); | ||
|
||
export function HotkeysPanelShowcase() { | ||
const [visible, setVisible] = React.useState<boolean>(true); | ||
|
||
const handleClose = () => { | ||
setVisible(false); | ||
}; | ||
|
||
return ( | ||
<div className={b()}> | ||
<div className={b('header')}> | ||
<Button view="action" size="l" onClick={() => setVisible(!visible)}> | ||
{visible ? 'Hide hotkeys' : 'Show hotkeys'} | ||
</Button> | ||
</div> | ||
<div className={b('body')} /> | ||
<HotkeysPanel | ||
hotkeys={hotkeys} | ||
visible={visible} | ||
onClose={handleClose} | ||
topOffset={77} | ||
title={ | ||
<span className={b('title')}> | ||
Hotkeys | ||
<Hotkey value="shift+K" /> | ||
</span> | ||
} | ||
filterPlaceholder="Search" | ||
emptyState={<div className={b('empty')}>No hotkeys found</div>} | ||
/> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import {HotkeysGroup} from '..'; | ||
|
||
export const hotkeys: HotkeysGroup[] = [ | ||
{ | ||
title: 'General', | ||
items: [ | ||
{ | ||
title: 'Copy', | ||
value: 'ctrl+c', | ||
}, | ||
{ | ||
title: 'Paste', | ||
value: 'ctrl+v', | ||
}, | ||
], | ||
}, | ||
{ | ||
title: 'Issue', | ||
items: [ | ||
{ | ||
title: 'Go to comments', | ||
value: 'shift+c', | ||
}, | ||
{ | ||
title: 'Go to history', | ||
value: 'shift+h', | ||
}, | ||
{ | ||
title: 'Go to attachments', | ||
value: 'shift+a', | ||
}, | ||
{ | ||
title: 'Edit description', | ||
value: 'alt+d', | ||
}, | ||
{ | ||
title: 'Add new comment', | ||
value: 'alt+c', | ||
}, | ||
{ | ||
title: 'Edit assignee', | ||
value: 'alt+e', | ||
}, | ||
{ | ||
title: 'Edit watchers', | ||
value: 'alt+w', | ||
}, | ||
{ | ||
title: 'Assignee me', | ||
value: 'm', | ||
}, | ||
{ | ||
title: 'Add me to watchers', | ||
value: 'w', | ||
}, | ||
], | ||
}, | ||
{ | ||
title: 'Board', | ||
items: [ | ||
{ | ||
title: 'Activate grouping select', | ||
value: 'alt+g', | ||
}, | ||
{ | ||
title: 'Activate sorting select', | ||
value: 'alt+s', | ||
}, | ||
{ | ||
title: 'Go to the backlog', | ||
value: 'shift+b', | ||
}, | ||
], | ||
}, | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './HotkeysPanel'; | ||
export type {HotkeysGroup, HotkeysItem} from './types'; |
Oops, something went wrong.