Categories
React

Add Animation to HTML Elements in a React App with React Motion

The react-motion library lets us add a component to add HTML elements in a React app.

In this article, we’ll look at how to use this to add animations to various HTML elements.

Installation

We can install the package by running:

npm install --save react-motion

Simple Animation

We can add simple animation by using the Motion component.

For instance, we can write:

import React from "react";
import { Motion, spring } from "react-motion";

export default function App() {
  return (
    <div className="App">
      <Motion defaultStyle={{ x: 0 }} style={{ x: spring(10) }}>
        {(value) => <div>{value.x}</div>}
      </Motion>
    </div>
  );
}

The defaultStyle has an object with the initial value.

style has the animation we want to run.

The x property will be animated from 0 to 10.

value has the objects with the x property, and x has numbers between 0 and 10.

Now we should see the number 10 displayed an animation is added.

StaggeredMotion

The StaggeredMotion component lets us animate a collection of items.

The collection must have a constant length.

For example, we can use it by writing:

import React from "react";
import { StaggeredMotion, spring } from "react-motion";

export default function App() {
  return (
    <div className="App">
      <StaggeredMotion
        defaultStyles={[{ h: 0 }, { h: 0 }, { h: 0 }]}
        styles={(prevInterpolatedStyles) =>
          prevInterpolatedStyles.map((_, i) => {
            return i === 0
              ? { h: spring(100) }
              : { h: spring(prevInterpolatedStyles[i - 1].h) };
          })
        }
      >
        {(interpolatingStyles) => (
          <div>
            {interpolatingStyles.map((style, i) => (
              <div key={i} style={{ border: "1px solid", height: style.h }} />
            ))}
          </div>
        )}
      </StaggeredMotion>
    </div>
  );
}

The defaultStyles has an array of styles with the initial styles, h is used to animate the heights.

The styles prop has the styles to map the initial styles to the end styles.

spring animated the height from 0 to 100px if it’s the first element.

Otherwise, we animate it to the height of the previous element.

Then in the child in between the tags, we set the height of the divs.

TransitionMotion

The TransitionMotion lets us do mounting and unmounting animation.

For example, we can write:

import React, { useEffect } from "react";
import { TransitionMotion, spring } from "react-motion";

export default function App() {
  const [items, setItems] = React.useState([
    { key: "a", size: 10 },
    { key: "b", size: 20 },
    { key: "c", size: 30 }
  ]);

useEffect(() => {
    setItems([
      { key: "a", size: 10 },
      { key: "b", size: 20 }
    ]);
  }, []);

const willLeave = () => {
    return { width: spring(0), height: spring(0) };
  };

  return (
    <div className="App">
      <TransitionMotion
        willLeave={willLeave}
        styles={items.map((item) => ({
          key: item.key,
          style: { width: item.size, height: item.size }
        }))}
      >
        {(interpolatedStyles) => (
          <div>
            {interpolatedStyles.map((config) => {
              return (
                <div
                  key={config.key}
                  style={{ ...config.style, border: "1px solid" }}
                />
              );
            })}
          </div>
        )}
      </TransitionMotion>
    </div>
  );
}

We set the items with an array with 3 entries.

They’re used to render 3 squares.

Then in the useEffect hook, we call setItems to set the items.

We removed the last entry, so we removed the shape.

willLeave is called to shrink the square to 0 to make it disappear.

The TransitionMotion component does the animation.

willLeave is run when the element is removed.

The function in between the tags with by mapping the interpolatedStyles into the divs we render.

The styles prop has the styles we display for each item.

It has the values of items and we map to the latest styles.

This way, we see the animation displayed.

Conclusion

React Motion lets us animate shapes easily by changing the styles from the initial ones to the latest ones with transition effects.

Categories
React

Add a Stacked Bar Chart Easily with the react-horizontal-stacked-bar-chart Library

The react-horizontal-stacked-bar-chart library lets us add a bar chart easily in our React app.

In this article, we’ll look at how to use it to add a stacked bar chart to our React app.

Installation

We can install the library by running:

npm i react-horizontal-stacked-bar-chart

Simple Chart

After we installed the package, we write:

import React from "react";
import HSBar from "react-horizontal-stacked-bar-chart";

export default function App() {
  return (
    <div className="App">
      <HSBar data={[{ value: 10 }, { value: 20 }]} />
    </div>
  );
}

to add 2 bars stacked together with the HSBar component.

There is nothing else displayed except the bars.

Complete Chart

To add a complete chart with the labels, we write:

import React from "react";
import HSBar from "react-horizontal-stacked-bar-chart";

export default function App() {
  return (
    <div className="App">
      <HSBar
        height={50}
        showTextIn
        showTextUp
        showTextDown
        outlineWidth={0.5}
        outlineColor="black"
        id="chart"
        fontColor="rgb(50,20,100)"
        data={[
          {
            name: "Owed",
            value: 80,
            description: "$80,00",
            color: "red"
          },
          {
            name: "Paid",
            value: 200,
            description: "$200,00",
            color: "lightgreen"
          }
        ]}
        onClick={(e) => console.log(e.bar)}
      />
    </div>
  );
}

The showTextIn prop shows text inside the bars.

showTextUp shows the label text above the bars.

showTextDown shows the label text below the bars.

outlineWidth has the width of the border.

outlineColor has the color of the border.

fontColor has the font color.

data has the data for the stacked bars.

The name has the name that is displayed in the labels.

value has the length of the bar.

description has the description shown before the name .

color has the color of the bar.

onClick is a function that’s called when the bar is clicked.

A single bar would be displayed with the bars with thedata array stacked together.

Conclusion

The react-horizontal-stacked-bar-chart library lets us add a stacked bar chart within a React app with a single bar.

Categories
React

Add a Histogram to a React App with the @data-ui/histogram Library

To add a histogram into our React app, we can use the @data-ui/histogram library.

In this article, we’ll look at how to add a histogram to our React app with this library.

Installation

We can install it by running:

npm i @data-ui/histogram

Add a Histogram

We can add a histogram by writing:

import React from "react";
import {
  Histogram,
  DensitySeries,
  BarSeries,
  withParentSize,
  XAxis,
  YAxis
} from "@data-ui/histogram";

const ResponsiveHistogram = withParentSize(
  ({ parentWidth, parentHeight, ...rest }) => (
    <Histogram width={parentWidth} height={parentHeight} {...rest} />
  )
);

const rawData = Array(100).fill().map(Math.random);

export default function App() {
  return (
    <div className="App" style={{ height: 300 }}>
      <ResponsiveHistogram
        ariaLabel="histogram"
        orientation="vertical"
        cumulative={false}
        normalized={true}
        binCount={25}
        valueAccessor={(datum) => datum}
        binType="numeric"
        renderTooltip={({ event, datum, data, color }) => (
          <div>
            <strong style={{ color }}>
              {datum.bin0} to {datum.bin1}
            </strong>
            <div>
              <strong>count </strong>
              {datum.count}
            </div>
            <div>
              <strong>cumulative </strong>
              {datum.cumulative}
            </div>
            <div>
              <strong>density </strong>
              {datum.density}
            </div>
          </div>
        )}
      >
        <BarSeries animated rawData={rawData} />
        <XAxis />
        <YAxis />
      </ResponsiveHistogram>
    </div>
  );
}

We created the ResponsiveHistorgram component to make the histogram fir to the parent’s dimensions.

This is done by calling the withParentSize function to render the histogram with the height of the parent.

In the App component, we use the ResponsiveHistogram component by passing in a few props.

orientation has the orientation of the histogram.

cumulative indicates whether the histogram is cumulative.

normalized sets whether the histogram is normalized as a fraction of the total.

binCount is approximate of the number of bins to use.

renderTooltip is a prop with the function to let us get an entry from the bar we’re hovering on and render them in the tooltip.

bin0 has the bin name.

count has the count of the items in the bin.

cumulative has the cumulative number of items from the leftmost bin to the current bin.

density has the density.

The bars are rendered with the BarSeries component.

animated animates the display of the histogram when it’s loading.

rawData has the raw data.

XAxis adds the x-axis. YAxis adds the y-axis.

Also, we need to specify the height of the histogram container so it fits to the height.

Other properties include the stroke to change the color of the bar.

strokeWidth changes the width of the bar.

DensitySeries

The DensitySeries component lets us plot an estimate of the probability density function.

For example, we can write:

import React from "react";
import {
  Histogram,
  DensitySeries,
  BarSeries,
  withParentSize,
  XAxis,
  YAxis
} from "@data-ui/histogram";

const ResponsiveHistogram = withParentSize(
  ({ parentWidth, parentHeight, ...rest }) => (
    <Histogram width={parentWidth} height={parentHeight} {...rest} />
  )
);

const rawData = Array(100).fill().map(Math.random);

export default function App() {
  return (
    <div className="App" style={{ height: 300 }}>
      <ResponsiveHistogram
        ariaLabel="histogram"
        orientation="vertical"
        cumulative={false}
        normalized={true}
        binCount={25}
        valueAccessor={(datum) => datum}
        binType="numeric"
      >
        <DensitySeries animated rawData={rawData} />
        <XAxis />
        <YAxis />
      </ResponsiveHistogram>
    </div>
  );
}

to add the density series to add the histogram.

Conclusion

We can use the @data-ui/histogram library to add a histogram easily to our React app.

Categories
Vue

Add a Dialog Box to a Vue App with the vue-js-modal Library

The Vue.js modal library is a popular and useful modal library for Vue apps.

In this article, we’ll look at how to add a modal with the vue-js-modal library.

Dialogs

Dialogs are a simplified version of the modal which has most parameters set by default.

It’s useful for quick prototyping and showing alerts.

We can set the dialog to true when we call Vue.use to show the dialog.

For example, we can write:

main.js

import Vue from "vue";
import App from "./App.vue";
import VModal from "vue-js-modal";
Vue.use(VModal, {
  dialog: true
});

Vue.config.productionTip = false;

new Vue({
  render: (h) => h(App)
}).$mount("#app");

App.vue

<template>
  <div>
    <v-dialog/>
  </div>
</template>
<script>
export default {
  name: "App",
  methods: {
    show() {
      this.$modal.show("dialog", {
        title: "Dialog title",
        text: "Lorem ipsum dolor sit amet.",
        buttons: [
          {
            title: "Cancel",
            handler: () => {
              this.$modal.hide("dialog");
            }
          },
          {
            title: "Like",
            handler: () => {
              alert("Like action");
            }
          },
          {
            title: "OK",
            handler: () => {
              alert("success");
            }
          }
        ]
      });
    }
  },
  mounted() {
    this.show();
  }
};
</script>

We register the plugin with an object with the dialog property to true .

Then in the show method, we add the this.$modal.show method to show the dialog.

The first argument has the name of the dialog.

The object in the 2nd argument has various options we can set as the dialog.

The title has the dialog title.

The text has the text.

The buttons property has an array with the button options.

They are defined by objects. title has the button text.

handler has the event handler that’s run when clicking the button.

this.$modal.hide lets us hide the modal. We reference the dialog to close we reference the name of the dialog.

Events

The modal emits various events. To listen to them, we can write:

<template>
  <modal name="example" @before-open="beforeOpen" @before-close="beforeClose">
    <span>Hello, {{ name }}!</span>
  </modal>
</template>
<script>
export default {
  name: "Example",
  data() {
    return {
      name: "world"
    };
  },
  methods: {
    beforeOpen(event) {
      console.log("Opening...");
    },
    beforeClose(event) {
      console.log("Closing...");
      if (Math.random() < 0.5) {
        event.cancel();
      }
    }
  },
  mounted() {
    this.$modal.show("example");
  }
};
</script>

We listen to the before-open and before-close events emitted from the modal component.

before-open is emitted when the modal is opening.

before-close is emitted when the modal is closing.

The event parameter is an object with the cancel method that we can use to cancel the action.

Since we call event.cancel in the beforeClose method, it’ll cancel the close modal close action.

Slots

The modal component has a slot that we can populate with our own content.

For example, we can write:

<template>
  <modal name="example">
    <div slot="top-right">
      <button @click="$modal.hide('example')">❌</button>
    </div>Hello, ☀️!
  </modal>
</template>
<script>
export default {
  name: "App",
  mounted() {
    this.$modal.show("example");
  }
};
</script>

The top-right slot adds content to the top right of the modal.

The default slot has the main modal content.

Conclusion

We can add dialog boxes easily and customize its content with the vue-js-modal library.

Categories
Vue

Add a Modal to a Vue App with the vue-js-modal Library

The Vue.js modal library is a popular and useful modal library for Vue apps.

In this article, we’ll look at how to add a modal with the vue-js-modal library.

Installation

We can install the library by running:

npm i vue-js-modal

or

yarn add vue-js-modal

Add a Modal

Once we install the modal, then we can use it by writing:

main.js

import Vue from "vue";
import App from "./App.vue";
import VModal from "vue-js-modal";
Vue.use(VModal);

Vue.config.productionTip = false;

new Vue({
  render: (h) => h(App)
}).$mount("#app");

App.vue

<template>
  <modal name="hello-world-modal">hello world modal</modal>
</template>

<script>
export default {
  name: "App",
  methods: {
    show() {
      this.$modal.show("hello-world-modal");
    },
    hide() {
      this.$modal.hide("hello-world-modal");
    }
  },
  mounted() {
    this.show();
  }
};
</script>

We add the modal component with the name prop so that we can assign the name to it.

This way, we can show and hide the modal.

Also, we can create dynamic modals by call the this.$modal.show method with a component.

For example, we can write:

components/ModalContent.vue

<template>
  <div>{{text}}</div>
</template>

<script>
export default {
  name: "ModalContent",
  props: {
    text: String
  }
};
</script>

App.vue

<template>
  <div></div>
</template>

<script>
import ModalContent from "./components/ModalContent.vue";
export default {
  name: "App",
  methods: {
    show() {
      this.$modal.show(
        ModalContent,
        { text: "hello world" },
        { draggable: true }
      );
    }
  },
  mounted() {
    this.show();
  }
};
</script>

We call the show method with the component as the first argument.

The 2nd argument is an object with the props.

The last argument has the options for the modal.

The draggable property makes the modal draggable if it’s true .

We can also pass in a component that’s defined inline instead of importing it:

<template>
  <div></div>
</template>
<script>
export default {
  name: "App",
  methods: {
    show() {
      this.$modal.show(
        {
          template: `
            <div>
              <p>{{ text }}</p>
            </div>
          `,
          props: ["text"]
        },
        { text: "hello world" },
        { draggable: true },
        { "before-close": event => console.log("before close") }
      );
    }
  },
  mounted() {
    this.show();
  }
};
</script>

We added a 4th argument to listen to the before-close event emitted by the modal before it’s closed.

Also, we can set the options globally when we register the plugin.

For example, we can write:

main.js

import Vue from "vue";
import App from "./App.vue";
import VModal from "vue-js-modal";
Vue.use(VModal, {
  dynamicDefaults: {
    draggable: true,
    resizable: true,
    height: "auto"
  }
});

Vue.config.productionTip = false;

new Vue({
  render: (h) => h(App)
}).$mount("#app");

App.vue

<template>
  <div></div>
</template>
<script>
export default {
  name: "App",
  methods: {
    show() {
      this.$modal.show(
        {
          template: `
            <div>
              <p>{{ text }}</p>
            </div>
          `,
          props: ["text"]
        },
        { text: "hello world" }
      );
    }
  },
  mounted() {
    this.show();
  }
};
</script>

We make all the modals added with the draggable and resizable properties added when we call Vue.use .

Conclusion

The vue-js-modal library lets us add modals easily into our Vue app.