Socket
Socket
Sign inDemoInstall

react-film

Package Overview
Dependencies
104
Maintainers
2
Versions
96
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    react-film

React component for showing carousel just like a film strip


Version published
Weekly downloads
6.4K
decreased by-3.04%
Maintainers
2
Install size
6.07 MB
Created
Weekly downloads
 

Changelog

Source

[3.1.0] - 2021-10-14

Changes

Readme

Source

react-film

npm version Build Status

Please refer to README.md on our repository for most up-to-date information.

HTML component for showing carousel just like a film strip. It is lightweight and focus on performance and accessibility.

Although this component is built on top of React, it can be used outside of a React project.

This project scaffolding is from react-component-template.

Demo

Try out our demo at https://spyip.github.io/react-film/.

Sample code

Retrofitting DOM element without React

You can use react-film to retrofit existing DOM element outside of a React project.

Every children in the target element will become an individual carousel item.

<!DOCTYPE html>
<html lang="en-US">
  <head>
    <title>React Film</title>
    <script src="https://unpkg.com/react-film@latest/umd/react-film.production.min.js"></script>
  </head>
  <body>
    <div id="film">
      <img alt="Cat 01" src="image/01.jpg" />
      <img alt="Cat 02" src="image/02.jpg" />
      <img alt="Cat 03" src="image/03.jpg" />
    </div>
    <script>
      window.ReactFilm.retrofit(
        document.getElementById('film'),
        { height: 316 }
      );
    </script>
  </body>
</html>

Using in React projects

First, import react-film on your JSX file, namely BasicFilm.

import BasicFilm from 'react-film';

Then, instantiate a component using BasicFilm.

<BasicFilm height={ 316 }>
  <img alt="Cat 01" src="image/01.jpg" />
  <img alt="Cat 02" src="image/02.jpg" />
  <img alt="Cat 03" src="image/03.jpg" />
</BasicFilm>

Note: we need to specify height here because there are no CSS rule one can use to hide scroll bars in Firefox.

Customization

When we design react-film, customization is our top priority. From shallow to deep, we support these customizations:

Props

You can control <BasicFilm> using props listed below.

NameDefaultDescription
autoCentertruetrue will enable auto-center after scroll stopped for a second, otherwise, false
autoHidetruetrue to auto hide controls after pointer leave or scroll stopped, otherwise, false (surfaced from style set)
dir'ltr''ltr' for left-to-right mode. 'rtl' for right-to-left mode.
flipperBlurFocusOnClickfalsetrue will force the carousel flippers to blur on click, otherwise, false
heightHeight of the carousel, in number (required for Firefox)
leftFlipperText'<'Text for the left flipper
rightFlipperText'>'Text for the right flipper
showDotstruetrue to show dots below the carousel, otherwise, false
showFlippertruetrue to show flippers (side buttons), otherwise, false
showScrollBartruetrue to show scroll bar, otherwise, false
styleSet.carousel'css-*'Class name for carousel component
styleSet.dotsBox'css-*'Class name for dots container
styleSet.dotsItem'css-*'Class name for every dot
styleSet.leftFlipper'css-*'Class name for left flipper
styleSet.rightFlipper'css-*'Class name for right flipper
styleSet.scrollBarBox'css-*'Class name for scroll bar container
styleSet.scrollBarHandler'css-*'Class name for scroll bar handler

Basic style set

To better assist designer to style the component, we introduce style set, a clean way to override or replace existing styles. This help designers to create their unique styles without the need to overcome the effect of existing styles.

To start with the basic style set, just copy the following code:

.my-scroll-bar-class { background: Red; }
import BasicFilm, { createBasicStyleSet } from 'react-film';

const originalStyleSet = createBasicStyleSet();
const myStyleSet = {
  ...originalStyleSet,
  scrollBarHandler: originalStyleSet.scrollBarHandler + ' my-scroll-bar-class'
};

export default props =>
  <BasicFilm styleSet={ myStyleSet }>
    <img alt="Cat 01" src="image/01.jpg" />
    <img alt="Cat 02" src="image/02.jpg" />
    <img alt="Cat 03" src="image/03.jpg" />
  </BasicFilm>

Style using glamor

If you are familiar with glamor, you can also use it to style.

import { css } from 'glamor';
import BasicFilm, { createBasicStyleSet } from 'react-film';

const originalStyleSet = createBasicStyleSet();
const myStyleSet = {
  ...originalStyleSet,
  scrollBarHandler: css(originalStyleSet.scrollBarHandler, { backgroundColor: 'Red' })
};

export default props =>
  <BasicFilm styleSet={ myStyleSet }>
    <img alt="Cat 01" src="image/01.jpg" />
    <img alt="Cat 02" src="image/02.jpg" />
    <img alt="Cat 03" src="image/03.jpg" />
  </BasicFilm>

Presets for style set

