Search code examples
javascriptcssreactjsstylesstyled-components

how can i focus only one button at a time and not several at the same time?


can you help me with styling? I have these buttons, but only one can turn blue (focus) at a time and not several at the same time

my components is like this...

import { Container, Content } from './styles';

function PressedButton({ children, ...rest }) {
  const [pressed, setPressed] = useState(false);

  return (
    <Container>
      <Content
        type="button" {...rest}
        pressed={pressed}
        onFocus={() => setPressed(!pressed)}
        >
      {children}
      </Content>
    </Container>
  );
}

styles of PressedButton...

import styled from 'styled-components';
(...)
export const Content = styled.button`
  (...)

  //props
  background: ${({ pressed })  => pressed ? `linear-gradient(#449fd8, #1b699a)`: '#2a2a2a'};
  color: ${({ pressed })  => pressed ? '#fff': '#7d7d7d'};

my problem rendered

in the parent is rendering like this...

tags.forEach((tag) => {
    let saida = <PressedButton onClick={() => handleTag(tag)}>{tag}</PressedButton>

Solution

  • Your code could look something like this to achieve what you're looking for:

    function parentComponet() {
      // vvv this was added vvv
      const [pressedIndex, setPressedIndex] = useState(null);
      // ... everything else
      // vvv code was added here too compare to your original code vvv
      tags.forEach((tag, index) => {
        let saida = <PressedButton pressed={pressedIndex === index} onClick={() => {handleTag(tag); setPressedIndex(index)}}>{tag}</PressedButton>
    }
    

    And then on the child:

    function PressedButton({ children, pressed, ...rest }) {
      // vvv this was removed vvv
      // const [pressed, setPressed] = useState(false);
    
      return (
        <Container>
          <Content
            type="button" {...rest}
            pressed={pressed}
            onFocus={() => setPressed(!pressed)}
            >
          {children}
          </Content>
        </Container>
      );
    }
    

    Essentially what this is doing is moving the state up to the parent component. This is inline with react state methodology that if you have a piece of state that needs to be coordinated between buttons, then you should move that state up to the component that is responsible for rendering the buttons.