From 2c321175c6cc03f741cb146779c4bdfd5f916aee Mon Sep 17 00:00:00 2001 From: mertJF Date: Fri, 29 May 2020 00:46:45 +0300 Subject: [PATCH] App :: keyboard navigation added MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit left arrow — hide sidebar right arrow — show sidebar up arrow — previous block down arrow — next block --- src/App.js | 124 ++++++++++++++++++++++++++++++----- src/blocks/footer/dark/a.js | 4 +- src/blocks/footer/dark/b.js | 4 +- src/blocks/footer/dark/c.js | 2 +- src/blocks/footer/dark/d.js | 4 +- src/blocks/footer/dark/e.js | 4 +- src/blocks/footer/light/a.js | 4 +- src/blocks/footer/light/b.js | 4 +- src/blocks/footer/light/c.js | 2 +- src/blocks/footer/light/d.js | 4 +- src/blocks/footer/light/e.js | 4 +- src/blocks/header/dark/a.js | 2 +- src/blocks/header/dark/b.js | 2 +- src/blocks/header/dark/c.js | 2 +- src/blocks/header/dark/d.js | 2 +- src/blocks/header/light/a.js | 2 +- src/blocks/header/light/b.js | 2 +- src/blocks/header/light/c.js | 2 +- src/blocks/header/light/d.js | 2 +- src/index.css | 106 +++++++++++++++++++++++++++++- 20 files changed, 237 insertions(+), 45 deletions(-) diff --git a/src/App.js b/src/App.js index 5c30bc0..35d9d09 100644 --- a/src/App.js +++ b/src/App.js @@ -6,6 +6,12 @@ import getBlock from './blocks'; import getIcons from './icons'; const iconList = getIcons(); +const blockListArr = []; + +Object.entries(iconList).forEach(([type, icons]) => { + Object.keys(icons).map(name => blockListArr.push(`${name},${type}`)); +}); + const themeList = ["indigo", "orange", "teal", "red", "purple", "pink", "blue", "green"]; const desktopIcon = ( @@ -88,6 +94,7 @@ class App extends Component { copied: false, sidebar: true, codeView: false, + currentKeyCode: null, view: 'desktop', theme: 'indigo', blockType: 'Blog', @@ -103,6 +110,7 @@ class App extends Component { this.toggleSidebar = this.toggleSidebar.bind(this); this.toggleView = this.toggleView.bind(this); this.copyToClipboard = this.copyToClipboard.bind(this); + this.keyboardNavigation = this.keyboardNavigation.bind(this); this.markupRef = React.createRef(); this.textareaRef = React.createRef(); this.sidebarRef = React.createRef(); @@ -110,21 +118,12 @@ class App extends Component { } componentDidMount() { - window.focus(); - const iframe = document.querySelector('iframe'); + document.addEventListener('keydown', this.keyboardNavigation); + } + + hideSidebar() { const sidebar = this.sidebarRef.current; const opener = this.openerRef.current; - let iframeMouseOver = false; - - window.focus(); - window.addEventListener('blur', () => { - if (iframeMouseOver) { - this.setState({ sidebar: false }); - } - }); - - iframe.addEventListener('mouseover', () => iframeMouseOver = true); - iframe.addEventListener('mouseout', () => iframeMouseOver = false); document.addEventListener('click', (e) => { if (e.target === opener) { @@ -137,11 +136,77 @@ class App extends Component { }); } + keyboardNavigation(e) { + const { blockType, blockName } = this.state; + const blockStringFormat = `${blockName},${blockType}`; + const keyCode = e.which || e.keyCode; + + switch (keyCode) { + case 40: // Down + e.preventDefault(); + blockListArr.forEach((block, index) => { + if (block === blockStringFormat) { + const newActiveBlock = index + 1 <= blockListArr.length - 1 ? blockListArr[index + 1].split(',') : blockListArr[0].split(','); + const newBlockName = newActiveBlock[0]; + const newBlockType = newActiveBlock[1]; + const newBlockNode = document.querySelector(`.block-item[block-name="${newBlockName}"]`); + if (newBlockNode) newBlockNode.focus(); + this.setState({ + blockType: newBlockType, + blockName: newBlockName, + codeView: false, + currentKeyCode: 40 + }); + } + }); + break; + case 37: // Left + e.preventDefault(); + this.setState({ sidebar: false, currentKeyCode: 37 }); + break; + case 39: // Right + e.preventDefault(); + this.setState({ sidebar: true, currentKeyCode: 39 }); + break; + case 38: // Up + e.preventDefault(); + blockListArr.forEach((block, index) => { + if (block === blockStringFormat) { + const newActiveBlock = index - 1 >= 0 ? blockListArr[index - 1].split(',') : blockListArr[blockListArr.length - 1].split(','); + const newBlockName = newActiveBlock[0]; + const newBlockType = newActiveBlock[1]; + const newBlockNode = document.querySelector(`.block-item[block-name="${newBlockName}"]`); + if (newBlockNode) newBlockNode.focus(); + + this.setState({ + blockType: newBlockType, + blockName: newBlockName, + codeView: false, + currentKeyCode: 38 + }); + } + }); + break; + default: + return; + } + + setTimeout(() => { + if (keyCode === 37 || keyCode === 38 || keyCode === 39 || keyCode === 40) { + this.setState({ currentKeyCode: null }) + } + }, 200); + } + changeMode() { this.setState({ darkMode: !this.state.darkMode }) } handleContentDidMount() { + const iframe = document.querySelector('iframe'); + iframe.contentWindow.document.addEventListener('keydown', this.keyboardNavigation); + iframe.contentWindow.document.addEventListener('click', () => this.setState({ sidebar: false })); + setTimeout(() => { this.setState({ ready: true, @@ -187,7 +252,6 @@ class App extends Component { blockType, blockName, codeView: false }); - } changeTheme(e) { @@ -209,7 +273,7 @@ class App extends Component { themeListRenderer() { const { theme } = this.state; return themeList.map((t, k) => - + ) } @@ -219,7 +283,7 @@ class App extends Component {
{type}
- {Object.entries(icons).map(icon => )} + {Object.entries(icons).map(icon => )}
); @@ -251,7 +315,7 @@ class App extends Component { } render() { - const { darkMode, theme, blockName, blockType, sidebar, view, copied } = this.state; + const { darkMode, theme, blockName, blockType, sidebar, view, copied, currentKeyCode } = this.state; return (