You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

KeyboardShortcutsDialog.web.js 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /* @flow */
  2. import Lozenge from '@atlaskit/lozenge';
  3. import { withStyles } from '@material-ui/core/styles';
  4. import clsx from 'clsx';
  5. import React, { Component } from 'react';
  6. import { Dialog } from '../../base/dialog';
  7. import { translate } from '../../base/i18n';
  8. /**
  9. * The type of the React {@code Component} props of
  10. * {@link KeyboardShortcutsDialog}.
  11. */
  12. type Props = {
  13. /**
  14. * An object containing the CSS classes.
  15. */
  16. classes: Object,
  17. /**
  18. * A Map with keyboard keys as keys and translation keys as values.
  19. */
  20. shortcutDescriptions: Object,
  21. /**
  22. * Invoked to obtain translated strings.
  23. */
  24. t: Function
  25. };
  26. /**
  27. * Creates the styles for the component.
  28. *
  29. * @param {Object} theme - The current UI theme.
  30. *
  31. * @returns {Object}
  32. */
  33. const styles = theme => {
  34. return {
  35. list: {
  36. listStyleType: 'none',
  37. padding: 0,
  38. '& .shortcuts-list__item': {
  39. display: 'flex',
  40. justifyContent: 'space-between',
  41. marginBottom: theme.spacing(2)
  42. }
  43. }
  44. };
  45. };
  46. /**
  47. * Implements a React {@link Component} which displays a dialog describing
  48. * registered keyboard shortcuts.
  49. *
  50. * @augments Component
  51. */
  52. class KeyboardShortcutsDialog extends Component<Props> {
  53. /**
  54. * Implements React's {@link Component#render()}.
  55. *
  56. * @inheritdoc
  57. * @returns {ReactElement}
  58. */
  59. render() {
  60. const shortcuts = Array.from(this.props.shortcutDescriptions)
  61. .map(description => this._renderShortcutsListItem(...description));
  62. return (
  63. <Dialog
  64. cancelKey = { 'dialog.close' }
  65. submitDisabled = { true }
  66. titleKey = 'keyboardShortcuts.keyboardShortcuts'
  67. width = 'small'>
  68. <div
  69. id = 'keyboard-shortcuts'>
  70. <ul
  71. className = { clsx('shortcuts-list', this.props.classes.list) }
  72. id = 'keyboard-shortcuts-list'>
  73. { shortcuts }
  74. </ul>
  75. </div>
  76. </Dialog>
  77. );
  78. }
  79. /**
  80. * Creates a {@code ReactElement} for describing a single keyboard shortcut.
  81. *
  82. * @param {string} keyboardKey - The keyboard key that triggers an action.
  83. * @param {string} translationKey - A description of what the action does.
  84. * @private
  85. * @returns {ReactElement}
  86. */
  87. _renderShortcutsListItem(keyboardKey, translationKey) {
  88. let modifierKey = 'Alt';
  89. if (window.navigator?.platform) {
  90. if (window.navigator.platform.indexOf('Mac') !== -1) {
  91. modifierKey = '⌥';
  92. }
  93. }
  94. return (
  95. <li
  96. className = 'shortcuts-list__item'
  97. key = { keyboardKey }>
  98. <span
  99. aria-label = { this.props.t(translationKey) }
  100. className = 'shortcuts-list__description'>
  101. { this.props.t(translationKey) }
  102. </span>
  103. <span className = 'item-action'>
  104. <Lozenge isBold = { true }>
  105. { keyboardKey.startsWith(':')
  106. ? `${modifierKey} + ${keyboardKey.slice(1)}`
  107. : keyboardKey }
  108. </Lozenge>
  109. </span>
  110. </li>
  111. );
  112. }
  113. }
  114. export default translate(withStyles(styles)(KeyboardShortcutsDialog));