mirror of
https://github.com/tabler/tabler.git
synced 2026-10-12 13:17:00 +04:00
89 lines
3.3 KiB
Plaintext
89 lines
3.3 KiB
Plaintext
---
|
|
import { staticPath } from '@shared/lib/assets'
|
|
import photos from '@data/photos.json'
|
|
import CardTitle from '@ui/CardTitle.astro'
|
|
|
|
interface Props {
|
|
id?: string
|
|
title?: string
|
|
indicators?: boolean
|
|
indicatorsThumb?: boolean
|
|
indicatorsThumbRatio?: boolean
|
|
indicatorsDot?: boolean
|
|
indicatorsVertical?: boolean
|
|
controls?: boolean
|
|
captions?: boolean
|
|
offset?: number
|
|
fade?: boolean
|
|
}
|
|
|
|
const { id: idProp, title = 'Carousel', indicators, indicatorsThumb, indicatorsThumbRatio, indicatorsDot, indicatorsVertical, controls, captions, offset = 0, fade } = Astro.props
|
|
|
|
const limit = 5
|
|
const carouselId = idProp ?? 'carousel'
|
|
const filteredPhotos = (photos as { file: string; title?: string; horizontal?: boolean }[]).filter((p) => p.horizontal)
|
|
const slides = filteredPhotos.slice(offset, offset + limit)
|
|
---
|
|
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<CardTitle>{title}</CardTitle>
|
|
</div>
|
|
<div class="card-body">
|
|
<div id={`carousel-${carouselId}`} class={`carousel slide${fade ? ' carousel-fade' : ''}`} data-bs-ride="carousel" aria-roledescription="carousel" aria-label={title}>
|
|
{
|
|
indicators && (
|
|
<div class={`carousel-indicators${indicatorsVertical ? ' carousel-indicators-vertical' : ''}${indicatorsDot ? ' carousel-indicators-dot' : indicatorsThumb ? ' carousel-indicators-thumb' : ''}`}>
|
|
{slides.map((photo, i) => (
|
|
<button
|
|
type="button"
|
|
data-bs-target={`#carousel-${carouselId}`}
|
|
data-bs-slide-to={`${i}`}
|
|
class={`${indicatorsThumbRatio ? ' ratio ratio-4x3' : ''}${i === 0 ? ' active' : ''}`}
|
|
style={indicatorsThumb ? `background-image: url(${staticPath(`photos/${photo.file}`)})` : undefined}
|
|
aria-label={`Slide ${i + 1}`}
|
|
aria-current={i === 0 ? 'true' : undefined}
|
|
/>
|
|
))}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
<div class="carousel-inner" aria-live="polite" aria-atomic="true">
|
|
{
|
|
slides.map((photo, i) => (
|
|
<div class={`carousel-item${i === 0 ? ' active' : ''}`}>
|
|
<img class="d-block w-100" alt={captions ? '' : (photo.title ?? '')} src={staticPath(`photos/${photo.file}`)} />
|
|
|
|
{captions && (
|
|
<Fragment>
|
|
<div class="carousel-caption-background d-none d-md-block" />
|
|
<div class="carousel-caption d-none d-md-block">
|
|
<h3>Slide label</h3>
|
|
<p>Nulla vitae elit libero, a pharetra augue mollis interdum.</p>
|
|
</div>
|
|
</Fragment>
|
|
)}
|
|
</div>
|
|
))
|
|
}
|
|
</div>
|
|
|
|
{
|
|
controls && (
|
|
<Fragment>
|
|
<button type="button" class="carousel-control-prev" data-bs-target={`#carousel-${carouselId}`} data-bs-slide="prev">
|
|
<span class="carousel-control-prev-icon" aria-hidden="true" />
|
|
<span class="visually-hidden">Previous</span>
|
|
</button>
|
|
<button type="button" class="carousel-control-next" data-bs-target={`#carousel-${carouselId}`} data-bs-slide="next">
|
|
<span class="carousel-control-next-icon" aria-hidden="true" />
|
|
<span class="visually-hidden">Next</span>
|
|
</button>
|
|
</Fragment>
|
|
)
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|