Skip to content

Commit

Permalink
feat(count-down): add some slots
Browse files Browse the repository at this point in the history
  • Loading branch information
qianmoQ committed Dec 6, 2024
1 parent d0b3920 commit 6cd514c
Show file tree
Hide file tree
Showing 3 changed files with 243 additions and 71 deletions.
107 changes: 105 additions & 2 deletions docs/components/count-down.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,100 @@ This document is mainly used to describe some features and usage of the ShadcnCo

:::

## Custom Slots

::: raw

<CodeRunner title="Custom Slots">
<div class="space-y-2">
<ShadcnCard title="Custom Time Block">
<ShadcnCountDown title="Activity events" :time="new Date(Date.now() + 6 * 1000)">
<template #days="{ value, isWarning }">
<div class="flex flex-col items-center">
<div class="text-5xl font-bold" :class="{ 'text-red-500': isWarning }">
{{ value }}
</div>
<div class="text-sm">Days Left</div>
</div>
</template>
</ShadcnCountDown>
</ShadcnCard>
<ShadcnCard title="Custom Label">
<ShadcnCountDown title="Activity events" :time="new Date(Date.now() + 6 * 1000)">
<template #days-label>
<span class="text-sm mt-2 text-blue-500">DAYS</span>
</template>
</ShadcnCountDown>
</ShadcnCard>
<ShadcnCard title="Custom Full">
<ShadcnCountDown :time="new Date(Date.now() + 6 * 1000)">
<template #blocks="{ timeLeft, isWarning }">
<div class="flex flex-col gap-2">
<div class="text-2xl" :class="{ 'text-red-500': isWarning }">
Time Left: {{ timeLeft.days }} D
</div>
<div class="flex gap-2">
<span>{{ timeLeft.hours }} H</span>
<span>{{ timeLeft.minutes }} M</span>
<span>{{ timeLeft.seconds }} S</span>
</div>
</div>
</template>
</ShadcnCountDown>
</ShadcnCard>
</div>
</CodeRunner>

:::

::: details Show code

```vue
<template>
<div class="space-y-2">
<ShadcnCard title="Custom Time Block">
<ShadcnCountDown title="Activity events" :time="new Date(Date.now() + 6 * 1000)">
<template #days="{ value, isWarning }">
<div class="flex flex-col items-center">
<div class="text-5xl font-bold" :class="{ 'text-red-500': isWarning }">
{{ value }}
</div>
<div class="text-sm">Days Left</div>
</div>
</template>
</ShadcnCountDown>
</ShadcnCard>
<ShadcnCard title="Custom Label">
<ShadcnCountDown title="Activity events" :time="new Date(Date.now() + 6 * 1000)">
<template #days-label>
<span class="text-sm mt-2 text-blue-500">DAYS</span>
</template>
</ShadcnCountDown>
</ShadcnCard>
<ShadcnCard title="Custom Full">
<ShadcnCountDown :time="new Date(Date.now() + 6 * 1000)">
<template #blocks="{ timeLeft, isWarning }">
<div class="flex flex-col gap-2">
<div class="text-2xl" :class="{ 'text-red-500': isWarning }">
Time Left: {{ timeLeft.days }} D
</div>
<div class="flex gap-2">
<span>{{ timeLeft.hours }} H</span>
<span>{{ timeLeft.minutes }} M</span>
<span>{{ timeLeft.seconds }} S</span>
</div>
</div>
</template>
</ShadcnCountDown>
</ShadcnCard>
</div>
</template>
```

:::

## Count Down Props

<ApiTable title="Props"
Expand All @@ -144,9 +238,18 @@ This document is mainly used to describe some features and usage of the ShadcnCo
## Count Down Slots

<ApiTable title="Slots"
:headers="['Slot', 'Description']"
:headers="['Slot', 'Description', 'Params']"
:columns="[
['title', 'Count down content'],
['title', 'Count down content', '-'],
['blocks', 'Count down blocks', '{ timeLeft, isWarning, isCompleted, isPaused }'],
['days', 'Days block content', '{ timeLeft, isWarning, isCompleted, isPaused }'],
['hours', 'Hours block content', '{ timeLeft, isWarning, isCompleted, isPaused }'],
['minutes', 'Minutes block content', '{ timeLeft, isWarning, isCompleted, isPaused }'],
['seconds', 'Seconds block content', '{ timeLeft, isWarning, isCompleted, isPaused }'],
['days-label', 'Days label content', '-'],
['hours-label', 'Hours label content', '-'],
['minutes-label', 'Minutes label content', '-'],
['seconds-label', 'Seconds label content', '-']
]">
</ApiTable>

