@reuters-graphics/graphics-components 0.0.25 → 0.0.26

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.
@@ -0,0 +1,70 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ import '@splidejs/svelte-splide/css/core';
3
+ declare const __propDef: {
4
+ props: {
5
+ /** Width of the component within the text well. */ width?: "normal" | "wide" | "wider" | "widest" | "fluid";
6
+ /** Add an ID to target with SCSS. */ id?: string;
7
+ /** Add a class to target with SCSS. */ cls?: string;
8
+ /**
9
+ * Array of photos.
10
+ * @required
11
+ */ photos?: {
12
+ /**
13
+ * Image src
14
+ * @required
15
+ */
16
+ src: string;
17
+ /**
18
+ * Image alt-text
19
+ * @required
20
+ */
21
+ altText: string;
22
+ /** Optional caption */
23
+ caption?: string;
24
+ /** Optional credit */
25
+ credit?: string;
26
+ /** Optional object-fit rule */
27
+ objectFit?: string;
28
+ /** Optional object-position rule */
29
+ objectPosition?: string;
30
+ }[];
31
+ /**
32
+ * Max height of the carousel
33
+ */ maxHeight?: number;
34
+ /**
35
+ * Default Image object-fit style, either `cover` or `contain`.
36
+ */ defaultImageObjectFit?: "cover" | "contain";
37
+ /**
38
+ * Default image object-position style, e.g., `center center` or `50% 50%`.
39
+ */ defaultImageObjectPosition?: string;
40
+ /**
41
+ * ARIA label for the carousel.
42
+ * @required
43
+ */ carouselAriaLabel?: string;
44
+ /**
45
+ * Set height of the carousel as a ratio of its width
46
+ * as long as its below whatever you set in `maxHeight`.
47
+ */ heightRatio?: number;
48
+ /**
49
+ * Number of images to preload ahead of the active image.
50
+ */ preloadImages?: number;
51
+ };
52
+ events: {
53
+ [evt: string]: CustomEvent<any>;
54
+ };
55
+ slots: {
56
+ credit: {
57
+ credit: string;
58
+ };
59
+ caption: {
60
+ caption: string;
61
+ };
62
+ };
63
+ };
64
+ export declare type PhotoCarouselProps = typeof __propDef.props;
65
+ export declare type PhotoCarouselEvents = typeof __propDef.events;
66
+ export declare type PhotoCarouselSlots = typeof __propDef.slots;
67
+ /** `PhotoCarousel` [Read the docs.](https://reuters-graphics.github.io/graphics-components/?path=/docs/components-PhotoCarousel--default) */
68
+ export default class PhotoCarousel extends SvelteComponentTyped<PhotoCarouselProps, PhotoCarouselEvents, PhotoCarouselSlots> {
69
+ }
70
+ export {};
@@ -11,6 +11,7 @@ export { default as Headline } from "./components/Headline/Headline.svelte";
11
11
  export { default as Hero } from "./components/Hero/Hero.svelte";
12
12
  export { default as NoteText } from "./components/NoteText/NoteText.svelte";
13
13
  export { default as PaddingReset } from "./components/PaddingReset/PaddingReset.svelte";
14
+ export { default as PhotoCarousel } from "./components/PhotoCarousel/PhotoCarousel.svelte";
14
15
  export { default as PhotoPack } from "./components/PhotoPack/PhotoPack.svelte";
15
16
  export { default as PymChild } from "./components/PymChild/PymChild.svelte";
16
17
  export { pymChildStore } from "./components/PymChild/stores.js";
@@ -0,0 +1,232 @@
1
+ <!-- @component `PhotoCarousel` [Read the docs.](https://reuters-graphics.github.io/graphics-components/?path=/docs/components-PhotoCarousel--default) -->
2
+ <script>/** Width of the component within the text well. */
3
+ export let width = 'wider';
4
+ /** Add an ID to target with SCSS. */
5
+ export let id = '';
6
+ /** Add a class to target with SCSS. */
7
+ export let cls = '';
8
+ /**
9
+ * Array of photos.
10
+ * @required
11
+ */
12
+ export let photos = [];
13
+ /**
14
+ * Max height of the carousel
15
+ */
16
+ export let maxHeight = 660;
17
+ /**
18
+ * Default Image object-fit style, either `cover` or `contain`.
19
+ */
20
+ export let defaultImageObjectFit = 'cover';
21
+ /**
22
+ * Default image object-position style, e.g., `center center` or `50% 50%`.
23
+ */
24
+ export let defaultImageObjectPosition = 'center center';
25
+ /**
26
+ * ARIA label for the carousel.
27
+ * @required
28
+ */
29
+ export let carouselAriaLabel = 'Photo gallery';
30
+ /**
31
+ * Set height of the carousel as a ratio of its width
32
+ * as long as its below whatever you set in `maxHeight`.
33
+ */
34
+ export let heightRatio = 0.68;
35
+ /**
36
+ * Number of images to preload ahead of the active image.
37
+ */
38
+ export let preloadImages = 1;
39
+ import Block from '../Block/Block.svelte';
40
+ import { Splide, SplideSlide, SplideTrack } from '@splidejs/svelte-splide';
41
+ import '@splidejs/svelte-splide/css/core';
42
+ import Fa from 'svelte-fa/src/fa.svelte';
43
+ import { faChevronLeft, faChevronRight, } from '@fortawesome/free-solid-svg-icons';
44
+ import { fly } from 'svelte/transition';
45
+ import PaddingReset from '../PaddingReset/PaddingReset.svelte';
46
+ let containerWidth;
47
+ let activeImageIndex = 0;
48
+ $: carouselHeight = containerWidth
49
+ ? Math.min(containerWidth * heightRatio, maxHeight)
50
+ : maxHeight;
51
+ const handleActiveChange = (e) => {
52
+ activeImageIndex = e.detail.dest;
53
+ };
54
+ </script>
55
+
56
+ <Block width="{width}" id="{id}" cls="photo-carousel {cls}">
57
+ <div class="carousel-container" bind:clientWidth="{containerWidth}">
58
+ <Splide
59
+ hasTrack="{false}"
60
+ options="{{
61
+ height: carouselHeight,
62
+ fixedHeight: carouselHeight,
63
+ lazyLoad: 'nearby',
64
+ preloadPages: preloadImages,
65
+ }}"
66
+ aria-label="{carouselAriaLabel}"
67
+ on:move="{handleActiveChange}"
68
+ >
69
+ <div class="image-container">
70
+ <SplideTrack>
71
+ {#each photos as photo, i}
72
+ <SplideSlide>
73
+ <div class="photo-slide">
74
+ <figure style="height: {carouselHeight}px;">
75
+ <img
76
+ data-splide-lazy="{photo.src}"
77
+ alt="{photo.altText}"
78
+ style:object-fit="{photo.objectFit ||
79
+ defaultImageObjectFit}"
80
+ style:object-position="{photo.objectPosition ||
81
+ defaultImageObjectPosition}"
82
+ />
83
+ {#if $$slots.credit}
84
+ <slot name="credit" credit="{photo.credit}" />
85
+ {:else}
86
+ <span
87
+ class="credit"
88
+ class:contain-fit="{photo.objectFit === 'contain' ||
89
+ defaultImageObjectFit === 'contain'}"
90
+ >{photo.credit}</span
91
+ >
92
+ {/if}
93
+ </figure>
94
+ </div>
95
+ </SplideSlide>
96
+ {/each}
97
+ </SplideTrack>
98
+
99
+ {#if photos[activeImageIndex].caption}
100
+ <PaddingReset containerIsFluid="{width === 'fluid'}">
101
+ {#if $$slots.caption}
102
+ <slot
103
+ name="caption"
104
+ caption="{photos[activeImageIndex].caption}"
105
+ />
106
+ {:else}
107
+ {#key activeImageIndex}
108
+ <p class="caption" in:fly|local="{{ x: 20, duration: 175 }}">
109
+ {photos[activeImageIndex].caption}
110
+ </p>
111
+ {/key}
112
+ {/if}
113
+ </PaddingReset>
114
+ {/if}
115
+
116
+ <div class="splide__progress">
117
+ <div class="splide__progress__bar"></div>
118
+ </div>
119
+
120
+ <div class="splide__arrows">
121
+ <button class="splide__arrow splide__arrow--prev">
122
+ <Fa icon="{faChevronLeft}" fw />
123
+ </button>
124
+ <button class="splide__arrow splide__arrow--next">
125
+ <Fa icon="{faChevronRight}" fw />
126
+ </button>
127
+ </div>
128
+ </div>
129
+ </Splide>
130
+ </div>
131
+ </Block>
132
+
133
+ <style>.carousel-container {
134
+ margin-bottom: 10px;
135
+ }
136
+ .carousel-container .photo-slide {
137
+ height: 100%;
138
+ width: 100%;
139
+ position: relative;
140
+ }
141
+ .carousel-container .photo-slide figure {
142
+ margin: 0;
143
+ width: 100%;
144
+ position: relative;
145
+ }
146
+ .carousel-container .photo-slide figure img {
147
+ height: 100%;
148
+ width: 100%;
149
+ }
150
+ .carousel-container .photo-slide figure span.credit {
151
+ position: absolute;
152
+ bottom: 4px;
153
+ left: 10px;
154
+ margin: 0;
155
+ font-size: 0.7rem;
156
+ color: white;
157
+ letter-spacing: 0.75px;
158
+ text-shadow: -1px -1px 0 #333, 1px -1px 0 #333, -1px 1px 0 #333, 1px 1px 0 #333;
159
+ font-family: var(--theme-font-family-note);
160
+ }
161
+ .carousel-container .photo-slide figure span.credit.contain-fit {
162
+ left: 50%;
163
+ transform: translate(-50%, 0%);
164
+ }
165
+ .carousel-container :global(.splide) {
166
+ max-height: 100%;
167
+ }
168
+ .carousel-container :global(.splide__arrows) {
169
+ width: 275px;
170
+ margin: 0 auto;
171
+ display: flex;
172
+ justify-content: space-between;
173
+ padding: 0px;
174
+ padding-top: 4px;
175
+ }
176
+ .carousel-container :global(.splide__arrows) :global(button) {
177
+ display: flex;
178
+ font-size: 12px;
179
+ height: 30px;
180
+ width: 30px;
181
+ padding: 0;
182
+ justify-content: center;
183
+ align-items: center;
184
+ border: 1px solid transparent;
185
+ border-radius: 50%;
186
+ background-color: transparent;
187
+ color: var(--theme-colour-text-secondary);
188
+ opacity: 0.4;
189
+ }
190
+ .carousel-container :global(.splide__arrows) :global(button:hover) {
191
+ opacity: 1;
192
+ border-color: var(--theme-colour-text-secondary);
193
+ color: var(--theme-colour-text-secondary);
194
+ }
195
+ .carousel-container :global(.splide__arrows) :global(button:disabled) {
196
+ opacity: 0.4;
197
+ }
198
+ .carousel-container :global(.splide__arrows) :global(button:disabled:hover) {
199
+ border-color: transparent;
200
+ }
201
+ .carousel-container :global(ul.splide__pagination) {
202
+ width: 200px;
203
+ padding: 0;
204
+ text-align: center;
205
+ margin: -26px auto 0;
206
+ display: flex;
207
+ flex-wrap: nowrap;
208
+ }
209
+ .carousel-container :global(ul.splide__pagination) :global(li) {
210
+ flex-grow: 1;
211
+ }
212
+ .carousel-container :global(ul.splide__pagination) :global(li) :global(button) {
213
+ width: 100%;
214
+ height: 7px;
215
+ border-radius: 0;
216
+ margin: 0 0px;
217
+ padding: 0;
218
+ border: 1px solid var(--theme-colour-background);
219
+ background: var(--theme-colour-text-secondary);
220
+ opacity: 0.4;
221
+ }
222
+ .carousel-container :global(ul.splide__pagination) :global(li) :global(button.is-active) {
223
+ opacity: 1;
224
+ }
225
+ .carousel-container p.caption {
226
+ margin: 5px 0 0;
227
+ font-family: var(--theme-font-family-note, "Knowledge", "Source Sans Pro", Arial, sans-serif);
228
+ color: var(--theme-colour-text-secondary, #666666);
229
+ font-size: 0.85rem;
230
+ line-height: 1.1rem;
231
+ font-weight: 300;
232
+ }</style>
package/dist/index.js CHANGED
@@ -12,6 +12,7 @@ export { default as Headline } from './components/Headline/Headline.svelte';
12
12
  export { default as Hero } from './components/Hero/Hero.svelte';
13
13
  export { default as NoteText } from './components/NoteText/NoteText.svelte';
14
14
  export { default as PaddingReset } from './components/PaddingReset/PaddingReset.svelte';
15
+ export { default as PhotoCarousel } from './components/PhotoCarousel/PhotoCarousel.svelte';
15
16
  export { default as PhotoPack } from './components/PhotoPack/PhotoPack.svelte';
16
17
  export { default as PymChild } from './components/PymChild/PymChild.svelte';
17
18
  export { pymChildStore } from './components/PymChild/stores.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reuters-graphics/graphics-components",
3
- "version": "0.0.25",
3
+ "version": "0.0.26",
4
4
  "type": "module",
5
5
  "private": false,
6
6
  "homepage": "https://reuters-graphics.github.io/graphics-components",
@@ -78,6 +78,7 @@
78
78
  "@fortawesome/free-brands-svg-icons": "^5.15.4",
79
79
  "@fortawesome/free-regular-svg-icons": "^5.15.3",
80
80
  "@fortawesome/free-solid-svg-icons": "^5.15.3",
81
+ "@splidejs/svelte-splide": "^0.2.9",
81
82
  "@sveltejs/svelte-scroller": "^2.0.7",
82
83
  "bootstrap": "^5.2.0",
83
84
  "classnames": "^2.3.1",
@@ -119,6 +120,7 @@
119
120
  "./components/Hero/Hero.svelte": "./dist/components/Hero/Hero.svelte",
120
121
  "./components/NoteText/NoteText.svelte": "./dist/components/NoteText/NoteText.svelte",
121
122
  "./components/PaddingReset/PaddingReset.svelte": "./dist/components/PaddingReset/PaddingReset.svelte",
123
+ "./components/PhotoCarousel/PhotoCarousel.svelte": "./dist/components/PhotoCarousel/PhotoCarousel.svelte",
122
124
  "./components/PhotoPack/PhotoPack.svelte": "./dist/components/PhotoPack/PhotoPack.svelte",
123
125
  "./components/PhotoPack/docProps.ts": "./dist/components/PhotoPack/docProps.ts",
124
126
  "./components/PymChild/PymChild.svelte": "./dist/components/PymChild/PymChild.svelte",