From 3273ca17512ef3fd102bb39122cd2c6493cb10b0 Mon Sep 17 00:00:00 2001 From: Pedro Guerrato Date: Fri, 18 Mar 2022 09:59:35 -0300 Subject: [PATCH] Implement marquee component (#71) * Create the basic for marquee (sc2156) * Finish marquee creation (sc2156) * Format Marquee stories file (sc2156) * Add functionality to slide when mouse is over (sc2156) * Improve names on stories (sc2156) * Export Marquee (sc2156) * Remove left padding on Marquee (sc2156) * Remove global variation addition (sc2156) --- .../common/Marquee/Marquee.stories.tsx | 95 +++++++++++++++++++ .../common/Marquee/Marquee.styles.tsx | 94 ++++++++++++++++++ src/lib/components/common/Marquee/Marquee.tsx | 20 ++++ src/lib/components/common/Marquee/index.tsx | 1 + src/lib/components/common/index.ts | 1 + 5 files changed, 211 insertions(+) create mode 100644 src/lib/components/common/Marquee/Marquee.stories.tsx create mode 100644 src/lib/components/common/Marquee/Marquee.styles.tsx create mode 100644 src/lib/components/common/Marquee/Marquee.tsx create mode 100644 src/lib/components/common/Marquee/index.tsx diff --git a/src/lib/components/common/Marquee/Marquee.stories.tsx b/src/lib/components/common/Marquee/Marquee.stories.tsx new file mode 100644 index 00000000..7bfc2ef6 --- /dev/null +++ b/src/lib/components/common/Marquee/Marquee.stories.tsx @@ -0,0 +1,95 @@ +import { Story } from '@storybook/react' +import React, { useState } from 'react' +import { Marquee, MarqueeProps } from '.' +import { Icon, IconData, IconName } from '../../icons' + +export default { + title: 'Components/Common/Marquee', + component: Marquee, + parameters: { + layout: 'fullscreen' + } +} + +const icons = Object.keys(IconData).map((key) => ( +
+ +   +

{key}

+
+)) + +const longLorem = ( +

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin feugiat bibendum vehicula. Cras + et eros vitae velit commodo volutpat ac eget ex. Donec sed felis scelerisque, scelerisque nisl + non, maximus nunc. +

+) + +const shortLorem = ( +

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. +

+) + +const DefaultTemplate = (args: MarqueeProps) => { + return +} + +const BoxTemplate = (args: MarqueeProps) => { + const [slide, setSlide] = useState(args.slide && false) + return ( +
setSlide(true)} + onMouseLeave={() => setSlide(false)} + > + + + ) +} + +export const Default: Story = DefaultTemplate.bind({}) +Default.args = { + children:
{icons}
, + duration: 120 +} + +export const ShortText: Story = DefaultTemplate.bind({}) +ShortText.args = { + children: shortLorem, + duration: 15 +} + +export const LongText: Story = DefaultTemplate.bind({}) +LongText.args = { + children: longLorem, + duration: 25 +} + +export const ShortTextInBox: Story = BoxTemplate.bind({}) +ShortTextInBox.args = { + children: shortLorem, + duration: 15 +} + +export const LongTextInBox: Story = BoxTemplate.bind({}) +LongTextInBox.args = { + children: longLorem, + duration: 25 +} + +export const SlideWhenMouseover: Story = BoxTemplate.bind({}) +SlideWhenMouseover.args = { + children: shortLorem, + duration: 15, + slide: true +} diff --git a/src/lib/components/common/Marquee/Marquee.styles.tsx b/src/lib/components/common/Marquee/Marquee.styles.tsx new file mode 100644 index 00000000..90431eec --- /dev/null +++ b/src/lib/components/common/Marquee/Marquee.styles.tsx @@ -0,0 +1,94 @@ +import styled, { keyframes } from 'styled-components' + +export type MarqueeStyles = { + duration: number + width?: string +} + +const slideMainWhenStart = (props) => { + return keyframes` + 0% { + transform: 0px; + } + + 100% { + transform: translateX(-100%); + } + ` +} + +const slideMainForever = (props) => { + return keyframes` + 0% { + transform: translateX(100%); + } + + 100% { + transform: translateX(-100%); + } + ` +} + +const slideFakeForever = (props) => { + return keyframes` + 0% { + transform: translateX(0); + } + + 100% { + transform: translateX(-200%); + } + ` +} + +export const Track = styled.div` + --duration: ${(props) => props.duration}s; + box-sizing: border-box; + width: ${(props) => props.width || '100%'}; + overflow: hidden; + + * { + margin: 0; + padding: 0; + } +` + +export const Roller = styled.div.attrs((props) => ({ + 'aria-hidden': true +}))` + display: block; + width: max-content; + min-width: 200%; +` + +export const MainContent = styled.div` + display: inline-block; + box-sizing: border-box; + margin: 0; + padding: 0 20px 0 0; + width: fit-content; + min-width: 50%; + &.slide { + animation-name: ${slideMainWhenStart}, ${slideMainForever}; + animation-duration: var(--duration), calc(var(--duration) * 2); + animation-delay: 0s, var(--duration); + animation-timing-function: linear, linear; + animation-iteration-count: 1, infinite; + } +` + +export const FakeContent = styled.div` + display: inline-block; + box-sizing: border-box; + margin: 0; + padding: 0 20px 0 0; + width: fit-content; + min-width: 50%; + &.slide { + animation-name: ${slideFakeForever}; + animation-duration: calc(var(--duration) * 2); + animation-timing-function: linear; + animation-iteration-count: infinite; + animation-delay: 0; + } +` diff --git a/src/lib/components/common/Marquee/Marquee.tsx b/src/lib/components/common/Marquee/Marquee.tsx new file mode 100644 index 00000000..7f1dc6ba --- /dev/null +++ b/src/lib/components/common/Marquee/Marquee.tsx @@ -0,0 +1,20 @@ +import React, { ReactNode } from 'react' +import { FakeContent, MainContent, MarqueeStyles, Roller, Track } from './Marquee.styles' + +export type MarqueeProps = MarqueeStyles & { + children: ReactNode + slide?: boolean +} + +export const Marquee = (props: MarqueeProps) => { + const { slide = true } = props + + return ( + + + {props.children} + {props.children} + + + ) +} diff --git a/src/lib/components/common/Marquee/index.tsx b/src/lib/components/common/Marquee/index.tsx new file mode 100644 index 00000000..394b437f --- /dev/null +++ b/src/lib/components/common/Marquee/index.tsx @@ -0,0 +1 @@ +export * from './Marquee' diff --git a/src/lib/components/common/index.ts b/src/lib/components/common/index.ts index e083d590..edefd5ec 100644 --- a/src/lib/components/common/index.ts +++ b/src/lib/components/common/index.ts @@ -2,3 +2,4 @@ export * from './AspectRatio' export * from './Tooltip' export * from './Modal' export * from './Toast' +export * from './Marquee'