Categories
React

Add a Modal to a React App with Styled React Modal and react-overlays

Modals are something that we have to add often into our React app.

To make this task easier, we can use existing component libraries to add them.

In this article, we’ll look at how to add a modal into our React app with the Styled React Modal and react-overlays libraries.

Styled React Modal

The Styled React Modal library lets us add a modal easily into our React app.

To install it, we run:

npm i styled-react-modal

Then we can use it by writing:

import React, { useState } from "react";
import Modal, { ModalProvider } from "styled-react-modal";
import { ThemeProvider } from "styled-components";

const StyledModal = Modal.styled`
  width: 20rem;
  height: 20rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: white;
`;

function FancyModalButton() {
  const [isOpen, setIsOpen] = useState(false);

  function toggleModal(e) {
    setIsOpen(!isOpen);
  }

  return (
    <div>
      <button onClick={toggleModal}>Click me</button>
      <StyledModal
        isOpen={isOpen}
        onBackgroundClick={toggleModal}
        onEscapeKeydown={toggleModal}
      >
        <span>I am a modal!</span>
        <button onClick={toggleModal}>Close me</button>
      </StyledModal>
    </div>
  );
}

export default function App() {
  return (
    <ThemeProvider theme={{}}>
      <ModalProvider>
        <FancyModalButton />
      </ModalProvider>
    </ThemeProvider>
  );
}

We add the FancyModalButton component to add the modal trigger.

Inside the component, we add the StyledModal inside the component.

It’s created from the Modal.style tag.

We control whether StyledModal is open or close with the isOpen prop.

The onBackgroundClick prop lets us run code when the background is clicked.

And onEscapeKeydown lets us run code when the Esc key is pressed.

We just toggle the isOpen state to open or close the modal since we pass that as the value of the isOpen prop.

Then we use the styled modal by passing it inside the ThemeProvider and ModalProvider .

react-overlays

We can use the react-overlays library to add a modal to our React app.

To install it, we run:

npm install react-overlays

with NPM or:

yarn add react-overlays

with Yarn.

Then we can use it by writing:

import React, { useState } from "react";
import styled from "styled-components";
import Modal from "react-overlays/Modal";

const Backdrop = styled.div`
  position: fixed;
  z-index: 1040;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: #000;
  opacity: 0.5;
`;

const AModal = styled(Modal)`
  position: fixed;
  width: 400px;
  z-index: 1040;
  top: 20px;
  left: 30px;
  border: 1px solid #e5e5e5;
  background-color: white;
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
  padding: 20px;
`;

export default function App() {
  const [show, setShow] = useState(false);

  const renderBackdrop = (props) => <Backdrop {...props} />;

  return (
    <div className="modal-example">
      <button
        type="button"
        className="btn btn-primary mb-4"
        onClick={() => setShow(true)}
      >
        Open Modal
      </button>

      <AModal
        show={show}
        onHide={() => setShow(false)}
        renderBackdrop={renderBackdrop}
      >
        <div>
          <h4 id="modal-label">Text in a modal</h4>
          <p>Lorem ipsum</p>
        </div>
      </AModal>
    </div>
  );
}

We create the Backdrop component, which is a div with some styles applied.

Then we create the AModal component, which is a modal that has a fixed position.

And we also set the background color and box-shadow to add some effects to show with the modal.

In App , we have a button to open the modal by calling setShow with true .

And we have the AModal component that shows the modal if show is true .

We pass in the Backdrop component as the value of renderBackdrop to render the backdrop.

onHide is called when we hide the modal.

Conclusion

We can add modals easily into our React app with the Styled React Modal and react-overlays libraries.

Categories
React

Add a Modal to a React App with Rodal and Reactjs-popup

Modals are something that we have to add often into our React app.

To make this task easier, we can use existing component libraries to add them.

In this article, we’ll look at how to add a modal into our React app with the Rodal and Reactjs-popup libraries.

Rodal

We can add the Rodal library by running:

npm i rodal --save

Then we can use it by writing:

import React, { useState } from "react";
import Rodal from "rodal";
import "rodal/lib/rodal.css";

export default function App() {
  const [visible, setVisible] = useState(false);

  return (
    <div>
      <div>
        <button onClick={() => setVisible(true)}>show</button>

        <Rodal visible={visible} onClose={() => setVisible(false)}>
          <div>Content</div>
        </Rodal>
      </div>
    </div>
  );
}

We import the Rodal library with its styles.

Then we set the visible prop to the visible state so that we can control when it’s shown.

We set visible to true to show the modal.

onClose is run when we click the close button.

In it, we call setVisible with false to close the modal.

It has many other options available as props.

width sets the wdith. height sets the hrigjt.

showMask controls whether we show a mask.

animation sets the animation type.

enterAnimation and leaveAnimation sets the animation for when the modal is shown or hidden..

duration sets the duration of the animation.

closeOnEsc lets us close the modal when we press escape.

For example, we can use some of them by writing:

import React, { useState } from "react";
import Rodal from "rodal";
import "rodal/lib/rodal.css";

export default function App() {
  const [visible, setVisible] = useState(false);

  return (
    <div>
      <div>
        <button onClick={() => setVisible(true)}>show</button>

        <Rodal
          enterAnimation="zoom"
          leaveAnimation="zoom"
          closeOnEsc
          visible={visible}
          onClose={() => setVisible(false)}
        >
          <div>Content</div>
        </Rodal>
      </div>
    </div>
  );
}

Other animation types available include:

  • fade
  • flip
  • door
  • rotate
  • slideUp
  • slideDown
  • slideLeft
  • slideRight

Reactjs-popup

The Reactjs-popup library lets us add a popup that’s attached to a trigger element.

To install it, we run:

npm i reactjs-popup

Then we can use it by writing:

import React from "react";
import Popup from "reactjs-popup";
import "reactjs-popup/dist/index.css";

export default function App() {
  return (
    <div>
      <div>
        <Popup trigger={<button> Trigger</button>} position="right center">
          <div>Popup content here !!</div>
        </Popup>
      </div>
    </div>
  );
}

We import the Popup component with the associated styles.

Then we set the trigger prop to the trigger element.

position lets us set the position of the popup with a string.

We can add whatever content we want between the tags.

We can also use it to open a modal by adding the modal prop:

import React from "react";
import Popup from "reactjs-popup";
import "reactjs-popup/dist/index.css";

export default function App() {
  return (
    <div>
      <div>
        <Popup trigger={<button> Trigger</button>} modal nested>
          {(close) => (
            <div className="modal">
              <button className="close" onClick={close}>
                &times;
              </button>
              <div className="header"> Modal Title </div>
              <div className="content">Lorem ipsum</div>
              <div className="actions">
                <Popup
                  trigger={<button className="button"> Trigger </button>}
                  position="top center"
                  nested
                >
                  <span>Lorem ipsum</span>
                </Popup>
                <button
                  className="button"
                  onClick={() => {
                    console.log("modal closed ");
                    close();
                  }}
                >
                  close modal
                </button>
              </div>
            </div>
          )}
        </Popup>
      </div>
    </div>
  );
}

The close function is available to let us close the modal.

The nested prop lets us open another modal in the modal.

Conclusion

We can add modals into our React app with the Rodal and react-popup libraries.

Categories
React

Add a Modal to a React App with react-modal and react-confirm-alert

Modals are something that we have to add often into our React app.

To make this task easier, we can use existing component libraries to add them.

In this article, we’ll look at how to add a modal into our React app with the react-modal and react-confirm-alert libraries.

Installation

We can install the library by running:

npm install --save react-modal

with NPM or:

yarn add react-modal

with Yarn.

Usage

We can use it by adding the Modal component into our React component.

To do this, we write:

import React from "react";
import Modal from "react-modal";

const customStyles = {
  content: {
    top: "50%",
    left: "50%",
    right: "auto",
    bottom: "auto",
    marginRight: "-50%",
    transform: "translate(-50%, -50%)"
  }
};

Modal.setAppElement("#root");

export default function App() {
  let subtitle;

  const [modalIsOpen, setIsOpen] = React.useState(false);
  function openModal() {
    setIsOpen(true);
  }

  function afterOpenModal() {
    subtitle.style.color = "#f00";
  }

  function closeModal() {
    setIsOpen(false);
  }

  return (
    <div>
      <button onClick={openModal}>Open Modal</button>
      <Modal
        isOpen={modalIsOpen}
        onAfterOpen={afterOpenModal}
        onRequestClose={closeModal}
        style={customStyles}
        contentLabel="Example Modal"
      >
        <h2 ref={(_subtitle) => (subtitle = _subtitle)}>Hello</h2>
        <button onClick={closeModal}>close</button>
        <div>I am a modal</div>
        <form>
          <input />
          <br />
          <button>ok</button>
          <button>cancel</button>
        </form>
      </Modal>
    </div>
  );
}

We add the customStyles object to style the items.

And we add the modalIsOpen state to control when the modal opens or closes.

The isOpen prop controls whether the modal is opened or closed.

onAfterOpen takes a function that runs code after the modal is open.

onRequestClose takes a function that runs code after the modal is closed.

style takes an object with some properties to change the styles.

contentLabel is a label for the modal.

