Pārlūkot izejas kodu

Carousel component for Atlas.

Pedro Semeano 4 gadi atpakaļ
vecāks
revīzija
e076c96c8d

+ 33 - 0
packages/components/src/components/Carousel/Carousel.style.ts

@@ -0,0 +1,33 @@
+import { css } from "@emotion/core"
+
+export type CarouselStyleProps = {
+  navTopPosition?: string
+}
+
+export let makeStyles = ({
+  navTopPosition = "0"
+}: CarouselStyleProps) => {
+  return {
+    wrapper: css`
+      position: relative;
+    `,
+    container: css`
+      display: flex;
+      width: 100%;
+      overflow: hidden;
+    `,
+    item: css`
+      display: inline-block;
+    `,
+    navLeft: css`
+      position: absolute;
+      left: 0;
+      top: ${navTopPosition};
+    `,
+    navRight: css`
+      position: absolute;
+      right: 0;
+      top: ${navTopPosition};
+    `
+  }
+}

+ 40 - 0
packages/components/src/components/Carousel/Carousel.tsx

@@ -0,0 +1,40 @@
+import React, { ReactNode, useRef } from "react"
+import { makeStyles, CarouselStyleProps } from "./Carousel.style"
+import { NavButton } from "./../../"
+
+type CarouselProps = {
+  children: Array<ReactNode>
+  scrollAmount?: Number
+} & CarouselStyleProps
+
+export default function Carousel({
+  children,
+  scrollAmount = 200,
+  ...styleProps
+}: CarouselProps) {
+
+  const container = useRef(null)
+
+  function onScroll(direction: "right" | "left") {
+    container.current.scrollBy({
+      left: direction === "left" ? -(scrollAmount) : scrollAmount,
+      behavior: 'smooth'
+    })
+  }
+
+  let styles = makeStyles(styleProps)
+
+  return (
+    <div css={styles.wrapper}>
+      <div ref={container} css={styles.container}>
+        {children.map((item, index) => <div key={`carousel-${index}`} css={styles.item}>{item}</div>)}
+      </div>
+      <div css={styles.navLeft}>
+        <NavButton type="primary" direction="left" onClick={() => onScroll("left")} />
+      </div>
+      <div css={styles.navRight}>
+        <NavButton type="primary" direction="right" onClick={() => onScroll("right")} />
+      </div>
+    </div>
+  )
+}

+ 3 - 0
packages/components/src/components/Carousel/index.ts

@@ -0,0 +1,3 @@
+import { memo } from "react"
+import Carousel from "./Carousel"
+export default memo(Carousel)

+ 1 - 0
packages/components/src/index.ts

@@ -1,4 +1,5 @@
 export { default as Button } from "./components/Button"
+export { default as Carousel } from "./components/Carousel"
 export { default as Dropdown } from "./components/Dropdown"
 export { default as Grid } from "./components/Grid"
 export { default as Header } from "./components/Header"

+ 33 - 0
packages/components/stories/12-Carousel.stories.tsx

@@ -0,0 +1,33 @@
+import React, { Children } from "react"
+import { Carousel } from "./../src"
+
+export default {
+  title: "Carousel",
+  component: Carousel
+}
+
+const CarouselItem = ({ children }) => 
+  <div style={{ width: "300px", height: "100px", textAlign: "center" }}>
+    {children}
+  </div>
+
+export const Default = () =>
+  <Carousel>
+    <CarouselItem>CarouselItem 1</CarouselItem>
+    <CarouselItem>CarouselItem 2</CarouselItem>
+    <CarouselItem>CarouselItem 3</CarouselItem>
+    <CarouselItem>CarouselItem 4</CarouselItem>
+    <CarouselItem>CarouselItem 5</CarouselItem>
+    <CarouselItem>CarouselItem 6</CarouselItem>
+  </Carousel>
+
+export const LongerScroll = () =>
+  <Carousel scrollAmount={500}>
+    <CarouselItem>CarouselItem 1</CarouselItem>
+    <CarouselItem>CarouselItem 2</CarouselItem>
+    <CarouselItem>CarouselItem 3</CarouselItem>
+    <CarouselItem>CarouselItem 4</CarouselItem>
+    <CarouselItem>CarouselItem 5</CarouselItem>
+    <CarouselItem>CarouselItem 6</CarouselItem>
+  </Carousel>
+