import { useRef, useState } from 'react'
import { Text } from 'react-native'
import Carousel from '../Carousel'
import { Div, Span, Row } from '@startupjs/ui'

# Carousel

```js
import Carousel from '@dmapper/carousel'
```

## Simple example

All you need to use is to transfer children in Carousel
Such an example of a carousel, used on instagram or vk for stories, children have no clear boundaries, such a carousel should be adaptive for all extensions and devices

```jsx example noscroll
const carouselStyle = { marginLeft: 4, marginRight: 4 }
const caseStyle = {
  height: 180,
  width: 200,
  paddingLeft: 4,
  paddingRight: 4
}
const itemStyle = { width: '100%', height: '100%' }

return (
  <Carousel style={carouselStyle}>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'blue' }} />
    </Div>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'red' }} />
    </Div>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'yellow' }} />
    </Div>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'gray' }} />
    </Div>
  </Carousel>
)
```

You can also set different widths for children, the component knows how to handle this case

```jsx example noscroll
const carouselStyle = { marginLeft: 4, marginRight: 4 }
const caseStyle = {
  height: 180,
  width: 200,
  paddingLeft: 4,
  paddingRight: 4
}
const itemStyle = { width: '100%', height: '100%' }

return (
  <Carousel style={carouselStyle}>
    <Div style={{ ...caseStyle, width: 120 }}>
      <Div style={{ ...itemStyle, backgroundColor: 'blue' }} />
    </Div>
    <Div style={{ ...caseStyle, width: 200 }}>
      <Div style={{ ...itemStyle, backgroundColor: 'red' }} />
    </Div>
    <Div style={{ ...caseStyle, width: 240 }}>
      <Div style={{ ...itemStyle, backgroundColor: 'yellow' }} />
    </Div>
    <Div style={{ ...caseStyle, width: 150 }}>
      <Div style={{ ...itemStyle, backgroundColor: 'gray' }} />
    </Div>
    <Div style={{ ...caseStyle, width: 240 }}>
      <Div style={{ ...itemStyle, backgroundColor: 'yellow' }} />
    </Div>
    <Div style={{ ...caseStyle, width: 150 }}>
      <Div style={{ ...itemStyle, backgroundColor: 'gray' }} />
    </Div>
  </Carousel>
)
```

## Adaptability

If you need clear boundaries
There is a property for this - isResponsive (by default - false)
In conjunction with this property, each children needs to minWidth and maxWidth
The component itself will calculate how many blocks need to be displayed for a specific resolution
For example, when minWidth 100 and maxWidth 500, on the desktop extension there will be 2 blocks, on mobile 1

```jsx example noscroll
const carouselStyle = { marginLeft: 4, marginRight: 4 }
const caseStyle = {
  height: 180,
  paddingLeft: 4,
  paddingRight: 4,
  minWidth: 100,
  maxWidth: 500
}
const itemStyle = { width: '100%', height: '100%' }

return (
  <Carousel style={carouselStyle} isResponsive={true}>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'blue' }} />
    </Div>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'red' }} />
    </Div>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'yellow' }} />
    </Div>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'gray' }} />
    </Div>
  </Carousel>
)
```

To use 1 visible block, children minWidth to be 100%

```jsx example noscroll
const carouselStyle = { marginLeft: 4, marginRight: 4 }
const caseStyle = {
  height: 180,
  paddingLeft: 4,
  paddingRight: 4,
  minWidth: '100%'
}
const itemStyle = { width: '100%', height: '100%' }

return (
  <Carousel style={carouselStyle} isResponsive={true}>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'blue' }} />
    </Div>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'red' }} />
    </Div>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'yellow' }} />
    </Div>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'gray' }} />
    </Div>
  </Carousel>
)
```

## Infinite scrolling

Set by isEndless property (default is false)
Without isResponsive property, infinite scrolling works only on arrow clicks

