Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
@skava/ui / src / components / organisms / MediaCarousel / renderProps.tsx
Size: Mime:
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,
}