npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@lumberyard/react-doomsday

v1.1.5

Published

A nifty countdown component for React

Downloads

27

Readme

react-doomsday

npm bundle size NPM npm

A nifty countdown component for React

Doomsday is a component written originally for one of my projects. I needed something that would be very flexible at displaying time countdown and existing solutions required hacking around to make the countdown behave as I intended, so I wrote my own and decided to publish it. Maybe someone finds it useful.

react-doomsday is written with TypeScript and uses dayjs in the background. It's sole purpose is to count time from now until some date in the future.

Menu

Usage

import * as React from 'react'

import Doomsday from '@lumberyard/react-doomsday'

const Example: React.FC = () => {
  const date = "2029-05-25T02:23:35.000Z" // or use dayjs or native or timestamp
  return (
    ...
    <Doomsday date={date} />
    ...
  )
}

Install

yarn add @lumberyard/react-doomsday

npm install --save @lumberyard/react-doomsday

Demo

Codesandbox

Doomsday component

<Doomsday/> is a <div> wrapper around logic based on dayjs. The component gives you a bunch of ways of displaying the date. Each unit of time (eg. month, minute, etc.) is separate from the rest and works independently.

Props

All <Doomsday/> props are optional, however, bear in mind that this component has only bare minimum of styling. You can use style, className or any other popular CSS-in-JS solution to style it. DoomsdayProps are extended by <div>'s native props, so whatever <div> takes, so does <Doomsday/>

Default styles of the component can be overwritten.

const defaultStyles = {
  display: 'flex',
  alignItems: 'center',
  justifyContent: 'center'
}

See DoomsdayProps

Examples

import * as React from 'react'

import Doomsday from '@lumberyard/react-doomsday'

const Example: React.FC = () => {
  return (
    ...
    <Doomsday
      date="2029-05-25T02:23:35.000Z"
      format="[YYYYescape] YYYY-MM-DDTHH:mm:ssZ[Z]"
      render={(doom) => ({
        // `doom.date` will be in a format passed above
        <div>
          <h3>{doom.date}</h3>
          <p>{doom.endOfTimeSequence.months} months</p>
          <p>{doom.endOfTimeSequence.minutes} minutes</p>
          <p>{doom.endOfTimeSequence.seconds} seconds</p>
        </div>
      })}
    />
    ...
  )
}
import * as React from 'react'

import Doomsday from '@lumberyard/react-doomsday'

const Example: React.FC = () => {
  const [play, setPlay] = React.useState(true)

  return (
    ...
    <Doomsday
      play={play}
      showDefaults={false} // hides default units
      goodbye={<div>KAPUT!</div>}
      date="2029-05-25T02:23:35.000Z"
      years={({ label, endOfTimeSequence }) => (
        // label() displays the unit's label ('years' in this case) and cuts the plural form when necessary
        <div>
          <span>{endOfTimeSequence}</span>
          <span>{label(endOfTimeSequence)}</span>
        </div>
      )}
      months={({ type, endOfTimeSequence }) => (
        // label() also takes a second string argument that gets singu/pluralized
        <div>
          <span>{endOfTimeSequence}</span>
          <span>{label(endOfTimeSequence, 'pidgeons')}</span>
        </div>
      )}
      days={(to) => (
        // type shows the unit's label
        <div>
          <span>{to.endOfTimeSequence}</span>
          <span>{type}</span>
        </div>
      )}
      hours={(to) => (
        <div>
          <span>{to.endOfTimeSequence}</span>
          <span>Is this a real life...</span>
        </div>
      )}
      minutes={(to) => (
        <div>
          <span>{to.endOfTimeSequence}</span>
          <span>...or just a fantasy?</span>
        </div>
      )}
      seconds={(to) => (
        <div>
          <span>{to.endOfTimeSequence}</span>
          <span>What does the fox say?</span>
        </div>
      )}
    />
    ...
  )
}

Doomsday hook

The hook is used inside the <Doomsday/> wrapper, so don't use both in the same component.

Use the hook in the very last child of the parent tree

If you want more freedom (but keep the default calculations), you can import a useDoomsday hook instead of <Doomsday/> component. This function is the ticker written using setInterval(). I didn't use window.requestAnimationFrame() because I know setInterval() better and didn't have time to learn and understand how the other works - I'll probably rewrite it at some point. There shouldn't be any breaking changes.

The hook takes a date and an optional play argument and returns a doomsday object and an isHere flag.

