1.1.2 • Published 5 years ago

mithril-slider v1.1.2

Weekly downloads
24
License
MIT
Repository
github
Last release
5 years ago

Content Slider for Mithril on mobile and desktop

Handles series of pageable content. This code is a Mithril component wrapper around HammerJS, with additional features.

Compatible with Mithril 1.0.

Examples

Examples

Features

  • Elements can be swiped or dragged.
  • Content can be anything that can be shown with HTML: a single image, a card, and so on.
  • Elements can be grouped, for instance for series of thumbnails that are shown a group at a time.
  • Elements content can be lazily loaded (see example code).
  • The slider can be controlled with next/previous buttons and queried for state.
  • Right-to-left language support, using mirrored transitions.

Installation

As npm module:

npm install --save mithril-slider

Or download from Github

  • git clone https://github.com/ArthurClemens/mithril-slider.git
  • cd mithril-slider
  • Install Lerna globally: npm install -g lerna
  • npm install
  • lerna init
  • lerna bootstrap

To build the source:

  • cd packages/mithril-slider
  • npm run build

To run the examples:

Usage

import { slider } from 'mithril-slider';

Slider panel contents is called a "page". Call the slider as component, with (at least) options pageData and page:

m(slider, {
  pageData,
  page
})

For option pageData, create a function to fetch page data:

const getPageData = () =>
  m.request({
    method: 'GET',
    url: 'app/data/images.json',
    background: false
  });

The function needs to return a promise (which m.request does).

The data can be anything, as long as a list is passed in the end. For example:

[
  "images/1.jpg",
  "images/2.jpg"
]

or

[
  {
    "title": "Love Valley, Cappadocia",
    "image": "images/1.jpg"
  },
]

For option page, create a function that returns a Mithril object for each single data item:

const page = opts =>
  m('.page', {
    style: {
      backgroundImage: `url(${opts.data})`
    }
  });

This function will be called for all list items.

Optimizing with lazy loading

The page function is called for all items in the list, so in the current form all images will get downloaded. For longer sliders this is not ideal, especially not on mobile.

We can optimize this by only loading the current, next and previous image:

const page = opts => {
  const currentIndex = opts.currentIndex;
  const listIndex = opts.listIndex;
  const data = opts.data;
  const style = (Math.abs(currentIndex - listIndex) < 2)
    ? { backgroundImage: `url(${data})` }
    : null;
  return m('.page', {
    style: style
  });
};

Sliding multiple pages

When showing more than one "page", for instance a series of thumbnails, use option groupBy:

const mySlider = m(slider, {
  pageData,
  page,
  groupBy: 3
});

For responsive interfaces, the number of pages within a group may be set dynamically (for instance divide the window width by the number of items to show).

No additional HTML markup is created for groups.

Use CSS to set the proper page size for each element.

Slider controls

The above example is fine for simply interacting with the slider (swiping/dragging). For more advanced functionality - for instance to conditionally show next/previous buttons - we need to access the slider instance.

By passing option sliderController, we can get a reference to the slider controller. The option is actually a function reference, and we can use m.prop to store the controller for later reference:

const app = {
  view: vnode => {
    const mySlider = m(slider, {
      pageData,
      page,
      sliderController: ctrl => vnode.state.sliderController = ctrl,
      ...
    });
  }
};

Now we can access slider controller methods:

const sliderController = vnode.state.sliderController;
const nextButton = m("a.next", {
  class: sliderController.hasNext()
    ? "enabled"
    : "disabled",
  onclick: () => sliderController.goNext()
}, "Next")

Styling

Note: With horizontal orientation and position: absolute, the page must have a width; with vertical orientation and position: absolute, the page must have a height.

There is very little CSS involved. The simplest approach is to link to the CSS file dist/mithril-slider.css, or copy the few lines to your own project.

Alternatively, Mithril Slider comes with a JavaScript based CSS object that is prepared for j2c, but does not import j2c itself. In the examples the CSS object is used to add styles to head:

import { css } from "mithril-slider";
import { addStyle } from "../app/styler";
addStyle("slider", css);

Configuration options

ParameterMandatoryTypeDefaultDescription
pagerequiredFunction :: ({data :: any, listIndex :: Number, currentIndex :: Number}) => Mithril Template or StringFunction that creates an page from data
pageDatarequiredFunction :: () => PromiseFunction that fetches a list of page data; should return a promise; after resolving m.redraw is called
sliderControlleroptionalFunction :: () => FunctionReceives the slider controller function
classoptionalStringExtra CSS class appended to 'slider'
durationoptionalNumber200Default transition duration in ms (when not dragging); when dragging, duration is dependent on dragging velocity, this setting is the maximum duration for slow drags
orientationoptionalString'horizontal'Either 'horizontal', 'vertical' or 'all'; translates to HammerJS's direction
rtloptionalBooleanfalseRight-to-left language support (for instance Arabic and Hebrew); set to true to mirror transitions
pageOffsetXoptionalNumber0The offset when the page element is displayed with an x offset relative to the slider container
pageOffsetYoptionalNumber0The offset when the page element is displayed with an y offset relative to the slider container
groupByoptionalNumberNumber of items within a group
beforeoptionalMithril template or componentContent shown before the pages; has class before
afteroptionalMithril template or componentContent shown after the pages; has class after
indexoptionalNumber0Starting page index
cancelDragFactoroptionalNumber1/5Fraction of page width below which the transition is cancelled
getStateoptionalFunction(state {Object})Callback function that accepts the slider state (Object with properties index {Number}, hasNext {Booleam}, hasPrevious {Boolean}, pageEl {HTMLElement})

Slider controller methods

MethodTypeDescription
indexindex() => NumberThe current page (index of the page list)
hasNexthasNext() => BooleanTrue if the current page has a next page
hasPrevioushasPrevious() => BooleanTrue if the current page has a previous page
goTogoTo(index :: Number, duration :: Number)Change the current page to the given index; transition duration is optional
goCurrentgoCurrent(duration :: Number)Go to current page; useful after resize; transition duration is optional
goNextgoNext(duration :: Number)Change the current page to the next index; if no next index exists, index is unchanged; transition duration is optional
goPreviousgoPrevious(duration :: Number)Change the current page to the previous index; if no previous index exists, index is unchanged; transition duration is optional

CSS classes

ElementKeyClass
sliderslidermithril-slider
contentcontentmithril-slider__content
beforebeforemithril-slider__before
afteraftermithril-slider__after

Size

Minified and gzipped: 1.8 Kb

Dependencies

Licence

MIT

1.1.2

5 years ago

1.1.1

5 years ago

1.1.0

6 years ago

1.0.1

7 years ago

1.0.0

7 years ago

0.4.1

7 years ago

0.4.0

7 years ago

0.3.6

8 years ago

0.3.5

8 years ago

0.3.4

8 years ago

0.3.3

8 years ago

0.3.2

8 years ago

0.3.1

8 years ago

0.3.0

9 years ago

0.2.0

9 years ago

0.1.4

9 years ago

0.1.3

9 years ago

0.1.2

9 years ago

0.1.1

9 years ago

0.1.0

9 years ago

0.0.1

9 years ago