1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | import classNames from "classnames";
|
18 | import * as React from "react";
|
19 | import { polyfill } from "react-lifecycles-compat";
|
20 |
|
21 | import { AbstractPureComponent2, Classes, DISPLAYNAME_PREFIX } from "../../common";
|
22 | import { HOTKEYS_HOTKEY_CHILDREN } from "../../common/errors";
|
23 | import { isElementOfType, isReactChildrenElementOrElements } from "../../common/utils";
|
24 | import { H4 } from "../html/html";
|
25 | import { Hotkey, IHotkeyProps } from "./hotkey";
|
26 | import { IHotkeysProps } from "./hotkeysTypes";
|
27 |
|
28 | @polyfill
|
29 | export class Hotkeys extends AbstractPureComponent2<IHotkeysProps> {
|
30 | public static displayName = `${DISPLAYNAME_PREFIX}.Hotkeys`;
|
31 |
|
32 | public static defaultProps = {
|
33 | tabIndex: 0,
|
34 | };
|
35 |
|
36 | public render() {
|
37 | if (!isReactChildrenElementOrElements(this.props.children)) {
|
38 | return null;
|
39 | }
|
40 |
|
41 | const hotkeys = React.Children.map(
|
42 | this.props.children,
|
43 | (child: React.ReactElement<IHotkeyProps>) => child.props,
|
44 | );
|
45 |
|
46 |
|
47 | hotkeys.sort((a, b) => {
|
48 | if (a.global === b.global && a.group && b.group) {
|
49 | return a.group.localeCompare(b.group);
|
50 | }
|
51 | return a.global ? -1 : 1;
|
52 | });
|
53 |
|
54 | let lastGroup: string | undefined;
|
55 | const elems = [] as JSX.Element[];
|
56 | for (const hotkey of hotkeys) {
|
57 | const groupLabel = hotkey.group;
|
58 | if (groupLabel !== lastGroup) {
|
59 | elems.push(<H4 key={`group-${elems.length}`}>{groupLabel}</H4>);
|
60 | lastGroup = groupLabel;
|
61 | }
|
62 | elems.push(<Hotkey key={elems.length} {...hotkey} />);
|
63 | }
|
64 | const rootClasses = classNames(Classes.HOTKEY_COLUMN, this.props.className);
|
65 | return <div className={rootClasses}>{elems}</div>;
|
66 | }
|
67 |
|
68 | protected validateProps(props: IHotkeysProps & { children: React.ReactNode }) {
|
69 | if (!isReactChildrenElementOrElements(props.children)) {
|
70 | return;
|
71 | }
|
72 |
|
73 | React.Children.forEach(props.children, (child: JSX.Element) => {
|
74 | if (!isElementOfType(child, Hotkey)) {
|
75 | throw new Error(HOTKEYS_HOTKEY_CHILDREN);
|
76 | }
|
77 | });
|
78 | }
|
79 | }
|