Code Monkey home page Code Monkey logo

hooper's Introduction

leaps logo

Average time to resolve an issue Percentage of issues still open npm npm

Hooper

Vue.js carousel component, optimized to work with Vue.

Features

  • Easily customizable through rich API and addons.
  • Touch, Keyboard, Mouse Wheel, and Navigation support.
  • Two way control carousels (sync).
  • Full RTL layout support.
  • Supports vertical sliding.
  • Responsive breakpoints.
  • Seamless infinite scroll.
  • Accessible by providing a robust structure and user control.
  • Optimized to work with Vue framework.
  • SSR Support.

Browser Support

Chrome Firefox Safari Opera Edge IE
Latest ✔ Latest ✔ Latest ✔ Latest ✔ Latest ✔ 11 ✔

Getting started

Installation

First step is to install it using yarn or npm:

npm install hooper

# or use yarn
yarn add hooper

Use Hooper

<template>
  <hooper>
    <slide>
      slide 1
    </slide>
    <slide>
      slide 2
    </slide>
    ...
  </hooper>
</template>

<script>
  import { Hooper, Slide } from 'hooper';
  import 'hooper/dist/hooper.css';

  export default {
    name: 'App',
    components: {
      Hooper,
      Slide
    }
  }
</script>

If you are using PurgeCSS, make sure to whitelist hooper css When importing hooper/dist/hooper.css.

more info at Documentation

Available Props

Prop Default Description
itemsToShow 1 count of items to showed per view (can be a fraction).
itemsToSlide 1 count of items to slide when use navigation buttons.
initialSlide 0 index number of initial slide.
infiniteScroll false enable infinite scrolling mode.
centerMode false enable center mode.
vertical false enable vertical sliding mode.
rtl null enable rtl mode.
mouseDrag true toggle mouse dragging.
touchDrag true toggle touch dragging.
wheelControl true toggle mouse wheel sliding.
keysControl true toggle keyboard control.
shortDrag true enable any move to commit a slide.
autoPlay false enable auto sliding to carousel. This could be changed dynamically.
playSpeed 2000 speed of auto play to trigger slide in ms.
transition 300 sliding transition time in ms.
sync '' sync two carousels to slide together.
hoverPause true pause autoPlay if the mouse enters the slide.
trimWhiteSpace false limit carousel to slide only when there will be no completely empty slide-space.
settings { } an object to pass all settings.

Available CSS Properties

Please also look at the source to style the slider. An initial style can be imported as @import '~hooper/dist/hooper.css';

Class Property Default Description
hooper height 200px the default height of the slider, set to auto to scale with content

hooper's People

Contributors

baianater 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

hooper's Issues

Easy way to click and select the slide

Is there any chance of providing an option to click on a slide and set it as currentSlide?

I'm currently showing itemsToShow=12 from 40 total items and would like to click on one of them and make it the currentSlide, making it slide to the center (with 'centerMode', of course).

Uncaught TypeError: Cannot read property 'style' of undefined

Hi

I found this error:

Uncaught TypeError: Cannot read property 'style' of undefined
at window.setTimeout (hooper.esm.js?7e04:225)

It's happen after v-if is set false on my template using Hooper, Slide, Navigation.

  window.setTimeout(() => {
    this.$refs.track.style.transition = '';   <----- null
    this.isSliding = false;
  }, this.$settings.transition);

Calling event.preventDefault() inside passive invocation.

Describe the bug
Chrome Console displays the message Unable to preventDefault inside passive event listener invocation. when using touch scroll on mobile.

To Reproduce
Steps to reproduce the behavior:

  1. Go to 'https://baianat.github.io/hooper/examples.html#default-example'
  2. Open JS console, and enable mobile device toolbar.
  3. Use any of the hoopers in the page doing 'touch scroll'.
  4. See error

Expected behavior
There should be no JS console warnings.

Desktop (please complete the following information):

  • OS: macOS
  • Browser Chrome
  • Version [e.g. 71.0]

Infinite Scroll loses click handlers

Describe the bug
When using infinite scroll, the slides are duplicated to ensure there are always slides on the screen.
If you put an @click handler on the contents of a slide, it only works on the original element, not the duplicated one

