This commit is contained in:
Jon McClure 2022-08-14 22:44:59 +01:00
parent 6db53c3944
commit d9def09527
25 changed files with 455 additions and 457910 deletions

View file

@ -40,6 +40,10 @@ p.sbdocs-p, ul.sbdocs-ul, li.sbdocs-li {
@include font-display;
}
.sbdocs {
@include font-display;
}
// .sbdocs {
// max-width: 800px;
// margin: 0 auto !important;

View file

@ -26,7 +26,7 @@
</Template>
<Story
name="Basic"
name="Default"
args="{{
embedded: false,
id: '',
@ -113,7 +113,7 @@
position: absolute;
bottom: 0;
left: 5px;
color: white;
color: #666;
}
.padding-label {
position: absolute;

View file

@ -4,7 +4,7 @@ The `Article` component contains all the content of our story and also establish
```svelte
<script>
import { Article } from '@reuters-graphics/graphics-svelte-components';
import { Article } from '@reuters-graphics/graphics-components';
</script>
<Article>

View file

@ -2,7 +2,7 @@ A before and after image comparison component.
```svelte
<script>
import { BeforeAfter } from '@reuters-graphics/graphics-svelte-components';
import { BeforeAfter } from '@reuters-graphics/graphics-components';
import { assets } from '$app/paths'; // If using in the Graphics Kit
</script>

View file

@ -41,7 +41,7 @@
</Template>
<Story
name="Basic"
name="Default"
args="{{
width: 'normal',
}}"

View file

@ -1,6 +1,6 @@
The `Block` component is the basic building block of stories, a responsive container that wraps each section of your piece.
Blocks are stacked vertically within the well created by the `Article` component. They can have different widths on larger screens depending on the `width` prop.
Blocks are stacked vertically within the well created by the [`Article`](./?path=/docs/layout-article) component. They can have different widths on larger screens depending on the `width` prop.
> 📌 Many of our other components already use the `Block` component, internally. You'll usually only need to use it yourself if you're making something custom.

View file

@ -1,4 +1,4 @@
Our article well is designed to provide a basic responsive layout issues for you, but it's also made to get out of the way quickly when you need to do something custom.
Our article well is designed to provide a basic responsive layout for you, but it's also made to get out of the way quickly when you need to do something custom.
If you need to get really radical, the easiest way is to create a `Block` with a `fluid` width -- which basically cancels out the article well dimensions -- and then code whatever you need from scratch or with another framework.

View file

