DEV Community

Breno Novelli
Breno Novelli

Posted on

2 2

useDeleteConfirmation()

Confirmando exclusão

Esse custom hook foi feito para facilitar o uso da caixa de confirmação de deletar um item que se repetia bastante ao longo da aplicação.

No projeto eu usei styled-components e polished no trechos de css. Fiquem a vontade para usar suas libs preferidas.

Importante
Esse artigo não tem o código completo do componente do box. Faltaria anexar seu componente de botão preferido.

Hook

useDeleteConfirmation.js

import { useState } from "react";

import DeleteConfirmation from "~/components/DeleteConfirmation";

/**
 * Gerencia o componente de confirmação de exclusão
 *
 * @example
 *
 *  const [DeleteConfirmation, activeConfirmation, setActiveConfirmation] = useDeleteConfirmation();
 *
 *  <Button onClick={setActiveConfirmation} />
 *
 *   <DeleteConfirmation
 *      active={activeConfirmation}
 *      onDelete={handleDelete}
 *      onCancel={setActiveConfirmation}
 *      yesMsg="Sim, desejo apagar"
 *      loading={loadingDelete}
 *    >
 *      Tem certeza que deseja apagar este produto?
 *    </DeleteConfirmation>
 *
 */

const useDeleteConfirmation = (initialValue = false) => {
  const [activeConfirmation, setActiveConfirmation] = useState(initialValue);

  const handleConfirmation = () => setActiveConfirmation(!activeConfirmation);

  return [DeleteConfirmation, activeConfirmation, handleConfirmation];
};

export { useDeleteConfirmation };
Enter fullscreen mode Exit fullscreen mode

Componente do box de confirmação

components/DeleteConfirmation/index.js

import React from "react";
import PropTypes from "prop-types";
import { Button } from "~/components/Buttons";
import { Container } from "./styles";

/**
 *
 *
 * @param {node} children Text for box
 * @param {boolean} active State on parent component
 * @param {function} onDelete Function to call on delete
 * @param {function} onCancel Function to call on cancel
 * @param {boolean} loading State on reducer ou parent component
 *
 */

const DeleteConfirmation = ({
  children,
  active,
  onDelete,
  onCancel,
  yesMsg,
  loading,
}) => (
  <Container active={active} className="deleteItem">
    <div className="alertBox">
      <span>{children}</span>
      <Button
        onClick={onDelete}
        type="button"
        text={yesMsg}
        template="alert"
        loading={loading}
      />
      <Button
        onClick={onCancel}
        type="button"
        template="delete"
        text="Cancelar"
        loading={loading}
      />
    </div>
  </Container>
);

export default DeleteConfirmation;

DeleteConfirmation.propTypes = {
  children: PropTypes.oneOfType([
    PropTypes.arrayOf(PropTypes.node),
    PropTypes.node,
  ]).isRequired,
  active: PropTypes.bool.isRequired,
  onDelete: PropTypes.func.isRequired,
  onCancel: PropTypes.func.isRequired,
  yesMsg: PropTypes.string,
  loading: PropTypes.bool,
};

DeleteConfirmation.defaultProps = {
  yesMsg: "Sim, quero apagar.",
  loading: false,
};
Enter fullscreen mode Exit fullscreen mode

components/DeleteConfirmation/styles.js

import styled, { css } from "styled-components";
import { darken, rgba } from "polished";

export const Container = styled.div`
  z-index: 20;
  overflow: hidden;

  max-height: 0;
  padding: 0;
  width: 100%;

  display: flex;
  align-items: center;
  justify-content: center;

  border-radius: 0.25rem;
  border: 0 solid #d9534f;
  background: ${darken(0.1, rgba(#d9534f, 0.05))};

  transition: all 0.2s ease-in-out;

  ${(props) =>
    props.active &&
    css`
      max-height: 7rem;
      padding: 0.75rem 0;

      @media (min-width: 992px) {
        padding: 1rem 0;
        max-height: 4rem;
      }
      border-width: 1px;
      margin-bottom: 1.25rem;
    `}

  .alertBox {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-flow: wrap;

    max-width: 100%;
    max-height: 100%;

    padding: 0 0.5rem;
    font-weight: 500;

    > * {
      margin: 0 0.5rem;
    }
  }

  @media (max-width: 992px) {
    .alertBox {
      > span {
        flex: 1 1 100%;
        text-align: center;
        margin-bottom: 0.5rem;
      }

      button {
        min-width: 40%;
      }
    }
  }
`;
Enter fullscreen mode Exit fullscreen mode

O hook exporta:

DeleteConfirmation - Componente

activeConfirmation - Sate do componente / Ativo ou não

setActiveConfirmation - SetState do componente / Abre e fecha box


Componente

SomeComponentWithDeleteAction.js

import { useDeleteConfirmation } from "~/hooks/useDeleteConfirmation";

const [
  DeleteConfirmation,
  activeConfirmation,
  setActiveConfirmation,
] = useDeleteConfirmation();

return (
  <>
    <Button
      template="delete"
      text="Excluir local"
      customWidth="auto"
      onClick={setActiveConfirmation}
      loading={loadingDelete}
    />
    <DeleteConfirmation
      active={activeConfirmation}
      onDelete={handleDelete}
      onCancel={setActiveConfirmation}
      yesMsg="Sim, desejo apagar"
      loading={loadingDelete}
    >
      Tem certeza que deseja apagar este local?
    </DeleteConfirmation>
  </>
);
Enter fullscreen mode Exit fullscreen mode

Do your career a big favor. Join DEV. (The website you're on right now)

It takes one minute, it's free, and is worth it for your career.

Get started

Community matters

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Dive into an ocean of knowledge with this thought-provoking post, revered deeply within the supportive DEV Community. Developers of all levels are welcome to join and enhance our collective intelligence.

Saying a simple "thank you" can brighten someone's day. Share your gratitude in the comments below!

On DEV, sharing ideas eases our path and fortifies our community connections. Found this helpful? Sending a quick thanks to the author can be profoundly valued.

Okay