Expected behavior
Click events should be retained

Screenshots
Original element has the handler:
image
Duplicated element does not:
image

Desktop (please complete the following information):

  • OS: Windows
  • Browser Chrome
  • Version 0.0.8

Documentation error; 'wheelControl' defaults to 'true'

Describe the bug
The documentation states that 'wheelControl' defaults to 'false'. This isn't true as of version 0.1.1

To Reproduce
Steps to reproduce the behavior:

  1. Create a Hooper component.
  2. Don't pass any settings, use the defaults.
  3. Get stuck when trying to scroll while hovering the slider.

Expected behavior
Scrolling should happen as normal, per the documentation, as 'wheelControl' should be 'false'

Desktop:

  • OS: macOS
  • Browser: Google Chrome 73
  • Version: 0.0.1

Additional context
Submitted PR #63 to fix this.

Cannot get Demo to run

Describe the bug
The simple slider demo just displays boxes, no slides

To Reproduce
vue-cli 3.3.0

vue create slider
cd slider
npm install hooper
edit HelloWorld.vue and replace most of the template with

   <hooper>
      <slide>
        1
      </slide>
     <slide>
        2
      </slide>
     <slide>
        3
      </slide>
     <slide>
        4
      </slide>
    </hooper>

(and add the import and component stuff for Hooper and Slide)

Expected behavior
I would expect to see one "slide" with one number and that I could then scroll through the rest of the slides.

Screenshots
screenshot 2019-01-29 at 20 09 18

Desktop (please complete the following information):

  • OS: macOS 10.14.2
  • Browser Chrome
  • Version 71

Additional context
I've tried the demo, too, but same behaviour. Don't know what I'm missing...

hooper.update() not working when adding new slides to slider

Describe the bug
Calling .update() after adding slides does not update the slider.

To Reproduce
Steps to reproduce the behavior:

  1. Go to https://codesandbox.io/s/34zjprk68m
  2. Click on "add more items'
  3. Slide through slider... the slider doesn't update.

Note: The Hooper component is implemented inside components/HelloWorld.vue

Expected behavior
After adding new slides and callling .update() the slider should work correctly with the new total number of slides.

Add ability to turn component on and off

I.e. I have 5 elements that i want to behave responsively (wrap, etc.) when window is wider than some breakpoint and start using hooper only when window width is smaller than breakpoint.

Either property or method to invoke.

Behavior: First show of `centerMode` without initial transition

Hi,

This issue is referred to keep more clean the first exhibition of Hoper with centerMode:true.

Now on the first show the slides move from initial position to centered position with an animation:

image
image
image

The idea of this enhancement is make the first show of center mode in correct position or/and without transition move instead on initial position with transition move.

Perhaps, remove the transition on beginning, or hide elements before complete position.

Hooper isn't working fine when images are async

Describe the bug
I am retrieving the images I want to add to Hooper from Google Storage. It turns out that Hooper won't display correctly these images that are obtained later.

To Reproduce
Code to reproduce the behavior:

<hooper ref="gallery" :items-to-show="images.length" :center-mode="false" 
:infinite-scroll="true" class="property__slider property__slider__thumbs">

 <slide v-for="(image, i) in images" :key="i">

    <span class="property__fund__image__span">
       <img class="img-fluid property__fund__image" :src="image" alt="Fund pic" @click="slideTo(i)"/>
    </span>

 </slide>

</hooper>

Where images comes from props and it is the array of strings to the url of the imgs.

Expected behavior
Hooper should render a slide per downloaded image and it doesn't.

Option to customize hooper css classes

Is your feature request related to a problem? Please describe.
It will be nice if we can customize the hooper css classes.

Describe the solution you'd like
A new prop to customize the css classes.

Add ability to redraw width of hooper-slide

Is your feature request related to a problem? Please describe.
I have a slideshow for a product. The product can show itself as a list layout or grid. This changed the height/width of the slideshow. When I switch between the two different layouts I change the container classes but I'm unable to tell hooper to update its hooper-slide widths.

Describe the solution you'd like
Add the ability to have hooper-slide recalc its width.

Describe alternatives you've considered
Currently I'm using a v-if/setTimeout hack to force the layout update.

Following simple examples creates multiple slides

Looking into testing the basic slide example on chrome and not sure if i'm missing something or it's broken. I am using multiple slides from the sample, but they just stack on top of each other, and they do not show up in a seperate view like the examples.

Any ideas?

<hooper ref="carousal" @slide="updateCarousel"> <slide> <h1>Collaborate. License Your Music. Get Discovered.</h1> <p>Welcome to a new, better music company.</p> <button class="">Get Started</button> </slide> <slide> <h1>Collaborate. License Your Music. Get Discovered.</h1> <p>Welcome to a new, better music company.</p> <button class="">Get Started</button> </slide> </hooper>

`<script>
import { Hooper, Slide, Progress as HooperProgress, Navigation as HooperNavigation } from 'hooper'

export default {
name: 'home',
components: {
Hooper,
Slide,
HooperProgress,
HooperNavigation
},
data () {
return {
carousalData: 0,
hooperSettings: {
itemsToShow: 1,
centerMode: true,
progress: true,
playSpeed: 2000,
autoplay: true
}
}
},
watch: {
carousalData () {
this.$refs.carousal.slideTo(this.carousalData)
}
},
methods: {
slidePrev () {
this.$refs.carousal.slidePrev()
},
slideNext () {
this.$refs.carousal.slideNext()
},
updateCarousel (payload) {
this.myCarousalData = payload.currentSlide
}
}
}
</script>`

Thanks in advance and thank you for the great component!

Breakpoints don't work as expected

Describe the bug
If we provide a breakpoints option and the viewport changes, the updateConfig method is called. In this method the breakpoints are sorted - in ascending order by default. This causes an issue since the smallest breakpoint will be used, regardless of a larger one existing - due to the way the breakpoints are matched with min-width.

To Reproduce
Steps to reproduce the behavior:
Provide different configs for different breakpoints.

hooperSettings = {
  // mobile
  itemsToShow: 1,
  breakpoints: {
    576: { 
      // tablet
      itemsToShow: 2
    },
    992: { 
      // laptop/desktop
      itemsToShow: 4
    }      
  }
}

Expected behavior
I would expect to see 4 items on large screens, 2 items on medium screens (tablets), and 1 item on small screens.

Screenshots
N/A

Desktop (please complete the following information):

  • OS: macOS
  • Browser: firefox
  • Version: N/A

Smartphone (please complete the following information):
N/A

Additional context
Add any other context about the problem here.

The issue is inside the updateConfig method:

hooper/src/Hooper.vue

Lines 329 to 347 in dd66a5e

updateConfig () {
const breakpoints = Object.keys(this.breakpoints).sort();
let matched;
breakpoints.some(breakpoint => {
matched = window.matchMedia(`(min-width: ${breakpoint}px)`).matches
if (matched) {
this.config = Object.assign(
{},
this.config,
this.defaults,
this.breakpoints[breakpoint]
);
return true;
}
});
if (!matched) {
this.config = Object.assign(this.config, this.defaults);
}
},

If I chain on a .reverse() after the sort - it works as expected.

I believe the best / most efficient solution would be to drop the sort all-together, and let the user order their breakpoints. Another option would be to change the sort call to sort((a,b) => b-a) to sort in a descending order.

Control which first slide to show

Thank you for a nice slider.
Is there a way to control which first slide to show?
It will be great to have some prop, like :firstSlide="3"

How to display half of previous slide

Describe the bug
This is not a bug itself, in the docs we can see how to show half of the next slide by setting itemsToShow prop to 1.25 for example. But I want to know how can I show half of the previous slide after scrolling the first one.

I want to achieve the following effect, taking a slider with 4 slides:

  • First slide: Half of the second slide is shown.
  • Second and Third slide: Half of the previous and half of next slide is shown.
  • Last slide: Only half of the previous slide is shown.

Screenshots
image

Every slide item has same class **hooper-slide is-active is-current**

Describe the bug
Every slide item has same class hooper-slide is-active is-current

To Reproduce

<slide v-for="(element, indx) in contentSection" :key="indx">
slide content
</slide>

Screenshots
http://prntscr.com/ng75zw

Desktop:

  • OS: Windows
  • Browser: Chrome
  • Version 73.0.3683.103

Additional context
Full code

<template>
<hooper :settings="hooperSettings" ref="hooper">
  <slide v-for="(element, indx) in contentSection" :key="indx">
       {{element.content}}
  </slide>
  <hooper-navigation slot="hooper-addons">
    <button slot="hooper-next">
      <i class="far fa-chevron-right"></i>
     </button>
     <button slot="hooper-prev">
        <i class="far fa-chevron-left"></i>
      </button>
    </hooper-navigation>
</hooper>
</template>
export default {
  data () {
    return {
      hooperSettings: {
        wheelControl: false,
        mouseDrag: false,
        transition: 600,
        centerMode: true
      }
    }
  },
  components: {
    Hooper,
    Slide,
    HooperNavigation
  }
}

Bug with timer

Thanks for component, great work.
Found a small bug. After destruction of slider timer continue working.
this.$refs.slider.timer.stop(); fixes problem.

Infinite Scroll slider was not correct when changed a language with vue-i18n plugin.

Firstly, thanks for the slider, it is very good.

Describe the bug

Recently I use the hooper width the vue-i18n plugin, and I make the slider setting width the settings prop, see bellow:

{
      infiniteScroll: true,
      autoPlay: true,
      playSpeed: 3000,
      wheelControl: false,
}

When change the language, the clone item was lost. see the example (codepen)

To Reproduce
Steps to reproduce the behavior:

  1. Set infiniteScroll=true
  2. Change the language

the items of Infinite Scroll slider were disappeared.

Expected behavior
Only change a component local language, the slider should be normal.

Screenshots
see the example (codepen)

Desktop (please complete the following information):

Smartphone (please complete the following information):

Additional context

import { Hooper, Slide } from 'hooper'; will make an error

When I want to import this import { Hooper, Slide } from 'hooper';

The vue cli will show this erorr:

error in ./~/hooper/dist/hooper.esm.js

Module parse failed: D:\node\my-project\node_modules\hooper\dist\hooper.esm.js Unexpected token (336:23)
You may need an appropriate loader to handle this file type.
| initDefaults () {
| this.breakpoints = this.settings.breakpoints;
| this.defaults = {...this.$props, ...this.settings};
| this.$settings = this.defaults;
| },

@ .//babel-loader/lib!.//vue-loader/lib/selector.js?type=script&index=0!./src/components/Plan_a_trip_en.vue 156:0-39
@ ./src/components/Plan_a_trip_en.vue
@ ./src/router/index.js
@ ./src/main.js
@ multi ./build/dev-client ./src/main.js

Can somebody help me please

Sync not working

Im trying to sync to sliders but its not working and in the console this message is show
Hooper: expects an element with attribute ref="myCarousel2", but found none.

<hooper sync="myCarousel2" ref="carousel" @slide="updateCarousel"> <slide> slide 1 </slide> <slide> slide 2 </slide> </hooper> <hooper ref="myCarousel2" :itemsToShow="3" :centerMode="true"> <slide> slide 1 </slide> <slide> slide 2 </slide> </hooper>

That's my code, any help please?

Allow setting title of arrow icons in Navigation.vue

Is your feature request related to a problem? Please describe.
Not really a problem, but the website I'm building is in spanish, and the title of the generated svgs for navigation are "Arrow Left" and "Arrow right", which are not really convenient for me.

Describe the solution you'd like
Well, of course the best solution for this would be internalization, but seeing that is very ambicious, I'd be happy passing a prop or something like that to the navigation component indicating the title the arrows should have.

Describe alternatives you've considered
I guess I could create my own component and use that instead, but it seems like it would be better to simply implement this upstream. I'm sure other people could benefit from it

Additional context
Nothing really, I'm just building a website that needs a carousel and is in spanish.

Custom Controllers Cannot read property 'currentSlide' of undefined"

I use Custom Controllers from your documentation
It's all work, but in debugger I see error
Error in nextTick: "TypeError: Cannot read property 'currentSlide' of undefined"
I guess it's about
updateCarousel(payload) {
this.myCarousalData = payload.currentSlide;
}
I can't find where is currentSlide in code.
I try to get payload updateCarouse but get undefined

Old hooper.esm.js in npm?

updated: function updated() {
    console.log(this.slides);
    this.slides = this.$slots.default.filter(function (e) {
      return e.componentOptions;
    });
    console.log(this.slides);
  },

Some strange console.logs and overall showing only tip of the last slide in the far right side

carry hooper-navigation out of hooper carousel

I need put ouside buttons navigations, but css overflow: hidden; hidden buttons if set negative positions for them. So, how can add paddings for hooper-track or bring navigations buttons outside of main container carousel like this
image

Console.log is shown when using slider

Describe the bug
Console.log is shown when using slider

To Reproduce

  1. Go to 'node_modules > hooper > dist'
  2. Click on 'hooper_esm.js'
  3. Scroll down to 'updateSlidesStatus(index)'
  4. See 'console.log(lower, upper);'

Expected behavior
I hope to remove this code

Screenshots
image

Macbook Pro 15-inch:

  • OS: Mojave 10.14.3
  • Browser chrome
  • Version

Nuxtjs

Sorry my english!

Please, would you like to add compatibility with nuxtjs ssr?
I know it works if you use

Slide looses "index" prop value

Describe the bug
Slide looses "index" prop value after adding or removing slides.

To Reproduce
https://codesandbox.io/s/644pkk7y0z

After changing the number os slides, the slides loose their index, making the is-active and is-current classes not being properly set.
Basically, this setter stops working (https://github.com/baianat/hooper/blob/master/src/Hooper.vue#L285), leaving the index with the default value of 0

Expected behavior
It would be expected for the slider to get the current index so that the classes is-active and is-current get correctly applied

removeEventListener('transitionend', temp);

So, I have a nuxt app, and if I change pages fast enough I can sometimes get
Cannot read property 'removeEventListener' of undefined on line
_this.$refs.track.removeEventListener('transitionend', temp);

Documentation error

Describe the bug
Please change the documentation wheel Control Default to true instead false

Code :
wheelControl: {
default: true,
type: Boolean
}

in the document:
default is false

Sync not working inside vuetify VCard

Describe the bug
If hooper put inside vuetify VCard it cant resolve ref and so sync not working

To Reproduce
Steps to reproduce the behavior:
https://codesandbox.io/s/m5v6zpvyjy
Hooper: expects an element with attribute ref="hooper2", but found none.

Expected behavior
Sync working

Work fine if put outside of VCard element

Init happens in mounted,

https://github.com/baianat/hooper/blob/master/src/Hooper.vue#L467

but Note that mounted does not guarantee that all child components have also been mounted.

https://vuejs.org/v2/api/#mounted

So then refs got undefined in init because its not in nextTick

Error when used in production with Nuxt.js

Describe the bug
I'm working with Nuxt.

package.json version: "nuxt": "^2.0.0"

In development mode it's working fine. It's configured with 3 items and navigation arrows visible with some breakpoints, all good.
But when I make the build (npm run generate or npm run start) for production the website crashes and slider is not working anymore.

Slider is not working and it's showing 2 only because the javascript error. Images are missing, and slider items width/height is wrong. Navigation arrows are broken too.

Error message:

Uncaught (in promise) TypeError: Cannot assign to read only property 'message' of object ''
    at 94653d717eea14401790.js:1 

To Reproduce
Steps to reproduce the behavior:

  1. npm run generate with nuxt
  2. Open generated page in /dist
  3. See error

Expected behavior
Render the slider fully functional with 3 images by default and the navigation arrows working.

Screenshots

image

Desktop (please complete the following information):

  • Node: Tested with v8, v10 and v11
  • OS: OSX
  • Browser: Chrome
  • Version: 72.0.3626.109 (Build oficial) (64 bits)

Additional context
Add any other context about the problem here.

Style different for item of middle

I'm trying to use the @slideAfter method to capture the items with the isActive class and put a different style in the middle item, for example, whenever three itemsToShow: 3 ​​slides are displayed, the middle item gets bigger than the others

class active in the middle item

slide-item-middle

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.