Components
Weather Widget
BetaWeatherWidget renders a monthly temperature bar chart with best-month highlighting to help travellers choose when to visit a destination.
When to visit Kenya
Purpose
WeatherWidget answers the most common pre-booking question: "when is the best time to go?" It appears on destination pages, holiday guides, and the inspiration section of the booking funnel.
The component is not a general-purpose charting tool. It has one job — communicate the temperature profile of a destination across 12 months and highlight the months that offer the best combination of weather, value, and crowd levels. The yellow best-month bars create an immediate visual anchor that lets travellers find their travel window without reading a paragraph of editorial text.
Key design decisions:
- Bars over lines — a bar chart is more readable at the narrow widths common on destination pages than a line chart, and maps intuitively to "amount of heat per month"
- Max temperature only by default — average temperatures are optional because max temperature is the figure most travellers relate to ("how hot will it feel?")
- Sunshine hours as a summary line — displayed as a footer note with a sun icon rather than a second chart axis, keeping the visualisation simple
- Yellow for best months — Kuoni yellow (
bg-kuoni-yellow) is used specifically for highlighted months; teal (bg-teal) for all other months
Usage
Use WeatherWidget specifically to answer "when should I go?" with a 12-month temperature profile — it is not a general-purpose charting component, so don't repurpose it for unrelated data series. It is a fairly standalone display component with no close substitute in this library; if you need a different kind of comparison (e.g. flight times or prices across months), build a bespoke chart rather than stretching WeatherWidget's props to fit.
It appears on destination pages, holiday guides, and the inspiration section of the booking funnel — typically once per destination, near the top of the page alongside other destination-level content.
Anatomy
When to visit Maldives
- 1Heading — "When to visit [destination]" — auto-generated from the destination prop. 18px semibold.
- 2Bar chart — 12 vertical bars, one per month. Height proportional to maxTemp relative to the highest value in the dataset. Bars are teal by default, yellow for best months.
- 3Temperature labels — Max temperature in °C (or °F when unit="F") displayed in 11px above each bar.
- 4Month labels — Three-letter month abbreviations (Jan–Dec) in 11px grey below each bar.
- 5Legend — Small colour key at the bottom: teal swatch "All months" · yellow swatch "Best months to visit".
- 6Sunshine summary — Optional. A single line below the legend: sun icon (yellow) + "Up to X hours of sunshine per day in [best month range]." Only appears when at least one data item provides sunshineHours.
Variants
Standard — Celsius
The default variant. All 12 months displayed with maxTemp in °C. Best months highlighted in yellow.
When to visit Zanzibar
Fahrenheit
Pass unit="F" to display temperatures in Fahrenheit. The bar heights remain identical — only the labels change. The heading does not change.
When to visit Maldives
With sunshine hours
When sunshineHours is provided on one or more data items, a sunshine summary line appears below the legend. The component calculates the maximum sunshine hours across the best months and displays it as "Up to X hours of sunshine per day."
When to visit Sri Lanka
No best months
When bestMonths is omitted or empty, all bars render in teal and the legend is hidden. Use this for destinations where the editorial team has not yet identified a recommended season, or for destinations with year-round good weather where no month is significantly better.
When to visit Maldives
States
Default
The chart renders statically. Bars animate in on first render with a vertical grow transition (200ms ease-out per bar, staggered by 30ms). This draws the eye and gives the chart a sense of life without being distracting.
Bar hover
On pointer hover over an individual bar, a tooltip appears above the bar showing the full detail: "July · 22°C max · 8h sunshine". The hovered bar lightens slightly. This is the only interactive state — the chart is informational, not a filter control.
Best practices
Always pass destination so the heading 'When to visit [destination]' renders correctly. Do not use a generic heading like 'Climate'.
The heading answers the question before the traveller reads the chart.
Omit the destination prop and rely on surrounding page context to identify the chart.
A headingless chart is ambiguous — the traveller does not know which destination the data refers to.
Pass bestMonths with the 2–4 months that represent the genuine best travel window for the destination.
Yellow best-month bars create an immediate visual priority — the traveller knows where to look.
Set bestMonths to all 12 months to avoid showing any month as 'not best'.
Highlighting every month defeats the purpose of the feature — the traveller gets no guidance.
Include sunshineHours on data items for the best months when the data is available — it appears only when provided.
Sunshine hours add a second dimension of useful data without adding a second chart.
Estimate or guess sunshineHours values — only include them when sourced from meteorological data.
Fabricated sunshine data erodes traveller trust if it contradicts their experience on the ground.
Use maxTemp for the bar height. Use avgTemp only as a secondary data point in the tooltip.
Max temperature is the figure travellers relate to — 'how hot will it feel?'
Use avgTemp as the primary bar height value instead of maxTemp, or mix the two without labelling them.
Average and max temperatures mean different things — mixing them creates a misleading chart.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| destination | string | — | Destination name used in the auto-generated heading 'When to visit [destination]'. e.g. 'Kenya', 'the Maldives', 'Zanzibar'. |
| data* | Array<{ month: string | number; maxTemp: number; avgTemp?: number; sunshineHours?: number }> | — | Array of 12 monthly data items. month can be a string abbreviation (Jan–Dec) or a number (0–11). maxTemp is required per item; avgTemp and sunshineHours are optional. |
| bestMonths | number[] | [] | Zero-based month indices (0 = Jan, 11 = Dec) to highlight in yellow. When empty, all bars render in teal and the legend is hidden. |
| unit | 'C' | 'F' | 'C' | Temperature unit for the bar labels. Does not convert the data values — pass pre-converted values when using F. |
| className | string | — | Additional Tailwind classes on the root element. |
Accessibility
Chart as a table
The bar chart is accompanied by a visually hidden <table> containing the same data in tabular form. Screen readers will read the table rather than the SVG bars. The table structure is:
| Month | Max Temp | Best Month |
|---|---|---|
| January | 27°C | No |
| July | 22°C | Yes |
This ensures the data is fully accessible without requiring SVG accessibility workarounds.
Colour independence
Best months are indicated by yellow bars. A text label "Best" also appears in the visually hidden table, and the legend uses both colour swatches and text labels. Travellers who cannot distinguish teal from yellow can still identify best months via the legend text and the accessible table.
Tooltip
The hover tooltip is triggered on both pointer hover and keyboard focus of each bar. Keyboard users can Tab through each bar and read the tooltip via aria-describedby. The tooltip content format is: "[Month] · [N]°[C/F] max[· N hours sunshine]".
Heading level
The "When to visit [destination]" heading renders as an <h3> by default, appropriate for placement inside a destination page section that has an <h2>. Pass headingLevel to override if the document structure requires a different heading rank.
Animation
The bar entrance animation respects prefers-reduced-motion. When the user has reduced motion enabled, bars render at full height immediately with no transition.
Related components
WeatherWidget is a standalone display component with no closely related pattern in this library — it does not extend or replace another chart or card component.