| prop | type | description | | -------- | ----------------------------------- | ------------------------------------------------- | | doomsday | DoomsdayCreator | object containing default doomsday's calculations | | isHere | boolean | flag indicating countdown's completion |

import * as React from 'react'

import { useDoomsday } from '@lumberyard/react-doomsday'

const Example: React.FC = () => {
  const [play, setPlay] = React.useState(true);
  const date = "2029-05-25T02:23:35.000Z";
  const { doomsday, isHere } = useDoomsday(date, play);

  if (isHere) return <div>KAPUT!</div>

  return (
    ...
    <div>{doomsday.endOfTime.months}</div>
    ...
  )
}

Doomsday types

Since react-doomsday is written with TypeScript I am going to list typings instead of your regular props.

DoomsdayProps

| prop | type | default | description | | -------------------------------------------- | --------------------------------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | date | dayjs.ConfigType | dayjs().endOf('year') | This prop takes any date you might want to throw into dayjs(). It only takes dates from the future | | format | string | 'DD/MM/YYYY HH:mm:ss' | You can set the date's format using strings from dayjs | | play | boolean | true | This prop lets you programatically decide when to initialise the countdown | | showDefaults | boolean | true | If you use one of the RenderUnit props, a corresponding default will be overwritten. This turns the defaults off | | goodbye | React.ReactElement | undefined | goodbye renders the component you wish to show when the countdown is finished | | render | RenderDoomsday | undefined | This prop returns DoomsdayCreator object. It basically is an inner wraper around plugin's logic that gives you access to all date calculations. It overwrites RenderUnits, so it's either this or the rest... | | renderAll | boolean | false | ...unless this prop is set to true, which will display component passed with render as a last child (after) seconds | | years, months, days, hours, minutes, seconds | RenderUnit | undefined | returns a function that passes DoomsdayUnit object as its prop and takes a JSX component that gets rendered inside <Doomsday/>'s wrapper |

DoomsdayCreator

| prop | type | default | description | | ----------------- | --------------- | --------------------- | ------------------------------------------------------------------------------------------------------------ | | now | dayjs.Dayjs | dayjs() | now captured by dayjs | | target | dayjs.Dayjs | dayjs(date) | date passed as a prop used as an argument for dayjs | | nowTimestamp | number | now.valueOf() | timestamp of now | | targetTimestamp | number | target.valueOf() | timestamp of target | | diffTimestamp | number | target - now | timestamp of a difference between targetTimestamp and nowTimestamp | | date | string | 'DD/MM/YYYY HH:mm:ss' | date in a given dayjs format | | endOfTimeSequence | Units | - | returns an object with calculations per unit indicating logical sequence of time units until target is met | | endOfTimeFloat | Units | - | returns time left per unit after subtracting endOfTime years | | endOfTime | Units | - | returns units left until target | | endOfYear | Units | - | returns units left until end of year, if it's short, it returns 0 | | endOfMonth | Units | - | same story, different end | | endOfDay | Units | - | you get the gist | | endOfHour | Units | - | ... | | endOfMinute | Units | - | ... |

Units

| prop | type | description | | ------- | ------ | ------------------------------------------- | | years | number | years it will take to reach the end of unit | | months | number | months until the end of unit | | days | number | ... | | hours | number | ... | | minutes | number | ... | | seconds | number | ... |

RenderUnit

(to: DoomsdayUnit) => React.ReactElement

RenderDoomsday

(doom: DoomsdayCreator) => React.ReactElement

DoomsdayUnit

This is DoomsdayCreator in (sort of) reverse. Depending on which RenderUnit you render in <Doomsday/> instead of returning the entire DoomsdayCreator, you get only endOfs for that specific unit.

| prop | type | description | | ----------------- | ----------------------------------------- | -------------------------------------------------------- | | type | UnitType | string indicating which unit is selected | | label | (endOf: number, text?: string) => string; | slice(0, -1) on UnitType or text removing plural 's' | | endOfTimeSequence | number | endOfTimeSequence in selected UnitType | | endOfTimeFloat | number | ... | | endOfTime | number | ... | | endOfYear | number | ... | | endOfMonth | number | ... | | endOfDay | number | ... | | endOfHour | number | ... | | endOfMinute | number | ... |

UnitType

"seconds" | "minutes" | "hours" | "days" | "months" | "years"

Stuff

If you feel the docs are missing something, or some stuff isn't clear, feel free to open an issue. I feel this plugin is simple enough to get by without unit tests. TS is here to keep an eye on things. As for the Code of Conduct, there is none. Just be humane to humans and non-humans alike.

License

MIT © MatulaDesign