Marquee

Layout

텍스트·이미지·카드를 무한히 흐르게 하는 컴포넌트.

Usage

로고·공지·카드처럼 반복 콘텐츠를 끊김 없이 자동 스크롤할 때 사용한다.

import

import

import { Marquee } from '@mildang/design-system/Marquee';

예제를 복사해 쓸 때 필요한 준비

@mildang/styled-system 은 이 저장소에서 Panda 가 생성하는 산출물이다. 저장소 안에서는 turbo run ship 이후 쓸 수 있고, 패키지 소비자는 자기 Panda 산출물이나 다른 레이아웃 수단으로 바꿔야 한다.

API Reference

Marquee Props

Prop

Type

Default

children
필수

ReactNode

지정 안 함

pauseOnHover

boolean

false

repeat

number

4

reverse

boolean

false

vertical

boolean

false

흐름과 방향

Marquee는 반복 콘텐츠를 자동으로 흐르게 한다. pauseOnHover로 포인터가 올라왔을 때 멈추고, reverse로 기본 방향을 뒤집는다.

기본 흐름

반복 콘텐츠를 가로로 흐르게 하며 호버 시 일시정지한다.

import type { ComponentProps } from 'react';
import { Marquee } from '@mildang/design-system/Marquee';
import { css } from '@mildang/styled-system/css';

const tagStyle = css({
  flexShrink: 0,
  padding: '8px 16px',
  borderRadius: '8px',
  backgroundColor: 'neutral.surface.high',
  color: 'neutral.text.low',
  fontSize: '14px',
  fontWeight: 500,
});

const STORY_DEFAULT_ARGS = { ...({}), ...({
    reverse: false,
    pauseOnHover: false,
    vertical: false,
    repeat: 4,
  }) } as ComponentProps<typeof Marquee>;

const MarqueeDefaultExampleRender = (args: ComponentProps<typeof Marquee>) => (
    <Marquee {...args} style={{ '--marquee-duration': '20s' } as React.CSSProperties}>
      <span className={tagStyle}>Next.js</span>
      <span className={tagStyle}>React</span>
      <span className={tagStyle}>TypeScript</span>
      <span className={tagStyle}>Tailwind CSS</span>
      <span className={tagStyle}>Panda CSS</span>
    </Marquee>
  );

export default function MarqueeDefaultExample(props: Partial<ComponentProps<typeof Marquee>>) {
  const mergedProps = { ...STORY_DEFAULT_ARGS, ...props } as ComponentProps<typeof Marquee>;
  return MarqueeDefaultExampleRender(mergedProps);
}

방향과 일시정지

reverse와 pauseOnHover 조합을 보여준다.

import { Marquee } from '@mildang/design-system/Marquee';
import { token } from '@mildang/styled-system/tokens';
import { css } from '@mildang/styled-system/css';

const cardStyle = css({
  flexShrink: 0,
  width: '200px',
  padding: '16px',
  borderRadius: '12px',
  border: '1px solid',
  borderColor: 'neutral.border.base',
  backgroundColor: 'neutral.surface.high',
});

const MarqueeCardRowExample = () => (
    <div style={{ display: 'flex', flexDirection: 'column', gap: '24px' }}>
      <Marquee pauseOnHover style={{ '--marquee-duration': '30s' } as React.CSSProperties}>
        <div className={cardStyle}>
          <div style={{ fontWeight: 600, marginBottom: 4 }}>Card A</div>
          <div style={{ fontSize: 14, color: token.var('colors.neutral.text.low') }}>Description for card A</div>
        </div>
        <div className={cardStyle}>
          <div style={{ fontWeight: 600, marginBottom: 4 }}>Card B</div>
          <div style={{ fontSize: 14, color: token.var('colors.neutral.text.low') }}>Description for card B</div>
        </div>
        <div className={cardStyle}>
          <div style={{ fontWeight: 600, marginBottom: 4 }}>Card C</div>
          <div style={{ fontSize: 14, color: token.var('colors.neutral.text.low') }}>Description for card C</div>
        </div>
      </Marquee>
      <Marquee pauseOnHover reverse style={{ '--marquee-duration': '35s' } as React.CSSProperties}>
        <div className={cardStyle}>
          <div style={{ fontWeight: 600, marginBottom: 4 }}>Card 1</div>
          <div style={{ fontSize: 14, color: token.var('colors.neutral.text.low') }}>Reverse row</div>
        </div>
        <div className={cardStyle}>
          <div style={{ fontWeight: 600, marginBottom: 4 }}>Card 2</div>
          <div style={{ fontSize: 14, color: token.var('colors.neutral.text.low') }}>Reverse row</div>
        </div>
        <div className={cardStyle}>
          <div style={{ fontWeight: 600, marginBottom: 4 }}>Card 3</div>
          <div style={{ fontSize: 14, color: token.var('colors.neutral.text.low') }}>Reverse row</div>
        </div>
      </Marquee>
    </div>
  );

export default MarqueeCardRowExample;

예제

Vertical

import type { ComponentProps } from 'react';
import { Marquee } from '@mildang/design-system/Marquee';
import { css } from '@mildang/styled-system/css';

const tagStyle = css({
  flexShrink: 0,
  padding: '8px 16px',
  borderRadius: '8px',
  backgroundColor: 'neutral.surface.high',
  color: 'neutral.text.low',
  fontSize: '14px',
  fontWeight: 500,
});

const STORY_DEFAULT_ARGS = {
  reverse: false,
  pauseOnHover: false,
  vertical: true,
  repeat: 4,
} as ComponentProps<typeof Marquee>;

const MarqueeVerticalExampleRender = (args: ComponentProps<typeof Marquee>) => (
    <Marquee
      {...args}
      style={
        {
          '--marquee-duration': '25s',
          height: '200px',
        } as React.CSSProperties
      }
    >
      <span className={tagStyle}>Item 1</span>
      <span className={tagStyle}>Item 2</span>
      <span className={tagStyle}>Item 3</span>
      <span className={tagStyle}>Item 4</span>
    </Marquee>
  );

export default function MarqueeVerticalExample(props: Partial<ComponentProps<typeof Marquee>>) {
  const mergedProps = { ...STORY_DEFAULT_ARGS, ...props } as ComponentProps<typeof Marquee>;
  return MarqueeVerticalExampleRender(mergedProps);
}