Code Monkey home page Code Monkey logo

keen-slider's People

Contributors

angelokarugo avatar braincore avatar dependabot[bot] avatar emilmassey avatar hotscotch92 avatar joostmeijles avatar kang-heewon avatar kmorales13 avatar komeyl94 avatar kongallis avatar kroofy avatar m424m avatar markpinero avatar pawelkaczoruk avatar pichiste avatar ponciusz avatar rasteiner avatar rcbyr avatar roderickhsiao avatar themosaad avatar thenoim avatar umemotoryo avatar wajeshubham avatar zingerj avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

keen-slider's Issues

React Typescript dragSpeed for Date/Time pickers

I'm using React v16.3.1 and Typescript.

dragSpeed: (val, instance) => {
      const height = instance.details().widthOrHeight;
      return val * (height / ((height / 2) * Math.tan(slideDegree * (Math.PI / 180))) / slidesPerView);
    },

I am getting an error about the type (val, instance) => {...
and how do I set the type?

Even if I specify as below, type error occurs.
js(val:number, instance:any) => {...

CSS scroll snap support

add the use of modern CSS Scroll Snap API. it might bring a better performance.
Also a common behaviour is scrolling with mouse / pad and the slider does not react to these common gestures.

Angular: keen-slider within cdk-virtual-scroll-viewport problem

I realise this is likely not so much an issue as a feature request or cry for help...

My data is a list / array of items, each of which has as one value an array of a varying number of image URLs that I'd like to display in a keen-slider instance. I want to display all my data in a scrollable list.

I created a component that creates an instance of keen-slider from an @input that is an array of URLs (the images to display). All pretty standard stuff. Works fine.

If I use a standard '*ngFor' style list for my data this works a treat, but my data could grow and cause my list to get very long so I tried to use a 'cdk-virtual-scroll-viewport' and a '*cdkVirtualFor' list within that. This breaks my keen-slider implementation though. It seems to be down to the implementation using '*ngFor' internally to create it's 'slides'. Projecting the 'slides' using ng-content has the same issue (only the final 'slide' is present). I though that maybe using the 'slides' option of keen-slider with a function to create the slide elements might be a way forward, but I can't figure out how to write such a function. From the docs:

Function, that return HtmlElement[]

If my 'slides' were a set of fixed elements and didn't have to be created from data then there wouldn't be problem. It just seems that once you try to iterate something to create slides within a component within a '*cdkVirtualFor' list something goes haywire.

Rubberband might not pull back

Hi,
First of all thanks for a great slider, I'm really enjoying it.

I ran in to a little bug where the "rubberband" might not pull the slides back if you push it enough.
See attachment.

Thanks
rubberband.mov.zip

Variable widths?

Hey @rcbyr!

I saw your library on reddit and was blown away! I was wondering if you plan on supporting variable widths for slides?

Thanks!

Bug?: Slidechanged event is delayed, when using dot-values in slidesPerView

I don't know if this is a bug, or a feature request
I've noticed, that the slideChanged event, is slightly delayed, when using a dot-value in slidesPerView – I've been able yo replicate it, with the following example:

import "./styles.css";
import "keen-slider/keen-slider.min.css";
import KeenSlider from "keen-slider";

const slider = new KeenSlider("#my-keen-slider", {
  slidesPerView: 2.5,
  slideChanged: (instance) => {
    console.log("slideChanged");
  }
});

const next = document.querySelector("[data-next]");

next.addEventListener("click", () => slider.next());

Vertical carousel

Hi there!

The slider looks brilliant, wonderful job! I'm curious if there are any plans on adding support for vertical sliders/carousels? We'd definitely switch over to your library in my company but vertical support is, unfortunately, a must.

Thanks so much!

Regards!
F.

TypeError when using dot navigation

Hi i'm getting an error in my Gatsby site when trying to use the dot naviation from the example. I'm assuming this is from my lack of experience with react and gatsby. I've copied everything from the example - if anyone could help me, i'd apprecitate it! (Loving keen-slider btw - thank you!)

TypeError: Array(...).keys(...).concat is not a function
Compiled:
Array(slider.details().size).keys().concat().map(function (idx) {

Source:

{slider && (
        <div className="dots">
          {[...Array(slider.details().size).keys()].map(idx => {
            return (
              <button
                key={idx}
                onClick={() => {
                  slider.moveToSlideRelative(idx);
                }}
                className={"dot" + (currentSlide === idx ? " active" : "")}
              />
            );
          })}
        </div>
      )}

How to get instance DOM or ID?

I try to add multiple keen-slider on one page with dots using vanilla.js. Some sliders may have 3 dots, some have 4.

When I change slider, the event "slideChanged" will pass "instance" value. But I can't map to the slider that using it. Then I can't add active class to proper ".dot" element.

Do you have any suggestion if I'd like to use multiple sliders? Or how can I get DOM / ID from instance.details() ?

Thank you very much for your time and your great slider :)

This is..

mind blowing pure work in super clean and easy to read JS. Wow, just wow. What do you think of sliders in sliders?

RequestAnimationFrame block by media(img, background etc.) rendering

Env:
iOS webkit
A mediocre network traffic

Problem:
Found the issue that slide animation lost a lot of frames when page is almost loaded and ui thread is painting some media elements such as img tag or CSS background.

Some info:
Dived into performance debugging and found the requestAnimationFrame was delayed by nothing. But it took 50ms, 100ms or even more time to do next moveAnimateUpdate detecting by console.log. The issue could be reproduced in the demo page without page cache in a mediocre network traffic.

Width keen-slider__slide with scrollbar

Hi!

If the site has a preloader and at the beginning of the page loading there is no scrollbar, then "keen-slider__slide" has a width excluding the width of the scrollbar

keenslider within component renders only one slide

Hey!

I am trying to implement the slider ("keen-slider": "^4.2.1") inside a component. This component then renders within a page component that has a <section></section>. The slide that I am trying to render is material cards with a min-width of 365px;

I want three to show in the center of the page max-width 80% on large screens and two on tablets and only one on mobiles.

Similar to this: codesandbox.

The component renders only 1 card for some reason.

width will change when total slider number is smaller than slidesPerView

when the total slider count is smaller than slidesPerView, the slides width is not parentWidth / slidesPerview

this is the source code
https://codesandbox.io/s/keen-slider-spacing-react-forked-48x2h?fontsize=14&hidenavigation=1&theme=dark

import React from "react";
import { useKeenSlider } from "keen-slider/react";
import "keen-slider/keen-slider.min.css";
import "./styles.css";

export default (props) => {
  const [sliderRef] = useKeenSlider({ slidesPerView: 3, spacing: 15 });
  const [sliderRef2] = useKeenSlider({ slidesPerView: 3, spacing: 15 });

  return (
    <>
      <div ref={sliderRef} className="keen-slider">
        <div className="keen-slider__slide number-slide1">1</div>
        <div className="keen-slider__slide number-slide2">2</div>
        <div className="keen-slider__slide number-slide3">3</div>
        <div className="keen-slider__slide number-slide4">4</div>
        <div className="keen-slider__slide number-slide5">5</div>
        <div className="keen-slider__slide number-slide6">6</div>
      </div>
      <div ref={sliderRef2} className="keen-slider">
        <div className="keen-slider__slide number-slide1">1</div>
        <div className="keen-slider__slide number-slide2">2</div>
      </div>
    </>
  );
};

this is the screenshot
image

Is it possible to keep the slider's width the same when the slider count is smaller than slidesPerView?

How to use the same snapping for scrolling with a trackpad?

I saw your post on reddit and I have to say, I'm really glad I found out about this library! Definitely the best one out there with the most native feeling indeed.

However, I was wondering if it's supported to use the snapping when just scrolling? Like with a trackpad for example. I created a repo where I tried to use css scrollsnapping as well, but this won't work as all "children" are positioned absolute.

Is there a way to achieve this? Or is it not supported, which I could also understand.

React Typescript sliderRef from useKeenSlider type error

So I'm using React v16.3.1 and Typescript.

         const [sliderRef] = useKeenSlider();
        ...
        <div ref={sliderRef}>
          <img src={imageUrl} alt="some" />
          <img src={imageUrl} alt="some" />
          <img src={imageUrl} alt="some" />
        </div>

And basically it has the red underline on the ref prop of the div saying
Type 'RefObject<HTMLElement>' is not assignable to type 'string | ((instance: HTMLDivElement | null)

Suggestion - Plug-able mode option

Thanks for the awesome library.

One suggestion here is for the mode option,

function moveWithSpeed() {
    hook('beforeChange')
    switch (options.mode) {
      case 'free':
        moveFree()
        break
      case 'free-snap':
        moveSnapFree()
        break
      case 'snap':
      default:
        moveSnapOne()
        break
    }
  }

wondering if we can make it pluggable so only the default one will be built in, and the library could export other mode such as

import { freesnap }, KeenSlider from 'keen-slider';

const slider = new KeenSlider('#my-slider', {
  loop: true,
  modeFunc: freesnap
});

In this case its easier to tree-shake methods the people are not using it and reduce the overall bundle size.
It might not be totally easy to implement without refactor as most of the function are written accessing global variable, just throwing some idea to make the library more flexible.

Cheers

Autoplay feature missing

While testing it, I realised that the autoplay feature is missing.

Are we going to see this implemented soon ?
Autoplay with the control of duration and an onHoverStop event would be a nice addition

Slide for other actions?

Would you happen to have a blog post or resource about how you implemented native-like sliding?

I'm working on an application where I want users to slide to flip flash cards so your package stood out to me in this week's issue of JS Weekly. Next time I need a carousel I'll be sure to give this package a try 😊

Feature Request: Group Slide

Although currently there is a way to display multiple slides per view I wasn't able to find any built it way to make it work properly with controls. Provided controls example only account for one slide per view, but what I would like to do is to slide per view when user clicks on the arrow or dot. Amount of dots should also represent the amount of views, not slides.

Please, more Vanilla.js examples!

Just started using keen-slider in my Svelte/Sapper project and I hope it will go well. I plan to replace Siema (keen-slider seems to be even more lightweight?) but getting inspiration and converting existing examples from React to Svelte way is a bit of pain, I guess would be really cool for everyone if there would always be a Vanilla.js example a reference alongside already existing examples? (Not asking for Svelte ones, as this would be too much). Cheers!

Slider not rendering when loading data through an API

I saw your post on Reddit and was very 'keen' on using this! :) I initialized the container on ngAfterViewInit and then make an API call. The data from the API call render in an ngFor loop in the HTML within the slider. I don't see it rendering. Am I missing something here?

I'm using Angular 9 btw.

Feature Request: Overflowing Loop Support

The Problem

When trying to force overflow: visible; on .keen-slider and setting loop: true on the slider instance, slides appear and disappear as the slider jumps between the start/end transforms.

keen-loop-overflow

Possible Solution

I'm sure you've sen how other libs get around this by cloning the start/end elements, maybe could be done if loop: true is set. Glide also has a really nice peek option, allowing elements just outside the bounds of the slider to be pulled in.

Also, thanks for creating this – all of the slider libraries I've tried over the past few years are either extremely large (swiper.js), or have average to horrible touch behaviour (glide.js and many others). You have nailed both of these, so well done!

internal "hooks" internal references do not update if external data updates

See console output from this example: https://codesandbox.io/s/keen-slider-hooks-issue-9yneh?file=/src/App.js

When I navigate between slides, slideChanged will update the state value for currentSlide with the sliders relative slide.

dragEnd is called momentarily before slideChanged, and will output the sliders relative slide, and the state value for currentSlide

However, even when currentSlide is updated, the internal hook hangs on to the old value as seen in the console output:

****** currentSlide 0
****** currentSlide 0
***** slideChanged - relativeSlide 0 currentSlide 0
****** currentSlide 0
****** currentSlide 0
***** dragEnd - relativeSlide 0 currentSlide 0
***** slideChanged - relativeSlide 1 currentSlide 0
****** currentSlide 1
****** currentSlide 1
***** slideChanged - relativeSlide 2 currentSlide 0
****** currentSlide 2
****** currentSlide 2
***** dragEnd - relativeSlide 2 currentSlide 0
***** slideChanged - relativeSlide 3 currentSlide 0
****** currentSlide 3
****** currentSlide 3
***** dragEnd - relativeSlide 3 currentSlide 0
***** slideChanged - relativeSlide 4 currentSlide 0
****** currentSlide 4
****** currentSlide 4
***** dragEnd - relativeSlide 4 currentSlide 0
***** slideChanged - relativeSlide 5 currentSlide 0
****** currentSlide 5
****** currentSlide 5
***** dragEnd - relativeSlide 5 currentSlide 0

Seems like a scoping issue

.arrow--disabled class set even when loop is true

When using loop = true, and reaching the last (or the first) slide, the arrow change it's style because the .arrow--disabled class is set.

We shouldn't change arrow style when loop = true since none of them should be disabled

Financing

Hi 👋,

I'm Romuald from the Lsos, an organization that develops financial solutions for open source, and we are currently reaching out to projects we like.

We have several solutions depending on your financial goals and we can help with:

  • Increasing donations
  • Starting/increasing consulting work for your users
  • Earning a living from your open source work
  • Remunerating and hiring a small engineering team for your open source projects

For example, we can increase donations with the Lsos Donation Reminder and the Lsos Donation Fund.

We can also leverage a license clause if you are interested in receiving a substantial remuneration from your open source work. Our license clauses are designed to keep code:

  1. Accessible: everything stays free for individuals and small companies — only large companies pay a small fee.
  2. Open: anyone can fork the code and remove the license clause.

Large companies want two things: open source and a way to pay for software. They prefer paying for well-maintained tools rather than using free but unreliable tools. At the end of the day, a license clause can be a win for everyone.

We are focusing on solving the financials of a handful of projects first to then eventually tackle the open source financing problem at large. Let me know if you are interested.

Rom

Implement "passive" event listeners where events will not "preventDefault"

I am unsure whether this is configurable at all, but at present, using keen-slider impacts our lighthouse scores on a project I'm working on for the following reasons:

https://web.dev/uses-passive-event-listeners/?utm_source=lighthouse&utm_medium=devtools

I've investigated and can see that there are a few places where the event listeners never call preventDefault, or optionally call preventDefault based on configuration, and can therefore identify if they are passive or not.

Without this flag, the browser will wait for events to complete before deciding if it should take over scrolling. With the flag, the browser knows immediately that it can scroll without waiting.


Multiple event listeners in this block can identify that they are passive event listeners that will not prevent scrolling:

function eventsAdd() {
eventAdd(window, 'orientationchange', sliderResizeFix)
eventAdd(window, 'resize', () => sliderResize())
eventAdd(container, 'dragstart', function (e) {
if (!isTouchable()) return
e.preventDefault()
})
eventAdd(container, 'mousedown', eventDragStart)
eventAdd(container, 'mousemove', eventDrag)
eventAdd(container, 'mouseleave', eventDragStop)
eventAdd(container, 'mouseup', eventDragStop)
eventAdd(container, 'touchstart', eventDragStart)
eventAdd(container, 'touchmove', eventDrag)
eventAdd(container, 'touchend', eventDragStop)
eventAdd(container, 'touchcancel', eventDragStop)
eventAdd(window, 'wheel', eventWheel, {
passive: !1,
})
}

dragstart

eventAdd(container, 'dragstart', function (e) {
if (!isTouchable()) return
e.preventDefault()
})

Potentially above should indicate passive flag when isTouchable() returns false

eventDragStart

function eventDragStart(e) {
if (touchActive || !isTouchable() || eventIsIgnoreTarget(e.target)) return
touchActive = true
touchJustStarted = true
touchIdentifier = eventGetIdentifier(e)
eventIsSlide(e)
moveAnimateAbort()
touchIndexStart = trackCurrentIdx
touchLastX = eventGetX(e).x
trackAdd(0, e.timeStamp)
hook('dragStart')
}

Doesn't appear to preventDefault, so the following references should use the passive flag:

eventAdd(container, 'mousedown', eventDragStart)

eventAdd(container, 'touchstart', eventDragStart)

eventDragStop

function eventDragStop(e) {
if (
!touchActive ||
touchIdentifier !== eventGetIdentifier(e, true) ||
!isTouchable()
)
return
container.removeAttribute(attributeMoving)
touchActive = false
moveWithSpeed()
hook('dragEnd')
}

Doesn't appear to preventDefault, so the following references should use the passive flag:

eventAdd(container, 'mouseleave', eventDragStop)
eventAdd(container, 'mouseup', eventDragStop)

eventAdd(container, 'touchend', eventDragStop)
eventAdd(container, 'touchcancel', eventDragStop)

wheel

eventAdd(window, 'wheel', eventWheel, {
passive: !1,
})

Seems to indicate it is never passive, but is passive when isTouchable() returns false:

function eventWheel(e) {
if (!isTouchable()) return
if (touchActive) e.preventDefault()
}

Refresh() does not override original method

Hi!
So I had been trying to override the slideChanged() method using the refresh() method, as mentioned in the documentation, the refresh method will accept an object that will initialize the slider and override with the method passed in the options object:

Original

      slideChanged: s => {
          state = s.details().relativeSlide;
      }

Using a button onclick function to call the refresh:

  function move_to_slide(n) {
    slider.refresh({
      slideChanged: s => {
        state = s.details().relativeSlide;
        console.log("Slide change");
      }
    });
    slider.moveToSlideRelative(n);
  }

Expected output:
It will console log "Slide change" when after I click the button and interact with the slider

Actual output:
No log is output in the console.

Very much thanks for helping!

Shortest route moveToSlide and loop

For loop: true

If we have 5 slides and use slider.next() we move slide 5 > 1.
If we have 5 slides and use slider.moveToSlide(0) we move slide 5 > 4 > 3 > 2 > 1

It might feel the mostest native if we would slide the shortest route to the next slide.

Use case: A slider with thumbails underneath for navigation

Feature Request: Support Vue directive syntax similar to React Hooks

As a Vue developer I would like to use directive based syntax that is similar to React Hooks:

import React from 'react'
import 'keen-slider/keen-slider.min.css'
import { useKeenSlider } from 'keen-slider/react'

export default () => {
  const [sliderRef, slider] = useKeenSlider()

  return (<div ref={sliderRef}>
    <div class="keen-slider__slide">1</div>
    <div class="keen-slider__slide">2</div>
    <div class="keen-slider__slide">3</div>
  </div>)
}

Proposed Vue syntax:

<template>
<div
        class="keen-slider"
        v-slider:mySlider="sliderOptions"
...
</div>
</template>

import 'keen-slider/keen-slider.min.css'
import { useKeenSlider } from 'keen-slider/vue'

const {directive} = useKeenSlider()

export default {
    name: 'MySlider',
    directives: {
      slider: directive
    },
   data() {
      return {
          sliderOptions: {...}
      }
    }
}

Such syntax will allow much cleaner slider instantiation with no need to do anything in mounted hook as well as no need to manually destroy slider instance since that can be done internally by watching directive detachment from the DOM

clicks and drag events collision if slider content has interactive (clickable) elements

hi there,
is there a built in way to intercept or distinguish clicks from drags within a slider element?
my slide content is interactive and might probably have even another slider embedded.
problem is that if i click i also receive drag events and vice versa.
or do i need to stop event propagation by using hammerjs to the parent slide container or similar?

thanks for help!

Animations and Autoplay build-in

Can we have animations (fade/slide) and autoplay functionality build-in instead on depending on external code for vue/angular/react? As it is this functionality is not avaliable for vanillajs at all. In other carousel/slider scripts this is normally passed as arguments like this.

var slider = new KeenSlider('#my-slider', {  
    loop: true,  
    animation: 'slide', // or fade  
    autoplay: 1000, // time in ms  
})

Provide SCSS within NPM package

node-sass@v5 does not watch or properly import CSS, but converts any such calls to import(example.css);. Whilst Webpack handles this change gracefully, CSS files are not similarly handled when importing directly using node-sass (using something like Gulp and without any additional plugins).

I see in the src/ for this repo there is a SCSS file - it would be great if this was included as part of the npm package for import, as well as a CSS file.

The stylesheet can also be converted to actual SCSS too, nesting the selectors and removing the prefixes (which can ultimately be handled by the end user IMO, allowing them to negate any prefixes they don't want/need), turning the SCSS into this (as a quick, untested example):

.keen-slider {
  display: block;
  overflow: hidden;
  position: relative;
  user-select: none;
  touch-action: pan-y;
  -webkit-tap-highlight-color: transparent;
  
  &__slide {
    position: absolute;
    overflow: hidden;
    width: 100%;
    min-height: 100%;
  }

  &--vertical &__slide {
    min-height: auto;
  }
}

P.S. Thanks for the plugin!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.