<div id='root'></div>
table, th, td {
  border: 1px solid black;
  border-collapse: collapse;
}

th, td {
  padding: 5px;
}

.sidebar {
  background-color: #dddddd;
  position: fixed;
  top: 0;
  right: 0px;
  transition: right 0.5s;
  width: 40%;
  height: 100vh;
  padding: 0.5rem;
  
  h1 {
    text-transform: capitalize;
  }
  
  &.hidden {
    right: -100%;
    transition: right 0.7s ease;
  }
}
View Compiled
const { Fragment, useState, useRef } = React;

const TableCell = ({ colors, updateSidebar }) => {
  const buttonRef = useRef(null);
  
  return (
    <td>
      <button
        onClick={() => updateSidebar(colors, buttonRef)}
        ref={buttonRef}
      >
        { colors.output }
      </button>
    </td>
  )
}

const Table = ({ updateSidebar }) => (
  <table>
    <tr>
      <td></td>
      <th>Red</th>
      <th>Blue</th>
    </tr>
    <tr>
      <th>Blue</th>
      <TableCell
        colors={{
          input1: "blue",
          input2: "red",
          output: "purple"
        }}
        updateSidebar={updateSidebar}
      />
      <TableCell
        colors={{
          input1: "blue",
          input2: "blue",
          output: "blue"
        }}
        updateSidebar={updateSidebar}
      />
    </tr>
    <tr>
      <th>Yellow</th>
      <TableCell
        colors={{
          input1: "red",
          input2: "yellow",
          output: "orange"
        }}
        updateSidebar={updateSidebar}
      />
      <TableCell
        colors={{
          input1: "blue",
          input2: "yellow",
          output: "green"
        }}
        updateSidebar={updateSidebar}
      />
    </tr>
  </table>
)

const Sidebar = ({ colors, hideSidebar, isHidden, sidebarRef }) => {
  const sidebarClasses = [
      "sidebar",
      isHidden ? "hidden" : null,
  ].join(' ');
  
  return (
    <aside className={sidebarClasses}>
      <h1
        ref={sidebarRef}
        tabIndex={-1}
      >
        {colors && colors.output}
      </h1>
      <button
        onClick={hideSidebar}
        >
        Close sidebar
      </button>
      <p>
        Mixing {colors && colors.input1} and {colors && colors.input2} makes {colors && colors.output}!
      </p>
    </aside>
  )
}

const App = () => {
  const [showSidebar, setShowSidebar] = useState(false);
  const [activeCell, setActiveCell] = useState(null);
  const [lastCellClicked, setLastCellClicked] = useState(null);
  const sidebarRef = useRef(null);
  
  const updateSidebar = (colors, buttonRef) => {
    setLastCellClicked(buttonRef);
    setActiveCell(colors);
    setShowSidebar(true);
    sidebarRef.current.focus();
  };

  const hideSidebar = () => {
    setShowSidebar(false);
    lastCellClicked.current.focus();
  };
  
  return (
    <Fragment>
      <Table
        updateSidebar={updateSidebar}
      />
      <Sidebar
        colors={activeCell}
        hideSidebar={hideSidebar}
        isHidden={!showSidebar}
        sidebarRef={sidebarRef}
      /> 
    </Fragment>
  )
};

ReactDOM.render(<App />, document.getElementById('root'));
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.12.0/umd/react-dom.production.min.js