```jsx example noscroll
const carouselStyle = { marginLeft: 4, marginRight: 4 }
const caseStyle = {
  height: 180,
  paddingLeft: 4,
  paddingRight: 4,
  minWidth: 100,
  maxWidth: 500
}
const itemStyle = { width: '100%', height: '100%' }

return (
  <Carousel style={carouselStyle} isEndless={true}>
    <Div style={{ ...caseStyle, width: 400 }}>
      <Div style={{ ...itemStyle, backgroundColor: 'blue' }} />
    </Div>
    <Div style={{ ...caseStyle, width: 260 }}>
      <Div style={{ ...itemStyle, backgroundColor: 'red' }} />
    </Div>
    <Div style={{ ...caseStyle, width: 320 }}>
      <Div style={{ ...itemStyle, backgroundColor: 'yellow' }} />
    </Div>
    <Div style={{ ...caseStyle, width: 200 }}>
      <Div style={{ ...itemStyle, backgroundColor: 'gray' }} />
    </Div>
    <Div style={{ ...caseStyle, width: 140 }}>
      <Div style={{ ...itemStyle, backgroundColor: 'green' }} />
    </Div>
    <Div style={{ ...caseStyle, width: 180 }}>
      <Div style={{ ...itemStyle, backgroundColor: 'black' }} />
    </Div>
  </Carousel>
)
```

With isResponsive property, works also through swipe

```jsx example noscroll
const carouselStyle = { marginLeft: 4, marginRight: 4 }
const caseStyle = {
  height: 180,
  paddingLeft: 4,
  paddingRight: 4,
  minWidth: 100,
  maxWidth: 500
}
const itemStyle = { width: '100%', height: '100%' }

return (
  <Carousel
    style={carouselStyle}
    isResponsive={true}
    isEndless={true}
    hasDots={true}
  >
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'blue' }} />
    </Div>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'red' }} />
    </Div>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'yellow' }} />
    </Div>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'gray' }} />
    </Div>
  </Carousel>
)
```

## Swipe

The ability to scroll with the mouse or finger is set by isSwipe
The default is true, and you can always turn it off:

```jsx example noscroll
const carouselStyle = { marginLeft: 4, marginRight: 4 }
const caseStyle = { height: 180, paddingLeft: 4, paddingRight: 4 }
const itemStyle = { width: '100%', height: '100%' }

return (
  <Carousel style={carouselStyle} isSwipe={false}>
    <Div style={{ ...caseStyle, width: 400 }}>
      <Div style={{ ...itemStyle, backgroundColor: 'blue' }} />
    </Div>
    <Div style={{ ...caseStyle, width: 260 }}>
      <Div style={{ ...itemStyle, backgroundColor: 'red' }} />
    </Div>
    <Div style={{ ...caseStyle, width: 320 }}>
      <Div style={{ ...itemStyle, backgroundColor: 'yellow' }} />
    </Div>
    <Div style={{ ...caseStyle, width: 200 }}>
      <Div style={{ ...itemStyle, backgroundColor: 'gray' }} />
    </Div>
  </Carousel>
)
```

## Display arrows and dots

Set by properties hasArrows (default is true) and hasDots (default is false)
Without isResponsive - hasDots always false

```jsx example noscroll
const carouselStyle = { marginLeft: 4, marginRight: 4 }
const caseStyle = { minWidth: '100%', height: 180, paddingLeft: 4, paddingRight: 4 }
const itemStyle = { width: '100%', height: '100%' }

return (
  <Carousel
    style={carouselStyle}
    hasArrows={false}
    hasDots={true}
    isResponsive={true}
  >
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'blue' }} />
    </Div>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'red' }} />
    </Div>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'yellow' }} />
    </Div>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'gray' }} />
    </Div>
  </Carousel>
)
```

## Auto scroll

Set by isLoop property (default is false)

```jsx example noscroll
const carouselStyle = { marginLeft: 4, marginRight: 4 }
const caseStyle = { minWidth: '100%', height: 180, paddingLeft: 4, paddingRight: 4 }
const itemStyle = { width: '100%', height: '100%' }

return (
  <Carousel
    style={carouselStyle}
    hasDots={true}
    isLoop={true}
    isEndless={true}
    isResponsive={true}
  >
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'blue' }} />
    </Div>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'red' }} />
    </Div>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'yellow' }} />
    </Div>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'gray' }} />
    </Div>
  </Carousel>
)
```

## Start value

Set by startIndex (Number) property

```jsx example noscroll
const carouselStyle = { marginLeft: 4, marginRight: 4 }
const caseStyle = { minWidth: '100%', height: 180, paddingLeft: 4, paddingRight: 4 }
const itemStyle = { width: '100%', height: '100%' }

return (
  <Carousel
    style={carouselStyle}
    hasDots={true}
    isResponsive={true}
    startIndex={2}
  >
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'blue' }} />
    </Div>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'red' }} />
    </Div>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'yellow' }} />
    </Div>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'gray' }} />
    </Div>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'green' }} />
    </Div>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'black' }} />
    </Div>
  </Carousel>
)
```

