Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NIMBUS] [BUG] Can't control Popover visibility directly #251

Open
GustavoSmith opened this issue Sep 13, 2024 · 0 comments
Open

[NIMBUS] [BUG] Can't control Popover visibility directly #251

GustavoSmith opened this issue Sep 13, 2024 · 0 comments
Labels
bug Something isn't working

Comments

@GustavoSmith
Copy link

🐛 Describe the bug

Currently, the popover component doesn't offer any way to control it's visibility. This leads to some bugs that are not desirable.

🧐 To Reproduce
Steps to reproduce the behavior:

  1. Open a Popover that opens a modal (for example, a Menu popover on a Table Row with actions).
  2. Both the modal and the popover will be shown on screen, and the only way to disable this is targeting ALL the popovers via CSS (as suggested by Tiendanube's support team).
  3. This leads to another bug: I can't use any Popover inside the modal (like the Calendar for Date Picking).

Expected behavior
The popover should expose a variable for controlling it's visibility. Because Popovers are rendered at the document.body level via React Portal, targeting the visibility of any parent element is not enough.

📷 Screenshots

image

🖥 Desktop (please complete the following information):

  • OS: Windows 10
  • Browser: Chrome
  • Version: 128.0.6613.138

❗️ Additional context
Here's a code snippet for testing purposes:

import React from "react";
import {
  Box,
  Button,
  Icon,
  Input,
  Modal,
  Popover,
  Text,
  Title,
} from "@nimbus-ds/components";
import {
  DownloadIcon,
  FileAltIcon,
  EllipsisIcon,
  CalendarIcon,
} from "@nimbus-ds/icons";
import { Calendar } from "@nimbus-ds/patterns";

import { format } from "date-fns";
import { es } from "date-fns/locale";

const Example = () => {
  const [modalProps, setModalProps] = React.useState({
    isOpen: false,
    invoiceId: "",
    amount: "",
  });

  // Tiendanube's official fix: This prevents the Date Picker modal from showing.

  /* React.useEffect(() => {
    if (modalProps.isOpen) {
      document.body.classList.add("[&>#nimbus-popover-floating]:hidden");
    } else {
      document.body.classList.remove("[&>#nimbus-popover-floating]:hidden");
    }
  }, [modalProps]); */

  const InvoiceModal = () => {
    const [selectedDate, setSelectedDate] = React.useState<Date | undefined>();
    return (
      <Modal
        open={modalProps.isOpen}
        onDismiss={() =>
          setModalProps((prev) => ({
            ...prev,
            isOpen: false,
          }))
        }
      >
        <Modal.Header>
          <Box
            alignItems="center"
            display="flex"
            gap="4"
            justifyContent="space-between"
          >
            <Title as="h3">Custom action</Title>
          </Box>
        </Modal.Header>
        <Modal.Body>
          <Box display="flex" flexDirection="column" gap="2">
            <Text fontSize="base" lineHeight="base" textAlign="left">
              Invoice id:
              <span className="font-bold">{modalProps.invoiceId}</span>
            </Text>

            <Text fontSize="base" lineHeight="base" textAlign="left">
              Amount: <span className="font-bold">{modalProps.amount}</span>
            </Text>
          </Box>
          <Box width="full" display="flex" flexDirection="column" gap="1">
            <Text>Date field</Text>
            <Popover
              content={
                <Calendar
                  mode="single"
                  showOutsideDays
                  selected={selectedDate}
                  onSelect={setSelectedDate}
                  hideBorder
                  locale={es}
                  fullWidthDays
                  containerProps={{
                    width: "100%",
                    height: "100%",
                    overflowY: "auto",
                    maxHeight: "400px",
                  }}
                  required
                />
              }
              padding="none"
              arrow={true}
            >
              <Input
                id="customDate"
                name="customDate"
                readOnly
                value={selectedDate && format(selectedDate, "dd-MM-yyyy")}
                placeholder="03/04/2024"
                append={
                  <Icon color="neutral-textLow" source={<CalendarIcon />} />
                }
                appendPosition="end"
              />
            </Popover>
          </Box>
        </Modal.Body>
        <Modal.Footer>
          <Button
            appearance="neutral"
            onClick={() => {
              setModalProps((prev) => ({
                ...prev,
                isOpen: false,
              }));
            }}
          >
            Close
          </Button>
          <Button
            appearance="primary"
            onClick={() => {
              setModalProps((prev) => ({
                ...prev,
                isOpen: false,
              }));
            }}
          >
            Submit
          </Button>
        </Modal.Footer>
      </Modal>
    );
  };

  return (
    <>
      <InvoiceModal />
      <Box display="flex" justifyContent="center">
        <Popover
          position="left"
          content={
            <Box display="flex" flexDirection="column" gap="2">
              <Button appearance="transparent" as="a" href="/">
                <Icon source={<DownloadIcon />} />
                Option 1
              </Button>
              <Button
                appearance="transparent"
                onClick={() => {
                  setModalProps({
                    isOpen: true,
                    invoiceId: "123456",
                    amount: "1000",
                  });
                }}
              >
                <Icon source={<FileAltIcon />} />
                Open Action Modal (with props)
              </Button>
            </Box>
          }
        >
          <Button appearance="transparent">
            <Icon color="neutral-textHigh" source={<EllipsisIcon />} />
          </Button>
        </Popover>
      </Box>
    </>
  );
};

export default Example;
@GustavoSmith GustavoSmith added the bug Something isn't working label Sep 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant