diff --git a/demo/components/demos/responsive/variable-width-with-arrows.vue b/demo/components/demos/responsive/variable-width-with-arrows.vue
new file mode 100644
index 0000000..6c30aa8
--- /dev/null
+++ b/demo/components/demos/responsive/variable-width-with-arrows.vue
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/content/responsive.md b/demo/content/responsive.md
index 2b6c8d1..140f2a4 100644
--- a/demo/content/responsive.md
+++ b/demo/content/responsive.md
@@ -70,7 +70,10 @@ While it's not the primary use case of this package, you if you set `slidesPerPa
- If there are not enough slides to fill the viewport, slides will be left aligned rather than center aligned.
- This hasn't been tested with responsive props or looping. Peeking doesn't make sense for this use case but care hasn't been taken to disabling it.
-- Pagination controls aren't supported yet, this is purely drag only.
+- Pagination controls are in beta
+ - Pagination is done on a per slide basis
+ - Looping still has not been implemented
+ - Slides are left aligned
@@ -82,6 +85,24 @@ While it's not the primary use case of this package, you if you set `slidesPerPa
```
+Carousel with variable width and arrows:
+
+
+
+```vue
+
+
+
+
+
+
+
+
+
+
+
+```
+
Here's an example where there aren't enough slides to exceed the carouel width:
diff --git a/src/concerns/dimensions.coffee b/src/concerns/dimensions.coffee
index 3258b42..b06713c 100644
--- a/src/concerns/dimensions.coffee
+++ b/src/concerns/dimensions.coffee
@@ -80,7 +80,7 @@ export default
@carouselWidth = @$el.getBoundingClientRect().width + @gutterWidth
@viewportWidth = window.innerWidth
@capturePeekingMeasurements()
- @captureTrackWidth() if @isVariableWidth
+ @captureCarouselDims() if @isVariableWidth
# Make the width style that gives a slide it's width given
# slidesPerPage. Reduce this width by the gutter if present
@@ -114,3 +114,10 @@ export default
(#{@autoUnit(peekLeft)} + #{@autoUnit(peekRight)}) / #{slidesPerPage} -
(#{@autoUnit(gutter)} * #{slidesPerPage - 1}) / #{slidesPerPage}
)"
+
+
+ # Get the target X scroll position of a given slide
+ targetXOfIdx: (idx) ->
+ if @isVariableWidth
+ then @measuredSlidesWidths[idx].targetXScroll
+ else @pageWidth / @currentSlidesPerPage
diff --git a/src/concerns/dragging.coffee b/src/concerns/dragging.coffee
index 67614d7..4ebd3bb 100644
--- a/src/concerns/dragging.coffee
+++ b/src/concerns/dragging.coffee
@@ -73,6 +73,8 @@ export default
fractionalIndex: ->
return 0 unless @trackWidth
+ if @isVariableWidth then return @fractionalIndexFromMeasurements
+
# Work in positive numbers
x = @currentX * -1
@@ -104,6 +106,16 @@ export default
# Return the final value by adding all the passed index values
return pageProgressPercent + setIndex * @pages + pageIndex
+ fractionalIndexFromMeasurements: ->
+ # Work in positive numbers
+ x = @currentX * -1
+
+ slideIdx = @measuredSlidesWidths.findIndex((measuredSlide) => measuredSlide.targetXScroll > x) - 1
+
+ percentage = (x - @measuredSlidesWidths[slideIdx].targetXScroll) / @measuredSlidesWidths[slideIdx].width
+
+ return slideIdx + percentage
+
# Determine if the user is dragging vertically
isVerticalDrag: ->
return unless @dragDirectionRatio
@@ -141,7 +153,7 @@ export default
else @gotoEnd()
# If rendering variable width slides, don't come to a rest at an index
- else if @isVariableWidth then @tweenToStop()
+ else if @isVariableWidth then @goto @dragIndex
# If user was vertically dragging, reset the index
else if @isVerticalDrag then @goto @index
diff --git a/src/concerns/pagination.coffee b/src/concerns/pagination.coffee
index 5b2d268..fe86a10 100644
--- a/src/concerns/pagination.coffee
+++ b/src/concerns/pagination.coffee
@@ -22,6 +22,8 @@ export default
# The current number of pages
pages: -> switch
+ # When variable width, pages is slide count
+ when @isVariableWidth then @slidesCount
# When looping and paginating per slide, make a dot per slide
when @paginateBySlide and @shouldLoop then @slidesCount
@@ -146,9 +148,10 @@ export default
getXForIndex: (index) ->
# Figure out the new x position
- x = if @paginateBySlide
- then index * @slideWidth * -1
- else index * @pageWidth * -1
+ x = switch
+ when @isVariableWidth then @targetXOfIdx(@applyIndexBoundaries(index)) * -1
+ when @paginateBySlide then index * @slideWidth * -1
+ else index * @pageWidth * -1
# Apply adjustments to x value and persist
x += @makeIncompletePageOffset index
diff --git a/src/concerns/variable-width.coffee b/src/concerns/variable-width.coffee
index 011f741..971031c 100644
--- a/src/concerns/variable-width.coffee
+++ b/src/concerns/variable-width.coffee
@@ -3,7 +3,9 @@ Functionality related to supporting variable width slides
###
export default
- data: -> measuredTrackWidth: 0
+ data: ->
+ measuredTrackWidth: 0
+ measuredSlidesWidths: []
computed:
@@ -11,8 +13,26 @@ export default
isVariableWidth: -> @slidesPerPage == null
methods:
+ # Capture all dimensions of carousel
+ captureCarouselDims: ->
+ @captureTrackWidth()
+ @captureSlideWidths()
# Measure the width of the track
captureTrackWidth: ->
return unless @$refs.track
@measuredTrackWidth = @$refs.track.$el.scrollWidth
+
+ # Capture slide dims and place them into an array of data
+ captureSlideWidths: ->
+ return unless @$refs.track
+ @measuredSlidesWidths = @$refs?.track?.$children.reduce((acc, child, idx, arr) =>
+ return [
+ ...acc
+ {
+ width: child.$el.clientWidth
+ targetXScroll: (acc[idx - 1]?.targetXScroll || 0) + (acc[idx - 1]?.width || 0) + @gutter * (idx > 0)
+ }
+ ]
+ , [] )
+