NickPiscitelli / Glider.js

A fast, lightweight, dependency free, native scrolling carousel alternative!
https://nickpiscitelli.github.io/Glider.js
MIT License
3.25k stars 295 forks source link

Improve responsive options to support input method #32

Open jasongerbes opened 5 years ago

jasongerbes commented 5 years ago

Currently, the responsive options are based entirely off the window width. It would be good if they could also depend on input method (touch vs cursor).

Rationale: I would like to show 3.5 slides on touch-based devices as an indication that the track can be scrolled. On cursor-based devices, as there are buttons, I do not want to show incomplete slides.

NickPiscitelli commented 5 years ago

The problem with this is the difficulty in determining input methods which all the multiple input devices such as touch screen laptops.

Have you tried binding to resize and setting the options manually based on your own touch criteria? I would expect that to work although I never tried.

NickPiscitelli commented 5 years ago

I wonder if an optional indicator in the break point hash of requiring touch would be useful, this could be really easy to implement I would think and should be able to solve your original problem by using verbose settings definitions.

jasongerbes commented 5 years ago

This is my current workaround:

const hasTouch = deviceHasTouch();
const carouselProps: Partial<CarouselProps> = {
    showDots: false,
    settings: {
        slidesToScroll: 'auto',
        slidesToShow: hasTouch ? 3.5 : 4,
        responsive: [
            {
                breakpoint: 500,
                settings: {
                    slidesToShow: hasTouch ? 5.5 : 5
                }
            },
            {
                breakpoint: 900,
                settings: {
                    slidesToShow: hasTouch ? 7.5 : 7
                }
            }
        ]
    }
};

While it does do what I need it to do, I don't like that my deviceHasTouch() logic isn't the same as the logic used by Glider.js.

There could be a situation where Glider.js is showing the arrow buttons, yet my settings (based on my deviceHasTouch() logic) assume that it isn't.

jasongerbes commented 5 years ago

One potential solution would be to add a inputMethod property to each breakpoint that accepts 'cursor' | 'touch' | 'any', with 'any' being the default value.

This leaves the issue where you may want the default settings to also depend on the input method. I suppose one option to get around it would be to define a breakpoint of 0 with inputMethod: 'touch'. You could also add the inputMethod property to the default settings, to give further flexibility.

For example:

const carouselProps: Partial<CarouselProps> = {
    showDots: false,
    settings: {
        slidesToScroll: 'auto',
        slidesToShow: 4,
        responsive: [
            {
                breakpoint: 0,
                inputMethod: 'touch',
                settings: {
                    slidesToShow: 3.5
                }
            },
            {
                breakpoint: 500,
                inputMethod: 'touch',
                settings: {
                    slidesToShow: 5.5
                }
            },
            {
                breakpoint: 500,
                inputMethod: 'cursor',
                settings: {
                    slidesToShow: 5
                }
            },
            {
                breakpoint: 900,
                inputMethod: 'touch',
                settings: {
                    slidesToShow: 7.5
                }
            },
            {
                breakpoint: 900,
                inputMethod: 'cursor',
                settings: {
                    slidesToShow: 7
                }
            }
        ]
    }
};

Just a suggestion... There may be better interface options, but it's going to be pretty messy unless you make a breaking change

NickPiscitelli commented 5 years ago

While it does do what I need it to do, I don't like that my deviceHasTouch() logic isn't the same as the logic used by Glider.js.

Glider.js does not do any touch detection, this is all handled by the native browser scrolling.

Anyway, I think the input control key in the break point settings hash is probably the cleanest solution. I'll keep it in mind as an enhancement for future versions, I can definitely see it being useful.