Countdown

Countdown with options control.

Usage

Use the seconds prop to set the number of seconds to Countdown.

02:00
<template>
  <B24Countdown :seconds="120" />
</template>

Show minutes

Use the show-minutes property to show or hide the minutes in the Countdown. Default value: true.

120
<template>
  <B24Countdown :show-minutes="false" :seconds="120" />
</template>

Size

Use the size prop to change the size of the Countdown.

02:00
<template>
  <B24Countdown size="xl" :seconds="120" />
</template>

Use Circle

Use the useCircle property to display a circle around the Countdown.

:120
<template>
  <B24Countdown use-circle :seconds="120" size="xl" />
</template>

Icon

Use the icon prop to show an Icon.

02:00
<script setup lang="ts">
import RocketIcon from '@bitrix24/b24icons-vue/main/RocketIcon'
</script>

<template>
  <B24Countdown :icon="RocketIcon" :seconds="120" size="xl" />
</template>

Avatar

Use the avatar prop to show an Avatar.

02:00
<template>
  <B24Countdown
    :avatar="{
      src: '/b24ui/avatar/employee.png'
    }"
    :seconds="120"
    size="xl"
  />
</template>

Examples

Information displayed

You can manage information using the default slot.

Time Remaining:2 days, 0 hours, 0 minutes, 0 seconds.
<script setup lang="ts">
import { ref } from 'vue'

const value = ref(2 * 24 * 60 * 60)
</script>

<template>
  <B24Countdown
    v-slot="{ days, hours, minutes, seconds }"
    :seconds="value"
  >
    Time Remaining:{{ days }} days, {{ hours }} hours, {{ minutes }} minutes, {{ seconds }} seconds.
  </B24Countdown>
</template>

With interval

You can control the countdown interval using the interval prop.

New Year Countdown:302 days, 17 hours, 29 minutes, 4.7 seconds.
<script setup lang="ts">
import { ref } from 'vue'

const now = new Date()
const newYear = new Date(now.getFullYear() + 1, 0, 1)

const secondsNY = ref((newYear.getTime() - now.getTime()) / 1000)
</script>

<template>
  <B24Countdown
    v-slot="{ days, hours, minutes, seconds, milliseconds }"
    :seconds="secondsNY"
    :interval="100"
  >
    <span>New Year Countdown:{{ days }} days, {{ hours }} hours, {{ minutes }} minutes, {{ seconds }}.<small>{{ Math.floor(milliseconds / 100) }}</small> seconds.</span>
  </B24Countdown>
</template>

Handling countdown emits

Use emit start, end, abort, progress to respond to countdown events.

<script setup lang="ts">
import { ref } from 'vue'

const value = ref(5)
const counting = ref(false)

const startCountdown = () => {
  counting.value = true
}

const onCountdownEnd = () => {
  counting.value = false
}
</script>

<template>
  <B24Button
    color="air-primary"
    size="xl"
    :disabled="counting"
    @click="startCountdown"
  >
    <B24Countdown
      v-if="counting"
      v-slot="{ totalSeconds }"
      :seconds="value"
      class="text-white dark:text-white text-xl leading-none"
      @end="onCountdownEnd"
    >
      Fetch again {{ totalSeconds }} sec. later
    </B24Countdown>
    <span v-else>
      Fetch Verification Code
    </span>
  </B24Button>
</template>

API

Props

Prop Default Type
as'span'any

The element or component this component should render as

size'md' "xs" | "sm" | "md" | "lg" | "xl"
emitEventstrueboolean

Emits the countdown events

seconds0 string | number

Number of seconds to countdown

showMinutestrueboolean

Should seconds be divided into minutes?

useCirclefalseboolean

Shows a Circle around the countdown

interval1000 number

The interval time (in milliseconds) of the countdown progress

needStartImmediatelytrueboolean

Starts the countdown automatically when initialized

nowDate.now() (): number

Generate the current time of a specific time zone

iconIconComponent

Display an icon on the left side.

avatar AvatarProps

Display an avatar on the left side.

b24ui { base?: ClassNameValue; label?: ClassNameValue; leadingIcon?: ClassNameValue; leadingAvatar?: ClassNameValue; leadingAvatarSize?: ClassNameValue; circleBase?: ClassNameValue; circleGroup?: ClassNameValue; circleElement?: ClassNameValue; circlePath?: ClassNameValue; }

Slots

Slot Type
leading{ b24ui: object; }
defaultCountdownData & { formatTime: string; b24ui: object; }

Emits

Event Type
abort[]
progress[value: CountdownData]
start[]
end[]

Theme

app.config.ts
export default defineAppConfig({
  b24ui: {
    countdown: {
      slots: {
        base: 'relative flex flex-row flex-nowrap items-center justify-between text-(--b24ui-typography-legend-color)',
        label: '',
        leadingIcon: 'shrink-0',
        leadingAvatar: 'shrink-0',
        leadingAvatarSize: '',
        circleBase: '-scale-x-100 absolute inset-x-0 inset-y-0',
        circleGroup: 'fill-none stroke-none',
        circleElement: 'stroke-transparent stroke-1',
        circlePath: 'stroke-[7px] rotate-90 origin-center stroke-current transition-all duration-1000 ease-linear'
      },
      variants: {
        size: {
          xs: {
            base: 'gap-0.5 text-(length:--ui-font-size-5xs)/(--ui-font-line-height-reset)',
            leadingIcon: 'size-sm',
            leadingAvatarSize: '3xs'
          },
          sm: {
            base: 'gap-1 text-(length:--ui-font-size-4xs)/(--ui-font-line-height-reset)',
            leadingIcon: 'size-sm2',
            leadingAvatarSize: '3xs'
          },
          md: {
            base: 'gap-1 text-(length:--ui-font-size-md)/(--ui-font-line-height-reset)',
            leadingIcon: 'size-[16px]',
            leadingAvatarSize: '3xs'
          },
          lg: {
            base: 'gap-1 text-(length:--ui-font-size-lg)/(--ui-font-line-height-reset)',
            leadingIcon: 'size-[22px]',
            leadingAvatarSize: '2xs'
          },
          xl: {
            base: 'gap-1 text-(length:--ui-font-size-xl)/(--ui-font-line-height-reset)',
            leadingIcon: 'size-[26px]',
            leadingAvatarSize: 'xs'
          }
        },
        leading: {
          true: ''
        },
        useCircle: {
          true: {
            base: 'justify-center',
            circleBase: 'size-full'
          }
        }
      },
      compoundVariants: [
        {
          size: 'xs',
          useCircle: true,
          class: 'text-(length:--ui-font-size-7xs)/[normal] p-0.5'
        },
        {
          size: 'sm',
          useCircle: true,
          class: 'text-(length:--ui-font-size-6xs)/[normal] p-1.5'
        },
        {
          size: 'md',
          useCircle: true,
          class: 'text-(length:--ui-font-size-3xs)/[normal] p-1.5'
        },
        {
          size: 'lg',
          useCircle: true,
          class: 'text-(length:--ui-font-size-xs)/[normal] p-1.5 pb-2'
        },
        {
          size: 'xl',
          useCircle: true,
          class: 'text-(length:--ui-font-size-sm)/[normal] p-2 pb-2.5'
        }
      ],
      defaultVariants: {
        size: 'md'
      }
    }
  }
})
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import bitrix24UIPluginVite from '@bitrix24/b24ui-nuxt/vite'

export default defineConfig({
  plugins: [
    vue(),
    bitrix24UIPluginVite({
      b24ui: {
        countdown: {
          slots: {
            base: 'relative flex flex-row flex-nowrap items-center justify-between text-(--b24ui-typography-legend-color)',
            label: '',
            leadingIcon: 'shrink-0',
            leadingAvatar: 'shrink-0',
            leadingAvatarSize: '',
            circleBase: '-scale-x-100 absolute inset-x-0 inset-y-0',
            circleGroup: 'fill-none stroke-none',
            circleElement: 'stroke-transparent stroke-1',
            circlePath: 'stroke-[7px] rotate-90 origin-center stroke-current transition-all duration-1000 ease-linear'
          },
          variants: {
            size: {
              xs: {
                base: 'gap-0.5 text-(length:--ui-font-size-5xs)/(--ui-font-line-height-reset)',
                leadingIcon: 'size-sm',
                leadingAvatarSize: '3xs'
              },
              sm: {
                base: 'gap-1 text-(length:--ui-font-size-4xs)/(--ui-font-line-height-reset)',
                leadingIcon: 'size-sm2',
                leadingAvatarSize: '3xs'
              },
              md: {
                base: 'gap-1 text-(length:--ui-font-size-md)/(--ui-font-line-height-reset)',
                leadingIcon: 'size-[16px]',
                leadingAvatarSize: '3xs'
              },
              lg: {
                base: 'gap-1 text-(length:--ui-font-size-lg)/(--ui-font-line-height-reset)',
                leadingIcon: 'size-[22px]',
                leadingAvatarSize: '2xs'
              },
              xl: {
                base: 'gap-1 text-(length:--ui-font-size-xl)/(--ui-font-line-height-reset)',
                leadingIcon: 'size-[26px]',
                leadingAvatarSize: 'xs'
              }
            },
            leading: {
              true: ''
            },
            useCircle: {
              true: {
                base: 'justify-center',
                circleBase: 'size-full'
              }
            }
          },
          compoundVariants: [
            {
              size: 'xs',
              useCircle: true,
              class: 'text-(length:--ui-font-size-7xs)/[normal] p-0.5'
            },
            {
              size: 'sm',
              useCircle: true,
              class: 'text-(length:--ui-font-size-6xs)/[normal] p-1.5'
            },
            {
              size: 'md',
              useCircle: true,
              class: 'text-(length:--ui-font-size-3xs)/[normal] p-1.5'
            },
            {
              size: 'lg',
              useCircle: true,
              class: 'text-(length:--ui-font-size-xs)/[normal] p-1.5 pb-2'
            },
            {
              size: 'xl',
              useCircle: true,
              class: 'text-(length:--ui-font-size-sm)/[normal] p-2 pb-2.5'
            }
          ],
          defaultVariants: {
            size: 'md'
          }
        }
      }
    })
  ]
})
Releases
Published under MIT License.

Copyright © 2024-present Bitrix24