@ -1,4 +1,6 @@
Body text includes the main text of your page.
The `BodyText` creates the main text of your page. You can pass the `text` prop a [markdown-formatted](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) string, which will be parsed into paragraphs, headers, lists, blockquotes or whatever else you need.
Use it like this:
```svelte
<script>
@ -14,6 +16,8 @@ Body text includes the main text of your page.
<BodyText text="{markdownText}" />
```
... or more commonly, you'll use it with a Google doc in the Graphics Kit like this:
```svelte
<script>
import { BodyText } from '@reuters-graphics/graphics-components';

View file

@ -14,7 +14,7 @@
import PlaceholderImg from './stories/placeholder.png';
const meta = {
title: 'Components/GraphicBlock',
title: 'Layout/GraphicBlock',
component: GraphicBlock,
...withComponentDocs(componentDocs),
// https://storybook.js.org/docs/svelte/essentials/controls
@ -42,7 +42,7 @@
</Template>
<Story
name="Basic"
name="Default"
args="{{
width: 'normal',
title: 'Bacon ipsum dolor amet t-bone',

View file

@ -1,4 +1,4 @@
The `GraphicBlock` component is a more specific type of `Block` that handles text elements around your chart.
The `GraphicBlock` component is a subset of the [`Block`](./?path=/docs/layout-block) component that also handles text elements around a graphic.
Many other components use this one to wrap graphics with styled text. When you use it, you'll also wrap your chart elements or component with it like this:

View file

@ -0,0 +1,97 @@
<script>
import { Meta, Template, Story } from '@storybook/addon-svelte-csf';
// @ts-ignore
import componentDocs from './stories/docs/component.md?raw';
// @ts-ignore
import playAndLoopDocs from './stories/docs/playAndLoop.md?raw';
// @ts-ignore
import controlsDocs from './stories/docs/controls.md?raw';
// @ts-ignore
import withSoundDocs from './stories/docs/withSound.md?raw';
// @ts-ignore
import SilentVideo from './stories/videos/silent-video.mp4';
// @ts-ignore
import SoundVideo from './stories/videos/sound-video.mp4';
import Video from './Video.svelte';
import {
withComponentDocs,
withStoryDocs
} from '$lib/docs/utils/withParams.js';
const meta = {
title: 'Components/Video',
component: Video,
...withComponentDocs(componentDocs),
};
</script>
<Meta {...meta} />
<Template let:args>
<Video {...args} />
</Template>
<Story
name="Default"
args={{
ariaDescription: "Compulsory description of your video for screen readers.",
src: SilentVideo,
width: 'wide',
caption: 'Optional caption for your video.',
}}
/>
<Story
name="Playing and looping"
args={{
ariaDescription: "Compulsory description of your video for screen readers.",
src: SilentVideo,
width: 'normal',
loopVideo: true,
caption: 'World\'s longest glass bridge opens to public in Vietnam. (c) 2022 Thomson Reuters',
playVideoThreshold: 0.9,
}}
{...withStoryDocs(playAndLoopDocs)}
/>
<Story
name="Controls"
args={{
ariaDescription: "Compulsory description of your video for screen readers.",
src: SilentVideo,
width: 'normal',
caption: 'World\'s longest glass bridge opens to public in Vietnam. (c) 2022 Thomson Reuters',
playVideoThreshold: 0.9,
controlsColour: 'white',
controlsOpacity: 1,
controlsPosition: 'bottom right',
separateReplayIcon: true,
loopVideo: false,
hoverToSeeControls: true,
}}
{...withStoryDocs(controlsDocs)}
/>
<Story
name="Videos with sound"
args={{
ariaDescription: "Compulsory description of your video for screen readers.",
src: SoundVideo,
width: 'normal',
caption: 'World\'s longest glass bridge opens to public in Vietnam. (c) 2022 Thomson Reuters',
playVideoThreshold: 0.9,
showControls: true,
loopVideo: false,
muteVideo: false,
playVideoWhenInView: true,
allowSoundToAutoplay: true,
}}
{...withStoryDocs(controlsDocs)}
/>

View file

@ -1,20 +1,43 @@
<script>
<script lang="ts">
import IntersectionObserver from 'svelte-intersection-observer';
import Controls from './Controls.svelte';
import Block from '../Block/Block.svelte';
/// //////////////////////////////////
/// /////////// Props ////////////////
/// //////////////////////////////////
/**
* Video src.
*/
export let src = '';
export let ariaHidden = true;
export let ariaDescription = null;
export let caption = '';
export let size = 'normal'; // normal, wide, wider, widest or fluid
export let preloadVideo = 'auto'; // preload the video by default; this is ignored if autoplay is true; can also be none or metadata
export let loopVideo = true; // whether the video should loop
type ColumnWidth = 'narrower' | 'narrow' | 'normal' | 'wide' | 'wider' | 'widest' | 'fluid';
/**
* Width of the block within the article well.
* @type {string}
*/
export let width: ColumnWidth = 'normal';
export let muteVideo = true; // whther video should have sound or not
type PreloadOptions = 'auto' | 'none' | 'metadata';
/**
* Preload options. `auto` is ignored if `autoplay` is true. Can also be `none` or `metadata`.
* @type {string}
*/
export let preloadVideo: PreloadOptions = 'auto';
/**
* Whether the video should loop.
*/
export let loopVideo: boolean = true;
/**
* Whether video should have sound or not.
*/
export let muteVideo: boolean = true;
export let allowSoundToAutoplay = false; // for video with sound, whether video should be allowed to autoplay if the user has previously interacted with DOM
export let playVideoWhenInView = true; // whether the video should play when it comes into view or just on page load
@ -100,36 +123,89 @@
on:touchstart="{setInteractedWithDom}"
/>
<section
class="video-container graphic {size}"
on:mouseover="{() => {
interactiveControlsOpacity = controlsOpacity;
}}"
on:focus="{() => {
interactiveControlsOpacity = controlsOpacity;
}}"
on:mouseout="{() => {
interactiveControlsOpacity = 0;
}}"
on:blur="{() => {
interactiveControlsOpacity = 0;
}}"
>
{#if (ariaHidden && ariaDescription) || !ariaHidden}
{#if ariaDescription}
<p class="visually-hidden">{ariaDescription}</p>
{/if}
<Block {width} cls="video-container">
<div
on:mouseover="{() => {
interactiveControlsOpacity = controlsOpacity;
}}"
on:focus="{() => {
interactiveControlsOpacity = controlsOpacity;
}}"
on:mouseout="{() => {
interactiveControlsOpacity = 0;
}}"
on:blur="{() => {
interactiveControlsOpacity = 0;
}}"
>
{#if (ariaHidden && ariaDescription) || !ariaHidden}
{#if ariaDescription}
<p class="visually-hidden">{ariaDescription}</p>
{/if}
{#if playVideoWhenInView}
<!-- Video element with Intersection Observer -->
<IntersectionObserver
element="{element}"
bind:intersecting
threshold="{playVideoThreshold}"
once="{false}"
>
{#if playVideoWhenInView}
<!-- Video element with Intersection Observer -->
<IntersectionObserver
element="{element}"
bind:intersecting
threshold="{playVideoThreshold}"
once="{false}"
>
<div
bind:this="{element}"
class="video-wrapper"
aria-hidden="{ariaHidden}"
bind:clientWidth="{widthVideoContainer}"
bind:clientHeight="{heightVideoContainer}"
>
{#if possibleToPlayPause}
{#if showControls}
<Controls
on:pausePlayEvent="{pausePlayEvent}"
paused="{paused}"
clickedOnPauseBtn="{clickedOnPauseBtn}"
controlsOpacity="{hoverToSeeControls
? interactiveControlsOpacity
: controlsOpacity}"
controlsPosition="{controlsPosition}"
widthVideoContainer="{widthVideoContainer}"
heightVideoContainer="{heightVideoContainer}"
controlsBorderOffset="{controlsBorderOffset}"
resetCondition="{resetCondition}"
separateReplayIcon="{separateReplayIcon}"
controlsColour="{controlsColour}"
/>
{:else}
<button
on:click="{() => {
paused === true ? (paused = false) : (paused = true);
}}"
style="position: absolute; top: 0; left: 0; width: {widthVideoContainer}px; height: {heightVideoContainer}px;"
></button>
{/if}
{/if}
<video
bind:this="{videoElement}"
src="{src}"
width="100%"
muted="{muteVideo}"
playsinline
preload="{preloadVideo}"
loop="{loopVideo}"
bind:currentTime="{time}"
bind:duration
bind:paused
bind:clientWidth="{widthVideo}"
bind:clientHeight="{heightVideo}"
style="{showControls ? 'position: relative' : 'position: relative'}"
>
<track kind="captions" />
</video>
</div>
</IntersectionObserver>
{:else}
<!-- Video element without Intersection observer -->
<div
bind:this="{element}"
class="video-wrapper"
aria-hidden="{ariaHidden}"
bind:clientWidth="{widthVideoContainer}"
@ -141,9 +217,7 @@
on:pausePlayEvent="{pausePlayEvent}"
paused="{paused}"
clickedOnPauseBtn="{clickedOnPauseBtn}"
controlsOpacity="{hoverToSeeControls
? interactiveControlsOpacity
: controlsOpacity}"
controlsOpacity="{controlsOpacity}"
controlsPosition="{controlsPosition}"
widthVideoContainer="{widthVideoContainer}"
heightVideoContainer="{heightVideoContainer}"
@ -172,6 +246,7 @@
bind:currentTime="{time}"
bind:duration
bind:paused
autoplay
bind:clientWidth="{widthVideo}"
bind:clientHeight="{heightVideo}"
style="{showControls ? 'position: relative' : 'position: relative'}"
@ -179,64 +254,13 @@
<track kind="captions" />
</video>
</div>
</IntersectionObserver>
{:else}
<!-- Video element without Intersection observer -->
<div
class="video-wrapper"
aria-hidden="{ariaHidden}"
bind:clientWidth="{widthVideoContainer}"
bind:clientHeight="{heightVideoContainer}"
>
{#if possibleToPlayPause}
{#if showControls}
<Controls
on:pausePlayEvent="{pausePlayEvent}"
paused="{paused}"
clickedOnPauseBtn="{clickedOnPauseBtn}"
controlsOpacity="{controlsOpacity}"
controlsPosition="{controlsPosition}"
widthVideoContainer="{widthVideoContainer}"
heightVideoContainer="{heightVideoContainer}"
controlsBorderOffset="{controlsBorderOffset}"
resetCondition="{resetCondition}"
separateReplayIcon="{separateReplayIcon}"
controlsColour="{controlsColour}"
/>
{:else}
<button
on:click="{() => {
paused === true ? (paused = false) : (paused = true);
}}"
style="position: absolute; top: 0; left: 0; width: {widthVideoContainer}px; height: {heightVideoContainer}px;"
></button>
{/if}
{/if}
<video
bind:this="{videoElement}"
src="{src}"
width="100%"
muted="{muteVideo}"
playsinline
preload="{preloadVideo}"
loop="{loopVideo}"
bind:currentTime="{time}"
bind:duration
bind:paused
autoplay
bind:clientWidth="{widthVideo}"
bind:clientHeight="{heightVideo}"
style="{showControls ? 'position: relative' : 'position: relative'}"
>
<track kind="captions" />
</video>
</div>
{/if}
{#if caption}
<figcaption>{caption}</figcaption>
{/if}
{/if}
{#if caption}
<figcaption>{caption}</figcaption>
{/if}
{/if}
</section>
</div>
</Block>
<style lang="scss">
.video-wrapper {

View file

@ -5,9 +5,8 @@ slug: video
---
<script>
import { assets } from '$app/paths';
import Video from './index.svelte';
import DemoContainer from '../_docs/DemoContainer/index.svelte';
import {assets} from '$app/paths'; import Video from './index.svelte'; import
DemoContainer from '../_docs/DemoContainer/index.svelte';
</script>
<section>
@ -18,14 +17,13 @@ slug: video
</section>
```svelte
<script>
import { assets } from '$app/paths'; // helper if importing video from 'statics'
import { Video } from '@reuters-graphics/graphics-svelte-components';
</script>
<Video
<Video
ariaDescription={"Compulsory description of your video for screen readers."}
src={`${assets}/videos/myVideo.mp4`} // or a URL to an external video
size={'wide'} // normal, wide, wider, widest or fluid
@ -33,94 +31,94 @@ slug: video
/>
```
<DemoContainer>
<Video
<Video
ariaDescription="Description of your video for screen readers."
src={`${assets}/videos/Sequence silent video_4.mp4`}
size='wide'
size="wide"
caption="World's longest glass bridge opens to public in Vietnam. (c) 2022 Thomson Reuters"
/>
</DemoContainer>
<section>
#### When to play and whether to loop
`playVideoWhenInView`, `playVideoThreshold`
- By default, the video will **start playing when 50% of the video element's height is visible on the page**.
To control the threshold of visibility at which the video starts playing, add the prop `playVideoThreshold` and set it to a value between 0 and 1,
where 0 means that the video will start playing as soon as its top enters the viewport, while 1 means it will start when the whole video is in the viewport.
- By default, the video will **start playing when 50% of the video element's height is visible on the page**.
To control the threshold of visibility at which the video starts playing, add the prop `playVideoThreshold` and set it to a value between 0 and 1,
where 0 means that the video will start playing as soon as its top enters the viewport, while 1 means it will start when the whole video is in the viewport.
- If you don't want the video to play when you scroll to it, but **on page load**, add the prop `playVideoWhenInView={false}`. The default of the prop is `true`,
which corresponds to the behaviour described above.
which corresponds to the behaviour described above.
`loopVideo`
- By default, the video will **loop**. If you don't want that, add the prop `loopVideo={false}`.
Here is an example of what the same video would look like with a visibility threshold of 0.9 and not looping. Scroll down slowly to observe the behaviour.
- By default, the video will **loop**. If you don't want that, add the prop `loopVideo={false}`.
Here is an example of what the same video would look like with a visibility threshold of 0.9 and not looping. Scroll down slowly to observe the behaviour.
</section>
```svelte
<script>
import { Video } from '@reuters-graphics/graphics-svelte-components';
</script>
<Video
ariaDescription={"Compulsory description of your video for screen readers."}
src={'path-to-video-or-external-url'}
size={'normal'}
loopVideo={false}
playVideoThreshold={0.9}
<Video
ariaDescription="{'Compulsory description of your video for screen readers.'}"
src="{'path-to-video-or-external-url'}"
size="{'normal'}"
loopVideo="{false}"
playVideoThreshold="{0.9}"
/>
```
<DemoContainer>
<Video
<Video
ariaDescription="Description of your video for screen readers."
src={`${assets}/videos/Sequence silent video_4.mp4`}
size='normal'
src={`${assets}/videos/Sequence silent video_4.mp4`}
size="normal"
caption="World's longest glass bridge opens to public in Vietnam. (c) 2022 Thomson Reuters"
loopVideo={false}
playVideoThreshold={0.9}
/>
</DemoContainer>
<section>
#### Controls (play / pause)
`showControls`
- By default, the video has a play/pause button, which corresponds to
`showControls={true}`. If you don't want these, just set `showControls={false}`.
When you do that, the icons themselves will disappear but the functionality of playing and pausing remains and can be done by clicking on the video itself.
If you don't want to enable any play/pause functionality, add `possibleToPlayPause={false}`.
- If you want to show the controls only when the video is hovered, set `hoverToSeeControls={true}`.
`controlsColour`, `controlsOpacity`, `controlsPosition`, `separateReplayIcon`
- By default, the video has a play/pause button, which corresponds to
`showControls={true}`. If you don't want these, just set `showControls={false}`.
When you do that, the icons themselves will disappear but the functionality of playing and pausing remains and can be done by clicking on the video itself.
If you don't want to enable any play/pause functionality, add `possibleToPlayPause={false}`.
- If you want to show the controls only when the video is hovered, set `hoverToSeeControls={true}`.
`controlsColour`, `controlsOpacity`, `controlsPosition`, `separateReplayIcon`
If you do want to leave the controls, you have a couple of options to style them:
- Set `controlsColour` to a colour of your choosing.
- Set `controlsOpacity` to a value between `0` and `1` to control the opacity. The default is `0.5`.
- Change the placement of the controls to one of: `top right`, `top left`, `bottom right`, `bottom left` by setting `controlsPosition`.
- Set `controlsColour` to a colour of your choosing.
- Set `controlsOpacity` to a value between `0` and `1` to control the opacity. The default is `0.5`.
- Change the placement of the controls to one of: `top right`, `top left`, `bottom right`, `bottom left` by setting `controlsPosition`.
- Change the play button to a replay button at the end of the video with the option `separateReplayIcon={true}`.
Here is an example with bottom right corner white opaque controls, with a replay button, where you have to hover on the video to see the controls.
Here is an example with bottom right corner white opaque controls, with a replay button, where you have to hover on the video to see the controls.
</section>
```svelte
<script>
import { Video } from '@reuters-graphics/graphics-svelte-components';
</script>
<Video
<Video
ariaDescription={"Compulsory description of your video for screen readers."}
src={'path-to-video-or-external-url'}
src={'path-to-video-or-external-url'}
size={'normal'}
caption={'Optional caption for your video.'}
playVideoThreshold={0.1}
@ -134,70 +132,69 @@ Here is an example with bottom right corner white opaque controls, with a replay
```
<DemoContainer>
<Video
<Video
ariaDescription="Description of your video for screen readers."
src={`${assets}/videos/Sequence silent video_4.mp4`}
size='normal'
src={`${assets}/videos/Sequence silent video_4.mp4`}
size="normal"
caption="World's longest glass bridge opens to public in Vietnam. (c) 2022 Thomson Reuters"
playVideoThreshold={0.1}
controlsColour={'white'}
controlsOpacity={1}
controlsPosition={'bottom right'}
separateReplayIcon={true}
loopVideo={false}
loopVideo={false}
hoverToSeeControls={true}
/>
</DemoContainer>
<section>
#### Videos with sound
If you've ever had to put sound on a page in recent years,
you'll know that auto-playing sound is not allowed by browsers. The user will need to interact with the page first, and it will depend on your
particular use case how and when you'd like this to happen. This component provides two options to deal with this.
If you've ever had to put sound on a page in recent years,
you'll know that auto-playing sound is not allowed by browsers. The user will need to interact with the page first, and it will depend on your
particular use case how and when you'd like this to happen. This component provides two options to deal with this.
If you have a video with sound, make sure to add the prop `muteVideo={false}`.
Then you can either:
- `allowSoundToAutoplay={false}` (default) : Don't allow the video to autoplay under any circumstances other than when the user clicks the 'play' on the video. Note that this
works whether or not you have the controls visible, i.e. with `showControls` being `true` or `false`, as long as you allow
play/pause behaviour with `possibleToPlayPause={true}` (default).
- `allowSoundToAutoplay={true}` : Allow the video to autoplay when it comes into view as long as the user has interacted with the page preivously, i.e. they have clicked/tapped
anywhere on the page.
- `allowSoundToAutoplay={false}` (default) : Don't allow the video to autoplay under any circumstances other than when the user clicks the 'play' on the video. Note that this
works whether or not you have the controls visible, i.e. with `showControls` being `true` or `false`, as long as you allow
play/pause behaviour with `possibleToPlayPause={true}` (default).
You should keep `playVideoWhenInView={true}` (default). There is no option to autoplay video with sound when the user clicks on the page
elsewhere if the video is not in view. In other words, you can't start playing sound for a video which is not in view with this component.
This is probably not a behaviour you'd want anyway.
- `allowSoundToAutoplay={true}` : Allow the video to autoplay when it comes into view as long as the user has interacted with the page preivously, i.e. they have clicked/tapped
anywhere on the page.
The example below allows for autoplay if the user has interacted with the page before the video comes into view. To see this, reload the page
and go to the top. Click anywhere on the page before scrolling down to the video and you should see it autoplay when it comes into view.
You should keep `playVideoWhenInView={true}` (default). There is no option to autoplay video with sound when the user clicks on the page
elsewhere if the video is not in view. In other words, you can't start playing sound for a video which is not in view with this component.
This is probably not a behaviour you'd want anyway.
The example below allows for autoplay if the user has interacted with the page before the video comes into view. To see this, reload the page
and go to the top. Click anywhere on the page before scrolling down to the video and you should see it autoplay when it comes into view.
</section>
```svelte
<script>
import { Video } from '@reuters-graphics/graphics-svelte-components';
</script>
<Video
ariaDescription={"Compulsory description of your video for screen readers."}
src={'path-to-video-or-external-url'}
size={'normal'}
controlsOpacity={1}
loopVideo={false}
muteVideo={false}
allowSoundToAutoplay={true}
<Video
ariaDescription="{'Compulsory description of your video for screen readers.'}"
src="{'path-to-video-or-external-url'}"
size="{'normal'}"
controlsOpacity="{1}"
loopVideo="{false}"
muteVideo="{false}"
allowSoundToAutoplay="{true}"
/>
```
<DemoContainer>
<Video
<Video
ariaDescription="Description of your video for screen readers."
src={`${assets}/videos/Sequence sound video.mp4`}
size='normal'
src={`${assets}/videos/Sequence sound video.mp4`}
size="normal"
caption="World's longest glass bridge opens to public in Vietnam. (c) 2022 Thomson Reuters"
controlsOpacity={1}
loopVideo={false}
@ -208,69 +205,65 @@ and go to the top. Click anywhere on the page before scrolling down to the video
/>
</DemoContainer>
<section>
### All the props
Here is a list of all the props that you can pass to the component for reference. Most of them are discussed above.
##### Required
- **src** (string) - Path to the video relative to the `statics` folder.
- **ariaDescription** (string) and **ariaHidden** (bool) - Either write a description for screen readers in ariaDescription or set ariaHidden to false.
- **src** (string) - Path to the video relative to the `statics` folder.
- **ariaDescription** (string) and **ariaHidden** (bool) - Either write a description for screen readers in ariaDescription or set ariaHidden to false.
##### Optional
- **caption** (string) - default <span class='default'>**" " (none)**</span> <span class='separator'></span> options: Write a caption to go with the video.
- **size** (string) - default <span class='default'>**'normal'**</span> <span class='separator'></span> options: *'normal'*, *'wide'*, *'wider'*, *'widest'*, *'fluid'*
- **size** (string) - default <span class='default'>**'normal'**</span> <span class='separator'></span> options: _'normal'_, _'wide'_, _'wider'_, _'widest'_, _'fluid'_
- **preloadVideo** (string) - default <span class='default'>**'auto'**</span> <span class='separator'></span>
options: *'none'* (Don't preload the video on page load),
*'auto'* (Preload the video),
*'metadata'* (Only preload the metadata)
- **preloadVideo** (string) - default <span class='default'>**'auto'**</span> <span class='separator'></span>
options: _'none'_ (Don't preload the video on page load),
_'auto'_ (Preload the video),
_'metadata'_ (Only preload the metadata)
- **loopVideo** (bool) - default <span class='default'>**true**</span> <span class='separator'></span> options: *true*, *false*
- **loopVideo** (bool) - default <span class='default'>**true**</span> <span class='separator'></span> options: _true_, _false_
- **muteVideo** (bool) - default <span class='default'>**true**</span> <span class='separator'></span> options: *true*, *false*
- **muteVideo** (bool) - default <span class='default'>**true**</span> <span class='separator'></span> options: _true_, _false_
- **allowSoundToAutoplay** (bool) - default <span class='default'>**false**</span><span class='separator'></span> options: *true*, *false*.
For video with sound, whether video should be allowed to autoplay if the user has previously interacted with DOM. You need to set `muteVideo` to `true`
for this to work.
- **allowSoundToAutoplay** (bool) - default <span class='default'>**false**</span><span class='separator'></span> options: _true_, _false_.
For video with sound, whether video should be allowed to autoplay if the user has previously interacted with DOM. You need to set `muteVideo` to `true`
for this to work.
- **playVideoWhenInView** (bool) - default <span class='default'>**true**</span> <span class='separator'></span>
options: _true_ (Only start playing the video when it comes into view), _false_ (Start playing as soon as the page and video load)
- **playVideoWhenInView** (bool) - default <span class='default'>**true**</span> <span class='separator'></span>
options: *true* (Only start playing the video when it comes into view), *false* (Start playing as soon as the page and video load)
- **playVideoThreshold** (float) - default <span class='default'>**0.5**</span> <span class='separator'></span> options: _float between 0 and 1_.
How much of the video should be into view to start playing when playVideoWhenInView is true.
- **playVideoThreshold** (float) - default <span class='default'>**0.5**</span> <span class='separator'></span> options: *float between 0 and 1*.
How much of the video should be into view to start playing when playVideoWhenInView is true.
- **possibleToPlayPause** (bool) - default <span class='default'>**true**</span> <span class='separator'></span> options: _true_, _false_
- **possibleToPlayPause** (bool) - default <span class='default'>**true**</span> <span class='separator'></span> options: *true*, *false*
- **showControls** (bool) - default <span class='default'>**true**</span> <span class='separator'></span> options: _true_, _false_.
Whether to show the play/pause controls or not.
- **showControls** (bool) - default <span class='default'>**true**</span> <span class='separator'></span> options: *true*, *false*.
Whether to show the play/pause controls or not.
- **hoverToSeeControls** (bool) - default <span class='default'>**false**</span><span class='separator'></span> options: _true_, _false_.
Whether you need to hover over the video to see the controls.
- **hoverToSeeControls** (bool) - default <span class='default'>**false**</span><span class='separator'></span> options: *true*, *false*.
Whether you need to hover over the video to see the controls.
- **separateReplayIcon** (bool) - default <span class='default'>**false**</span> <span class='separator'></span> options: _true_, _false_.
Whether to use a separate replay icon or use the play icon for replay as well.
- **separateReplayIcon** (bool) - default <span class='default'>**false**</span> <span class='separator'></span> options: *true*, *false*.
Whether to use a separate replay icon or use the play icon for replay as well.
- **controlsColour** (colour string) - default <span class='default'>**'#333'**</span> <span class='separator'></span> options: _any valid colour string_.
Controls the colour of the play/pause buttons.
- **controlsColour** (colour string) - default <span class='default'>**'#333'**</span> <span class='separator'></span> options: *any valid colour string*.
Controls the colour of the play/pause buttons.
- **controlsOpacity** (float) - default <span class='default'>**0.5**</span> <span class='separator'></span> options: *float between 0 and 1*.
Controls the opacity of the play/pause buttons.
- **controlsPosition** (string) - default <span class='default'>**'top left'**</span> <span class='separator'></span>
options: *'top right'*, *'top left'*, *'bottom right'*, *'bottom left'*.
Controls the position of the play/pause buttons.
- **controlsOpacity** (float) - default <span class='default'>**0.5**</span> <span class='separator'></span> options: _float between 0 and 1_.
Controls the opacity of the play/pause buttons.
- **controlsPosition** (string) - default <span class='default'>**'top left'**</span> <span class='separator'></span>
options: _'top right'_, _'top left'_, _'bottom right'_, _'bottom left'_.
Controls the position of the play/pause buttons.
</section>
<style>
ul {
list-style-type: none;
@ -290,4 +283,4 @@ Controls the position of the play/pause buttons.
margin: 0 5px 0 5px;
transform: translateY(-2.5px);
}
</style>
</style>

View file

@ -0,0 +1,15 @@
General-purpose video component. Can play on load or when the video comes into view and has play/pause controls. Supports videos with or without audio.
```svelte
<script>
import { Video } from '@reuters-graphics/graphics-components';
import { assets } from '$app/paths'; // If using local video in the Graphics Kit
</script>
<Video
ariaDescription={"Compulsory description of your video for screen readers."}
src={`${assets}/videos/myVideo.mp4`}
size={'wide'}
caption={'Optional caption for your video.'}
/>
```

View file

@ -0,0 +1,38 @@
`showControls`
- By default, the video has a play/pause button, which corresponds to
`showControls={true}`. If you don't want these, just set `showControls={false}`.
When you do that, the icons themselves will disappear but the functionality of playing and pausing remains and can be done by clicking on the video itself.
If you don't want to enable any play/pause functionality, add `possibleToPlayPause={false}`.
- If you want to show the controls only when the video is hovered, set `hoverToSeeControls={true}`.
`controlsColour`, `controlsOpacity`, `controlsPosition`, `separateReplayIcon`
If you do want to leave the controls, you have a couple of options to style them:
- Set `controlsColour` to a colour of your choosing.
- Set `controlsOpacity` to a value between `0` and `1` to control the opacity. The default is `0.5`.
- Change the placement of the controls to one of: `top right`, `top left`, `bottom right`, `bottom left` by setting `controlsPosition`.
- Change the play button to a replay button at the end of the video with the option `separateReplayIcon={true}`.
Here is an example with bottom right corner white opaque controls, with a replay button, where you have to hover on the video to see the controls.
```svelte
<script>
import { Video } from '@reuters-graphics/graphics-components';
</script>
<Video
ariaDescription={"Compulsory description of your video for screen readers."}
src={'path-to-video-or-external-url'}
size={'normal'}
caption={'Optional caption for your video.'}
playVideoThreshold={0.1}
controlsColour={'white'}
controlsOpacity={1}
controlsPosition={'bottom right'}
separateReplayIcon={true}
loopVideo={false}
hoverToSeeControls={true}
/>
```

View file

@ -0,0 +1,28 @@
`playVideoWhenInView`, `playVideoThreshold`
- By default, the video will **start playing when 50% of the video element's height is visible on the page**.
To control the threshold of visibility at which the video starts playing, add the prop `playVideoThreshold` and set it to a value between 0 and 1,
where 0 means that the video will start playing as soon as its top enters the viewport, while 1 means it will start when the whole video is in the viewport.
- If you don't want the video to play when you scroll to it, but **on page load**, add the prop `playVideoWhenInView={false}`. The default of the prop is `true`,
which corresponds to the behaviour described above.
`loopVideo`
- By default, the video will **loop**. If you don't want that, add the prop `loopVideo={false}`.
Here is an example of what the same video would look like with a visibility threshold of 0.9 and not looping. Scroll down slowly to observe the behaviour.
```svelte
<script>
import { Video } from '@reuters-graphics/graphics-components';
</script>
<Video
ariaDescription={"Compulsory description of your video for screen readers."}
src={'path-to-video-or-external-url'}
size={'normal'}
loopVideo={false}
playVideoThreshold={0.9}
/>
```

View file

@ -0,0 +1,36 @@
If you've ever had to put sound on a page in recent years,
you'll know that auto-playing sound is not allowed by browsers. The user will need to interact with the page first, and it will depend on your
particular use case how and when you'd like this to happen. This component provides two options to deal with this.
If you have a video with sound, make sure to add the prop `muteVideo={false}`.
Then you can either:
- `allowSoundToAutoplay={false}` (default) : Don't allow the video to autoplay under any circumstances other than when the user clicks the 'play' on the video. Note that this
works whether or not you have the controls visible, i.e. with `showControls` being `true` or `false`, as long as you allow
play/pause behaviour with `possibleToPlayPause={true}` (default).
- `allowSoundToAutoplay={true}` : Allow the video to autoplay when it comes into view as long as the user has interacted with the page preivously, i.e. they have clicked/tapped
anywhere on the page.
You should keep `playVideoWhenInView={true}` (default). There is no option to autoplay video with sound when the user clicks on the page
elsewhere if the video is not in view. In other words, you can't start playing sound for a video which is not in view with this component.
This is probably not a behaviour you'd want anyway.
The example below allows for autoplay if the user has interacted with the page before the video comes into view. To see this, reload the page
and go to the top. Click anywhere on the page before scrolling down to the video and you should see it autoplay when it comes into view.
```svelte
<script>
import { Video } from '@reuters-graphics/graphics-svelte-components';
</script>
<Video
ariaDescription={"Compulsory description of your video for screen readers."}
src={'path-to-video-or-external-url'}
size={'normal'}
controlsOpacity={1}
loopVideo={false}
muteVideo={false}
allowSoundToAutoplay={true}
/>
```

View file

@ -27,5 +27,5 @@ export {
themes as SiteHeaderThemes
} from './components/SiteHeader/SiteHeader.svelte';
export { default as Spinner } from './components/Spinner/Spinner.svelte';
// export { default as Video } from './Video/index.svelte';
export { default as Video } from './components/Video/Video.svelte';
export { default as Visible } from './components/Visible/Visible.svelte';

View file

@ -14,9 +14,9 @@
line-height: 1.5rem;
color: $tr-dark-grey;
margin-bottom: 1rem;
// &:last-of-type {
// margin-bottom: 0;
// }
&:last-of-type {
margin-bottom: 1rem;
}
@media(max-width: 540px) {
font-size: 1rem;
@ -45,6 +45,9 @@
color: $tr-medium-grey;
font-size: 0.9rem;
line-height: 1.2rem;
&:last-of-type {
margin-bottom: 0;
}
@media(max-width: 540px) {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 490 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 315 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 270 KiB

File diff suppressed because it is too large Load diff