@mycujoo/mcls-components
v0.1.8
Published
--- 📌 **Deprecation Notice** This version of the library is deprecated. We advise you to use the new components:
Downloads
48
Maintainers
Keywords
Readme
React MCLS components library
📌 Deprecation Notice This version of the library is deprecated. We advise you to use the new components:
- Data providers - Colleaction of react data provider contexts
- Player - Player component; Exports
Player
,PlayerWithContexts
(the previousPlayer
is notPlayerWithContexts
; andPlayer
now needs to be a child of Event data context provider, player state and annotation context providers) - Card - Card components
- Slider - Slider component
- Grid - Grid component
- Carousel - Carousel component
- Paywall - Paywall component
- Checkout - Checkout component
- AdSlot - Ad slots component
- InfoColumns, MatchScore, Lineup, EventTimeline - Single event related components
A library of configurable components for MyCujoo Live Services Platform
- Storybook documentation: https://mcls-components.pages.dev
Installation
MCLS components library uses a Universal Module Definition so you can use it in NPM.
npm install @mycujoo/mcls-components
or yarn add @mycujoo/mcls-components
The package requires: react
, react-dom
, @emotion/react
to be also installed if not already present.
Dev notes
This library uses two private npm packages that require access. First one is for MyCujoo's private npm packages, this can be retrieved from npm after getting access: https://www.npmjs.com/settings/USERNAME/tokens.
The second token can be retrieved from https://buf.build/settings/user.
After getting both make them available as environment variables: NPM_TOKEN
and BUF_TOKEN
. Use either of the two methods
Open command line and run:
nano ~/.zshrc
# Scroll to the bottom of the file and add the following line to set your environment variables
# export NPM_TOKEN=YOUR_NPM_TOKEN
# export BUF_TOKEN=YOUR_BUF_TOKEN
# Save and close
Or
export NPM_TOKEN=YOUR_NPM_TOKEN
export BUF_TOKEN=YOUR_BUF_TOKEN
Basic Use
For full components documentation please check Storybook.
Player
To use the react player import Player
from the library and pass at least a valid MCLS eventId
and you MCLS publicKey
import { Player } from '@mycujoo/player-components'
<Player
eventId= 'EVENT_ID'
publicKey= 'PUBLIC_KEY'
identityToken=''
autoplay
debug
showInfoButton
showLiveViewers
showSeekbar
showFullscreen
showBackForwardButtons
showQualitySelector
showVolume
showTimers
showChromecast
showPictureInPicture
enableAnnotations
analyticsType= 'youbora'
lang= 'en'
analyticsAccount=''
analyticsUserId=''
defaultVolume={0}
startPosition={0}
seekTo={0}
totalViewers={0}
customPlaylistUrl=''
adUnit=''
adCustParams = 'age_category=u19&id_channel=6486&logged_in=1'
className=''
analyticsCustomParams= {
customParam1: 'test p1',
customParam3: 'test p3',
customParam4: 'test p4',
customParam5: 'test p5',
customParam6: 'test p6',
customParam7: 'test p7',
}
globalStyle={globalStyle}
onTimeUpdate={action('onTimeUpdate')}
onGetTitle={action('onGetTitle')}
onGetEvent={action('onGetEvent')}
onVideoPlay={action('onVideoPlay')}
onVideoFirstPlay={action('onVideoFirstPlay')}
onLoadedMetadata={action('onLoadedMetadata')}
onVideoPause={action('onVideoPause')}
onVideoEnd={action('onVideoEnd')}
onMediaControlChange={action('onMediaControlChange')}
onFullscreenChange={action('onFullscreenChange')}
onPlayerViewChange={action('onPlayerViewChange')}
onGetMetadata={action('onGetMetadata')}
onPlayerInitialize={action('onPlayerInitialize')}
onAdsBreakStart={action('onAdsBreakStart')}
onAdStart={action('onAdStart')}
onAdSkip={action('onAdSkip')}
onAdComplete={action('onAdComplete')}
onAdsBreakComplete={action('onAdsBreakComplete')}
onAdsManager={action('onAdsManager')}
onQualityChange={action('onQualityChange')}
onWaiting={action('onWaiting')}
onSeeked={action('onSeeked')}
onSeeking={action('onSeeking')}
>
<div>Injected content</div>
</Player>
In order IMA ads to play IMA SDK scripts needs to be loaded on the page where the Player is used. For chromecast to be available the cast sender framework needs to be loaded on the page. For ad annotations to fill in, GPT library needs to be loaded on the page.
<script
async
src="//imasdk.googleapis.com/js/sdkloader/ima3.js"
id="googleIMASdk"
></script>
<script
async
src="//gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"
id="googleCastFramework"
></script>
<script
async
src="https://securepubads.g.doubleclick.net/tag/js/gpt.js"
></script>
For more details on all the available options of the player configuration go to Player component documentation.
AdSlot
To use the react ad unit import AdSlot
from the library and pass at least unitPath
and sizeMapping
props.
import { AsSlot } from '@mycujoo/player-components'
;<AsSlot
unitPath={'/6355419/Travel/Europe'}
targeting={{
name: 'name',
}}
sizeMapping={[
{
viewport: [0, 0],
slot: [[728, 90]],
},
{
viewport: [900, 0],
slot: [
[1024, 768],
[750, 200],
],
},
]}
slotRefreshRate={60000}
/>
In order for GPT ads to work the gpt library must be loaded on the pages where the AdSlots are used.
<script
async
src="https://securepubads.g.doubleclick.net/tag/js/gpt.js"
></script>
- useAdsEvents hook. For implementing custom logic around adSlots on a page this hook can be used. The hook handles subscriptions to Ad events listeners in a react hook. Below is an example of extending the hook to manage hiding some low priority ads from the page when ads with a higher priority are being shown.
import { useAdEvents } from '@mycujoo/player-components'
export const useLowPriorityAdsHandler = (): void => {
const [adUnits] = useState(new Map<string, googletag.Slot>())
useAdsEvents({
onSlotLoad: (unitPath, unit) => {
adUnits.set(unitPath, unit)
},
onSlotVisibilityChange: (unitPath, _unit, visualViewport) => {
if (unitPath === '/test/ad/path') {
const lowPriorityAd = adUnits.get('/test/ad/low/prio/path')
if (visualViewport > 0) {
lowPriorityAd && window?.googletag?.destroySlots([lowPriorityAd])
}
}
},
})
}
MCLS Events Slider
To use the MCLS events slider import MCLSEventsSlider
from the library and pass at least your publicKey
, a valid jsx card component and a type
('upcoming', 'live', 'past' or 'featured'). The type 'featured' is available for cases in which a predefined list of events needs to be displayed, in which case, the event IDs are passed through featuredEvents
. For other slider types featuredEvents will be ignored.
MCLSEventsSlider handles the fetching of events from MCLS api's and uses the data agnostic Slider
, passing the event data as data
to each card. This Slider
component is available for more advanced screnarios where a custom data-fetching wrapper might be preferred.
Visual configuration options of the slider are passed through a config
object where arrows, title, and general slider layout can be customized.
import { MCLSEventsSlider, MatchCard } from '@mycujoo/mcls-components'
;<MCLSEventsSlider
publicKey={'YOUR_PUBLIC_KEY'}
lang={'en'}
config={{
title: {
align: 'left',
color: '#FFF',
fontFamily: 'inherit',
uppercase: true,
underline: false,
size: '12',
weight: '500',
},
}}
maxCards={20}
type="featured"
featuredEvents={['eventId1']}
card={
<MatchCard
fallbackData={{
metadata: { league_name: 'League Name A' },
thumbnail_url:
'https://mycujoo-assets-fastly.images.mcls.live/theme-fifa%2B/fall-background-test.svg',
}}
dataPaths={dataPathsObj}
onClick={onOpenEvent}
config={{
size: 'l',
primaryColor: '#F12D4B',
secondaryColor: '#02102a',
thumbnail: {
viewers: false,
},
showTag: true,
borderRadius: 5,
action: {
buttonConfig: {
position: 'left',
},
},
}}
/>
}
/>
MCLS Events Grid
To use the MCLS Events Grid import MCLSEventsGrid
from the library and pass at least your publicKey
, a valid jsx card component, and a type
('upcoming', 'live', 'past' or 'featured'). The type 'featured' is available for cases in which a predefined list of events needs to be displayed, in which case, the event IDs are passed through featuredEvents
.
MCLSEventsGrid handles the fetching of events from MCLS api's and uses the data agnostic CardsGrid
, passing the event data as data
to each card. This CardsGrid
component is available for more advanced screnarios where a custom data-fetching wrapper might be preferred.
MCLSEventsGrid component includes logic for infinite scrolling of cards on the the grid when the type is other than 'featured'.
import { MCLSEventsGrid, MatchCard } from '@mycujoo/mcls-components'
;<MCLSEventsGrid
publicKey={'YOUR_PUBLIC_KEY'}
title="Upcoming events"
titleLeftComponent={<Button>Your custom button</Button>}
type="upcoming"
lang="de"
config={{
layout: {
gutter: 15,
marginTop: 20,
},
}}
card={
<MatchCard
dataPaths={dataPathsObj}
onClick={handleCardClick}
config={{
size: 'm',
borderRadius: 8,
thumbnail: {
icon: true,
viewers: true,
},
primaryColor: '#f12d4b',
showTag: true,
}}
/>
}
/>
Cards components
Cards are a set of highly configurable components that are available to be used and passed to sliders, grids or columns. Each card is meant to be better suited for a different purpose, design or event type.
Match Card
This card is intended to be used for Match-type events where there is or will be a score.
MatchCard receives data
object directly from the parent slider, grid or column.
It requires to be passed at least dataPaths
object which maps the path from the event data
object to the different fields that are displayed (team names, scores, logos, event start time, id, etc). Clicking on the card may be handled through a function passed as onClick
or as a <a>
HTML element. href
value for the card is provided through hrefBasePath
. This string needs to include {id}
in it, where the card id will be 'injected' automatically into it. As an example hrefPath="/events/{id}"
The basic structure of the card consists of an optional thumbnail, a body and an optional action section which can be customized through config
object.
Match Card relies on MCLS Events status and will display different visual behaviours based on the current status of the event. For example, live events show scores while upcoming events display event start time, and the default styles and label for the card action buttons is different for each event status. This can be overriden through config.
import { MatchCard } from "@mycujoo/mcls-components";
const dataPaths = {
homeTeamLogo: 'metadata.home_team.logo',
homeTeamName: 'metadata.home_team.name',
homeTeamShortCode: 'metadata.home_team.abbreviation',
homeTeamScore: 'metadata.home_team.score',
awayTeamLogo: 'metadata.away_team.logo',
awayTeamName: 'metadata.away_team.name',
awayTeamShortCode: 'metadata.away_team.abbreviation',
awayTeamScore: 'metadata.away_team.score',
eventVenue: 'location.physical.venue',
startTime: 'start_time',
status: 'status',
thumbnailUrl: 'thumbnail_url',
viewers: 'viewers',
leagueName: 'metadata.league_name',
id: "id"
}
<MatchCard
dataPaths={dataPaths}
onClick={handleCardClick}
config={{
size: 'm',
borderRadius: '16px',
thumbnail: {
icon: true,
viewers: true,
},
action: {
buttonConfig: {
position: 'left',
text: 'Custom text',
borderRadius: '4px',
type: 'outlined',
},
},
showSeparator: true,
primaryColor: '#ddd000',
secondaryColor: '#000ddd',
showTag: true,
}}
/>
Simple Card
This card is intended to be used for any event or data where only a title, a subtitle or description and aditional data like time is needed to be displayed.
SimpleCard receives data
object directly from the parent slider, grid or column.
It requires dataPaths
object which maps the path from the event data
object to the different fields that are displayed (Title, subtitle, thumbnail, id, etc). Clicking on the card may be handled through a function passed as onClick
or as a <a>
HTML element. href
value for the card is provided through hrefBasePath
. This string needs to include {id}
in it, where the card id will be 'injected' automatically into it. As an example hrefPath="/events/{id}"
import { SimpleCard } from "@mycujoo/mcls-components";
const dataPaths = {
title: 'title',
titleRight: 'metadata.highlight_time',
thumbnailUrl: 'thumbnail_url',
subtitle: 'description',
}
<SimpleCard
dataPaths={dataPaths}
onClick={handleCardClick}
config={{
size: 'm',
thumbnail: { viewers: false, borderRadius: 6, height: 150 },
textColor: '#fff',
bgColor: 'transparent',
bodyPadding: '20px 0',
title: {
fontSize: 20,
fontWeight: 500,
},
}}
/>
Match Line Card
This Match Line is intended to be used as a card in a column for listing Match-type events where there are two teams and the match start time needs to be displayed.
MatchLine receives data
object directly from the parent column.
It requires to be passed at least dataPaths
object which maps the path from the event data
object to the different fields that are displayed (team names, scores, logos, event start time, id, etc). Clicking on the card may be handled through a function passed as onClick
or as a <a>
HTML element. href
value for the card is provided through hrefBasePath
. This string needs to include {id}
in it, where the card id will be 'injected' automatically into it. As an example hrefPath="/events/{id}"
import { MatchLine } from "@mycujoo/mcls-components";
const dataPaths = {
homeTeamLogo: 'metadata.home_team.logo',
homeTeamName: 'metadata.home_team.name',
awayTeamLogo: 'metadata.away_team.logo',
awayTeamName: 'metadata.away_team.name',
textLeft: 'location.physical.venue',
startTime: 'start_time',
textRight: 'start_time',
}
<MatchLine
dataPaths={dataPaths}
onClick={handleCardClick}
config={{
bgColor: 'white',
borderRadius: 4,
height: 30,
padding: '5px 25px',
}}
/>
Player component
To use the react player import Player
from the library and pass at least a valid MCLS eventId
and you MCLS publicKey
Import
import { Player } from '@mycujoo/mcls-components'
Usage
<Player
eventId= 'EVENT_ID'
publicKey= 'PUBLIC_KEY'
identityToken=''
primaryColor="#FFF"
secondaryColor="#000"
autoplay
debug
showInfoButton
showLiveViewers
showSeekbar
showFullscreen
showBackForwardButtons
showQualitySelector
showVolume
showTimers
showChromecast
showPictureInPicture
enableAnnotations
analyticsType= 'youbora'
lang= 'en'
analyticsAccount=''
analyticsUserId=''
defaultVolume={0}
startPosition={0}
seekTo={0}
totalViewers={0}
customPlaylistUrl=''
adUnit=''
adCustParams = 'age_category=u19&id_channel=6486&logged_in=1'
className=''
analyticsCustomParams= {
customParam1: 'test p1',
customParam3: 'test p3',
customParam4: 'test p4',
customParam5: 'test p5',
customParam6: 'test p6',
customParam7: 'test p7',
}
globalStyle={globalStyle}
onTimeUpdate={action('onTimeUpdate')}
onTimerUpdate={action('onTimerUpdate')}
onGetTitle={action('onGetTitle')}
onGetEvent={action('onGetEvent')}
onVideoPlay={action('onVideoPlay')}
onVideoPause={action('onVideoPause')}
onVideoEnd={action('onVideoEnd')}
onSeeking={action('onVideoSeeking')}
onSeeked={action('onVideoSeeking')}
onWaiting={action('onWaiting')}
onMediaControlChange={action('onMediaControlChange')}
onFullscreenChange={action('onFullscreenChange')}
onPlayerViewChange={action('onPlayerViewChange')}
onGetMetadata={action('onGetMetadata')}
onPlayerInit={action('onPlayerInit')}
onAdsBreakStart={action('onAdsBreakStart')}
onAdStart={action('onAdStart')}
onAdSkip={action('onAdSkip')}
onAdComplete={action('onAdComplete')}
onAdsBreakComplete={action('onAdsBreakComplete')}
onAdsManager={action('onAdsManager')}
onQualityChange={action('onQualityChange')}
>
<div>Injected content</div>
</Player>
Required props
| Name | Type | Description |
| ----------- | -------- | ----------------------- |
| eventId
| string
| MCLS event id |
| publicKey
| string
| MCLS account public key |
Optional props
| Name | Type | Default | Description |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| children
| node
| undefined | The children of the Player component will be injected in the player and should be visible when going to fullscreen etc. |
| autoplay
| boolean
| false | Indicates if video should autoplay |
| debug
| boolean
| false | Indicates if debug messages should be shown |
| showInfoButton
| boolean
| false | Controls visibility of info button |
| showLiveViewers
| boolean
| false | Controls visibility of info live simultaneous viewers |
| showSeekbar
| boolean
| true | Controls visibility of seekbar |
| showFullscreen
| boolean
| true | Controls visibility of fullscreen button |
| showBackForwardButtons
| boolean
| false | Controls visibility of +10, -10s buttons |
| showQualitySelector
| boolean
| true | Controls visibility of quality selector |
| showVolume
| boolean
| true | Controls visibility of volume selector |
| showTimers
| boolean
| true | Controls visibility of timers |
| showChromecast
| boolean
| false | Enables or disables the chromecast feature |
| showPictureInPicture
| boolean
| true | Controls visibility of picture in picture button |
| enableAnnotations
| boolean
| true | Enables or disables the annotations feature |
| analyticsType
| youbora
,mux
| true | Specifies which type of analytics to use |
| analyticsAccount
| string
| undefined | Analytics account id |
| analyticsUserId
| string
| undefined | Unique user id for analytics; |
| analyticsCustomParams
| { customParam1: string, customParam3: string, customParam4: string -> customParam12: string, customParam13: string }
| undefined | Flat object with customParamers starting from 1 to 12 (2 is reserved) |
| startPosition
| number
| 0 | Indicates starting playback possition |
| seekTo
| number
| 0 | Indicates position to seek to |
| totalViewers
| number
| 0 | Number of viewers to show on live events |
| customPlaylistUrl
| string
| undefined | Playlist to play instead of event source |
| info
| ReactElement
| defaultInfo | Custom info overlay |
| preloader
| ReactElement
| undefined | Custom preloader |
| geoblockedScreen
| ReactElement
| defaultTextScreen | Custom geoblocked screen |
| preEventScreen
| ReactElement
| defaultTextScreen | Custom scheduled event screen |
| authorizationScreen
| ReactElement
| defaultTextScreen | Custom authorization / payment screen |
| streamErrorScreen
| ReactElement
| defaultTextScreen | Custom error screen |
| lang
| 'de', 'en', 'es', 'fr', 'id', 'it', 'ja', 'ms', 'pt', 'ru', 'th', 'zh', 'ar', 'ko'
| en
| Language for the default text screen messages. |
| globalStyle
| Object
| {} | Style object (@emotion global style object) |
| onTimerUpdate
| (currentTime: number, totalTime: number) => void
| undefined | Function called whenever video display timers update |
| onTimeUpdate
| (videoTime: number) => void
| undefined | Function called on video player timeupdate
event |
| onVideoPlay
| () => void
| undefined | Function called on video player play
event |
| onFirstPlay
| () => void
| undefined | Function called on video player first play
event |
| onVideoPause
| () => void
| undefined | Function called on video player pause
event |
| onSeeking
| () => void
| undefined | Function called on video player seeking
event |
| onSeeked
| () => void
| undefined | Function called on video player seeked
event |
| onWaiting
| () => void
| undefined | Function called on video player waiting
event |
| onVideoEnd
| () => void
| undefined | Function called on video player ended
event |
| onGetTitle
| (title: string) => void
| undefined | Function called when event title is fetched |
| onGetEvent
| (event: EventInformation) => void
| undefined | Function called when event information is fetched |
| onGetMetadata
| (metadata: unknown) => void
| undefined | Function called when event metadata is fetched |
| onMediaControlChange
| (isOpen: boolean) => void
| undefined | Function called when media control visibility changes. This is triggered on an internal player event when user causes the control bar to show up. |
| onFullscreenChange
| (isFullscreen: boolean) => void
| undefined | Function called when full screen value changes |
| onVideoTypeChange
| (videoType: 'vod' | 'live') => void
| undefined | Function called when video type changes |
| onPlayerViewChange
| (eventViews: PlayerView) => void
| undefined | Function called when player shows a different internal screen |
| onPlayerInit
| (playerInstance: PlayerInstance) => void
| undefined | Function called after internal video player is created |
| onAdsManager
| (adsManager: GoogleImaAdsManager) => void
| undefined | Function called after google ima manager is created; GoogleImaAdsManager
is the IMA SDK ads manager |
| onAdsBreakStart
| () => void
| undefined | Function called after ima ad break starts |
| onAdStart
| (ad: GoogleImaAd | null) => void
| undefined | Function called after ima ad starts playing; GoogleImaAd
is the IMA SDK ad |
| onAdComplete
| () => void
| undefined | Function called after ima ad finished playing |
| onAdsBreakComplete
| () => void
| undefined | Function called after ima ad break is completed |
| onQualityChange
| (newValue: { bitrate: number, height: number, width: number}) => void
| undefined | Function called when video quality changes; This also triggers when quality changes internally |