0
votes

I have a grid with several columns. Each column contains a header with a title. On mouseover, a button to edit the title is appended to the header. This lead the column to grow.

On mouseover, I want to keep the same column width, append the button, and perform an ellipsis on the title if the latter is too long to properly append the button.

I have already managed to implement this behaviour when the columns are not in a grid nor in a flex layout.

How to implement this behaviour in a grid template? The columns should always take 1/3 of the available space, so I can't specify a width.

Here is the code & a sandbox:

// Header
const Root = styled.div`
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: orange;
  padding: 0 12px;
`;

const Title = styled.h1`
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  word-wrap: normal;
  margin-right: 12px;
`;

export default function Header({ title }) {
  const [edit, setEdit] = useState(false);
  return (
    <Root onMouseOver={() => setEdit(true)} onMouseLeave={() => setEdit(false)}>
      <Title>{title}</Title>
      {edit && <button>edit</button>}
    </Root>
  );
}

// Grid

const Grid = styled.div`
  display: grid;
  grid-template-columns: repeat(3, 1fr);
`;

const Col = styled.div`
  margin: 12px;
  padding: 24px;
`;

export default function App() {
  return (
    <>
      <h1>GRID (not ok)</h1>
      <Grid>
        <Col>
          <Header title="Col 1 long title" />
        </Col>
        <Col>
          <Header title="Col 2" />
        </Col>
        <Col>
          <Header title="Col 3" />
        </Col>
      </Grid>
      <h1>NO GRID (OK)</h1>
      <div>
        <Col>
          <Header title="Col 1 long title" />
        </Col>
        <Col>
          <Header title="Col 2" />
        </Col>
        <Col>
          <Header title="Col 3" />
        </Col>
      </div>
    </>
  );
}

the sandbox: https://codesandbox.io/s/dynamic-text-ellipsis-78vbw?file=/src/App.tsx:72-800

Thanks for your help!

1

1 Answers

-1
votes
import styled from "styled-components";

const Button = styled.button`
  opacity: 0;
`;

const Root = styled.div`
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: orange;
  padding: 0 12px;

  :hover {
    ${Button} {
      opacity: 1;
    }
   }
  `;

 const Title = styled.h1`
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  word-wrap: normal;
  margin-right: 12px;
  `;

 export default function Header({ title }) {
 return (
<Root>
  <Title>{title}</Title>
  <Button>edit</Button>
</Root>
);
}