Sometimes, just increasing some paddings are more than enough for your styling need. When calling createBasicStyleSet(options), you can specify the following options:

NameDefaultDescription
autoHidetrueAuto-hide controls
cursorpointerCursor style on dots and flippers
dotBoxSize20Hit box size of every dot
dotSize6Visible dot size
flipperBoxWidth60Hit box size of flippers
flipperSize40Visible flipper size (circle)
scrollBarHeight8Scroll bar handler height
scrollBarMargin4Margin around scroll bar

Deep-customization

Sometimes, CSS themeing is not enough for deep-customization. You may need to rebuild part of the carousel to achieve your customization goals.

Instead of forking our repository and building your carousel, you can rebuild react-film using composer/context pattern.

You can start from copying the following code, an absolute minimal without any non-essential styles. Our <BasicFilm> starts from here too.

import React from 'react';
import { AutoCenter, Composer, Dots, FilmStrip, Flipper, ScrollBar } from 'react-film';

export default ({ children }) =>
  <Composer numItems={ React.Children.count(children) }>
    <div>
      <FilmStrip>
        { children }
      </FilmStrip>
      <ScrollBar />
      <Flipper mode="left">&lt;</Flipper>
      <Flipper mode="right">&gt;</Flipper>
    </div>
    <Dots>
      { () => '.' }
    </Dots>
    <AutoCenter />
  </Composer>

You can also copy <BasicFilm> as your base template. There are no logic in it, so you can easily rebase latest changes from us without breaking your code.

Creating a new control

You can copy Flipper.js to start creating your own control, or from the simpler version below:

import React from 'react';
import { Context } from 'react-film';

export default ({ mode }) =>
  <Context.Consumer>
    { context =>
      <button onClick={ mode === 'left' ? context.scrollOneLeft : context.scrollOneRight }>
        { mode === 'left' ? '<' : '>' }
      </button>
    }
  </Context.Consumer>

Migrating from 1.x

To reduce an extra render callback, we now require deep-customization users to pass in numItems prop to <Composer>.

Context

Maybe you want to create a new flipper to control the carousel, the context object provides an API for interfacing with the carousel.

NameTypeDescription
indexnumberIndex of the current item
indexFractionnumberIndex of the current item, in fraction (1.5 means 50% between 2nd and 3rd item)
itemContainerRefReact refsRef of the immediate parent element containing all scrollable items
numItemsnumberNumber of items in the carousel
scrollableRefReact refsRef of the scrollable element, use for artificial scrolling and tracking scroll position
scrollBarPercentagestringPercentage of the scroll bar position
scrollBarWidthstringWidth (in percentage) of the scroll bar, respective to its total content
scrollingbooleantrue if the user is scrolling (debounced 500ms after last onScroll event), otherwise, false
scrollOneLeft() => {}Helper function to scroll one item to the left
scrollOneRight() => {}Helper function to scroll one item to the right
scrollTo(({ index: number, indexFraction: number }) => {}) => {}Scroll to a specified index, see sample below

If the context object lack of features you want to use, just tell us your idea.

Sample scrollTo code

scrollTo is the core of the carousel. You call it to jump to specific items in the carousel. For example, to scroll one item to the left:

context.scrollTo(({ indexFraction }) => {
  // indexFraction = 0 means it is on the first item
  // indexFraction = 0.5 means it is 50% between the first item and the second item

  return Math.ceil(indexFraction) - 1;
});

Road map

  • Native horizontal scrolling
    • Virtual scroll bar
    • Show when hover
    • Support touch scrolling
  • Bring your own flipper
    • Show only when overflow
    • Show when hover
  • Bring your own scrollbar
    • Show only when overflow
    • Show when hover
  • Bring your own dots
    • Show only when overflow
  • Variable container width
    • Users can resize the container width any time they want
  • Variable item width:
    • Users can resize item width any time they want
    • Item may resize itself from time to time (consider when the image is not loaded)
  • Minimal styling as possible, let user customize it
  • Support keyboard left/right arrow (supported natively)
  • Using without React

Features not planned to support

While you can dream about everything, engineering a piece of software that works great requires some opinions and it may not please everyone.

  • Non-native scrolling
    • Physics model are different across browsers
    • Too many inputs need to be handled, difficult to build a good model
      • Mouse with physical wheel (some browsers support SHIFT + wheel to scroll horizontally)
      • Mouse with capacitive touch wheel, or trackpoint devices
      • Precision Touchpad
      • Touchpad without precision scrolling
      • Pen input
      • Xbox controller
    • If items are focusable, it is difficult to scroll it into view because it is difficult to detect focus
  • Infinite or "wrap-around" scrolling
    • Does not play nice with browser native scrolling

Contributions

Like us? Star us.

Want to make it better? File us an issue.

Don't like something you see? Submit a pull request.

Keywords

FAQs

Last updated on 14 Oct 2021

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc