Categories
Vuetify

Vuetify — Badges and Banners

Vuetify is a popular UI framework for Vue apps.

In this article, we’ll look at how to work with the Vuetify framework.

Badges

The v-badge component lets us add an avatar-like icon or text onto the component to highlight information to the user.

They appear as superscripts or subscripts.

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-toolbar>
          <v-tabs dark background-color="primary" grow>
            <v-tab>
              <v-badge color="pink" dot>One</v-badge>
            </v-tab> <v-tab>
              <v-badge color="green" content="6">Two</v-badge>
            </v-tab> <v-tab>
              <v-badge color="deep-purple accent-4" icon="mdi-vuetify">Three</v-badge>
            </v-tab>
          </v-tabs>
        </v-toolbar>
      </v-col>
    </v-row>
  </v-container>
</template><script>
export default {
  name: "HelloWorld",
  data: () => ({
    alert: false,
  }),
};
</script>

We add badges to tab links with the v-tab component.

The color can be changed with the color prop.

icon lets us change the icon.

Show Badge on Hover

We can make a badge shows on hover with the v-hover component.

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-badge
          :value="hover"
          color="deep-purple accent-4"
          content="1000"
          left
          transition="slide-x-transition"
        >
          <v-hover v-model="hover">
            <v-icon color="grey lighten-1" large>mdi-account-circle</v-icon>
          </v-hover>
        </v-badge>
      </v-col>
    </v-row>
  </v-container>
</template><script>
export default {
  name: "HelloWorld",
  data: () => ({
    hover: undefined,
  }),
};
</script>

to add a badge that shows on hover.

The hover state is controlled by the hover state.

v-model son the v-hover component sets the hover state.

Dynamic Notifications

We can create dynamic notifications with badges.

The content can be controlled with the content prop.

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <div>
          <v-btn class="mx-1" color="primary" @click="messages++">Send Message</v-btn> <v-btn class="mx-1" color="error" @click="messages = 0">Clear Notifications</v-btn>
        </div> <v-badge :content="messages" :value="messages" color="green" overlap>
          <v-icon large>mdi-email</v-icon>
        </v-badge>
      </v-col>
    </v-row>
  </v-container>
</template><script>
export default {
  name: "HelloWorld",
  data: () => ({
    messages: 0,
  }),
};
</script>

We have the Send Message button that increments the message state.

This causes the content to update with the latest message value.

Banners

The v-banner component is used as a message for users with 1 to 2 actions.

It can have a single line or multiple lines.

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-banner single-line :sticky="sticky">
          Hello world.
          <template v-slot:actions>
            <v-btn text color="deep-purple accent-4">Get Online</v-btn>
          </template>
        </v-banner>
      </v-col>
    </v-row>
  </v-container>
</template><script>
export default {
  name: "HelloWorld",
  data: () => ({
    sticky: true
  }),
};
</script>

We have the v-banner component with the single-line prop to display a single line banner.

The sticky controls whether the banner is sticky or not.

Two-Line Banner

We can add a 2 line banner to store more data.

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-banner>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent cursus nec sem id malesuada.
          Curabitur lacinia sem et turpis euismod, eget elementum ex pretium.
          <template
            v-slot:actions
          >
            <v-btn text color="primary">Dismiss</v-btn>
            <v-btn text color="primary">Retry</v-btn>
          </template>
        </v-banner>
      </v-col>
    </v-row>
  </v-container>
</template><script>
export default {
  name: "HelloWorld",
  data: () => ({}),
};
</script>

to add a longer message.

The actions slot has the action buttons.

Conclusion

We can add badges and banners to our app with Vuetify.

Categories
Vuetify

Vuetify — Alert, Containers, and Avatars

Vuetify is a popular UI framework for Vue apps.

In this article, we’ll look at how to work with the Vuetify framework.

Alert Transition

Transition effects can be applied when we add alerts.

For instance, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <div class="text-center mb-4">
          <v-btn color="primary" @click="alert = !alert">Toggle</v-btn>
        </div>
        <v-alert
          :value="alert"
          color="pink"
          dark
          border="top"
          icon="mdi-home"
          transition="scale-transition"
        >
          lorem ipsum
        </v-alert>
      </v-col>
    </v-row>
  </v-container>
</template><script>
export default {
  name: "HelloWorld",
  data: () => ({
    alert: false
  }),
};
</script>

to add our alert with the transition.

We just add the transition prop to add the effect.

Application

The v-app component is a container for components like v-navigator-drawer , v-app-bar , v-footer , and other components.

It helps create our app with proper sizing around the v-main component.

This lets us avoid the hassle of managing layout sizing.

v-app is required for all apps.

It ensures that the proper styles are applied to the whole app.

Also, it should only be included once.

For example, we can write:

<template>
  <v-app>
    <v-app-bar
      app
      color="primary"
      dark
    >
      <div class="d-flex align-center">
        <v-img
          alt="Vuetify Logo"
          class="shrink mr-2"
          contain
          src="https://cdn.vuetifyjs.com/images/logos/vuetify-logo-dark.png"
          transition="scale-transition"
          width="40"
        /><v-img
          alt="Vuetify Name"
          class="shrink mt-1 hidden-sm-and-down"
          contain
          min-width="100"
          src="https://cdn.vuetifyjs.com/images/logos/vuetify-name-dark.png"
          width="100"
        />
      </div> <v-spacer></v-spacer> <v-btn
        href="https://github.com/vuetifyjs/vuetify/releases/latest"
        target="_blank"
        text
      >
        <span class="mr-2">Latest Release</span>
        <v-icon>mdi-open-in-new</v-icon>
      </v-btn>
    </v-app-bar> <v-main>
      <HelloWorld/>
    </v-main>
  </v-app>
</template><script>
import HelloWorld from './components/HelloWorld';export default {
  name: 'App', components: {
    HelloWorld,
  }, data: () => ({
    //
  }),
};
</script>

to use it.

v-app wraps around the whole app.

And we can have all the other Vuetify components inside.

Aspect Ratios

We can use the v-responsive component to add a container with a specific aspect ratio.

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-responsive :aspect-ratio="16/9">
          <v-card-text>Lorem ipsum</v-card-text>
        </v-responsive>
      </v-col>
    </v-row>
  </v-container>
</template><script>
export default {
  name: "HelloWorld",
  data: () => ({
    alert: false,
  }),
};
</script>

We added a 16×9 container with the v-response component and the aspect-ratio prop.

Avatars

The v-avatar component lets us display circular user profile pictures.

For example, we can add one by writing:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-avatar color="green" size="36">
          <span class="white--text headline">36</span>
        </v-avatar>
      </v-col>
    </v-row>
  </v-container>
</template><script>
export default {
  name: "HelloWorld",
  data: () => ({
    alert: false,
  }),
};
</script>

We added a green avatar with the color prop.

size is in pixels.

Also, we can make it square with a tile prop:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-avatar tile color="blue">
          <v-icon dark>mdi-alarm</v-icon>
        </v-avatar>
      </v-col>
    </v-row>
  </v-container>
</template><script>
export default {
  name: "HelloWorld",
  data: () => ({
    alert: false,
  }),
};
</script>

The default slot of v-avatar accepts the v-icon component, image or text.

We can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-avatar color="blue">
          <v-avatar>
            <img src="https://cdn.vuetifyjs.com/images/john.jpg" alt="John" />
          </v-avatar>
        </v-avatar>
      </v-col>
    </v-row>
  </v-container>
</template><script>
export default {
  name: "HelloWorld",
  data: () => ({
    alert: false,
  }),
};
</script>

to add an image.

Conclusion

We can add alerts, avatars, and responsive containers with Vuetify.

Categories
React

Create Auto-Resizeable Lists and Grid with the react-virtualized Library

The react-virtualized package lets us display a virtualized list.

We can use it with the AutoSizer component to create a virtualized list that resizes the item.

In this article, we’ll look at how to create automatically resizeable lists and grids with the react-virtualized library.

Installation

To install it, we run:

npm i react-virtualized

AutoSizer

We can use the AutoSizer component to add the auto-resizable list.

For example, we can write:

import React from "react";
import { AutoSizer, List } from "react-virtualized";
import "react-virtualized/styles.css";

const list = Array(1000)
  .fill(0)
  .map((_, i) => i);

function rowRenderer({ key, index, style }) {
  return (
    <div key={key} style={style}>
      {list[index]}
    </div>
  );
}

export default function App() {
  return (
    <div style={{ height: "100vh" }}>
      <AutoSizer>
        {({ height, width }) => (
          <List
            height={height}
            rowCount={list.length}
            rowHeight={20}
            rowRenderer={rowRenderer}
            width={width}
          />
        )}
      </AutoSizer>
    </div>
  );
}

We create a list with the AutoSizer component with a render prop inside it.

We get the height and width from the parameter and then pass that into the List component’s height component to set the width and height of the list.

We set the rowHeight prop to set the row height of each entry.

rowRendered has a function which has the key , index and style properties from the parameter and we use that to render the entry.

index has the index of the entry.

key has the unique key of the row.

Now when we resize the screen, we see the list resize with the screen.

Grid

We can add a grid with react-virtualize’s Grid component.

For instance, we can write:

import React from "react";
import "react-virtualized/styles.css";
import { Grid } from "react-virtualized";

let list = [];
let inner = [];
let width = 500;
let height = 100;
let xCoord = 0;
let yCoord = 0;

for (let i = 0; i < 1000; i++) {
  do {
    xCoord = Math.floor(Math.random() * width);
    yCoord = Math.floor(Math.random() * height);
  } while ((xCoord <= 0) | (yCoord <= 0));

if (xCoord > 0 && yCoord > 0) {
    inner.push(xCoord);
    inner.push(yCoord);
    list.push(inner);
  }

inner = [];
}

function cellRenderer({ columnIndex, key, rowIndex, style }) {
  return (
    <div key={key} style={style}>
      {list[rowIndex][columnIndex]}
    </div>
  );
}
export default function App() {
  return (
    <div>
      <Grid
        cellRenderer={cellRenderer}
        columnCount={list[0].length}
        columnWidth={100}
        height={300}
        rowCount={list.length}
        rowHeight={30}
        width={300}
      />
    </div>
  );
}

We have the data in the list nested array.

The cellRenderer component lets us render the nested array into the grid.

We also set the columnCount to the length of the first nested array.

And we set the columnWidth to set the column width.

The height is the height of the grid.

rowCount has the row count.

rowHeight has the row height.

width has the grid width.

Then we see the nested list rendered on the screen.

Conclusion

We can create an auto-resizable list and grids with the react-virtualized library.

Categories
React

Animation with the React Animation Library — Loading Animation and Easings

With the React Animation library, we can render animations in our React app easily.

In this article, we’ll take a look at how to get started with the React Animation library.

HideUntilLoaded

We can hide the content until a URL is loaded with the HideUntilLoaded component.

For example, we can write:

import React from "react";
import { HideUntilLoaded } from "react-animation";

export default function App() {
  return (
    <>
      <HideUntilLoaded imageToLoad="https://i.picsum.photos/id/23/200/300.jpg?hmac=NFze_vylqSEkX21kuRKSe8pp6Em-4ETfOE-oyLVCvJo">
        your content
      </HideUntilLoaded>
    </>
  );
}

We use the HideUntilLoaded component with the imageToLoad prop to wait for the image with the given URL to load until the content inside it is displayed.

We can add a spinner that’s displayed when the image with the given URL is loaded with the Spinner prop.

For instance, we can write:

import React from "react";
import { HideUntilLoaded } from "react-animation";

export default function App() {
  return (
    <>
      <HideUntilLoaded
        imageToLoad="https://i.picsum.photos/id/23/200/300.jpg?hmac=NFze_vylqSEkX21kuRKSe8pp6Em-4ETfOE-oyLVCvJo"
        Spinner={() => <div>Loading...</div>}
      >
        your content
      </HideUntilLoaded>
    </>
  );
}

We add the Spinner prop with a function that returns the JSX for the loading indicator.

The animation effect can be changed with the animationIn prop.

For example, we can write:

import React from "react";
import { HideUntilLoaded } from "react-animation";

export default function App() {
  return (
    <>
      <HideUntilLoaded
        animationIn="bounceIn"
        imageToLoad="https://i.picsum.photos/id/23/200/300.jpg?hmac=NFze_vylqSEkX21kuRKSe8pp6Em-4ETfOE-oyLVCvJo"
        Spinner={() => <div>Loading...</div>}
      >
        your content
      </HideUntilLoaded>
    </>
  );
}

We change the animation effect that’s displayed when the content is loading with the animationIn prop.

AnimateGroup

The AnimateGroup component lets us animate components being added, removed, or modified within a group of components.

For instance, we can write:

import React, { useState, useEffect } from "react";
import { AnimateGroup } from "react-animation";

export default function App() {
  const [nums, setNums] = useState([1, 2]);

  useEffect(() => {
    const timer = setInterval(() => {
      setNums((nums) => [...nums, nums[nums.length - 1] + 1]);
    }, 1500);

    return () => clearInterval(timer);
  }, []);

  return (
    <>
      <ul>
        <AnimateGroup animation="bounce">
          {nums.map((word) => (
            <li key={word}>{word}</li>
          ))}
        </AnimateGroup>
      </ul>
    </>
  );
}

to add the nums state and animate it with the AnimationGroup .

We set the animation prop to 'bounce' so that when we add an entry to nums , we’ll see the bounce effect rendered on the entry being added.

The useEffect callback adds an entry to nums by calling the setNums function.

We add a new entry to nums every 1500ms by calling setInterval .

Animations

We can add animations with our own styling by using the anuimations object.

For example, we can write:

import React from "react";
import { animations } from "react-animation";

export default function App() {
  return (
    <>
      <div style={{ animation: animations.popIn }}>hello world</div>
    </>
  );
}

to render the popIn effect when we mount the div with the animation.popIn property.

popIn is 'pop-in 500ms cubic-bezier(0.19, 1, 0.22, 1) forwards’ .

Easings

We can set the timing function for our animation with the easings object.

To do this, we write:

import React from "react";
import { easings } from "react-animation";

const style = {
  animation: `pop-in ${easings.easeOutExpo} 500ms forwards`
};
export default function App() {
  return (
    <>
      <div style={style}>hello world</div>
    </>
  );
}

We pass the easings.easeOutExpo string into our animation style string.

Then we apply the easing in our animation.

Conclusion

We can apply various animation effects with the React Animation library.

Categories
React

Add Animation with the React Animation Library

With the React Animation library, we can render animations in our React app easily.

In this article, we’ll take a look at how to get started with the React Animation library.

Installation

We can install the library by running:

npm install -s react-animation

Then we can use the provided components to add animation to our React apps.

AnimateOnChange

We can use the AnimateOnChange library to animate new content when the content changes.

We can a string or any child components inside it.

For example, we can write:

import React, { useState } from "react";
import { AnimateOnChange } from "react-animation";

export default function App() {
  const [count, setCount] = useState(0);

  return (
    <>
      <p>
        <button onClick={() => setCount((count) => count + 1)}>
          increment
        </button>
      </p>
      <AnimateOnChange>{count}</AnimateOnChange>
    </>
  );
}

We have the count state.

And the state is updated with the increment button.

We render the count in AnimateOnChange so we see some transition effect when we click the increment button.

The default transition effect is the fade effect.

We can set the duration of the animation with the durationOut prop:

import React, { useState } from "react";
import { AnimateOnChange } from "react-animation";

export default function App() {
  const [count, setCount] = useState(0);

  return (
    <>
      <p>
        <button onClick={() => setCount((count) => count + 1)}>
          increment
        </button>
      </p>
      <AnimateOnChange durationOut="1000">{count}</AnimateOnChange>
    </>
  );
}

The duration is in milliseconds.

The default value is 200.

We can change the animation effect rendered with the animationIn and animationOut props.

For example, we can write:

import React, { useState } from "react";
import { AnimateOnChange } from "react-animation";

export default function App() {
  const [count, setCount] = useState(0);

return (
    <>
      <p>
        <button onClick={() => setCount((count) => count + 1)}>
          increment
        </button>
      </p>
      <AnimateOnChange
        animationIn="bounceIn"
        animationOut="bounceOut"
        durationOut={500}
      >
        {count}
      </AnimateOnChange>
    </>
  );
}

We set the animationIn to set the effect to render when new content enters.

The animationOut sets the effect to render when existing content leaves.

Content is styled as inline-block by default, but we can override that by setting the style prop.

Custom Animations

We can add custom animations to the animationIn and animationOut props.

For instance, we can write:

import React, { useState } from "react";
import { AnimateOnChange } from "react-animation";

export default function App() {
  const [count, setCount] = useState(0);

  return (
    <>
      <p>
        <button onClick={() => setCount((count) => count + 1)}>
          increment
        </button>
      </p>
      <AnimateOnChange
        animationIn="custom-animation-in 500ms ease-out forwards"
        animationOut="custom-animation-out 500ms ease-out forwards"
        durationOut={500}
      >
        {count}
      </AnimateOnChange>
    </>
  );
}

We set the animationIn and animationOut props with the specific effects to render.

Then we would see them displayed when count changes.

Conclusion

We can add simple animations easily to our React app with the React Animation library.