Expand Down
43 changes: 38 additions & 5 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,42 @@
<template>
<div class="p-32">
<ShadcnCountDown title="Activity events"
toolbar
show-progress
:time="new Date(Date.now() + 6 * 1000)"/>
<div class="p-32 space-y-2">
<ShadcnCard title="Custom Time Block">
<ShadcnCountDown title="Activity events" :time="new Date(Date.now() + 6 * 1000)">
<template #days="{ value, isWarning }">
<div class="flex flex-col items-center">
<div class="text-5xl font-bold" :class="{ 'text-red-500': isWarning }">
{{ value }}
</div>
<div class="text-sm">Days Left</div>
</div>
</template>
</ShadcnCountDown>
</ShadcnCard>

<ShadcnCard title="Custom Label">
<ShadcnCountDown title="Activity events" :time="new Date(Date.now() + 6 * 1000)">
<template #days-label>
<span class="text-sm mt-2 text-blue-500">DAYS</span>
</template>
</ShadcnCountDown>
</ShadcnCard>

<ShadcnCard title="Custom Full">
<ShadcnCountDown :time="new Date(Date.now() + 6 * 1000)">
<template #blocks="{ timeLeft, isWarning }">
<div class="flex flex-col gap-2">
<div class="text-2xl" :class="{ 'text-red-500': isWarning }">
Time Left: {{ timeLeft.days }} D
</div>
<div class="flex gap-2">
<span>{{ timeLeft.hours }} H</span>
<span>{{ timeLeft.minutes }} M</span>
<span>{{ timeLeft.seconds }} S</span>
</div>
</div>
</template>
</ShadcnCountDown>
</ShadcnCard>
</div>
</template>

Expand Down
164 changes: 100 additions & 64 deletions src/ui/count-down/ShadcnCountDown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,72 +26,109 @@
</div>
</template>

<div class="grid grid-cols-4 gap-4 text-center">
<!-- Days -->
<div class="relative flex flex-col">
<div :class="['text-4xl font-bold rounded-lg p-4 transition-all duration-300',
{
'bg-slate-100': !isWarning && !isCompleted,
'bg-red-50': isWarning && !isCompleted,
'bg-green-50': isCompleted,
'animate-pulse': isWarning && !isPaused && !isCompleted
}
]">
{{ padNumber(timeLeft.days) }}
<span v-if="isWarning && !isCompleted"
class="absolute -top-1 -right-1 flex h-3 w-3">
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-red-400 opacity-75"></span>
<span class="relative inline-flex rounded-full h-3 w-3 bg-red-500"></span>
</span>
</div>
<span class="text-sm mt-2">{{ t('countDown.text.day') }}</span>
</div>
<slot name="blocks"
:time-left="timeLeft"
:is-warning="isWarning"
:is-completed="isCompleted"
:is-paused="isPaused">
<div class="grid grid-cols-4 gap-4 text-center">
<!-- Days -->
<slot name="days"
:value="timeLeft.days"
:is-warning="isWarning"
:is-completed="isCompleted"
:is-paused="isPaused">
<div class="relative flex flex-col">
<div :class="['text-4xl font-bold rounded-lg p-4 transition-all duration-300',
{
'bg-slate-100': !isWarning && !isCompleted,
'bg-red-50': isWarning && !isCompleted,
'bg-green-50': isCompleted,
'animate-pulse': isWarning && !isPaused && !isCompleted
}
]">
{{ padNumber(timeLeft.days) }}
<span v-if="isWarning && !isCompleted" class="absolute -top-1 -right-1 flex h-3 w-3">
<span class="absolute inline-flex h-full w-full rounded-full bg-red-400 opacity-75 animate-ping"></span>
<span class="relative inline-flex rounded-full h-3 w-3 bg-red-500"></span>
</span>
</div>
<slot name="days-label">
<span class="text-sm mt-2">{{ t('countDown.text.day') }}</span>
</slot>
</div>
</slot>

<!-- Hours -->
<div class="flex flex-col">
<div :class="['text-4xl font-bold rounded-lg p-4 transition-all duration-300',
{
'bg-slate-100': !isWarning && !isCompleted,
'bg-red-50': isWarning && !isCompleted,
'bg-green-50': isCompleted,
'animate-pulse': isWarning && !isPaused && !isCompleted
}
]">
{{ padNumber(timeLeft.hours) }}
</div>
<span class="text-sm mt-2">{{ t('countDown.text.hour') }}</span>
</div>
<!-- Hours -->
<slot name="hours"
:value="timeLeft.hours"
:is-warning="isWarning"
:is-completed="isCompleted"
:is-paused="isPaused">
<div class="flex flex-col">
<div :class="['text-4xl font-bold rounded-lg p-4 transition-all duration-300',
{
'bg-slate-100': !isWarning && !isCompleted,
'bg-red-50': isWarning && !isCompleted,
'bg-green-50': isCompleted,
'animate-pulse': isWarning && !isPaused && !isCompleted
}
]">
{{ padNumber(timeLeft.hours) }}
</div>
<slot name="hours-label">
<span class="text-sm mt-2">{{ t('countDown.text.hour') }}</span>
</slot>
</div>
</slot>

<!-- Minutes -->
<div class="flex flex-col">
<div :class="['text-4xl font-bold rounded-lg p-4 transition-all duration-300',
{
'bg-slate-100': !isWarning && !isCompleted,
'bg-red-50': isWarning && !isCompleted,
'bg-green-50': isCompleted,
'animate-pulse': isWarning && !isPaused && !isCompleted
}
]">
{{ padNumber(timeLeft.minutes) }}
</div>
<span class="text-sm mt-2">{{ t('countDown.text.minute') }}</span>
</div>
<!-- Minutes -->
<slot name="minutes"
:value="timeLeft.minutes"
:is-warning="isWarning"
:is-completed="isCompleted"
:is-paused="isPaused">
<div class="flex flex-col">
<div :class="['text-4xl font-bold rounded-lg p-4 transition-all duration-300',
{
'bg-slate-100': !isWarning && !isCompleted,
'bg-red-50': isWarning && !isCompleted,
'bg-green-50': isCompleted,
'animate-pulse': isWarning && !isPaused && !isCompleted
}
]">
{{ padNumber(timeLeft.minutes) }}
</div>
<slot name="minutes-label">
<span class="text-sm mt-2">{{ t('countDown.text.minute') }}</span>
</slot>
</div>
</slot>

<!-- Seconds -->
<div class="flex flex-col">
<div :class="['text-4xl font-bold rounded-lg p-4 transition-all duration-300',
{
'bg-slate-100': !isWarning && !isCompleted,
'bg-red-50': isWarning && !isCompleted,
'bg-green-50': isCompleted,
'animate-pulse': isWarning && !isPaused && !isCompleted
}
]">
{{ padNumber(timeLeft.seconds) }}
</div>
<span class="text-sm mt-2">{{ t('countDown.text.second') }}</span>
<!-- Seconds -->
<slot name="seconds"
:value="timeLeft.seconds"
:is-warning="isWarning"
:is-completed="isCompleted"
:is-paused="isPaused">
<div class="flex flex-col">
<div :class="['text-4xl font-bold rounded-lg p-4 transition-all duration-300',
{
'bg-slate-100': !isWarning && !isCompleted,
'bg-red-50': isWarning && !isCompleted,
'bg-green-50': isCompleted,
'animate-pulse': isWarning && !isPaused && !isCompleted
}
]">
{{ padNumber(timeLeft.seconds) }}
</div>
<slot name="seconds-label">
<span class="text-sm mt-2">{{ t('countDown.text.second') }}</span>
</slot>
</div>
</slot>
</div>
</div>
</slot>

<!-- Progress bar -->
<div v-if="showProgress" class="mt-4 h-2 bg-gray-200 rounded-full overflow-hidden">
Expand All @@ -103,8 +140,7 @@
'animate-pulse': isWarning && !isPaused && !isCompleted
}
]"
:style="{ width: `${progress}%` }"
></div>
:style="{ width: `${progress}%` }"/>
</div>

<!-- Status display -->
Expand Down

0 comments on commit 6cd514c

Please sign in to comment.