Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] 🚧 v3 #20

Draft
wants to merge 37 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
bfadc98
Remove support for IE
tannerhodges Sep 25, 2021
f439d09
Update all npm dependencies (and remove ones we don't need anymore)
tannerhodges Sep 25, 2021
3a7acc5
Upgrade Webpack
tannerhodges Sep 25, 2021
2be3317
Temporarily trash extra library versions so it's easier to focus duri…
tannerhodges Sep 25, 2021
1656c17
Remove legacy grid support
tannerhodges Sep 25, 2021
b240f77
Just use source files in demo
tannerhodges Sep 25, 2021
4fb866b
Remove polyfills
tannerhodges Sep 25, 2021
98bccec
Deprecate data-snap-slider-align
tannerhodges Sep 25, 2021
bd26422
Fix script path in test files
tannerhodges Sep 25, 2021
709dd01
Upgrade to ES 2020
tannerhodges Sep 25, 2021
a9f01ad
Remove unnecessary dependencies
tannerhodges Sep 25, 2021
8180677
Begin rewrite...
tannerhodges Sep 25, 2021
55f82aa
Start adding back JS options
tannerhodges Sep 25, 2021
69af918
Add JS option to initialize navs
tannerhodges Oct 2, 2021
59f17f5
npm updates
tannerhodges Oct 12, 2021
8ef81e5
Progress on JS options
tannerhodges Oct 12, 2021
ea0468e
Add JS loop option
tannerhodges Oct 12, 2021
3b4011d
Hide scrollbars
tannerhodges Oct 20, 2021
1b9c5c9
Progress on JS options
tannerhodges Oct 20, 2021
84c60a3
Update goto button tests
tannerhodges Oct 20, 2021
50d4f43
Speed up goto test
tannerhodges Oct 20, 2021
4c36d99
Update return types
tannerhodges Oct 22, 2021
32e7b2d
Fix change events firing on load; Add ignoreCallbacks option
tannerhodges Oct 22, 2021
51d7939
Handle resize events
tannerhodges Oct 22, 2021
bdf451f
Fix centered sliders
tannerhodges Oct 22, 2021
470625d
Fix data-snap-slider-buttons override options (and make prev/next opt…
tannerhodges Oct 22, 2021
3d89c2f
Swap current/visible colors for better UX
tannerhodges Oct 22, 2021
c2c9cbe
Add back build versions
tannerhodges Oct 22, 2021
06c2e0d
npm run build
tannerhodges Oct 22, 2021
dc17192
3.0.0-alpha.0
tannerhodges Oct 22, 2021
a0d2760
Upgrade to HTTPS npm registry
tannerhodges Oct 22, 2021
56f9905
3.0.0-alpha.1
tannerhodges Oct 22, 2021
4ca9788
Use ResizeObserver to handle slider resize events instead of window.r…
tannerhodges Oct 25, 2021
c64b5f6
npm run build
tannerhodges Oct 25, 2021
90d889b
3.0.0-alpha.2
tannerhodges Oct 25, 2021
4fda071
Merge branch 'main' into v3
tannerhodges Oct 27, 2021
51dad4f
Ignore Cypress screenshots
tannerhodges Oct 27, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .browserlistrc
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
defaults
ie 11
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Dropping IE support.

3 changes: 3 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
"browser": true,
"es6": true
},
"parserOptions": {
"ecmaVersion": 2020
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Upgrading to ES2020.

},
"rules": {
"class-methods-use-this": "off",
"no-console": "off",
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ report.html

# Cypress
cypress/videos/
cypress/screenshots/
1 change: 0 additions & 1 deletion cypress.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
{
"baseUrl": "http://localhost:8080",
"firefoxGcInterval": null,
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Removing deprecated Cypress options.

"video": false,
"viewportHeight": 660,
"viewportWidth": 1000
Expand Down
4 changes: 2 additions & 2 deletions cypress/integration/events.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ describe('Events', () => {
cy.getSlider('test').then(() => expect(fn).to.not.be.called);

// Scroll to trigger a change, then confirm the callback fired.
// NOTE: Need extra `.wait()` so `expect` happens after the callback.
// NOTE: Need extra `.wait()` so `expect` happens after the callback has debounced.
// eslint-disable-next-line cypress/no-unnecessary-waiting
cy.getSlider('test').scrollTo('right')
.wait(0)
.wait(350)
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Intersection Observer change callbacks are debounced by 300ms, so need to wait at least that long for events to fire.

.then(() => expect(fn).to.be.calledOnce);
});

Expand Down
7 changes: 5 additions & 2 deletions cypress/integration/goto-buttons.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ describe('Goto Buttons', () => {
.should('equal', 'next');
});

it('checks classes for prev/next terms if the button content is empty', () => {
// TODO: Class matching. Or remove???
xit('checks classes for prev/next terms if the button content is empty', () => {
cy.get('#prev-terms-class button')
.invoke('attr', 'data-snap-slider-goto')
.should('equal', 'prev');
Expand Down Expand Up @@ -91,7 +92,9 @@ describe('Goto Buttons', () => {
describe('Classes', () => {
it('adds a current class to numeric buttons when their slide is current', () => {
// Slide to the 3rd item.
cy.getSlider('test').children(':nth-child(3)').scrollIntoView();
// NOTE: Add `duration` so Intersection Observer fires.
// @see https://github.com/cypress-io/cypress/issues/3848#issuecomment-478132607
cy.getSlider('test').children(':nth-child(3)').scrollIntoView({ duration: 100 });
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❓ Is this duration still necessary? Or can we simply scroll and still get the same result?


// Current buttons should have the class.
cy.get('#standard [data-snap-slider-goto*="3"]')
Expand Down
43 changes: 4 additions & 39 deletions cypress/integration/html-api.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,45 +43,6 @@ describe('HTML API', () => {
});
});

it('`[data-snap-slider-align]` specifies the CSS align value for older browsers', () => {
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Removing data-snap-slider-align as it was only used for fallbacks in IE.

// Confirm slider start position, then go to the middle slide.
cy.getSlider('align').then(($el) => {
const slider = $el.get(0).SnapSlider;

expect(slider.container.scrollLeft).to.equal(0);

slider.goto('middle');
});

// Confirm slider position.
cy.getSlider('align').invoke('scrollLeft').should('equal', 152);
});

it('`[data-snap-slider-align]` is empty by default', () => {
cy.getSlider('align-default').then(($el) => {
const slider = $el.get(0).SnapSlider;

expect(slider.container.getAttribute('data-snap-slider-align')).to.equal('');
});
});

it('`[data-snap-slider-align]` only applies when CSS Scroll Snap is not supported', () => {
// Confirm slider start position, then go to the middle slide.
cy.getSlider('align-fallback').then(($el) => {
const slider = $el.get(0).SnapSlider;

expect(slider.container.scrollLeft).to.equal(0);

slider.goto('middle');
});

// Confirm slider position.
// NOTE: This test needs to be manually checked in Safari.
// Currently, Chrome snaps on JS scroll but Safari does not.
// Safari stays wherever JS scrolled it instead of snapping.
cy.getSlider('align').invoke('scrollLeft').should('equal', 0);
});

it('`[data-snap-slider-nav]` inits nav elements', () => {
// We know the nav loaded correctly if all its buttons
// have `[data-snap-slider-goto]` attributes.
Expand Down Expand Up @@ -141,6 +102,10 @@ describe('HTML API', () => {
.should('not.have.attr', 'data-snap-slider-goto');
});

// TODO: Prev/next buttons.
// data-snap-slider-prev
// data-snap-slider-next

it('`[data-snap-slider-goto="<SLIDE>"]` inits goto buttons in a container or nav element', () => {
// Make sure slider hasn't scrolled yet.
cy.getSlider('goto-buttons').invoke('scrollLeft').should('equal', 0);
Expand Down
112 changes: 49 additions & 63 deletions cypress/integration/js-api.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,22 +152,6 @@ describe('JS API', () => {
});
});

it('can specify the fallback alignment for older browsers', () => {
// Init the slider, but specify which elements should be considered slides.
cy.initSlider('.example', {
id: 'test',
align: 'end',
});

// Make sure the real slides are tracked, but not the non-slide element.
cy.getSlider('test').then(($el) => {
const slider = $el.get(0).SnapSlider;
const align = slider.container.getAttribute('data-snap-slider-align');

expect(align).to.equal('end');
});
});

it('inits nav elements', () => {
cy.initSlider('.example', {
id: 'test',
Expand Down Expand Up @@ -377,7 +361,8 @@ describe('JS API', () => {
});
});

it('`goto()` can force-update the current slide', () => {
// TODO: Does anyone actually use the `force` option? Seems unnecessary.
xit('`goto()` can force-update the current slide', () => {
cy.getSlider('test').then(($el) => {
// Setup a callback to test whether the force-update works.
const slider = $el.get(0).SnapSlider;
Expand Down Expand Up @@ -409,7 +394,8 @@ describe('JS API', () => {
});
});

it('`goto()` can ignore callbacks', () => {
// TODO: Should we still be able to ignore callbacks?
xit('`goto()` can ignore callbacks', () => {
cy.getSlider('test').then(($el) => {
// Setup a callback.
const slider = $el.get(0).SnapSlider;
Expand Down Expand Up @@ -458,7 +444,9 @@ describe('JS API', () => {
.should('include', '1');
});

it('`addGotoButtons()` can also take options as the first argument', () => {
// TODO: Is this still a good design decision?
// Feels like it would be simpler to handle prev/next separately.
xit('`addGotoButtons()` can also take options as the first argument', () => {
// Wait until slider has loaded.
cy.getSlider('test');

Expand Down Expand Up @@ -488,7 +476,8 @@ describe('JS API', () => {
.should('include', 'next');
});

it('`getButtons()` returns all the buttons currently targeting this slider', () => {
// TODO: Update `addGotoButtons()` to set slider ID when button is not already part of a nav.
xit('`getButtons()` returns all the buttons currently targeting this slider', () => {
let buttons = [];

// Get buttons so we can check for them later.
Expand Down Expand Up @@ -528,7 +517,8 @@ describe('JS API', () => {
.should('have.attr', 'data-snap-slider-goto');
});

it('`addNav()` also accepts options', () => {
// TODO: Nav options!
xit('`addNav()` also accepts options', () => {
// Init all nav elements.
cy.getSlider('test').then(($el) => {
const slider = $el.get(0).SnapSlider;
Expand All @@ -548,6 +538,7 @@ describe('JS API', () => {
.should('not.have.attr', 'data-snap-slider-goto');
});

// TODO: Deprecate in favor of `this.navs`.
it('`getNavs()` returns all the navs currently targeting this slider', () => {
let navs = [];

Expand All @@ -564,14 +555,15 @@ describe('JS API', () => {
expect(slider.getNavs()).to.be.empty;

// Add the navs.
slider.addNav('.example-nav');
slider.addNavs('.example-nav');

// Confirm we get back the real navs.
expect(slider.getNavs()).to.deep.equal(navs);
});
});

it('`update()` re-scrolls to the current slide', () => {
// TODO: Ignore callbacks!
xit('`update()` re-scrolls to the current slide', () => {
cy.getSlider('test').then(($el) => {
const slider = $el.get(0).SnapSlider;
const callback = cy.spy();
Expand All @@ -591,66 +583,60 @@ describe('JS API', () => {
});
});

// TODO: Make sure destroy kills all callbacks and listeners.
it('`destroy()` stops transitions, removes event listeners, and deletes slider references', () => {
let slider;
let slides;
const scrollListener = cy.spy();
const scrollEndListener = cy.spy();
const arrowKeyListener = cy.spy();
const focusListener = cy.spy();
// let slides;
// const arrowKeyListener = cy.spy();
// const focusListener = cy.spy();

cy.getSlider('test').then(($el) => {
slider = $el.get(0).SnapSlider;
slides = slider.slides;
// slides = slider.slides;

// Spy on each event listener's callbacks to test whether they've been removed.
slider.on('scroll', scrollListener);
slider.on('scroll.end', scrollEndListener);
slider.on('change.keydown', arrowKeyListener);
slider.on('change.focusin', focusListener);
// // Spy on each event listener's callbacks to test whether they've been removed.
// // TODO: Should we still listen for arrow keys and focus events?
// slider.on('change.keydown', arrowKeyListener);
// slider.on('change.focusin', focusListener);

// Make sure to stop transitions and observers.
slider.stopTransition = cy.stub();
// Make sure to stop current debounce and observers.
slider.maybeSetCurrentDebounce.cancel = cy.stub();
slider.intersectionObserver.disconnect = cy.stub();
slider.resizeObserver.disconnect = cy.stub();

// Trigger focus and arrow key to fire every event listener.
slides[1].focus();
slider.container.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight' }));
// // Trigger focus and arrow key to fire every event listener.
// slides[1].focus();
// slider.container.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight' }));
});

// Wait so `expect` happens after the callback.
// eslint-disable-next-line cypress/no-unnecessary-waiting
cy.getSlider('test').wait(1000).then(() => {
expect(scrollListener).to.be.called;
expect(scrollEndListener).to.be.called;
expect(arrowKeyListener).to.be.called;
expect(focusListener).to.be.called;
// expect(arrowKeyListener).to.be.called;
// expect(focusListener).to.be.called;

// Now reset and try again!
scrollListener.resetHistory();
scrollEndListener.resetHistory();
arrowKeyListener.resetHistory();
focusListener.resetHistory();
// // Now reset and try again!
// arrowKeyListener.resetHistory();
// focusListener.resetHistory();

// Kill it.
slider.destroy();

// Did we stop transitions and observers?
expect(slider.stopTransition).to.be.called;
// Did we stop current debounce and observers?
expect(slider.maybeSetCurrentDebounce.cancel).to.be.called;
expect(slider.intersectionObserver.disconnect).to.be.called;
expect(slider.resizeObserver.disconnect).to.be.called;

// Trigger focus and arrow key to fire every event listener.
slides[1].focus();
slider.container.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight' }));
// // Trigger focus and arrow key to fire every event listener.
// slides[1].focus();
// slider.container.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight' }));
});

// Wait so `expect` happens after the callback.
// eslint-disable-next-line cypress/no-unnecessary-waiting
cy.getSlider('test').wait(1000).then(() => {
expect(scrollListener).to.not.be.called;
expect(scrollEndListener).to.not.be.called;
expect(arrowKeyListener).to.not.be.called;
expect(focusListener).to.not.be.called;
// expect(arrowKeyListener).to.not.be.called;
// expect(focusListener).to.not.be.called;
});

// Last but not least, make sure we can't find any references to this slider anymore.
Expand All @@ -668,10 +654,12 @@ describe('JS API', () => {
it('`reset()` re-initializes a slider', () => {
cy.getSlider('test').then(($el) => {
const slider = $el.get(0).SnapSlider;
const destroy = cy.spy(slider, 'destroy');
const init = cy.spy(slider, 'init');

slider.reset();

expect(destroy).to.be.called;
expect(init).to.be.called;
});
});
Expand Down Expand Up @@ -719,17 +707,15 @@ describe('JS API', () => {
});
});

it('`reset()` can not change container or slider ID', () => {
it('`reset()` can not change slider ID', () => {
cy.getSlider('test').then(($el) => {
const slider = $el.get(0).SnapSlider;
const { container, id } = slider;
const { id } = slider;

slider.reset({
container: '#navigation',
id: 'fake',
});

expect(slider.container).to.equal(container);
expect(slider.id).to.equal(id);
});
});
Expand Down Expand Up @@ -785,7 +771,7 @@ describe('JS API', () => {
cy.initSlider('.example', { id: 'test' });
});

it('`getButtonTarget()` returns the slider ID and index for a goto button', () => {
xit('`getButtonTarget()` returns the slider ID and index for a goto button', () => {
// Init nav and external goto buttons.
cy.getSlider('test').then(($el) => {
const slider = $el.get(0).SnapSlider;
Expand All @@ -810,7 +796,7 @@ describe('JS API', () => {
});
});

it('`debug()` prints slider information for different elements', () => {
xit('`debug()` prints slider information for different elements', () => {
cy.getSlider('test').then(($el) => {
const { any } = Cypress.sinon.match;
const slider = $el.get(0).SnapSlider;
Expand Down
6 changes: 3 additions & 3 deletions cypress/integration/scroll-offset.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ describe('Scroll Offset', () => {

// Confirm slider position.
cy.getSlider('vertical-example').invoke('scrollLeft').should('equal', 0);
cy.getSlider('vertical-example').invoke('scrollTop').should('equal', 320);
cy.getSlider('vertical-example').invoke('scrollTop').should('equal', 288);
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Updating scroll positions to match design changes.

});

it('works with 2D sliders', () => {
Expand All @@ -25,14 +25,14 @@ describe('Scroll Offset', () => {
const slider = $el.get(0).SnapSlider;

expect(slider.container.scrollLeft).to.equal(320);
expect(slider.container.scrollTop).to.equal(240);
expect(slider.container.scrollTop).to.equal(224);

slider.goto('last');
});

// Confirm slider position.
cy.getSlider('2d-example').invoke('scrollLeft').should('equal', 640);
cy.getSlider('2d-example').invoke('scrollTop').should('equal', 480);
cy.getSlider('2d-example').invoke('scrollTop').should('equal', 448);
});

it('works with nested sliders', () => {
Expand Down
Loading