@synerise/ds-banner 1.3.1 → 1.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/CLAUDE.md +154 -0
  3. package/package.json +10 -9
package/CHANGELOG.md CHANGED
@@ -3,6 +3,14 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [1.3.3](https://github.com/Synerise/synerise-design/compare/@synerise/ds-banner@1.3.2...@synerise/ds-banner@1.3.3) (2026-08-11)
7
+
8
+ **Note:** Version bump only for package @synerise/ds-banner
9
+
10
+ ## [1.3.2](https://github.com/Synerise/synerise-design/compare/@synerise/ds-banner@1.3.1...@synerise/ds-banner@1.3.2) (2026-07-23)
11
+
12
+ **Note:** Version bump only for package @synerise/ds-banner
13
+
6
14
  ## [1.3.1](https://github.com/Synerise/synerise-design/compare/@synerise/ds-banner@1.3.0...@synerise/ds-banner@1.3.1) (2026-07-16)
7
15
 
8
16
  **Note:** Version bump only for package @synerise/ds-banner
package/CLAUDE.md ADDED
@@ -0,0 +1,154 @@
1
+ # Banner (`@synerise/ds-banner`)
2
+
3
+ > A slideshow banner component with optional autoplay, slide navigation, an expandable header bar, and a close button.
4
+
5
+ ## Package structure
6
+
7
+ ```
8
+ src/
9
+ Banner.tsx — main component
10
+ Banner.types.ts — all prop interfaces
11
+ Banner.styles.ts — styled-components (shared across all sub-components)
12
+ Banner.const.ts — DEFAULT_SLIDE_SPEED (5000ms), default status tag colors
13
+ index.ts — public exports (default Banner + BannerProps type)
14
+ components/
15
+ BannerCounter/ — prev/next buttons + dot navigation (shown only when slides > 1)
16
+ BannerHeader/ — collapsible header bar (rendered when expandable prop is set)
17
+ BannerSlide/ — single slide; decides text vs media layout
18
+ BannerSlideMediaContent/ — renders a media (image/video) content area
19
+ BannerSlideTextContent/ — renders title/description/buttons content area
20
+ index.ts — re-exports all sub-components
21
+ hooks/
22
+ useCarousel.ts — holds ref to the ds-carousel and exposes navigation handlers
23
+ useTexts.ts — merges react-intl defaults with caller-supplied texts
24
+ index.ts — re-exports hooks
25
+ utils/
26
+ isMediaContent.ts — type guard: 'media' in props
27
+ ```
28
+
29
+ ## Public exports
30
+
31
+ ### `Banner` (default export)
32
+
33
+ Props (`BannerProps` = `WithHTMLAttributes<HTMLDivElement, …>`):
34
+
35
+ | Prop | Type | Default | Description |
36
+ |------|------|---------|-------------|
37
+ | `slides` | `BannerSlideProps[]` | — | **Required.** Array of slide data objects. |
38
+ | `autoPlay` | `boolean` | `true` | Start the carousel on mount. |
39
+ | `autoPlaySpeed` | `number` | `5000` | Milliseconds per slide. |
40
+ | `transitionEffect` | `'scrollx' \| 'fade'` | `'scrollx'` | Carousel effect (`@synerise/ds-carousel`). |
41
+ | `onAfterChange` | `(index: number) => void` | `undefined` | Called after slide transition completes. |
42
+ | `onBeforeChange` | `(from: number, to: number) => void` | `undefined` | Called before slide transition starts. |
43
+ | `onClose` | `() => void` | `undefined` | Renders a close (✕) button in the top-right corner when provided. |
44
+ | `expandable` | `Omit<BannerHeaderProps, 'closeButton' \| 'onToggle' \| 'texts'>` | `undefined` | When set, renders a collapsible header bar above the slides. |
45
+ | `texts` | `Partial<BannerTexts>` | `undefined` | Override i18n strings (see BannerTexts below). |
46
+
47
+ Also accepts any standard `HTMLDivElement` attribute (spread onto the root `<div>`).
48
+
49
+ ### `BannerProps` (type export)
50
+
51
+ The full props type for the `Banner` component.
52
+
53
+ ## Slide content types
54
+
55
+ Each slide (`BannerSlideProps`) has three layout slots: `mainContent`, `leftSideContent`, `rightSideContent`. Each slot accepts either a **text** or **media** content object — the `isMediaContent` type guard (`'media' in props`) decides which sub-component to render.
56
+
57
+ ### `BannerSlideProps`
58
+
59
+ | Prop | Type | Default | Description |
60
+ |------|------|---------|-------------|
61
+ | `mainContent` | `BannerSlideTextContentProps \| BannerSlideMediaContentProps` | `undefined` | Flexible centre/full-width area. |
62
+ | `leftSideContent` | `BannerSlideTextContentProps \| BannerSlideMediaContentProps` | `undefined` | Fixed 240px left column. |
63
+ | `rightSideContent` | `BannerSlideTextContentProps \| BannerSlideMediaContentProps` | `undefined` | Fixed 240px right column. |
64
+
65
+ ### `BannerSlideTextContentProps`
66
+
67
+ | Prop | Type | Default | Description |
68
+ |------|------|---------|-------------|
69
+ | `title` | `ReactNode` | `undefined` | Slide heading (rendered as `<Title level={1}>`). |
70
+ | `titlePrefix` | `ReactNode` | `undefined` | Icon or avatar shown left of the title text. |
71
+ | `titleStatus` | `Pick<TagProps, 'textColor' \| 'color' \| 'name'>` | `undefined` | Status pill tag above the title. Falls back to `yellow-600` / `white` from `Banner.const.ts`. |
72
+ | `description` | `ReactNode` | `undefined` | Body text below the title. |
73
+ | `buttons` | `ReactNode` | `undefined` | Action buttons rendered below description (wrapped in flex row). |
74
+
75
+ ### `BannerSlideMediaContentProps`
76
+
77
+ | Prop | Type | Default | Description |
78
+ |------|------|---------|-------------|
79
+ | `media` | `ReactNode` | `undefined` | Image, video, or any element; constrained to `max-width/max-height: 100%`. |
80
+
81
+ ### `BannerHeaderProps` (expandable)
82
+
83
+ Pass via the `expandable` prop (omit `closeButton`, `onToggle`, `texts` — managed internally):
84
+
85
+ | Prop | Type | Default | Description |
86
+ |------|------|---------|-------------|
87
+ | `title` | `ReactNode` | — | **Required.** Header bar label. |
88
+ | `icon` | `ReactNode` | `undefined` | Icon shown left of the title. |
89
+ | `isExpanded` | `boolean` | `true` | Initial expanded state. |
90
+
91
+ ### `BannerTexts`
92
+
93
+ | Key | Default (react-intl) | Description |
94
+ |-----|----------------------|-------------|
95
+ | `expand` | `'Expand'` | Toggle button label when collapsed. |
96
+ | `collapse` | `'Collapse'` | Toggle button label when expanded. |
97
+ | `closeTooltip` | `'Close'` | Tooltip on the ✕ button. |
98
+
99
+ ## Usage patterns
100
+
101
+ ```tsx
102
+ import Banner from '@synerise/ds-banner';
103
+
104
+ // Single slide, no controls
105
+ <Banner
106
+ slides={[{
107
+ mainContent: { title: 'Hello', description: 'World' },
108
+ }]}
109
+ />
110
+
111
+ // Multi-slide with autoplay and close
112
+ <Banner
113
+ slides={[
114
+ { mainContent: { title: 'Slide 1', buttons: <Button>Learn more</Button> } },
115
+ { leftSideContent: { media: <img src="..." /> }, mainContent: { title: 'Slide 2' } },
116
+ ]}
117
+ autoPlaySpeed={3000}
118
+ onClose={() => setBannerVisible(false)}
119
+ />
120
+
121
+ // Expandable header
122
+ <Banner
123
+ slides={[{ mainContent: { title: 'News' } }]}
124
+ expandable={{ title: 'Announcements', icon: <Icon component={<InfoM />} />, isExpanded: false }}
125
+ />
126
+ ```
127
+
128
+ ## Key dependencies
129
+
130
+ - `@synerise/ds-carousel` (`Carousel`) — the underlying carousel/slideshow engine; `BannerSlides` is a styled `Carousel`; navigation is driven via `CarouselRef` (`.goTo`, `.next`, `.prev`)
131
+ - `react-intl` — **required peer dependency** used in `useTexts` for default i18n strings; app must be wrapped in `IntlProvider`
132
+ - `uuid` — generates a stable `id` per slide on each `slides` prop change (via `useMemo`) to use as React keys
133
+ - `@synerise/ds-tag` — renders `titleStatus` pill with `asPill` + `TagShape.SMALL_SQUARE`
134
+ - `@synerise/ds-typography` (`Title`, `Text`) — used for slide title and header bar text
135
+
136
+ ## Custom hooks
137
+
138
+ ### `useCarousel`
139
+
140
+ Holds a `useRef<CarouselRef>` (from `@synerise/ds-carousel`) and exposes `handleDotClick(index)`, `handleNextClick()`, `handlePrevClick()`. The `bannerRef` is passed directly to `<S.BannerSlides ref={bannerRef}>`.
141
+
142
+ ### `useTexts`
143
+
144
+ Merges react-intl formatted defaults (`DS.BANNER.EXPAND`, `DS.BANNER.COLLAPSE`, `DS.BANNER.CLOSE-TOOLTIP`) with any `texts` override passed by the caller. Always returns a complete `BannerTexts` object.
145
+
146
+ ## Implementation notes
147
+
148
+ - **Slide counter** only renders when `slides.length > 1`.
149
+ - **Close button vs expandable header**: if `expandable` is set, the close button is rendered *inside* the `BannerHeader`; otherwise it floats absolutely in the top-right corner (`position: absolute; right: 8px; top: 8px; z-index: 10`).
150
+ - **Expand/collapse state** is local — `isExpanded` in `expandable` is only the *initial* value. After mount the state is owned by `Banner`.
151
+ - **`slides` are re-keyed** on every render via `uuid()` inside a `useMemo([slides])`, so mutating slide objects in place (without replacing the array) will not re-key them.
152
+ - **Carousel CSS**: `ds-carousel` ships its own styling; `Banner.styles.ts` adds the layout tweaks via ds-carousel's `.ds-carousel` / `.ds-carousel-track` class hooks (no LESS side-effect import anymore).
153
+ - `BannerSlide` memoizes each content area (`useMemo`) keyed to the content prop; position (`left | right | main`) and `hasMainContent` flag control flex-basis (240px fixed) vs flex-grow (1).
154
+ - `titleStatus` defaults for colour (`yellow-600` / `white`) come from `Banner.const.ts` and are spread before the caller's overrides, so callers can override individual colour props.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synerise/ds-banner",
3
- "version": "1.3.1",
3
+ "version": "1.3.3",
4
4
  "description": "Banner UI Component for the Synerise Design System",
5
5
  "license": "ISC",
6
6
  "repository": "Synerise/synerise-design",
@@ -17,6 +17,7 @@
17
17
  "files": [
18
18
  "/dist",
19
19
  "CHANGELOG.md",
20
+ "CLAUDE.md",
20
21
  "README.md",
21
22
  "package.json",
22
23
  "LICENSE.md"
@@ -41,13 +42,13 @@
41
42
  ],
42
43
  "types": "dist/index.d.ts",
43
44
  "dependencies": {
44
- "@synerise/ds-button": "^1.5.34",
45
- "@synerise/ds-carousel": "^1.1.0",
46
- "@synerise/ds-icon": "^1.18.4",
47
- "@synerise/ds-tag": "^1.4.31",
48
- "@synerise/ds-tooltip": "^1.5.3",
49
- "@synerise/ds-typography": "^1.1.26",
50
- "@synerise/ds-utils": "^1.10.1",
45
+ "@synerise/ds-button": "^1.5.36",
46
+ "@synerise/ds-carousel": "^1.1.1",
47
+ "@synerise/ds-icon": "^1.18.5",
48
+ "@synerise/ds-tag": "^1.4.33",
49
+ "@synerise/ds-tooltip": "^1.5.5",
50
+ "@synerise/ds-typography": "^1.1.28",
51
+ "@synerise/ds-utils": "^1.10.2",
51
52
  "uuid": "^8.3.2"
52
53
  },
53
54
  "peerDependencies": {
@@ -57,5 +58,5 @@
57
58
  "styled-components": "^5.3.3",
58
59
  "vitest": "4"
59
60
  },
60
- "gitHead": "a81ab6519d49a3dea9c0cfebcdc9104cbb4f4226"
61
+ "gitHead": "6df24ed12cd5f276d8eccde730591807982e3385"
61
62
  }