Repository URL to install this package:
|
Version:
2.8.0-studio-release ▾
|
import React from 'react'
import { isNumber } from 'exotic'
import { application } from '@skava/state'
import Empty from 'atoms/Empty'
import { getSlotOrder } from './deps'
import {
MediaCarouselProps,
MediaCarouselState,
StepperProps,
DeviceSpecificProps,
ImageComponentProps,
} from './typings'
import {
GalleryWrapper,
StyledThumbNail,
Slot,
StyledBanner,
Stepper,
StyledImage,
StyledWrapper,
StyledBullets,
BulletIcon,
BackwardArrow,
ForwardArrow,
SliderWrapper,
StyledMaterialIcon,
} from './styled'
function addProtocolsWithURL(url) {
if (url && url.length > 0) {
const noProtocolURL = url.replace(/(^\w+:|^)\/\//, '')
const updatedURL = '//' + noProtocolURL
return updatedURL
}
return url
}
function defaultRenderDeviceSpecific(item: DeviceSpecificProps) {
const { desktop, tablet, mobile } = item
return application.isDesktop
? desktop
: application.isTablet
? tablet
: mobile
}
function defaultRenderArrow(item: StepperProps) {
const { arrow, arrowIconColor, arrowIconSize } = item
const attributes = {
arrowIconColor,
arrowIconSize,
type: arrow === 'prev' ? 'left' : 'right',
}
return <StyledMaterialIcon {...attributes} />
}
function defaultRenderComponent(item: ImageComponentProps) {
const { src } = item
return (
<StyledImage
src={addProtocolsWithURL(src)}
alt={addProtocolsWithURL(src)}
/>
)
}
function defaultRenderForwardArrow(props: StepperProps) {
const {
order,
onClick: handleClick,
isAbsolute,
align,
hasNavigations,
isDisabled,
arrowIconColor,
arrowIconSize,
} = props
const stepperView = hasNavigations ? (
<ForwardArrow
isAbsolute={isAbsolute}
align={align}
order={order}
onClick={handleClick}
isDisabled={isDisabled}
>
<StyledMaterialIcon
arrowIconColor={arrowIconColor}
arrowIconSize={arrowIconSize}
type={'right'}
/>
</ForwardArrow>
) : (
<Empty />
)
return stepperView
}
function defaultRenderBackwardArrow(props: StepperProps) {
const {
order,
onClick: handleClick,
isAbsolute,
align,
hasNavigations,
isDisabled,
arrowIconColor,
arrowIconSize,
} = props
const stepperView = hasNavigations ? (
<BackwardArrow
isAbsolute={isAbsolute}
align={align}
order={order}
onClick={handleClick}
isDisabled={isDisabled}
>
<StyledMaterialIcon
arrowIconColor={arrowIconColor}
arrowIconSize={arrowIconSize}
type={'left'}
/>
</BackwardArrow>
) : (
<Empty />
)
return stepperView
}
function defaultRenderStepper(props: StepperProps) {
const {
order,
onClick: handleClick,
arrow,
arrowIconColor,
arrowIconSize,
isAbsolute,
align,
hasNavigations,
isDisabled,
} = props
const stepperView = hasNavigations ? (
<Stepper
isAbsolute={isAbsolute}
align={align}
order={order}
onClick={handleClick}
arrow={arrow}
isDisabled={isDisabled}
>
{defaultRenderArrow({ arrow, arrowIconColor, arrowIconSize })}
</Stepper>
) : (
<Empty />
)
return stepperView
}
const renderThumbnail = (props: MediaCarouselProps) => {
const {
type,
deviceSpecific,
value,
index,
renderComponent,
state,
gridGap,
} = props
const { count, pick, position, setPick } = state
const handleClick = (event?: Event) => setPick(index)
const carouselType =
type === 'bannerWithThumbnail'
? getSlotOrder(position, index, count)
: index
return (
<Slot
deviceSpecific={deviceSpecific}
gridGap={gridGap}
type={type}
key={index}
data={position}
pick={pick}
onClick={handleClick}
order={carouselType}
>
{renderComponent(value)}
</Slot>
)
}
function defaultRenderGallery(
props: MediaCarouselProps,
state: MediaCarouselState
) {
const {
desktopColspan,
tabletColspan,
mobileColspan,
hasNavigations,
list,
...remainingProps
} = props
const { position, forwards, backwards } = state
const deviceSpecific = defaultRenderDeviceSpecific({
desktop: 100 / desktopColspan,
tablet: 100 / tabletColspan,
mobile: 100 / mobileColspan,
})
const arrowDeviceSpecific = defaultRenderDeviceSpecific({
desktop: desktopColspan,
tablet: tabletColspan,
mobile: mobileColspan,
})
const carouselOverAllLength = list.length % arrowDeviceSpecific
const overAllLengthDifference = arrowDeviceSpecific - carouselOverAllLength
const carouselStepLength =
list.length - carouselOverAllLength - overAllLengthDifference
const deviceSpecificValue =
(carouselStepLength < position ? carouselStepLength : position) *
deviceSpecific
const backwardArrow = defaultRenderBackwardArrow({
order: 0,
onClick: backwards,
arrow: 'prev',
hasNavigations,
isDisabled: position < arrowDeviceSpecific ? true : false,
...remainingProps,
})
const forwardArrow = defaultRenderForwardArrow({
order: 2,
onClick: forwards,
arrow: 'next',
hasNavigations,
isDisabled: position >= list.length - arrowDeviceSpecific ? true : false,
...remainingProps,
})
const thumbnailView = list.map((value: any, index: number) => {
const attributes = {
value,
index,
deviceSpecific,
state,
...remainingProps,
}
return renderThumbnail(attributes)
})
const arrowView =
arrowDeviceSpecific < list.length ? (
<React.Fragment>
{backwardArrow}
{forwardArrow}
</React.Fragment>
) : (
<Empty />
)
return (
<GalleryWrapper>
<SliderWrapper order={1}>
<StyledThumbNail steps={deviceSpecificValue} gridGap={props.gridGap}>
{thumbnailView}
</StyledThumbNail>
</SliderWrapper>
{arrowView}
</GalleryWrapper>
)
}
/**
* rendering banner view
*/
function defaultRenderBanner(
props: MediaCarouselProps,
state: MediaCarouselState
) {
const {
list,
arrowIconSize,
arrowIconColor,
hasNavigations,
renderComponent,
} = props
const { position, value, pickNext, pickPrevious } = state
return (
<StyledBanner>
{renderComponent(value)}
{defaultRenderStepper({
isAbsolute: true,
align: 'left',
onClick: pickPrevious,
arrow: 'prev',
hasNavigations,
arrowIconSize,
arrowIconColor,
isDisabled: position < 1 ? true : false,
})}
{defaultRenderStepper({
isAbsolute: true,
align: 'right',
onClick: pickNext,
arrow: 'next',
hasNavigations,
arrowIconSize,
arrowIconColor,
isDisabled: position >= list.length - 1 ? true : false,
})}
</StyledBanner>
)
}
/**
* rendering carousel view
*/
function defaultRenderCarousel(
props: MediaCarouselProps,
state: MediaCarouselState
) {
const thumbnailView = defaultRenderGallery(props, state)
return thumbnailView
}
/**
* rendering banner with thumbnail view
*/
function defaultRenderBannerWithThumbnail(
props: MediaCarouselProps,
state: MediaCarouselState
) {
const bannerView = defaultRenderBanner(props, state)
const thumbnailView = defaultRenderGallery(props, state)
return (
<React.Fragment>
{bannerView}
{thumbnailView}
</React.Fragment>
)
}
/**
* rendering bullets
*/
function defaultRenderBullets(
props: MediaCarouselProps,
state: MediaCarouselState
) {
const {
type,
bulletSize,
bulletColor,
desktopColspan,
tabletColspan,
mobileColspan,
list,
} = props
const { position, handleBullet } = state
const size = isNumber(bulletSize) ? bulletSize + 'px' : bulletSize
const listLength = list.length
const deviceSpecific = defaultRenderDeviceSpecific({
desktop: desktopColspan,
tablet: tabletColspan,
mobile: mobileColspan,
})
const view = list.map((value: any, index: number) => {
const positionIndex = type == 'banner' ? index : deviceSpecific * index
return listLength > positionIndex ? (
<BulletIcon
bulletSize={size}
bulletColor={bulletColor}
pick={position}
data={positionIndex}
onClick={handleBullet}
type={type}
/>
) : (
<Empty />
)
})
return <StyledBullets>{view}</StyledBullets>
}
/**
* rendering media carousel type
*/
const renderCarouselType = (
props: MediaCarouselProps,
state: MediaCarouselState
) => {
switch (props.type) {
case 'banner':
return defaultRenderBanner(props, state)
case 'bannerWithThumbnail':
return defaultRenderBannerWithThumbnail(props, state)
case 'carousel':
default:
return defaultRenderCarousel(props, state)
}
}
/**
* rendering media carousel wrapper
*/
function defaultRenderWrapper(
props: MediaCarouselProps,
state: MediaCarouselState
) {
const { className, hasBullets, ...remainingProps } = props
const deviceSpecific = defaultRenderDeviceSpecific({
desktop: props.desktopColspan,
tablet: props.tabletColspan,
mobile: props.mobileColspan,
})
const carouselView = renderCarouselType(remainingProps, state)
const bulletType = props.type == 'bannerWithThumbnail' ? false : hasBullets
const bulletView =
bulletType && deviceSpecific < props.list.length ? (
defaultRenderBullets(remainingProps, state)
) : (
<Empty />
)
return (
<StyledWrapper className={className}>
{carouselView}
{bulletView}
</StyledWrapper>
)
}
export {
defaultRenderDeviceSpecific,
defaultRenderComponent,
defaultRenderWrapper,
}