## Styling arrows

Set with arrowBackStyle and arrowNextStyle

```jsx example noscroll
const carouselStyle = { width: '80%', alignSelf: 'center' }
const caseStyle = { width: 200, height: 180, paddingLeft: 4, paddingRight: 4 }
const itemStyle = { width: '100%', height: '100%' }
const arrowBackStyle = {
  left: -50,
  backgroundColor: 'transpornant',
  border: '1px solid #333333',
  color: '#333333'
}
const arrowNextStyle = {
  right: -50,
  backgroundColor: 'transpornant',
  border: '1px solid #333333',
  color: '#333333'
}

return (
  <Carousel
    style={carouselStyle}
    arrowBackStyle={arrowBackStyle}
    arrowNextStyle={arrowNextStyle}
  >
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'blue' }} />
    </Div>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'red' }} />
    </Div>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'yellow' }} />
    </Div>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'gray' }} />
    </Div>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'green' }} />
    </Div>
    <Div style={caseStyle}>
      <Div style={{ ...itemStyle, backgroundColor: 'black' }} />
    </Div>
  </Carousel>
)
```

If you need full customization of arrows or points, can be transferred ref, it will contain functions to switch: toBack, toNext, toIndex

```jsx example noscroll
const ref = useRef()
const [slide, setSlide] = useState(0)
const carouselStyle = { width: '100%', marginLeft: 4, marginRight: 4 }
const caseStyle = {
  minWidth: '100%',
  width: 200,
  height: 180,
  paddingLeft: 4,
  paddingRight: 4
}
const itemStyle = { width: '100%', height: '100%' }
const arrowStyle = {
  backgroundColor: '#333',
  alignItems: 'center',
  justifyContent: 'center',
  height: 20,
  width: 20,
  paddingBottom: 2
}

const dotStyle = {
   backgroundColor: '#333',
   width: 10,
   height: 10,
   border: '2px solid #333',
   marginLeft: 2,
   marginRight: 2,
   borderRadius: 30
}

const data = [
  { backgroundColor: 'blue' },
  { backgroundColor: 'red' },
  { backgroundColor: 'yellow' },
  { backgroundColor: 'gray' },
  { backgroundColor: 'green' },
  { backgroundColor: 'black' }
]

return (
  <Div style={{ overflow: 'hidden' }}>
    <Row style={{ marginBottom: 4 }}>
      <Div style={arrowStyle} onPress={()=> ref.current.toBack()}>
        <Text style={{ color: '#fff' }}>{'<'}</Text>
      </Div>
      <Div style={arrowStyle} onPress={()=> ref.current.toNext()}>
        <Text style={{ color: '#fff' }}>{'>'}</Text>
      </Div>
    </Row>
    <Carousel
      ref={ref}
      style={{ marginLeft: -4, marginRight: -4 }}
      hasArrows={false}
      isResponsive={true}
      onChange={v => setSlide(v)}
    >
      {
        data.map((item, index) => (
          <Div key={index} style={caseStyle}>
            <Div style={{ ...itemStyle, ...item }} />
          </Div>
        ))
      }
    </Carousel>
    <Row style={{ alignSelf: 'center', marginTop: 8 }}>
      {
        data.map((item, index) => (
          <Div
            key={index}
            style={{
              ...dotStyle,
              ...(slide === index ? { backgroundColor: '#fff' } : {})
            }}
            onPress={()=> ref.current.toIndex(index)}
          />
        ))
      }
    </Row>
  </Div>
)
```

## Vertical mode

```jsx example
const carouselStyle = { marginLeft: 4, marginRight: 4 }
const caseStyle = {
  height: 56,
  width: 72,
  paddingLeft: 4,
  paddingRight: 4
}

const itemStyle = {
  width: '100%',
  height: '100%',
  justifyContent: 'center',
  alignItems: 'center'
}

const textStyle = { color: '#fff' }

const data = new Array(24).fill(true).map(Number)

return (
  <Carousel
    style={{ height: 240, width: 72 }}
    variant='vertical'
    isEndless
    hasArrows
  >
    {
      data.map((item, index) => (
        <Div key={index} style={caseStyle}>
          <Div style={itemStyle}>
            <Span>{index + 1}</Span>
          </Div>
        </Div>
      ))
    }
  </Carousel>
)
```
