about summary refs log tree commit diff
path: root/app/javascript/flavours/glitch/features/compose/components/dropdown.js
diff options
context:
space:
mode:
authorThibaut Girka <thib@sitedethib.com>2019-08-06 14:18:09 +0200
committerThibaut Girka <thib@sitedethib.com>2019-08-06 16:36:18 +0200
commitd10f6036cfeebec5b2c160db8659d2c19d29fe9c (patch)
tree696f5ae9a70891e96fdf819905b05aa6482bcf07 /app/javascript/flavours/glitch/features/compose/components/dropdown.js
parent6d2b0fa3f0f32c874863e7fe035270dc31cdcc58 (diff)
Implement keyboard navigation in glitch-soc composer
Diffstat (limited to 'app/javascript/flavours/glitch/features/compose/components/dropdown.js')
-rw-r--r--app/javascript/flavours/glitch/features/compose/components/dropdown.js44
1 files changed, 39 insertions, 5 deletions
diff --git a/app/javascript/flavours/glitch/features/compose/components/dropdown.js b/app/javascript/flavours/glitch/features/compose/components/dropdown.js
index 6a5f4575e..60035b705 100644
--- a/app/javascript/flavours/glitch/features/compose/components/dropdown.js
+++ b/app/javascript/flavours/glitch/features/compose/components/dropdown.js
@@ -36,11 +36,12 @@ export default class ComposerOptionsDropdown extends React.PureComponent {
   state = {
     needsModalUpdate: false,
     open: false,
+    openedViaKeyboard: undefined,
     placement: 'bottom',
   };
 
   //  Toggles opening and closing the dropdown.
-  handleToggle = ({ target }) => {
+  handleToggle = ({ target, type }) => {
     const { onModalOpen } = this.props;
     const { open } = this.state;
 
@@ -55,23 +56,52 @@ export default class ComposerOptionsDropdown extends React.PureComponent {
       }
     } else {
       const { top } = target.getBoundingClientRect();
+      if (this.state.open && this.activeElement) {
+        this.activeElement.focus();
+      }
       this.setState({ placement: top * 2 < innerHeight ? 'bottom' : 'top' });
-      this.setState({ open: !this.state.open });
+      this.setState({ open: !this.state.open, openedViaKeyboard: type !== 'click' });
     }
   }
 
   handleKeyDown = (e) => {
     switch (e.key) {
-    case 'Enter':
-      this.handleToggle(key);
-      break;
     case 'Escape':
       this.handleClose();
       break;
     }
   }
 
+  handleMouseDown = () => {
+    if (!this.state.open) {
+      this.activeElement = document.activeElement;
+    }
+  }
+
+  handleButtonKeyDown = (e) => {
+    switch(e.key) {
+    case ' ':
+    case 'Enter':
+      this.handleMouseDown();
+      break;
+    }
+  }
+
+  handleKeyPress = (e) => {
+    switch(e.key) {
+    case ' ':
+    case 'Enter':
+      this.handleToggle(e);
+      e.stopPropagation();
+      e.preventDefault();
+      break;
+    }
+  }
+
   handleClose = () => {
+    if (this.state.open && this.activeElement) {
+      this.activeElement.focus();
+    }
     this.setState({ open: false });
   }
 
@@ -174,6 +204,9 @@ export default class ComposerOptionsDropdown extends React.PureComponent {
           icon={icon}
           inverted
           onClick={this.handleToggle}
+          onMouseDown={this.handleMouseDown}
+          onKeyDown={this.handleButtonKeyDown}
+          onKeyPress={this.handleKeyPress}
           size={18}
           style={{
             height: null,
@@ -192,6 +225,7 @@ export default class ComposerOptionsDropdown extends React.PureComponent {
             onChange={onChange}
             onClose={this.handleClose}
             value={value}
+            openedViaKeyboard={this.state.openedViaKeyboard}
           />
         </Overlay>
       </div>