We call Modal.setAppElement(“#root”) to make the modal component attach to the element with ID root .

react-confirm-alert

The react-confirm-alert library is another library that lets us add a modal easily into our React app.

To install it, we run:

npm install react-confirm-alert --save

We can use it by writing:

import React from "react";
import { confirmAlert } from "react-confirm-alert";
import "react-confirm-alert/src/react-confirm-alert.css";

export default function App() {
  const submit = () => {
    confirmAlert({
      title: "Confirm to submit",
      message: "Are you sure to do this.",
      buttons: [
        {
          label: "Yes",
          onClick: () => alert("Click Yes")
        },
        {
          label: "No",
          onClick: () => alert("Click No")
        }
      ]
    });
  };

  return (
    <div>
      <button onClick={submit}>Confirm dialog</button>
    </div>
  );
}

We import the confirmAlert function and call it in the submit method to open the alert dialog with it.

The title property sets the dialog title.

message sets the message content.

buttons add buttons with the given labels and the event handlers for them.

We can also make it display a custom React component as the content:

import React from "react";
import { confirmAlert } from "react-confirm-alert";
import "react-confirm-alert/src/react-confirm-alert.css";

export default function App() {
  const submit = () => {
    confirmAlert({
      customUI: ({ onClose }) => {
        return (
          <div className="custom-ui">
            <h1>Are you sure?</h1>
            <p>You want to delete this file?</p>
            <button onClick={onClose}>No</button>
            <button
              onClick={() => {
                onClose();
              }}
            >
              Yes
            </button>
          </div>
        );
      }
    });
  };

  return (
    <div>
      <button onClick={submit}>Confirm dialog</button>
    </div>
  );
}

We just return a component in the customUI method.

It gets the onClose method from the parameter and call it whenever we want to close the dialog.

Conclusion

We can add modals easily into our React app with the react-modal and react-confirm-alert libraries.

Categories
Vue

Add a Calendar into a Vue App with Vue-FullCalendar

A calendar is something that is hard to create from scratch.

Therefore, there’re many calendar components created for Vue apps.

In this article, we’ll look at how to add a calendar with Vue-FullCalendar.

Installation

We can install the Vue-FullCalendar and its plugins with:

npm install --save @fullcalendar/vue @fullcalendar/daygrid @fullcalendar/interaction

@fullcalendar/vue has the Vue-FullCalendar plugin.

@fullcalendar/daygrid lets us show the day grid in the calendar.

And @fullcalendar/interaction lets us interact with the calendar.

Then we can add a calendar into our Vue component by writing:

<template>
  <FullCalendar :options="calendarOptions" />
</template>

<script>
import FullCalendar from "@fullcalendar/vue";
import dayGridPlugin from "@fullcalendar/daygrid";
import interactionPlugin from "@fullcalendar/interaction";

export default {
  components: {
    FullCalendar,
  },
  data() {
    return {
      calendarOptions: {
        plugins: [dayGridPlugin, interactionPlugin],
        initialView: "dayGridMonth",
      },
    };
  },
};
</script>

The calendarOptions.plugins property lets us add plugins to add the addons we installed.

And the initialView is set to 'dayGridMonth' to let us show a monthly calendar with today’s date as the default date.

To add events to the calendar, we can add the calendarOptions.events property:

<template>
  <FullCalendar :options="calendarOptions" />
</template>

<script>
import FullCalendar from "@fullcalendar/vue";
import dayGridPlugin from "@fullcalendar/daygrid";
import interactionPlugin from "@fullcalendar/interaction";

export default {
  components: {
    FullCalendar,
  },
  data() {
    return {
      calendarOptions: {
        plugins: [dayGridPlugin, interactionPlugin],
        initialView: "dayGridMonth",
        events: [
          { title: "event 1", date: "2020-12-01" },
          { title: "event 2", date: "2020-12-02" },
        ],
      },
    };
  },
};
</script>

title has the event title and date has the event date.

And to listen to events like clicking on dates, we can add more properties.

To listen to date clicks, we add the dateClick property:

<template>
  <FullCalendar :options="calendarOptions" />
</template>

<script>
import FullCalendar from "@fullcalendar/vue";
import dayGridPlugin from "@fullcalendar/daygrid";
import interactionPlugin from "@fullcalendar/interaction";

export default {
  components: {
    FullCalendar,
  },
  data() {
    return {
      calendarOptions: {
        plugins: [dayGridPlugin, interactionPlugin],
        initialView: "dayGridMonth",
        events: [
          { title: "event 1", date: "2020-12-01" },
          { title: "event 2", date: "2020-12-02" },
        ],
        dateClick: this.onDateClick,
      },
    };
  },
  methods: {
    onDateClick(arg) {
      console.log(arg.dateStr);
    },
  },
};
</script>

We set it to the onDateClick event handler to run it when we click on a date.

And we can get the date string of the date that’s clicked with the dateStr property.

We can add other options like show or hide weekends.

To hide weekends, we can set the calendarOptions.weekends property to false :

<template>
  <FullCalendar :options="calendarOptions" />
</template>

<script>
import FullCalendar from "@fullcalendar/vue";
import dayGridPlugin from "@fullcalendar/daygrid";
import interactionPlugin from "@fullcalendar/interaction";

export default {
  components: {
    FullCalendar,
  },
  data() {
    return {
      calendarOptions: {
        plugins: [dayGridPlugin, interactionPlugin],
        initialView: "dayGridMonth",
        events: [
          { title: "event 1", date: "2020-12-01" },
          { title: "event 2", date: "2020-12-02" },
        ],
        weekends: false,
      },
    };
  },
};
</script>

It also comes with some useful utilities like a formatDate function to format dates our way:

<template>
  <FullCalendar :options="calendarOptions" />
</template>

<script>
import FullCalendar from "@fullcalendar/vue";
import dayGridPlugin from "@fullcalendar/daygrid";
import interactionPlugin from "@fullcalendar/interaction";
import { formatDate } from "@fullcalendar/vue";

const str = formatDate(new Date(), {
  month: "long",
  year: "numeric",
  day: "numeric",
});

console.log(str);

export default {
  components: {
    FullCalendar,
  },
  data() {
    return {
      calendarOptions: {
        plugins: [dayGridPlugin, interactionPlugin],
        initialView: "dayGridMonth",
        events: [
          { title: "event 1", date: "2020-12-01" },
          { title: "event 2", date: "2020-12-02" },
        ],
        weekends: false,
      },
    };
  },
};
</script>

Conclusion

We can add the Vue-FullCalendar library to add an event calendar easily into our Vue app.

Categories
Vue

Add a Calendar into a Vue App with Vue-Simple-Calendar

A calendar is something that is hard to create from scratch.

Therefore, there’re many calendar components created for Vue apps.

In this article, we’ll look at how to add a calendar with Vue-Simple-Calendar.

Installation

We can install the plugin by running:

npm i --save vue-simple-calendar

Usage

Once we installed it, we can use the calendar by writing:

<template>
  <div id="app">
    <calendar-view
      :show-date="showDate"
      class="theme-default holiday-us-traditional holiday-us-official"
    >
      <calendar-view-header
        slot="header"
        slot-scope="t"
        :header-props="t.headerProps"
        @input="setShowDate"
      />
    </calendar-view>
  </div>
</template>
<script>
import { CalendarView, CalendarViewHeader } from "vue-simple-calendar";
import "vue-simple-calendar/static/css/default.css";
import "vue-simple-calendar/static/css/holidays-us.css";

export default {
  name: "app",
  data() {
    return { showDate: new Date() };
  },
  components: {
    CalendarView,
    CalendarViewHeader,
  },
  methods: {
    setShowDate(d) {
      this.showDate = d;
    },
  },
};
</script>

We set the show-date prop to set the default date.

Then we populate the header slot to show the render the header with the calendar-view-header component.

This lets us navigate to different months.

We can set the show the displayPeriodUom prop to show the different kinds of periods in the calendar.

We can set it to year to show years and week to show weeks.

The default is month .

We can also set the starting day of the week with the startingDayOfWeek prop.

dateClasses is an object with different date classes for different dates.

We can add more options by adding more props:

<template>
  <div id="app">
    <div class="calendar-controls">
      <div v-if="message" class="notification is-success">{{ message }}</div>

      <div class="box">
        <div class="field">
          <label class="label">Period UOM</label>
          <div class="control">
            <div class="select">
              <select v-model="displayPeriodUom">
                <option>month</option>
                <option>week</option>
                <option>year</option>
              </select>
            </div>
          </div>
        </div>
        <div class="field">
          <label class="label">Period Count</label>
          <div class="control">
            <div class="select">
              <select v-model="displayPeriodCount">
                <option :value="1">1</option>
                <option :value="2">2</option>
                <option :value="3">3</option>
              </select>
            </div>
          </div>
        </div>
        <div class="field">
          <label class="checkbox">
            <input v-model="useTodayIcons" type="checkbox" />
            Use icon for today's period
          </label>
        </div>
        <div class="field">
          <label class="checkbox">
            <input v-model="displayWeekNumbers" type="checkbox" />
            Show week number
          </label>
        </div>
        <div class="field">
          <label class="checkbox">
            <input v-model="showTimes" type="checkbox" />
            Show times
          </label>
        </div>
        <div class="field">
          <label class="label">Themes</label>
          <label class="checkbox">
            <input v-model="useDefaultTheme" type="checkbox" />
            Default
          </label>
        </div>
        <div class="field">
          <label class="checkbox">
            <input v-model="useHolidayTheme" type="checkbox" />
            Holidays
          </label>
        </div>
      </div>

      <div class="box">
        <div class="field">
          <label class="label">Title</label>
          <div class="control">
            <input v-model="newItemTitle" class="input" type="text" />
          </div>
        </div>
        <div class="field">
          <label class="label">Start date</label>
          <div class="control">
            <input v-model="newItemStartDate" class="input" type="date" />
          </div>
        </div>
        <div class="field">
          <label class="label">End date</label>
          <div class="control">
            <input v-model="newItemEndDate" class="input" type="date" />
          </div>
        </div>
        <button class="button is-info" @click="clickTestAddItem">
          Add Item
        </button>
      </div>
    </div>
    <div class="calendar-parent">
      <calendar-view
        :items="items"
        :show-date="showDate"
        :time-format-options="{ hour: 'numeric', minute: '2-digit' }"
        :enable-drag-drop="true"
        :disable-past="disablePast"
        :disable-future="disableFuture"
        :show-times="showTimes"
        :date-classes="myDateClasses"
        :display-period-uom="displayPeriodUom"
        :display-period-count="displayPeriodCount"
        :starting-day-of-week="startingDayOfWeek"
        :period-changed-callback="periodChanged"
        :current-period-label="useTodayIcons ? 'icons' : ''"
        :displayWeekNumbers="displayWeekNumbers"
        :enable-date-selection="true"
        :selection-start="selectionStart"
        :selection-end="selectionEnd"
        @date-selection-start="setSelection"
        @date-selection="setSelection"
        @date-selection-finish="finishSelection"
        @click-date="onClickDay"
        @click-item="onClickItem"
      >
        <calendar-view-header
          slot="header"
          slot-scope="{ headerProps }"
          :header-props="headerProps"
          @input="setShowDate"
        />
      </calendar-view>
    </div>
  </div>
</template>
<script>
import { CalendarView, CalendarViewHeader } from "vue-simple-calendar";
import "vue-simple-calendar/static/css/default.css";
import "vue-simple-calendar/static/css/holidays-us.css";

export default {
  name: "app",
  components: {
    CalendarView,
    CalendarViewHeader,
  },
  data() {
    return {
      showDate: this.thisMonth(1),
      message: "",
      startingDayOfWeek: 0,
      disablePast: false,
      disableFuture: false,
      displayPeriodUom: "month",
      displayPeriodCount: 1,
      displayWeekNumbers: false,
      showTimes: true,
      selectionStart: null,
      selectionEnd: null,
      newItemTitle: "",
      newItemStartDate: "",
      newItemEndDate: "",
      useDefaultTheme: true,
      useHolidayTheme: true,
      useTodayIcons: false,
      items: [
        {
          id: "e0",
          startDate: "2020-01-05",
        },
        {
          id: "e1",
          startDate: new Date(),
        },
        {
          id: "e2",
          startDate: new Date(2020, 11, 1),
          endDate: new Date(2020, 11, 10),
          title: "Multi-day item with a long title and times",
        },
      ],
    };
  },
  computed: {
    userLocale() {
      return this.getDefaultBrowserLocale;
    },
    myDateClasses() {
      const o = {
        ides: new Date().getDate() === 1,
      };
      return o;
    },
  },
  methods: {
    periodChanged() {},
    thisMonth(d, h, m) {
      const t = new Date();
      return new Date(t.getFullYear(), t.getMonth(), d, h || 0, m || 0);
    },
    onClickDay(d) {
      this.selectionStart = null;
      this.selectionEnd = null;
      this.message = `You clicked: ${d.toLocaleDateString()}`;
    },
    onClickItem(e) {
      this.message = `You clicked: ${e.title}`;
    },
    setShowDate(d) {
      this.message = `Changing calendar view to ${d.toLocaleDateString()}`;
      this.showDate = d;
    },
    setSelection(dateRange) {
      this.selectionEnd = dateRange[1];
      this.selectionStart = dateRange[0];
    },
    finishSelection(dateRange) {
      this.setSelection(dateRange);
      this.message = `You selected: ${this.selectionStart.toLocaleDateString()} -${this.selectionEnd.toLocaleDateString()}`;
    },
    clickTestAddItem() {
      this.items.push({
        startDate: this.newItemStartDate,
        endDate: this.newItemEndDate,
        title: this.newItemTitle,
        id: "e" + Math.random().toString(36).substr(2, 10),
      });
      this.message = "You added a calendar item!";
    },
  },
};
</script>

We add items to the items array with the clickTestAddItem method to add calendar events.

We also have select elements to change the period displayed and the number of periods displayed.

Conclusion

We can add the Vue-Simple-Calendar component to add an event calendar with many options in our Vue app.