skip to Main Content

I am having a component like this: (Code Sandbox: https://codesandbox.io/s/boring-platform-1ry6b2?file=/src/App.js)
enter image description here

The green part is div. Here’s my code:

import { useState } from "react";
import "./styles.css";

export default function App() {
  const [insideApp, setInsideApp] = useState(false);
  return (
    <div onFocus={() => setInsideApp(true)} onBlur={() => setInsideApp(false)}>
      <div className="App">
        <input className="input" />
        {insideApp && <button>Show Button</button>}
      </div>
      <p>Out of Box content</p>
    </div>
  );
}

/* css */
.App {
  display: flex;
  border: 2px solid aqua;
  align-items: center;
  column-gap: 2vw;
  padding: 2rem;
}

.App:focus-within {
  border: 2px solid lime;
}

.input {
  flex: auto;
}

What I want ideally is when I navigate to the button through tab it should get highlighted as shown below:

enter image description here

However since I am rendering the button conditionally I am losing focus. Can someone help me come up with some innovative idea to achieve the same? I want the div to change to lime when its focussed and then do a tab navigation such that it detects input as well as button.

Also I want button to be only shown when focus is within the div.

2

Answers


  1. Have look to SyntheticEvents https://reactjs.org/docs/events.html

    There are two events onMouseEnter and onMouseLeave to you use these two events for highlighting the div and hiding the button.

    <div
          onMouseEnter={() => setInsideApp(true)}
          onMouseLeave={() => setInsideApp(false)}
        >
          <div className="App">
            {insideApp ? (
              <div>
                <input className="input" />
    
                <button>Show Button</button>
              </div>
            ) : null}
          </div>
          <p>Out of Box content</p>
        </div>
    
    Login or Signup to reply.
  2. You could use plain CSS to handle all the process:

    import { useState } from "react";
    import "./styles.css";
    
    export default function App() {
      // const [insideApp, setInsideApp] = useState(false);
      return (
        <div>
          <div
            className="App">
            <input className="input" />
            <button>Show Button</button>
          </div>
          <p>Out of Box content</p>
        </div>
      );
    }
    

    CSS:

    .App {
      display: flex;
      border: 2px solid aqua;
      align-items: center;
      column-gap: 2vw;
      padding: 2rem;
    }
    
    .App:focus-within {
      border: 2px solid lime;
    }
    
    
    .App button {
      display: none;
      pointer-events: none;
    }
    .App:focus-within button {
      display: flex;
      pointer-events: auto;
    }
    
    .input {
      flex: auto;
    }
    

    Explanation:

    1. use :focus-within to conditionnaly display the button
    2. disable cursor events for the button element and hide it as default to prevent interactions
    3. enable cursor events and display the button when :focus-within is active
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search