Getting Started
Components
- Accordion
- Advanced Toast
- AlertMessage
- ArrowButton
- Arrows
- Avatar
- Backdrop
- Basic Toast
- Breadcrumb
- Button
- CardBackground
- Card
- Carousel
- Chapters
- ChatBody
- ChatButton
- ChatHeader
- ChatInput
- ChatMessageActions
- ChatMessageEditor
- ChatMessage
- ChatTypingIndicator
- ChatWindowCsatPrompt
- ChatWindowQuote
- ChatWindow
- CheckboxSelect
- Checkbox
- Checkboxes
- Chip
- ChoiceExpander
- Clickable
- ContentReview
- Countdown
- CriteriaDates
- CriteriaParticipants
- CriteriaTransports
- Date Field
- Datepicker
- Dropdown
- ElasticHeight
- ExpandableCard
- ExpandableText
- Filter
- FloatingLabelTextField
- Form Control
- Form Label
- Frame
- HamburgerIcon
- Heading
- Image
- JourneyCard
- LayerHeader
- Layer
- Link
- Loader
- Number Field
- PageNavigation
- Pagination
- Paragraph
- Password
- Phone Field
- Popin
- Portal
- ProductThumbnail
- Promises
- Prose
- Radio Group
- RadioSelect
- Radio
- Range
- Scrollbar
- Select
- SidebarLayout
- SliderFrame
- SparkleWrapper
- Spinner
- Switch
- Table
- Tabs
- Tag
- TextField
- Toggle
- Tooltip
- ValidationMessage
'use client';
import { Promises } from '@/ui/Promises/Promises';
export function PromisesDemo() {
return (
<Promises
className="min-h-500 w-full"
items={[
{
title: 'The most beautiful destinations',
href: '#',
image: {
src: 'https://images.unsplash.com/photo-1507525428034-b723cf961d3e?w=400',
alt: 'Beautiful beach destination',
},
},
{
title: 'Kids club starting from 4 months',
href: '#',
image: {
src: 'https://images.unsplash.com/photo-1529156069898-49953e39b3ac?w=400',
alt: 'Kids playing at the club',
},
},
{
title: 'The best restaurants on the coast',
href: '#',
image: {
src: 'https://images.unsplash.com/photo-1414235077428-338989a2e8c0?w=400',
alt: 'Fine dining restaurant',
},
},
]}
labels={{
anchor: { continue: 'Discover' },
layer: { close: 'Close menu', open: 'Open menu' },
scroller: { previous: 'Previous', next: 'Next' },
}}
/>
);
}
Installation
npx shadcn@latest add https://develop.trident-ui.pro.clubmed/r/promises.json
Usage
import { Promises } from '@/ui/Promises/Promises';
export function Component() {
return (
<Promises
items={[
{
title: 'The most beautiful destinations',
href: '/destinations',
image: { src: '/images/destinations.jpg', alt: 'Beach destination' },
},
{
title: 'Kids club starting from 4 months',
href: '/kids-club',
image: { src: '/images/kids.jpg', alt: 'Kids at the club' },
},
]}
labels={{
anchor: { continue: 'Discover' },
layer: { close: 'Close menu', open: 'Open menu' },
scroller: { previous: 'Previous', next: 'Next' },
}}
/>
);
}Anatomy
Promises is composed of three internal sub-components that are exported for advanced use:
| Sub-component | Role |
|---|---|
PromisesMedia | Stacked image slides with a progress dot bar and prev/next controls |
PromisesMenu | Title list — overlay on mobile, sidebar at @3xl container width |
API Reference
Promises
| Prop | Type | Default | Description |
|---|---|---|---|
items | PromisesItem[] | Required | Array of carousel items (title, href, image) |
labels | PromisesLabels | Required | Localised strings for the anchor, layer toggle, and scroller |
className | string | undefined | Additional CSS classes applied to the root container |
PromisesItem
| Field | Type | Default | Description |
|---|---|---|---|
title | string | Required | Title displayed on the media overlay and in the menu |
href | string | Required | URL the "continue" anchor links to |
image | ImageProps | Required | Props forwarded to the trident-ui Image component |
id | string | undefined | Optional stable id; used for accessible labelling |
PromisesLabels
| Field | Type | Description |
|---|---|---|
anchor.continue | string | Label for the "continue" anchor inside each item |
layer.open | string | Aria-label for the toggle button (closed state) |
layer.close | string | Aria-label for the toggle button (open state) |
scroller.previous | string | Screen-reader label for the previous button |
scroller.next | string | Screen-reader label for the next button |
Behaviour
Auto-advance
Items cycle automatically every 10 seconds. The timer resets whenever the user interacts with the previous/next buttons or the dot indicators. The interval clears on unmount.
Responsive layout
Promises uses a CSS container named promises. Below @3xl the menu is an overlay (toggle
with the up-arrow button). At @3xl and above the menu becomes a static sidebar and the toggle
button is hidden.
Dot progress bar
Each dot animates a fill from left to right over 10 s (animate-filling) while that item is
active. Dots for past items are filled white; future items show at 40 % opacity.
Accessibility
- Each image slide is an
<article>witharia-hiddenandinertwhen not active — screen readers and keyboard focus skip inactive slides. - The media region carries
aria-hidden/inertwhen the overlay menu is open, preventing accidental focus trap on the hidden layer. - Previous and next buttons expose their purpose through
sr-onlytext taken fromlabels.scroller. - The overlay toggle button updates its
aria-labelbetweenlabels.layer.openandlabels.layer.closeto communicate the current menu state. - Dot indicator buttons carry
aria-currentto announce the active slide to assistive technology.
Notes
- All three files (
Promises,PromisesMedia,PromisesMenu) are marked'use client'— they rely onuseState,useEffect, anduseCallback. PromisesMediaandPromisesMenuare internal sub-components; importPromisesto consume the full organism.@3xl/promises:container-query modifiers require@tailwindcss/container-queries. The@container/promisesclass is added to the root<div>automatically.