pull/380/head
Glen Cheney 2 years ago
parent 34b086274b
commit 8a4911e100

@ -1,13 +1,3 @@
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"browsers": "> 1%, not dead, not IE < 11, IE 11, not OperaMini all",
"node": "current"
}
}
]
]
"presets": [["@babel/preset-env"]]
}

@ -0,0 +1,4 @@
> 1%
not dead
not ie <= 11
not OperaMini all

@ -4,7 +4,6 @@ about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Shuffle version**
@ -18,6 +17,7 @@ A minimal JSBin, JSFiddle, Codepen, or a GitHub repository that can reproduce th
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
@ -30,15 +30,17 @@ A clear and concise description of what you expected to happen.
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

@ -4,7 +4,6 @@ about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**

@ -1,10 +1,10 @@
version: 2
updates:
- package-ecosystem: npm
directory: "/"
- package-ecosystem: npm
directory: '/'
schedule:
interval: weekly
time: "13:00"
time: '13:00'
open-pull-requests-limit: 10
ignore:
- dependency-name: cssnano

@ -0,0 +1,14 @@
node_modules
dist
coverage
docs/dist
docs/css
docs/_site
prism.js
prism.css
.jekyll-cache
# Prettier can't handle liquid templates AND changes the JSON attributes to use
# double quotes, breaking the parser.
*.html

@ -12,19 +12,19 @@ Without a reduced test case, your issue may be closed.
## Releasing a new version
* Update `changelog.html`.
* Run tests.
* Commit changes.
* `npm version major|minor|patch`.
* `npm publish`
* `git push && git push --tags`
* Create a [new release](https://github.com/Vestride/Shuffle/releases/new) on GitHub.
- Update `changelog.html`.
- Run tests.
- Commit changes.
- `npm version major|minor|patch`.
- `npm publish`
- `git push && git push --tags`
- Create a [new release](https://github.com/Vestride/Shuffle/releases/new) on GitHub.
## Running locally
This project uses [Jekyll](https://jekyllrb.com/).
* Head over to [their quickstart guide](https://jekyllrb.com/docs/quickstart/) to setup jekyll.
* Install npm dependencies `npm install`.
* Run `npm run watch` to rebuild, start the jekyll server, and watch for changes.
* go to `http://localhost:4000` to see it.
- Head over to [their quickstart guide](https://jekyllrb.com/docs/quickstart/) to setup jekyll.
- Install npm dependencies `npm install`.
- Run `npm run watch` to rebuild, start the jekyll server, and watch for changes.
- go to `http://localhost:4000` to see it.

984
dist/shuffle.js vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -3,8 +3,8 @@ destination: _site
plugins_dir: _plugins
layouts_dir: _layouts
data_dir: _data
include: ["dist"]
exclude: ["./_scss"]
include: ['dist']
exclude: ['./_scss']
permalink: /:title

@ -1,7 +1,6 @@
# Options in this file override ones set in _config.yml
host: 0.0.0.0
environment: "development"
environment: 'development'
url: http://localhost:4000
baseurl: ""
baseurl: ''

@ -8,7 +8,7 @@
* Create some DOM elements, append them to the shuffle container, then notify
* shuffle about the new items. You could also insert the HTML as a string.
*/
Demo.prototype.onAppendBoxes = function () {
onAppendBoxes() {
var elements = this._getArrayOfElementsToAdd();
elements.forEach(function (element) {

@ -13,12 +13,12 @@ shuffleInstance.filter(function (element) {
<h3>Searching</h3>
<div class="code-block">
<pre rel="JavaScript"><code class="language-javascript">// Advanced filtering
Demo.prototype.addSearchFilter = function () {
addSearchFilter() {
document.querySelector('.js-shuffle-search').addEventListener('keyup', this._handleSearchKeyup.bind(this));
};
// Filter the shuffle instance by items with a title that matches the search input.
Demo.prototype._handleSearchKeyup = function (evt) {
_handleSearchKeyup(evt) {
var searchText = evt.target.value.toLowerCase();
this.shuffle.filter(function (element, shuffle) {

@ -4,6 +4,7 @@
GitHub.
</p>
<ul>
<li><code>v6.0.0</code> 2022-02-01 - Drop IE 11, remove misspelled <code>delimeter</code> option, remove <code>matches-selector</code> package.</li>
<li>
<code>v5.4.1</code> 2021-05-29 - Add <code>sortedItems</code> property. Fix <code>getComputedStyle</code> bug for
Chrome on Windows.

@ -1,7 +1,6 @@
{% if page.requirejs %}
<script data-main="{{ site.baseurl }}/js/require-main.js" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.3/require.min.js"></script>
{% else %}
<script crossorigin="anonymous" src="https://polyfill.io/v3/polyfill.min.js?features=default%2Ces5%2Ces6%2Ces7"></script>
<!-- Syntax highlighting via Prism -->
<script src="{{ site.baseurl }}/js/prism.js"></script>
<!-- Shuffle! -->

@ -15,11 +15,11 @@
</div>
<div class="code-block">
<pre rel="JavaScript"><code class="language-javascript">Demo.prototype.addSorting = function () {
<pre rel="JavaScript"><code class="language-javascript">addSorting() {
document.querySelector('.sort-options').addEventListener('change', this._handleSortChange.bind(this));
};
Demo.prototype._handleSortChange = function (evt) {
_handleSortChange(evt) {
var value = evt.target.value;
function sortByDate(element) {

@ -10,7 +10,7 @@
</div>
</header>
{% endif %}
<main role="main" id="main">
<main id="main">
{{ content }}
</main>
{% include footer.html %}

@ -150,7 +150,7 @@ photoCredit: false
<h3>Adding elements</h3>
<p>Wherever you add the element in the DOM is where it will show up in the grid (assuming you&rsquo;re using the default sort-by-dom-order). With this in mind, you can append, prepend, or insert elements wherever you need to get them to show up in the right order.</p>
<div class="code-block">
<pre rel="JavaScript"><code class="language-javascript">Demo.prototype.setupEvents = function () {
<pre rel="JavaScript"><code class="language-javascript">setupEvents() {
document.querySelector('#append').addEventListener('click', this.onAppendBoxes.bind(this));
};
@ -158,7 +158,7 @@ photoCredit: false
* Create some DOM elements, append them to the shuffle container, then notify
* shuffle about the new items. You could also insert the HTML as a string.
*/
Demo.prototype.onAppendBoxes = function () {
onAppendBoxes() {
var elements = this._getArrayOfElementsToAdd();
elements.forEach(function (element) {

@ -4,7 +4,7 @@ title: Animate In Demo
description: When elements enter the viewport, they transition in from zero opacity and from the bottom.
image: /demos/animated.jpg
prism: true
externalJS: [ "https://unpkg.com/intersection-observer" ]
externalJS: []
extraJS: [ "demos/animate-in.js" ]
---
<div class="container">
@ -38,7 +38,7 @@ extraJS: [ "demos/animate-in.js" ]
<div class="col-12@sm">
<h2>About this demo</h2>
<p>This was inspired by <a href="http://tympanus.net/codrops/">codrops</a>&rsquo; demo <a href="http://tympanus.net/codrops/2013/07/02/loading-effects-for-grid-items-with-css-animations/">Loading effects for grid items with css animations</a>.</p>
<p><code>IntersectionObserver</code> is used to determine when the elements enter the viewport. <a href="https://github.com/WICG/IntersectionObserver/tree/gh-pages/polyfill">A polyfill</a> is included on the page for browsers which don't support it.</p>
<p><code>IntersectionObserver</code> is used to determine when the elements enter the viewport.</p>
</div>
<div class="col-12@sm">
<h2>Source code for this demo</h2>

@ -18,7 +18,7 @@
border-radius: 0 3px 3px 0;
}
label.btn input[type=radio] {
label.btn input[type='radio'] {
position: absolute;
clip: rect(0, 0, 0, 0);
pointer-events: none;
@ -27,14 +27,14 @@
.btn {
display: inline-block;
padding: .75em .8em;
padding: 0.75em 0.8em;
text-align: center;
border-radius: 3px;
border: 1px solid $gray20;
color: $gray20;
font-size: 1rem;
background-color: rgba($gray20, 0);
transition: .2s ease-out;
transition: 0.2s ease-out;
cursor: pointer;
-webkit-appearance: none;
@ -53,13 +53,13 @@
&.active,
&:active {
box-shadow: inset 0 1px 2px rgba(0,0,0,.3);
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
color: white;
background-color: $gray20;
}
&:focus.active {
box-shadow: inset 0 1px 2px rgba(0,0,0,.3), 0 0 0 2px rgba($gray20, 0.4);
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba($gray20, 0.4);
}
&:disabled {
@ -99,7 +99,7 @@ $btn-variants: (
}
&:focus.active {
box-shadow: inset 0 1px 2px rgba(0,0,0,.3), 0 0 0 2px rgba($color, 0.4);
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba($color, 0.4);
}
&:disabled {
@ -128,10 +128,10 @@ $btn-variants: (
left: 50%;
width: $size;
height: $size;
margin-left: -$size / 2;
margin-top: -$size / 2;
margin-left: -$size * 0.5;
margin-top: -$size * 0.5;
opacity: 0;
transition: .2s;
transition: 0.2s;
}
// Circle

@ -7,21 +7,20 @@
.demo-list .figure-wrap img {
// Promote to its own layer. makes filters look ok on retina with images
transform: translateZ(0);
transition: .1s ease;
transition: 0.1s ease;
}
.demo-list:hover .figure-wrap {
transform: scale3d( 1, 1, 1 );
transform: scale3d(1, 1, 1);
img {
filter: grayscale(1);
}
}
.demo-list:hover .figure-wrap:hover {
z-index: 2;
transform: scale3d( 1.05, 1.05, 1 );
transform: scale3d(1.05, 1.05, 1);
img {
filter: none;
@ -38,11 +37,10 @@
.demo-list .figure-wrap figcaption {
height: 2em;
margin-top: .5em;
margin-top: 0.5em;
margin-bottom: 1em;
}
.demo-link-container::before {
content: '';
display: inline-block;
@ -59,7 +57,6 @@ span.demo-link-container::before {
}
@media screen and (max-width: 47.9375em) {
.demo-list + .demo-list {
margin-top: 1em;
}

@ -1,4 +1,7 @@
.site-nav {
position: sticky;
top: 0;
z-index: 40;
padding: 10px 0;
border-bottom: 1px solid $gray90;
margin-bottom: 28px;
@ -37,7 +40,7 @@
}
.site-nav__logo rect {
transition: 180ms cubic-bezier(0.4, 0.0, 0.2, 1);
transition: 180ms cubic-bezier(0.4, 0, 0.2, 1);
}
.site-nav__link {
@ -51,7 +54,7 @@
.site-nav__dropdown {
position: absolute;
z-index: 2;
z-index: 50;
top: 40px;
right: 0;
opacity: 0;
@ -130,7 +133,7 @@
border-top: 6px solid currentColor;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
transition: transform 180ms cubic-bezier(0.4, 0.0, 0.2, 1);
transition: transform 180ms cubic-bezier(0.4, 0, 0.2, 1);
}
.site-nav__link--dropdown-active {
@ -302,7 +305,6 @@
}
.site-nav__dropdown--simple-links {
&::before {
right: 24px;
}

@ -1,3 +1,5 @@
@use 'sass:math';
$grid-gutter-width: 16px;
$grid-columns: 12;
$grid-container: 'container';
@ -8,34 +10,23 @@ $grid-ratio-name: 'aspect';
$grid-ratio-inner-name: 'aspect__inner';
$grid-container-padding: (
xs: 3.5%,
sm: 7%
sm: 7%,
);
$grid-max-width--desktop: 1200px;
$grid-ratios: (
(16, 9),
(9, 16),
(4, 3),
(3, 4),
(3, 2),
(3, 1),
(2, 3),
(2, 1),
(1, 2),
(1, 1)
);
$grid-ratios: ((16, 9), (9, 16), (4, 3), (3, 4), (3, 2), (3, 1), (2, 3), (2, 1), (1, 2), (1, 1));
// 7% => 0.07
$_grid-padding-pct: map-get($grid-container-padding, "sm") / 100%;
$_grid-padding-pct: math.div(map-get($grid-container-padding, 'sm'), 100%);
// 0.07 => 0.14 => 0.86
$_grid-padding-value: 1 - $_grid-padding-pct * 2;
// Size of the window when the grid row has hit max-width.
$_viewport-at-max-grid-width: $grid-max-width--desktop / $_grid-padding-value;
$_viewport-at-max-grid-width: math.div($grid-max-width--desktop, $_grid-padding-value);
$viewport-at-max-grid-width: round($_viewport-at-max-grid-width) + 0px;
$padding-at-max-grid-width: round($_viewport-at-max-grid-width * $_grid-padding-pct) + 0px;
@function get-column-selector($number, $breakpoint) {
@return ".#{$grid-prefix}-#{$number}\\@#{$breakpoint}";
@return '.#{$grid-prefix}-#{$number}\\@#{$breakpoint}';
}
@function get-grid-breakpoint-selectors($breakpoint) {
@ -56,7 +47,6 @@ $padding-at-max-grid-width: round($_viewport-at-max-grid-width * $_grid-padding-
@return $selectors;
}
@mixin make-grid-columns() {
$selectors: get-all-grid-breakpoint-selectors();
@ -66,12 +56,11 @@ $padding-at-max-grid-width: round($_viewport-at-max-grid-width * $_grid-padding-
// Prevent columns from collapsing when empty
min-height: 1px;
// Inner gutter via padding
padding-left: ($grid-gutter-width / 2);
padding-right: ($grid-gutter-width / 2);
padding-left: ($grid-gutter-width * 0.5);
padding-right: ($grid-gutter-width * 0.5);
}
}
@mixin float-grid-columns($breakpoint) {
$selectors: get-grid-breakpoint-selectors($breakpoint);
@ -80,21 +69,20 @@ $padding-at-max-grid-width: round($_viewport-at-max-grid-width * $_grid-padding-
}
}
@mixin grid-ratios($breakpoint: "") {
@mixin grid-ratios($breakpoint: '') {
// If there is a grid breakpoint class here, prepend a @.
// e.g. "@sm" or "" when there isn't a class.
@if $breakpoint != "" {
$breakpoint: "\\@" + $breakpoint;
@if $breakpoint != '' {
$breakpoint: '\\@'+ $breakpoint;
}
// Note @extend isn't used because it cannot be used within @media directives.
@each $list in $grid-ratios {
$top: nth($list, 1);
$bottom: nth($list, 2);
$name: "#{$top}x#{$bottom}";
$name: '#{$top}x#{$bottom}';
.#{$grid-ratio-name}--#{$name}#{$breakpoint} {
padding-bottom: percentage($bottom / $top);
padding-bottom: percentage(math.div($bottom, $top));
}
}
@ -109,34 +97,34 @@ $padding-at-max-grid-width: round($_viewport-at-max-grid-width * $_grid-padding-
}
@mixin calc-grid-column($index, $columns, $breakpoint, $type) {
@if ($type == "width") and ($index > 0) {
@if ($type == 'width') and ($index > 0) {
.#{$grid-prefix}-#{$index}\@#{$breakpoint} {
width: percentage(($index / $columns));
width: percentage(math.div($index, $columns));
}
}
@if ($type == "push") and ($index > 0) {
@if ($type == 'push') and ($index > 0) {
.#{$grid-prefix}-push-#{$index}\@#{$breakpoint} {
left: percentage(($index / $columns));
left: percentage(math.div($index, $columns));
}
}
@if ($type == "push") and ($index == 0) {
@if ($type == 'push') and ($index == 0) {
.#{$grid-prefix}-push-0\@#{$breakpoint} {
left: auto;
}
}
@if ($type == "pull") and ($index > 0) {
@if ($type == 'pull') and ($index > 0) {
.#{$grid-prefix}-pull-#{$index}\@#{$breakpoint} {
right: percentage(($index / $columns));
right: percentage(math.div($index, $columns));
}
}
@if ($type == "pull") and ($index == 0) {
@if ($type == 'pull') and ($index == 0) {
.#{$grid-prefix}-pull-0\@#{$breakpoint} {
right: auto;
}
}
@if ($type == "offset") {
@if ($type == 'offset') {
.#{$grid-prefix}-offset-#{$index}\@#{$breakpoint} {
margin-left: percentage(($index / $columns));
margin-left: percentage(math.div($index, $columns));
}
}
}
@ -152,8 +140,8 @@ $padding-at-max-grid-width: round($_viewport-at-max-grid-width * $_grid-padding-
@include float-grid-columns($breakpoint);
@include grid-ratios($breakpoint);
@include loop-grid-columns($columns, $breakpoint, "width");
@include loop-grid-columns($columns, $breakpoint, "pull");
@include loop-grid-columns($columns, $breakpoint, "push");
@include loop-grid-columns($columns, $breakpoint, "offset");
@include loop-grid-columns($columns, $breakpoint, 'width');
@include loop-grid-columns($columns, $breakpoint, 'pull');
@include loop-grid-columns($columns, $breakpoint, 'push');
@include loop-grid-columns($columns, $breakpoint, 'offset');
}

@ -1,4 +1,3 @@
// @param {string} bp Breakpoint value. One of `xs, sm, md, lg`.
// @param {boolean} isMaxWidth By default, the media queries are mobile first,
// so they use `min-width: __px`. By passing `true`, the mixin will subtract
@ -6,11 +5,13 @@
// @param {boolean} isScreenOnly Whether to hide this media query from print styles.
//
// Note: For print media, we want the default styles and the xs breakpoint to take effect.
@use 'sass:math';
@mixin breakpoint($bp, $isMaxWidth: false, $isScreenOnly: true) {
$media-query: get-breakpoint-query($bp, $isMaxWidth);
@if $isScreenOnly {
$media-query: "screen and #{$media-query}";
$media-query: 'screen and #{$media-query}';
}
@media #{$media-query} {
@ -29,7 +30,7 @@
@mixin clearfix() {
&::before,
&::after {
content: " ";
content: ' ';
display: table;
}
@ -47,7 +48,7 @@
}
@mixin aspect($width, $height) {
padding-bottom: percentage($height / $width);
padding-bottom: percentage(math.div($height, $width));
}
@mixin no-aspect() {
@ -65,9 +66,9 @@
}
@if map-has-key($breakpoints, $bp) {
@return "(#{$media}: #{$breakpoint})";
@return '(#{$media}: #{$breakpoint})';
} @else {
@warn "#{$bp} not recognized. Valid breakpoints: #{map-keys($breakpoints)}";
@return "screen";
@return 'screen';
}
}

@ -3,38 +3,38 @@ $breakpoints: (
sm: 768px,
md: 1024px,
lg: 1392px,
xl: 1680px
xl: 1680px,
);
// Colors from Flat UI
$turqoise: #1ABC9C;
$greenSea: #16A085;
$emerald: #2ECC71;
$nephritis: #27AE60;
$river: #3498DB;
$belizeHole: #2980B9;
$amethyst: #9B59B6;
$wisteria: #8E44AD;
$wet-asphalt: #34495E;
$midnightBlue: #2C3E50;
$sunflower: #F1C40F;
$orange: #F39C12;
$carrot: #E67E22;
$pumpkin: #D35400;
$alizarin: #E74C3C;
$pomegranate: #C0392B;
$clouds: #ECF0F1;
$silver: #BDC3C7;
$concrete: #95A5A6;
$asbestos: #7F8C8D;
$turqoise: #1abc9c;
$greenSea: #16a085;
$emerald: #2ecc71;
$nephritis: #27ae60;
$river: #3498db;
$belizeHole: #2980b9;
$amethyst: #9b59b6;
$wisteria: #8e44ad;
$wet-asphalt: #34495e;
$midnightBlue: #2c3e50;
$sunflower: #f1c40f;
$orange: #f39c12;
$carrot: #e67e22;
$pumpkin: #d35400;
$alizarin: #e74c3c;
$pomegranate: #c0392b;
$clouds: #ecf0f1;
$silver: #bdc3c7;
$concrete: #95a5a6;
$asbestos: #7f8c8d;
$black: #000;
$gray10: $midnightBlue;
$gray20: $wet-asphalt;
$gray30: #5D6D77;
$gray30: #5d6d77;
$gray50: $asbestos;
$gray60: $concrete;
$gray80: $silver;
$gray90: #E1E5E6;
$gray90: #e1e5e6;
$gray95: $clouds;
$white: #FFF;
$white: #fff;

@ -7,11 +7,11 @@
padding: 0.5em;
font-size: 1rem;
color: $gray20;
transition: .15s;
transition: 0.15s;
&::placeholder {
color: $gray60;
transition: .15s;
transition: 0.15s;
}
&:hover {

@ -1,9 +1,11 @@
@import "../extensions/grid-framework";
@use 'sass:math';
@import '../extensions/grid-framework';
// .container
.#{$grid-container} {
padding-left: map-get($grid-container-padding, "xs");
padding-right: map-get($grid-container-padding, "xs");
padding-left: map-get($grid-container-padding, 'xs');
padding-right: map-get($grid-container-padding, 'xs');
@include clearfix();
}
@ -14,8 +16,8 @@
@include clearfix();
.#{$grid-row} {
margin-left: $grid-gutter-width / -2;
margin-right: $grid-gutter-width / -2;
margin-left: math.div($grid-gutter-width, -2);
margin-right: math.div($grid-gutter-width, -2);
}
&--centered {
@ -50,13 +52,12 @@
@include make-grid(xs, 6);
@include breakpoint(sm) {
@include make-grid(sm);
// Add more padding to the container class.
.#{$grid-container} {
padding-left: map-get($grid-container-padding, "sm");
padding-right: map-get($grid-container-padding, "sm");
padding-left: map-get($grid-container-padding, 'sm');
padding-right: map-get($grid-container-padding, 'sm');
}
.#{$grid-row} {
@ -65,7 +66,6 @@
}
@include breakpoint(md) {
@include make-grid(md);
}
@ -73,9 +73,9 @@
position: relative;
overflow: visible;
margin-top: 0.5em;
margin-right: calc(-3.5vw - #{($grid-gutter-width / 2)});
margin-right: calc(-3.5vw - #{($grid-gutter-width * 0.5)});
margin-bottom: 0.5em;
margin-left: calc(-3.5vw - #{($grid-gutter-width / 2)});
margin-left: calc(-3.5vw - #{($grid-gutter-width * 0.5)});
pre {
position: relative;
@ -83,23 +83,22 @@
min-height: 56px;
padding-top: 1em;
padding-bottom: 1em;
padding-left: calc(3.5vw + #{($grid-gutter-width / 2)});
padding-right: calc(3.5vw + #{($grid-gutter-width / 2)});
padding-left: calc(3.5vw + #{($grid-gutter-width * 0.5)});
padding-right: calc(3.5vw + #{($grid-gutter-width * 0.5)});
margin: 0;
}
}
@include breakpoint(sm) {
.code-block {
margin-left: calc(-7vw - #{($grid-gutter-width / 2)});
margin-right: calc(-7vw - #{($grid-gutter-width / 2)});
margin-left: calc(-7vw - #{($grid-gutter-width * 0.5)});
margin-right: calc(-7vw - #{($grid-gutter-width * 0.5)});
pre {
position: relative;
z-index: 1;
padding-left: calc(7vw + #{($grid-gutter-width / 2)});
padding-right: calc(7vw + #{($grid-gutter-width / 2)});
padding-left: calc(7vw + #{($grid-gutter-width * 0.5)});
padding-right: calc(7vw + #{($grid-gutter-width * 0.5)});
}
}
}
@ -120,14 +119,13 @@
// }
@media (min-width: $viewport-at-max-grid-width) {
.code-block {
margin-left: calc(((100vw - #{$grid-max-width--desktop}) / -2) - #{$grid-gutter-width / 2});
margin-right: calc(((100vw - #{$grid-max-width--desktop}) / -2) - #{$grid-gutter-width / 2});
margin-left: calc(((100vw - #{$grid-max-width--desktop}) / -2) - #{$grid-gutter-width * 0.5});
margin-right: calc(((100vw - #{$grid-max-width--desktop}) / -2) - #{$grid-gutter-width * 0.5});
pre {
padding-left: calc(((100vw - #{$grid-max-width--desktop}) / 2) + #{$grid-gutter-width / 2});
padding-right: calc(((100vw - #{$grid-max-width--desktop}) / 2) + #{$grid-gutter-width / 2});
padding-left: calc(((100vw - #{$grid-max-width--desktop}) / 2) + #{$grid-gutter-width * 0.5});
padding-right: calc(((100vw - #{$grid-max-width--desktop}) / 2) + #{$grid-gutter-width * 0.5});
}
}
}

@ -1,15 +1,21 @@
.text-center { text-align: center; }
.text-center {
text-align: center;
}
.ib {
display: inline-block;
}
@include breakpoint(sm, true) {
.hidden\@xs { display: none; }
.hidden\@xs {
display: none;
}
}
@include breakpoint(sm) {
.visible\@xs { display: none; }
.visible\@xs {
display: none;
}
}
// Hide from both screenreaders and browsers.
@ -32,7 +38,7 @@
.clearfix,
.clearfix::after {
content: " ";
content: ' ';
display: table;
clear: both;
}
@ -45,8 +51,12 @@
float: right;
}
.full-width { width: 100%; }
.full-height { height: 100%; }
.full-width {
width: 100%;
}
.full-height {
height: 100%;
}
.hide-text {
font: 0/0 a;

@ -113,20 +113,20 @@ p {
text-decoration: underline;
}
code:not([class*="language"]) {
code:not([class*='language']) {
padding: 0;
padding-top: 0.2em;
padding-bottom: 0.2em;
margin: 0;
font-size: 85%;
color: $gray10;
background-color: rgba(27,31,35,0.05);
background-color: rgba(27, 31, 35, 0.05);
border-radius: 3px;
font-family: Menlo, Consolas, "Liberation Mono", Courier, monospace;
font-family: Menlo, Consolas, 'Liberation Mono', Courier, monospace;
}
code:not([class*="language"])::before,
code:not([class*="language"])::after {
content: "\00a0";
letter-spacing: -.2em;
code:not([class*='language'])::before,
code:not([class*='language'])::after {
content: '\00a0';
letter-spacing: -0.2em;
}

@ -1,5 +1,4 @@
@import "../extensions/variables";
@import '../extensions/variables';
.compound-filter-options {
margin-top: 20px;
@ -7,7 +6,6 @@
}
.filter-group--compound {
button {
width: 40px;
height: 40px;
@ -73,14 +71,13 @@
transform: rotate(45deg) scale(0.707106781);
}
@mixin equilateralTriangle($size) {
$sqrt3: 1.73205080757;
$halfSize: $size / 2;
$halfSize: $size * 0.5;
$fullSideWidth: round($sqrt3 * $halfSize);
$leftOver: $size - $fullSideWidth;
padding-top: $leftOver / 2;
padding-top: $leftOver * 0.5;
height: 0;
width: 0;
border-width: 0 $halfSize $fullSideWidth $halfSize;

@ -9,7 +9,7 @@
float: none;
margin: 2em 0;
overflow: hidden;
transition: .2s ease-out;
transition: 0.2s ease-out;
}
.question--collapsed {

@ -1,4 +1,3 @@
// Filters
.filter-label {
display: block;

@ -1,5 +1,5 @@
@import "./extensions/variables";
@import "./extensions/mixins";
@import './extensions/variables';
@import './extensions/mixins';
/*=============================================*\
Some styles to show off masonry layout
@ -67,15 +67,13 @@ img.picture-item__blur {
}
@include breakpoint(sm) {
.picture-item--overlay {
.picture-item__details {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
background-color: rgba(black, .6);
background-color: rgba(black, 0.6);
color: white;
overflow: hidden;
}
@ -86,9 +84,7 @@ img.picture-item__blur {
}
@supports (filter: blur(1px)) and (clip-path: inset(0 0 0 0)) {
.picture-item--overlay {
.picture-item__blur {
position: absolute;
z-index: 1;
@ -112,7 +108,6 @@ img.picture-item__blur {
}
}
/*
Shuffle needs either relative or absolute positioning on the container
It will set it for you, but it'll cause another style recalculation and layout.
@ -129,7 +124,6 @@ img.picture-item__blur {
visibility: hidden;
}
/* Animate in styles */
.shuffle--animatein {
overflow: visible;
@ -141,7 +135,7 @@ img.picture-item__blur {
}
.shuffle--animatein .picture-item__inner--transition {
transition: all .6s ease;
transition: all 0.6s ease;
}
.shuffle--animatein .picture-item.in .picture-item__inner {
@ -149,10 +143,7 @@ img.picture-item__blur {
transform: translate(0, 0);
}
@include breakpoint(sm, true) {
.picture-item {
height: auto;
margin-top: 20px;
@ -160,12 +151,12 @@ img.picture-item__blur {
.picture-item__details,
.picture-item__description {
font-size: .875em;
padding: .625em;
font-size: 0.875em;
padding: 0.625em;
}
.picture-item__description {
padding-right: .875em;
padding-right: 0.875em;
padding-bottom: 1.25em;
}

@ -1,16 +1,16 @@
@import "./extensions/variables";
@import "./extensions/mixins";
@import './extensions/variables';
@import './extensions/mixins';
@import "./global-rules/global";
@import "./global-rules/type";
@import "./global-rules/grid";
@import "./global-rules/forms";
@import "./global-rules/helpers";
@import './global-rules/global';
@import './global-rules/type';
@import './global-rules/grid';
@import './global-rules/forms';
@import './global-rules/helpers';
@import "./components/buttons";
@import "./components/demo-list";
@import "./components/site-nav";
@import './components/buttons';
@import './components/demo-list';
@import './components/site-nav';
@import "./pages/homepage-filters";
@import "./pages/compound-filters";
@import "./pages/faq";
@import './pages/homepage-filters';
@import './pages/compound-filters';
@import './pages/faq';

@ -1,183 +1,4 @@
/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+jsx+scss&plugins=line-highlight+file-highlight */
/**
* prism.js default theme for JavaScript, CSS and HTML
* Based on dabblet (http://dabblet.com)
* @author Lea Verou
*/
code[class*="language-"],
pre[class*="language-"] {
color: black;
background: none;
text-shadow: 0 1px white;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
text-shadow: none;
background: #b3d4fc;
}
pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
code[class*="language-"]::selection, code[class*="language-"] ::selection {
text-shadow: none;
background: #b3d4fc;
}
@media print {
code[class*="language-"],
pre[class*="language-"] {
text-shadow: none;
}
}
/* Code blocks */
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
overflow: auto;
}
:not(pre) > code[class*="language-"],
pre[class*="language-"] {
background: #f5f2f0;
}
/* Inline code */
:not(pre) > code[class*="language-"] {
padding: .1em;
border-radius: .3em;
white-space: normal;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: slategray;
}
.token.punctuation {
color: #999;
}
.namespace {
opacity: .7;
}
.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol,
.token.deleted {
color: #905;
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: #690;
}
.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
color: #a67f59;
background: hsla(0, 0%, 100%, .5);
}
.token.atrule,
.token.attr-value,
.token.keyword {
color: #07a;
}
.token.function {
color: #DD4A68;
}
.token.regex,
.token.important,
.token.variable {
color: #e90;
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}
pre[data-line] {
position: relative;
padding: 1em 0 1em 3em;
}
.line-highlight {
position: absolute;
left: 0;
right: 0;
padding: inherit 0;
margin-top: 1em; /* Same as .prisms padding-top */
background: hsla(24, 20%, 50%,.08);
background: linear-gradient(to right, hsla(24, 20%, 50%,.1) 70%, hsla(24, 20%, 50%,0));
pointer-events: none;
line-height: inherit;
white-space: pre;
}
.line-highlight:before,
.line-highlight[data-end]:after {
content: attr(data-start);
position: absolute;
top: .4em;
left: .6em;
min-width: 1em;
padding: 0 .5em;
background-color: hsla(24, 20%, 50%,.4);
color: hsl(24, 20%, 95%);
font: bold 65%/1.5 sans-serif;
text-align: center;
vertical-align: .3em;
border-radius: 999px;
text-shadow: none;
box-shadow: 0 1px white;
}
.line-highlight[data-end]:after {
content: attr(data-end);
top: auto;
bottom: .4em;
}
/* PrismJS 1.26.0
https://prismjs.com/download.html?#themes=prism&languages=markup+css+clike+javascript+jsx+scss&plugins=line-highlight+file-highlight */
code[class*=language-],pre[class*=language-]{color:#000;background:0 0;text-shadow:0 1px #fff;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{text-shadow:none;background:#b3d4fc}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{text-shadow:none;background:#b3d4fc}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#f5f2f0}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#708090}.token.punctuation{color:#999}.token.namespace{opacity:.7}.token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag{color:#905}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#690}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url{color:#9a6e3a;background:hsla(0,0%,100%,.5)}.token.atrule,.token.attr-value,.token.keyword{color:#07a}.token.class-name,.token.function{color:#dd4a68}.token.important,.token.regex,.token.variable{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}
pre[data-line]{position:relative;padding:1em 0 1em 3em}.line-highlight{position:absolute;left:0;right:0;padding:inherit 0;margin-top:1em;background:hsla(24,20%,50%,.08);background:linear-gradient(to right,hsla(24,20%,50%,.1) 70%,hsla(24,20%,50%,0));pointer-events:none;line-height:inherit;white-space:pre}@media print{.line-highlight{-webkit-print-color-adjust:exact;color-adjust:exact}}.line-highlight:before,.line-highlight[data-end]:after{content:attr(data-start);position:absolute;top:.4em;left:.6em;min-width:1em;padding:0 .5em;background-color:hsla(24,20%,50%,.4);color:#f4f1ef;font:bold 65%/1.5 sans-serif;text-align:center;vertical-align:.3em;border-radius:999px;text-shadow:none;box-shadow:0 1px #fff}.line-highlight[data-end]:after{content:attr(data-end);top:auto;bottom:.4em}.line-numbers .line-highlight:after,.line-numbers .line-highlight:before{content:none}pre[id].linkable-line-numbers span.line-numbers-rows{pointer-events:all}pre[id].linkable-line-numbers span.line-numbers-rows>span:before{cursor:pointer}pre[id].linkable-line-numbers span.line-numbers-rows>span:hover:before{background-color:rgba(128,128,128,.2)}

@ -1 +1 @@
.picture-item{height:220px;margin-left:0;margin-top:24px}.picture-item img{display:block;width:100%}@supports ((-o-object-fit:cover) or (object-fit:cover)){.picture-item img{height:100%;max-width:none;-o-object-fit:cover;object-fit:cover}}.picture-item--h2{height:464px}.picture-item__inner{background:#ecf0f1;height:100%;overflow:hidden;position:relative}img.picture-item__blur{display:none}.picture-item__details{align-items:baseline;display:flex;justify-content:space-between;padding:1em;width:100%}.picture-item__description{margin:0;padding:0 2em 1em 1em;width:100%}.picture-item__title{flex-shrink:0;margin-right:4px}.picture-item__tags{flex-shrink:1;margin:0;text-align:right}@media screen and (min-width:768px){.picture-item--overlay .picture-item__details{background-color:rgba(0,0,0,.6);bottom:0;color:#fff;left:0;overflow:hidden;position:absolute;width:100%}.picture-item--overlay .picture-item__description{display:none}@supports (filter:blur(1px)) and ((-webkit-clip-path:inset(0 0 0 0)) or (clip-path:inset(0 0 0 0))){.picture-item--overlay .picture-item__blur{-webkit-clip-path:inset(170px 0 0 0);clip-path:inset(170px 0 0 0);display:block;filter:blur(7px);left:0;position:absolute;top:0;z-index:1}.picture-item--overlay .picture-item__details{background:none}.picture-item--overlay .picture-item__tags,.picture-item--overlay .picture-item__title{position:relative;z-index:2}}}.my-shuffle-container{overflow:hidden;position:relative}.my-sizer-element{opacity:0;position:absolute;visibility:hidden}.shuffle--animatein{overflow:visible}.shuffle--animatein .picture-item__inner{opacity:0;transform:translateY(220px)}.shuffle--animatein .picture-item__inner--transition{transition:all .6s ease}.shuffle--animatein .picture-item.in .picture-item__inner{opacity:1;transform:translate(0)}@media screen and (max-width:767px){.picture-item{height:auto;margin-top:20px}.picture-item__description,.picture-item__details{font-size:.875em;padding:.625em}.picture-item__description{padding-bottom:1.25em;padding-right:.875em}.picture-item--h2{height:auto}}
.picture-item{height:220px;margin-left:0;margin-top:24px}.picture-item img{display:block;width:100%}@supports (object-fit:cover){.picture-item img{height:100%;max-width:none;object-fit:cover}}.picture-item--h2{height:464px}.picture-item__inner{background:#ecf0f1;height:100%;overflow:hidden;position:relative}img.picture-item__blur{display:none}.picture-item__details{align-items:baseline;display:flex;justify-content:space-between;padding:1em;width:100%}.picture-item__description{margin:0;padding:0 2em 1em 1em;width:100%}.picture-item__title{flex-shrink:0;margin-right:4px}.picture-item__tags{flex-shrink:1;margin:0;text-align:right}@media screen and (min-width:768px){.picture-item--overlay .picture-item__details{background-color:#0009;bottom:0;color:#fff;left:0;overflow:hidden;position:absolute;width:100%}.picture-item--overlay .picture-item__description{display:none}@supports (filter:blur(1px)) and ((-webkit-clip-path:inset(0 0 0 0)) or (clip-path:inset(0 0 0 0))){.picture-item--overlay .picture-item__blur{-webkit-clip-path:inset(170px 0 0 0);clip-path:inset(170px 0 0 0);display:block;filter:blur(7px);left:0;position:absolute;top:0;z-index:1}.picture-item--overlay .picture-item__details{background:none}.picture-item--overlay .picture-item__tags,.picture-item--overlay .picture-item__title{position:relative;z-index:2}}}.my-shuffle-container{overflow:hidden;position:relative}.my-sizer-element{opacity:0;position:absolute;visibility:hidden}.shuffle--animatein{overflow:visible}.shuffle--animatein .picture-item__inner{opacity:0;transform:translateY(220px)}.shuffle--animatein .picture-item__inner--transition{transition:all .6s ease}.shuffle--animatein .picture-item.in .picture-item__inner{opacity:1;transform:translate(0)}@media screen and (max-width:767px){.picture-item{height:auto;margin-top:20px}.picture-item__description,.picture-item__details{font-size:.875em;padding:.625em}.picture-item__description{padding-bottom:1.25em;padding-right:.875em}.picture-item--h2{height:auto}}

File diff suppressed because one or more lines are too long

984
docs/dist/shuffle.js vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -214,7 +214,6 @@ prism: true
<div class="col-12@sm">
<h2>Dependencies<a href="#dependencies"></a></h2>
<p>Shuffle's <a href="https://github.com/Vestride/Shuffle/blob/master/package.json">dependencies</a> are bundled with the dist file.</p>
<p id="polyfills">Shuffle does, however, expect the following ES6/7 features: <code>Set</code>, <code>Array.from</code>, <code>Object.assign</code>, <code>Array.prototype.find</code>, and <code>Array.prototype.includes</code>. In order to support browsers like IE11 and Safari 8, <strong class="type--underline">you must include a polyfill</strong> for these features. You can use a service like <a href="https://polyfill.io">polyfill.io</a> to only load the polyfills that specific browser needs, or a polyfill script like <a href="https://www.npmjs.com/package/@babel/polyfill">@babel/polyfill</a> (which uses <code>core-js</code> internally).</p>
</div>
</div>
</div>
@ -230,27 +229,28 @@ prism: true
<li>Chrome</li>
<li>Firefox</li>
<li>Edge</li>
<li>IE 11</li>
<li>Safari</li>
</ul>
<p>Depending on what browsers you support, you may <a href="#polyfills">need to polyfill features used by Shuffle</a>.</p>
<p>If you still need to support IE 11, you can use Shuffle v5.</p>
</div>
</div>
</div>
</section>
<section id="be-social">
<section id="share">
<div class="container">
<div class="row">
<div class="col-12@sm">
<h2>Be Social<a href="#be-social"></a></h2>
<div class="text-center">
<h2>Share<a href="#share"></a></h2>
<div>
<a href="https://www.buymeacoffee.com/glen.cheney" target="_blank" style="display:inline-block;">
<img loading="lazy" src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 45px !important;width: 160px !important;" />
</a>
<iframe src="https://ghbtns.com/github-btn.html?user=Vestride&repo=Shuffle&type=star&size=large" frameborder="0" scrolling="0" width="76px" height="30px" title="Star this repository on GitHub"></iframe>
<a href="https://twitter.com/share" class="twitter-share-button" data-via="Vestride" data-size="large">Tweet</a>
<div class="g-plusone" data-annotation="none"></div>
</div>
</div>
</div>
@ -268,12 +268,5 @@ prism: true
</section>
<script>
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/platform.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script>

@ -1,48 +1,38 @@
'use strict';
var Sprite = function (context, img, size) {
class Sprite {
constructor(context, img, size) {
this.ctx = context;
this.img = img;
this.width = size;
this.height = size;
this.frameWidth = size;
this.frameHeight = size;
};
}
// Assuming horizontal sprite
Sprite.prototype.getFrame = function (frame) {
// Assuming horizontal sprite
getFrame(frame) {
return {
x: frame * this.frameWidth,
y: 0,
};
};
}
Sprite.prototype.clearCanvas = function () {
clearCanvas() {
this.ctx.clearRect(0, 0, this.width, this.height);
};
}
Sprite.prototype.drawFrame = function (frameNumber) {
drawFrame(frameNumber) {
var frame = this.getFrame(frameNumber);
// Clear out the last frame
this.clearCanvas();
// Draw to the context. This method is really confusing...
this.ctx.drawImage(
this.img,
frame.x,
frame.y,
this.width,
this.height,
0,
0,
this.width,
this.height
);
};
var Favicon = function (src, numFrames, framesPerAnimation, animationDelay) {
this.ctx.drawImage(this.img, frame.x, frame.y, this.width, this.height, 0, 0, this.width, this.height);
}
}
class Favicon {
constructor(src, numFrames, framesPerAnimation, animationDelay) {
// Variables based on params
this.src = src;
this.numFrames = numFrames;
@ -87,25 +77,25 @@ var Favicon = function (src, numFrames, framesPerAnimation, animationDelay) {
// Trigger image to load
this.img.src = this.src;
};
}
Favicon.prototype.getData = function () {
getData() {
return this.canvas.toDataURL('image/png');
};
}
// Clone the current #favicon and replace it with a new element
// which has the updated data URI href
Favicon.prototype.setFavicon = function () {
// Clone the current #favicon and replace it with a new element
// which has the updated data URI href
setFavicon() {
var data = this.getData();
var originalFavicon = document.getElementById('favicon');
var clone = originalFavicon.cloneNode(true);
clone.setAttribute('href', data);
originalFavicon.parentNode.replaceChild(clone, originalFavicon);
};
}
// Request Animation Frame Loop
Favicon.prototype.loop = function (timestamp) {
// Request Animation Frame Loop
loop(timestamp) {
// If not enough time has elapse since the last call
// immediately call the next rAF
if (timestamp - this.lastExecuted < this.timeToElapse) {
@ -119,9 +109,7 @@ Favicon.prototype.loop = function (timestamp) {
}
// Completed an animation state
this.timeToElapse = this.currentFrame % this.framesPerAnimation === 0 ?
this.animationDelay :
1000 / this.fps;
this.timeToElapse = this.currentFrame % this.framesPerAnimation === 0 ? this.animationDelay : 1000 / this.fps;
// Draw current frame from sprite
this.sprite.drawFrame(this.currentFrame);
@ -134,10 +122,10 @@ Favicon.prototype.loop = function (timestamp) {
// Continue loop
return requestAnimationFrame(this.loop.bind(this));
};
}
// Sprite loaded
Favicon.prototype.onSpriteLoaded = function () {
// Sprite loaded
onSpriteLoaded() {
// Draw the first frame when the image loads
this.sprite.drawFrame(this.currentFrame);
@ -146,6 +134,7 @@ Favicon.prototype.onSpriteLoaded = function () {
// Start loop
requestAnimationFrame(this.loop.bind(this));
};
}
}
new Favicon(window.site_url + '/img/favicon-sprite.png', 21, 7, 3000 * 1);

@ -2,14 +2,15 @@
var Shuffle = window.Shuffle;
var Demo = function (element) {
class Demo {
constructor(element) {
this.element = element;
this.initShuffle();
this.setupEvents();
};
}
// Column width and gutter width options can be functions
Demo.prototype.initShuffle = function () {
// Column width and gutter width options can be functions
initShuffle() {
this.shuffle = new Shuffle(this.element, {
itemSelector: '.box',
speed: 250,
@ -24,9 +25,9 @@ Demo.prototype.initShuffle = function () {
return 0.025 * containerWidth;
},
});
};
}
Demo.prototype.setupEvents = function () {
setupEvents() {
document.querySelector('#append').addEventListener('click', this.onAppendBoxes.bind(this));
document.querySelector('#prepend').addEventListener('click', this.onPrependBoxes.bind(this));
document.querySelector('#randomize').addEventListener('click', this.onRandomize.bind(this));
@ -39,14 +40,14 @@ Demo.prototype.setupEvents = function () {
this.shuffle.on(Shuffle.EventType.REMOVED, function (data) {
console.log(data);
});
};
}
/**
/**
* Generate random DOM elements.
* @param {number} itemsToCreate Number of items to create.
* @return {Array.<Element>} Array of elements.
*/
Demo.prototype._generateBoxes = function (itemsToCreate) {
_generateBoxes(itemsToCreate) {
// Creating random elements. You could use an ajax request or clone elements instead.
var items = [];
var modifierClasses = ['w2', 'h2', 'w3'];
@ -69,21 +70,21 @@ Demo.prototype._generateBoxes = function (itemsToCreate) {
}
return items;
};
}
/**
/**
* Return an array of elements which have already been added to the DOM.
* @return {Array.<Element>}
*/
Demo.prototype._getArrayOfElementsToAdd = function () {
_getArrayOfElementsToAdd() {
return this._generateBoxes(5);
};
}
/**
/**
* Create an HTML string to insert. This could, for example, come from an XHR request.
* @return {string} A mock HTML string.
*/
Demo.prototype._getHtmlMarkupToAdd = function () {
_getHtmlMarkupToAdd() {
var fragment = document.createDocumentFragment();
this._generateBoxes(5).forEach(function (item) {
fragment.appendChild(item);
@ -92,13 +93,13 @@ Demo.prototype._getHtmlMarkupToAdd = function () {
var dummy = document.createElement('div');
dummy.appendChild(fragment);
return dummy.innerHTML;
};
}
/**
/**
* Create some DOM elements, append them to the shuffle container, then notify
* shuffle about the new items. You could also insert the HTML as a string.
*/
Demo.prototype.onAppendBoxes = function () {
onAppendBoxes() {
var elements = this._getArrayOfElementsToAdd();
elements.forEach(function (element) {
@ -108,14 +109,14 @@ Demo.prototype.onAppendBoxes = function () {
// Tell shuffle items have been appended.
// It expects an array of elements as the parameter.
this.shuffle.add(elements);
};
}
/**
/**
* Show that you can prepend elements by inserting before other elements. You
* can either insert a string like in this method or prepend real elements like
* the `onAppendBoxes` method.
*/
Demo.prototype.onPrependBoxes = function () {
onPrependBoxes() {
var markup = this._getHtmlMarkupToAdd();
// Prepend HTML string.
@ -126,18 +127,18 @@ Demo.prototype.onPrependBoxes = function () {
// Notify the instance.
this.shuffle.add(items);
};
}
Demo.prototype.getRandomInt = function (min, max) {
getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
};
}
Demo.prototype.getRandomColor = function () {
getRandomColor() {
return '#' + Math.random().toString(16).slice(2, 8);
};
}
// Randomly choose some elements to remove
Demo.prototype.onRemoveClick = function () {
// Randomly choose some elements to remove
onRemoveClick() {
var total = this.shuffle.visibleItems;
// None left
@ -161,9 +162,9 @@ Demo.prototype.onRemoveClick = function () {
// Tell shuffle to remove them
this.shuffle.remove(collection);
};
}
Demo.prototype.onRandomize = function () {
onRandomize() {
var label = document.getElementById('sorter').querySelector('label.btn.active');
if (label) {
var radio = label.querySelector('input');
@ -172,9 +173,9 @@ Demo.prototype.onRandomize = function () {
}
this.sortBy('random');
};
}
Demo.prototype.toggleActiveClasses = function (event) {
toggleActiveClasses(event) {
// Add and remove `active` class from buttons.
var buttons = Array.from(event.currentTarget.children);
buttons.forEach(function (button) {
@ -184,14 +185,14 @@ Demo.prototype.toggleActiveClasses = function (event) {
button.classList.remove('active');
}
});
}
}
Demo.prototype.onSortChange = function (evt) {
onSortChange(evt) {
this.toggleActiveClasses(evt);
this.sortBy(evt.target.value);
};
}
Demo.prototype.sortBy = function (value) {
sortBy(value) {
var sortOptions;
if (value === 'most-reviews') {
@ -199,33 +200,30 @@ Demo.prototype.sortBy = function (value) {
reverse: true,
by: this.getReviews,
};
} else if (value === 'least-reviews') {
sortOptions = {
by: this.getReviews,
};
} else if (value === 'random') {
sortOptions = { randomize: true };
} else {
sortOptions = {};
}
// Filter elements
this.shuffle.sort(sortOptions);
};
}
Demo.prototype.getReviews = function (element) {
getReviews(element) {
return parseInt(element.getAttribute('data-reviews'), 10);
}
}
Demo.prototype.onFilterChange = function (event) {
onFilterChange(event) {
this.toggleActiveClasses(event);
this.filterBy(event.target.value);
};
}
Demo.prototype.filterBy = function (value) {
filterBy(value) {
var filterBy;
var _this = this;
@ -242,13 +240,13 @@ Demo.prototype.filterBy = function (value) {
}
this.shuffle.filter(filterBy);
};
}
/**
/**
* Remove a shuffle item when it's clicked.
* @param {Object} event Event object.
*/
Demo.prototype.onContainerClick = function (event) {
onContainerClick(event) {
// Bail in older browsers. https://caniuse.com/#feat=element-closest
if (typeof event.target.closest !== 'function') {
return;
@ -258,7 +256,8 @@ Demo.prototype.onContainerClick = function (event) {
if (element !== null) {
this.shuffle.remove([element]);
}
};
}
}
document.addEventListener('DOMContentLoaded', function () {
window.demo = new Demo(document.getElementById('my-shuffle'));

@ -6,8 +6,6 @@ var loadMoreButton = document.getElementById('load-more-button');
var shuffleInstance;
// Fetch first page of results from the API.
// You should probably polyfill `fetch` if you're going to copy this demo.
// https://github.com/github/fetch
fetch('https://reqres.in/api/users?page=' + currentPage)
.then(function (response) {
return response.json();

@ -1,8 +1,7 @@
'use strict';
var Shuffle = window.Shuffle;
var Demo = function () {
class Demo {
constructor() {
this.element = document.getElementById('grid');
this.gridItems = this.element.querySelectorAll('.picture-item');
var sizer = this.element.querySelector('.my-sizer-element');
@ -13,7 +12,7 @@ var Demo = function () {
});
var callback = this.showItemsInViewport.bind(this);
this.observer = new window.IntersectionObserver(callback, {
this.observer = new IntersectionObserver(callback, {
threshold: 0.5,
});
@ -24,33 +23,34 @@ var Demo = function () {
// Add the transition class to the items after ones that are in the viewport
// have received the `in` class.
setTimeout(function () {
setTimeout(() => {
this.addTransitionToItems();
}.bind(this), 100);
};
}, 100);
}
/**
/**
* Add the `in` class to the element after it comes into view.
*/
Demo.prototype.showItemsInViewport = function (changes) {
showItemsInViewport(changes) {
changes.forEach(function (change) {
if (change.isIntersecting) {
change.target.classList.add('in');
}
});
};
}
/**
/**
* Only the items out of the viewport should transition. This way, the first
* visible ones will snap into place.
*/
Demo.prototype.addTransitionToItems = function () {
addTransitionToItems() {
for (var i = 0; i < this.gridItems.length; i++) {
var inner = this.gridItems[i].querySelector('.picture-item__inner');
inner.classList.add('picture-item__inner--transition');
}
};
}
}
document.addEventListener('DOMContentLoaded', function () {
document.addEventListener('DOMContentLoaded', () => {
window.demo = new Demo();
});

@ -2,12 +2,13 @@
var Shuffle = window.Shuffle;
var Demo = function (element) {
class Demo {
constructor(element) {
this.shapes = Array.from(document.querySelectorAll('.js-shapes input'));
this.colors = Array.from(document.querySelectorAll('.js-colors button'));
this.shuffle = new Shuffle(element, {
easing: 'cubic-bezier(0.165, 0.840, 0.440, 1.000)', // easeOutQuart
easing: 'cubic-bezier(0.165, 0.840, 0.440, 1.000)',
sizer: '.the-sizer',
});
@ -17,68 +18,62 @@ var Demo = function (element) {
};
this._bindEventListeners();
};
}
/**
/**
* Bind event listeners for when the filters change.
*/
Demo.prototype._bindEventListeners = function () {
_bindEventListeners() {
this._onShapeChange = this._handleShapeChange.bind(this);
this._onColorChange = this._handleColorChange.bind(this);
this.shapes.forEach(function (input) {
this.shapes.forEach((input) => {
input.addEventListener('change', this._onShapeChange);
}, this);
this.colors.forEach(function (button) {
this.colors.forEach((button) => {
button.addEventListener('click', this._onColorChange);
}, this);
};
}
/**
/**
* Get the values of each checked input.
* @return {Array.<string>}
*/
Demo.prototype._getCurrentShapeFilters = function () {
return this.shapes.filter(function (input) {
return input.checked;
}).map(function (input) {
return input.value;
});
};
_getCurrentShapeFilters() {
return this.shapes.filter((input) => input.checked).map((input) => input.value);
}
/**
/**
* Get the values of each `active` button.
* @return {Array.<string>}
*/
Demo.prototype._getCurrentColorFilters = function () {
return this.colors.filter(function (button) {
return button.classList.contains('active');
}).map(function (button) {
return button.getAttribute('data-value');
});
};
_getCurrentColorFilters() {
return this.colors
.filter((button) => button.classList.contains('active'))
.map((button) => button.getAttribute('data-value'));
}
/**
/**
* A shape input check state changed, update the current filters and filte.r
*/
Demo.prototype._handleShapeChange = function () {
_handleShapeChange() {
this.filters.shapes = this._getCurrentShapeFilters();
this.filter();
};
}
/**
/**
* A color button was clicked. Update filters and display.
* @param {Event} evt Click event object.
*/
Demo.prototype._handleColorChange = function (evt) {
_handleColorChange(evt) {
var button = evt.currentTarget;
// Treat these buttons like radio buttons where only 1 can be selected.
if (button.classList.contains('active')) {
button.classList.remove('active');
} else {
this.colors.forEach(function (btn) {
this.colors.forEach((btn) => {
btn.classList.remove('active');
});
@ -87,36 +82,36 @@ Demo.prototype._handleColorChange = function (evt) {
this.filters.colors = this._getCurrentColorFilters();
this.filter();
};
}
/**
/**
* Filter shuffle based on the current state of filters.
*/
Demo.prototype.filter = function () {
filter() {
if (this.hasActiveFilters()) {
this.shuffle.filter(this.itemPassesFilters.bind(this));
} else {
this.shuffle.filter(Shuffle.ALL_ITEMS);
}
};
}
/**
/**
* If any of the arrays in the `filters` property have a length of more than zero,
* that means there is an active filter.
* @return {boolean}
*/
Demo.prototype.hasActiveFilters = function () {
return Object.keys(this.filters).some(function (key) {
hasActiveFilters() {
return Object.keys(this.filters).some((key) => {
return this.filters[key].length > 0;
}, this);
};
}
/**
/**
* Determine whether an element passes the current filters.
* @param {Element} element Element to test.
* @return {boolean} Whether it satisfies all current filters.
*/
Demo.prototype.itemPassesFilters = function (element) {
itemPassesFilters(element) {
var shapes = this.filters.shapes;
var colors = this.filters.colors;
var shape = element.getAttribute('data-shape');
@ -133,8 +128,9 @@ Demo.prototype.itemPassesFilters = function (element) {
}
return true;
};
}
}
document.addEventListener('DOMContentLoaded', function () {
document.addEventListener('DOMContentLoaded', () => {
window.demo = new Demo(document.querySelector('.js-shuffle'));
});

@ -2,7 +2,8 @@
var Shuffle = window.Shuffle;
var Demo = function (element) {
class Demo {
constructor(element) {
this.element = element;
this.shuffle = new Shuffle(element, {
@ -20,31 +21,31 @@ var Demo = function (element) {
this.addSearchFilter();
this.mode = 'exclusive';
};
}
Demo.prototype.toggleMode = function () {
toggleMode() {
if (this.mode === 'additive') {
this.mode = 'exclusive';
} else {
this.mode = 'additive';
}
};
}
/**
/**
* Shuffle uses the CustomEvent constructor to dispatch events. You can listen
* for them like you normally would (with jQuery for example).
*/
Demo.prototype.addShuffleEventListeners = function () {
this.shuffle.on(Shuffle.EventType.LAYOUT, function (data) {
addShuffleEventListeners() {
this.shuffle.on(Shuffle.EventType.LAYOUT, (data) => {
console.log('layout. data:', data);
});
this.shuffle.on(Shuffle.EventType.REMOVED, function (data) {
this.shuffle.on(Shuffle.EventType.REMOVED, (data) => {
console.log('removed. data:', data);
});
};
}
Demo.prototype.addFilterButtons = function () {
addFilterButtons() {
var options = document.querySelector('.filter-options');
if (!options) {
@ -53,18 +54,17 @@ Demo.prototype.addFilterButtons = function () {
var filterButtons = Array.from(options.children);
filterButtons.forEach(function (button) {
filterButtons.forEach((button) => {
button.addEventListener('click', this._handleFilterClick.bind(this), false);
}, this);
};
}
Demo.prototype._handleFilterClick = function (evt) {
_handleFilterClick(evt) {
var btn = evt.currentTarget;
var isActive = btn.classList.contains('active');
var btnGroup = btn.getAttribute('data-group');
// You don't need _both_ of these modes. This is only for the demo.
// For this custom 'additive' mode in the demo, clicking on filter buttons
// doesn't remove any other filters.
if (this.mode === 'additive') {
@ -95,16 +95,16 @@ Demo.prototype._handleFilterClick = function (evt) {
this.shuffle.filter(filterGroup);
}
};
}
Demo.prototype._removeActiveClassFromChildren = function (parent) {
_removeActiveClassFromChildren(parent) {
var children = parent.children;
for (var i = children.length - 1; i >= 0; i--) {
children[i].classList.remove('active');
}
};
}
Demo.prototype.addSorting = function () {
addSorting() {
var buttonGroup = document.querySelector('.sort-options');
if (!buttonGroup) {
@ -112,12 +112,12 @@ Demo.prototype.addSorting = function () {
}
buttonGroup.addEventListener('change', this._handleSortChange.bind(this));
};
}
Demo.prototype._handleSortChange = function (evt) {
_handleSortChange(evt) {
// Add and remove `active` class from buttons.
var buttons = Array.from(evt.currentTarget.children);
buttons.forEach(function (button) {
buttons.forEach((button) => {
if (button.querySelector('input').value === evt.target.value) {
button.classList.add('active');
} else {
@ -149,10 +149,10 @@ Demo.prototype._handleSortChange = function (evt) {
}
this.shuffle.sort(options);
};
}
// Advanced filtering
Demo.prototype.addSearchFilter = function () {
// Advanced filtering
addSearchFilter() {
var searchInput = document.querySelector('.js-shuffle-search');
if (!searchInput) {
@ -160,17 +160,16 @@ Demo.prototype.addSearchFilter = function () {
}
searchInput.addEventListener('input', this._handleSearchKeyup.bind(this));
};
}
/**
/**
* Filter the shuffle instance by items with a title that matches the search input.
* @param {Event} evt Event object.
*/
Demo.prototype._handleSearchKeyup = function (evt) {
_handleSearchKeyup(evt) {
var searchText = evt.target.value.toLowerCase();
this.shuffle.filter(function (element, shuffle) {
this.shuffle.filter((element, shuffle) => {
// If there is a current filter applied, ignore elements that don't match it.
if (shuffle.group !== Shuffle.ALL_ITEMS) {
// Get the item's groups.
@ -188,8 +187,9 @@ Demo.prototype._handleSearchKeyup = function (evt) {
return titleText.indexOf(searchText) !== -1;
});
};
}
}
document.addEventListener('DOMContentLoaded', function () {
document.addEventListener('DOMContentLoaded', () => {
window.demo = new Demo(document.getElementById('grid'));
});

@ -25,7 +25,8 @@ class PhotoGrid extends Component {
// use that here while waiting on a network request.
const grayPixel = 'data:image/gif;base64,R0lGODlhAQABAIAAAMLCwgAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==';
const blackPixel = 'data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=';
const greenPixel = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mO02Vz4HwAE9AJhcLBN6AAAAABJRU5ErkJggg==';
const greenPixel =
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mO02Vz4HwAE9AJhcLBN6AAAAABJRU5ErkJggg==';
this.state = {
photos: [
@ -47,12 +48,42 @@ class PhotoGrid extends Component {
return new Promise((resolve) => {
setTimeout(() => {
resolve([
{ id: 4, username: '@stickermule', name: 'Sticker Mule', src: 'https://images.unsplash.com/photo-1484244233201-29892afe6a2c?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=800&h=600&fit=crop&s=14d236624576109b51e85bd5d7ebfbfc' },
{ id: 5, username: '@prostoroman', name: 'Roman Logov', src: 'https://images.unsplash.com/photo-1465414829459-d228b58caf6e?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=800&h=600&fit=crop&s=7a7080fc0699869b1921cb1e7047c5b3' },
{ id: 6, username: '@richienolan', name: 'Richard Nolan', src: 'https://images.unsplash.com/photo-1478033394151-c931d5a4bdd6?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=800&h=600&fit=crop&s=3c74d594a86e26c5a319f4e17b36146e' },
{ id: 7, username: '@wexor', name: 'Wexor Tmg', src: 'https://images.unsplash.com/photo-1437622368342-7a3d73a34c8f?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=800&h=600&fit=crop&s=11ff283143c782980861a442a957da8e' },
{ id: 8, username: '@dnevozhai', name: 'Denys Nevozhai', src: 'https://images.unsplash.com/photo-1465447142348-e9952c393450?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=800&h=600&fit=crop&s=ea06c0f0700ec469fdcb32e0d4c2928e' },
{ id: 9, username: '@aronvandepol', name: 'Aron Van de Pol', src: 'https://images.unsplash.com/photo-1469719847081-4757697d117a?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=800&h=600&fit=crop&s=9a568bc48e42d3bb60c97c0eb3dc20ac' },
{
id: 4,
username: '@stickermule',
name: 'Sticker Mule',
src: 'https://images.unsplash.com/photo-1484244233201-29892afe6a2c?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=800&h=600&fit=crop&s=14d236624576109b51e85bd5d7ebfbfc',
},
{
id: 5,
username: '@prostoroman',
name: 'Roman Logov',
src: 'https://images.unsplash.com/photo-1465414829459-d228b58caf6e?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=800&h=600&fit=crop&s=7a7080fc0699869b1921cb1e7047c5b3',
},
{
id: 6,
username: '@richienolan',
name: 'Richard Nolan',
src: 'https://images.unsplash.com/photo-1478033394151-c931d5a4bdd6?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=800&h=600&fit=crop&s=3c74d594a86e26c5a319f4e17b36146e',
},
{
id: 7,
username: '@wexor',
name: 'Wexor Tmg',
src: 'https://images.unsplash.com/photo-1437622368342-7a3d73a34c8f?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=800&h=600&fit=crop&s=11ff283143c782980861a442a957da8e',
},
{
id: 8,
username: '@dnevozhai',
name: 'Denys Nevozhai',
src: 'https://images.unsplash.com/photo-1465447142348-e9952c393450?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=800&h=600&fit=crop&s=ea06c0f0700ec469fdcb32e0d4c2928e',
},
{
id: 9,
username: '@aronvandepol',
name: 'Aron Van de Pol',
src: 'https://images.unsplash.com/photo-1469719847081-4757697d117a?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=800&h=600&fit=crop&s=9a568bc48e42d3bb60c97c0eb3dc20ac',
},
]);
}, 300);
});
@ -64,7 +95,10 @@ class PhotoGrid extends Component {
* @return {Promise<Object[]>} Loaded images.
*/
_whenPhotosLoaded(photos) {
return Promise.all(photos.map(photo => new Promise((resolve) => {
return Promise.all(
photos.map(
(photo) =>
new Promise((resolve) => {
const image = document.createElement('img');
image.src = photo.src;
@ -75,7 +109,9 @@ class PhotoGrid extends Component {
resolve(photo);
};
}
})));
}),
),
);
}
componentDidMount() {
@ -108,7 +144,9 @@ class PhotoGrid extends Component {
render() {
return (
<div ref={this.element} className="row my-shuffle">
{this.state.photos.map(image => <PhotoItem {...image}/>)}
{this.state.photos.map((image) => (
<PhotoItem {...image} />
))}
<div ref={this.sizer} className="col-1@xs col-1@sm photo-grid__sizer"></div>
</div>
);
@ -130,7 +168,7 @@ function PhotoItem({ id, username, src, name }) {
</div>
</div>
</div>
)
);
}
/**

@ -1,7 +1,5 @@
(function () {
'use strict';
var Questions = function () {
class Questions {
constructor() {
this.searchInput = document.querySelector('#search');
this.questions = document.querySelectorAll('.js-question');
@ -15,9 +13,9 @@
window.addEventListener('resize', this.onWindowResize.bind(this));
this.setHeights();
};
}
Questions.prototype._handleInput = function (evt) {
_handleInput(evt) {
var val = evt.target.value.toLowerCase();
// Filter elements based on if their string exists in the product model
@ -32,27 +30,26 @@
el.classList.remove('question--collapsed');
}
}
};
}
Questions.prototype.setHeights = function () {
setHeights() {
var elements = Array.from(this.questions);
elements.forEach(function (element) {
elements.forEach((element) => {
element.style.height = '';
});
var heights = elements.map(function (element) {
var heights = elements.map((element) => {
return element.firstElementChild.offsetHeight;
});
elements.forEach(function (element, i) {
elements.forEach((element, i) => {
element.style.height = heights[i] + 'px';
});
};
Questions.prototype.onWindowResize = function () {
}
onWindowResize() {
this.setHeights();
};
}
}
new Questions();
}());
new Questions();

File diff suppressed because one or more lines are too long

@ -2,14 +2,6 @@ requirejs.config({
baseUrl: window.site_url + '/js',
paths: {
shufflejs: '../dist/shuffle',
polyfill: 'https://polyfill.io/v3/polyfill.min.js?features=default%2Ces5%2Ces6%2Ces7',
},
// Load the polyfill before Shuffle.
shim: {
shufflejs: {
deps: ['polyfill'],
},
},
});

@ -1,5 +1,5 @@
(function () {
var SiteNav = function (element) {
class SiteNav {
constructor(element) {
this.element = element;
var buttons = Array.from(document.querySelectorAll('.site-nav__link-toggle'));
var dropdowns = buttons.map(function (button) {
@ -15,9 +15,9 @@
this.handleResize = this.handleResize.bind(this);
window.addEventListener('resize', this.handleResize);
window.addEventListener('load', this.handleResize);
};
}
SiteNav.prototype.toggle = function (event) {
toggle(event) {
var button = event.currentTarget;
var wrapper = button.parentNode;
var willOpen = !wrapper.classList.contains('site-nav__link--dropdown-active');
@ -36,16 +36,16 @@
} else {
document.body.classList.toggle('site-nav--open');
}
};
}
SiteNav.prototype.handleResize = function () {
handleResize() {
var viewportHeight = window.innerHeight;
var navHeight = this.element.offsetHeight;
var dropdowns = Array.from(document.querySelectorAll('.site-nav__dropdown'));
dropdowns.forEach(function (dropdown) {
dropdown.style.maxHeight = (viewportHeight - navHeight) + 'px';
dropdown.style.maxHeight = viewportHeight - navHeight + 'px';
});
};
}
}
new SiteNav(document.querySelector('.site-nav'));
})();
new SiteNav(document.querySelector('.site-nav'));

@ -9,6 +9,7 @@ const commonjsOptions = {
const babelOptions = {
exclude: 'node_modules/**',
babelHelpers: 'bundled',
};
const minifyOptions = {

@ -2,6 +2,5 @@ const gulp = require('gulp');
// Copy dist directory to docs. GitHub pages don't work with symlinks.
module.exports = function copyDist() {
return gulp.src('dist/*')
.pipe(gulp.dest('docs/dist/'));
return gulp.src('dist/*').pipe(gulp.dest('docs/dist/'));
};

@ -5,6 +5,5 @@ const shell = require('gulp-shell');
module.exports = function jekyll() {
const cmd = 'jekyll serve --config _config.yml,_config_dev.yml';
return gulp.src('docs/_config.yml', { read: false })
.pipe(shell([cmd], { cwd: path.join(process.cwd(), 'docs') }));
return gulp.src('docs/_config.yml', { read: false }).pipe(shell([cmd], { cwd: path.join(process.cwd(), 'docs') }));
};

@ -2,10 +2,12 @@ const { rollup } = require('rollup');
const { configs } = require('../config');
module.exports = function scripts() {
const bundles = configs.map(config => rollup(config).then((bundle) => {
const bundles = configs.map((config) =>
rollup(config).then((bundle) => {
config.cache = bundle;
return bundle.write(config.output);
}));
}),
);
return Promise.all(bundles);
};

@ -2,7 +2,8 @@ const gulp = require('gulp');
const shell = require('gulp-shell');
module.exports = function test() {
return gulp.src('package.json', {
return gulp
.src('package.json', {
read: false,
})
.pipe(shell(['npx jest']));

@ -7,11 +7,6 @@ gulp.task('css', require('./gulp/tasks/css'));
gulp.task('jekyll', require('./gulp/tasks/jekyll'));
gulp.task('test', require('./gulp/tasks/test'));
gulp.task('watch', gulp.series(
'set-watching',
gulp.parallel('css', 'scripts'),
'copy-dist',
'jekyll',
));
gulp.task('watch', gulp.series('set-watching', gulp.parallel('css', 'scripts'), 'copy-dist', 'jekyll'));
gulp.task('default', gulp.series('scripts', 'css', 'test', 'copy-dist'));

5
index.d.ts vendored

@ -1,4 +1,4 @@
// Type definitions for Shuffle 5.2.2
// Type definitions for Shuffle 6.0.0
// Project: https://github.com/Vestride/Shuffle
// Definitions by: Glen Cheney <https://github.com/Vestride>
@ -32,9 +32,6 @@ export interface ShuffleOptions {
*/
delimiter?: string;
/** @deprecated Misspelling that will be removed in v6 */
delimeter?: string;
/**
* CSS easing function to use.
*/

@ -1,6 +1,6 @@
{
"name": "shufflejs",
"version": "5.4.1",
"version": "6.0.0",
"description": "Categorize, sort, and filter a responsive grid of items",
"keywords": [
"gallery",
@ -47,7 +47,6 @@
],
"dependencies": {
"array-parallel": "^0.1.3",
"matches-selector": "^1.0.0",
"throttleit": "^1.0.0",
"tiny-emitter": "^2.1.0"
},
@ -69,6 +68,7 @@
"gulp-shell": "^0.8.0",
"jest": "^27.4.7",
"postcss": "^8.4.5",
"prettier": "^2.5.1",
"rollup": "^2.66.1",
"rollup-plugin-terser": "^7.0.0",
"sass": "^1.49.0",

@ -0,0 +1,7 @@
module.exports = {
printWidth: 120,
trailingComma: 'all',
semi: true,
tabWidth: 2,
singleQuote: true,
};

@ -1,3 +1,3 @@
export default function arrayMax(array) {
return Math.max.apply(Math, array); // eslint-disable-line prefer-spread
return Math.max(...array);
}

2
src/array-min.js vendored

@ -1,3 +1,3 @@
export default function arrayMin(array) {
return Math.min.apply(Math, array); // eslint-disable-line prefer-spread
return Math.min(...array);
}

@ -11,23 +11,22 @@ import testComputedSize from './computed-size';
* will return 'auto' when the element doesn't have margins instead of
* the computed style.
*/
export default function getNumberStyle(
element, style,
styles = window.getComputedStyle(element, null),
) {
export default function getNumberStyle(element, style, styles = window.getComputedStyle(element, null)) {
let value = getNumber(styles[style]);
// Support IE<=11 and W3C spec.
if (!testComputedSize() && style === 'width') {
value += getNumber(styles.paddingLeft)
+ getNumber(styles.paddingRight)
+ getNumber(styles.borderLeftWidth)
+ getNumber(styles.borderRightWidth);
value +=
getNumber(styles.paddingLeft) +
getNumber(styles.paddingRight) +
getNumber(styles.borderLeftWidth) +
getNumber(styles.borderRightWidth);
} else if (!testComputedSize() && style === 'height') {
value += getNumber(styles.paddingTop)
+ getNumber(styles.paddingBottom)
+ getNumber(styles.borderTopWidth)
+ getNumber(styles.borderBottomWidth);
value +=
getNumber(styles.paddingTop) +
getNumber(styles.paddingBottom) +
getNumber(styles.borderTopWidth) +
getNumber(styles.borderBottomWidth);
}
return value;

@ -100,9 +100,7 @@ export function getShortColumn(positions, buffer) {
* @param {number} buffer Vertical buffer for the height of items.
* @return {Point}
*/
export function getItemPosition({
itemSize, positions, gridSize, total, threshold, buffer,
}) {
export function getItemPosition({ itemSize, positions, gridSize, total, threshold, buffer }) {
const span = getColumnSpan(itemSize.width, gridSize, total, threshold);
const setY = getAvailablePositions(positions, span, total);
const shortColumnIndex = getShortColumn(setY, buffer);
@ -183,13 +181,15 @@ export function getCenteredPositions(itemRects, containerWidth) {
// elements could be in the way).
if (!canMove) {
let intersectingRect;
const hasOverlap = itemRects.some((itemRect) => rects.some((r) => {
const hasOverlap = itemRects.some((itemRect) =>
rects.some((r) => {
const intersects = Rect.intersects(itemRect, r);
if (intersects) {
intersectingRect = r;
}
return intersects;
}));
}),
);
// If there is any overlap, replace the overlapping row with the original.
if (hasOverlap) {
@ -206,7 +206,8 @@ export function getCenteredPositions(itemRects, containerWidth) {
// https://stackoverflow.com/a/10865042/373422
// Then reset sort back to how the items were passed to this method.
// Remove the wrapper object with index, map to a Point.
return [].concat.apply([], centeredRows) // eslint-disable-line prefer-spread
.sort((a, b) => (a.id - b.id))
return centeredRows
.flat()
.sort((a, b) => a.id - b.id)
.map((itemRect) => new Point(itemRect.left, itemRect.top));
}

@ -33,7 +33,7 @@ export default class Rect {
*/
static intersects(a, b) {
return (
a.left < b.left + b.width && b.left < a.left + a.width
&& a.top < b.top + b.height && b.top < a.top + a.height);
a.left < b.left + b.width && b.left < a.left + a.width && a.top < b.top + b.height && b.top < a.top + a.height
);
}
}

@ -69,11 +69,7 @@ class ShuffleItem {
}
dispose() {
this.removeClasses([
Classes.HIDDEN,
Classes.VISIBLE,
Classes.SHUFFLE_ITEM,
]);
this.removeClasses([Classes.HIDDEN, Classes.VISIBLE, Classes.SHUFFLE_ITEM]);
this.element.removeAttribute('style');
this.element = null;

@ -1,5 +1,4 @@
import TinyEmitter from 'tiny-emitter';
import matches from 'matches-selector';
import throttle from 'throttleit';
import parallel from 'array-parallel';
@ -31,14 +30,7 @@ class Shuffle extends TinyEmitter {
*/
constructor(element, options = {}) {
super();
// eslint-disable-next-line prefer-object-spread
this.options = Object.assign({}, Shuffle.options, options);
// Allow misspelling of delimiter since that's how it used to be.
// Remove in v6.
if (this.options.delimeter) {
this.options.delimiter = this.options.delimeter;
}
this.options = { ...Shuffle.options, ...options };
this.lastSort = {};
this.group = Shuffle.ALL_ITEMS;
@ -327,7 +319,7 @@ class Shuffle extends TinyEmitter {
_getItems() {
return Array.from(this.element.children)
.filter((el) => matches(el, this.options.itemSelector))
.filter((el) => el.matches(this.options.itemSelector))
.map((el) => new ShuffleItem(el, this.options.isRTL));
}
@ -641,8 +633,7 @@ class Shuffle extends TinyEmitter {
*/
getStylesForTransition(item, styleObject) {
// Clone the object to avoid mutating the original.
// eslint-disable-next-line prefer-object-spread
const styles = Object.assign({}, styleObject);
const styles = { ...styleObject };
if (this.options.useTransforms) {
const sign = this.options.isRTL ? '-' : '';

@ -44,8 +44,7 @@ const defaults = {
* @return {Array<T>}
*/
export default function sorter(arr, options) {
// eslint-disable-next-line prefer-object-spread
const opts = Object.assign({}, defaults, options);
const opts = { ...defaults, ...options };
const original = Array.from(arr);
let revert = false;

@ -623,15 +623,6 @@ describe('shuffle', () => {
expect(instance.visibleItems).toBe(3);
});
it('can use the old misspelled delimiter option', () => {
instance = new Shuffle(fixture, {
delimeter: ',',
group: 'design',
});
expect(instance.visibleItems).toBe(3);
});
});
describe('Custom shuffle item styles', () => {

@ -2,7 +2,7 @@
"compilerOptions": {
/* Basic Options */
// "incremental": true, /* Enable incremental compilation */
"target": "ES2018", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"target": "ES2018" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */,
// "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
// "lib": [], /* Specify library files to be included in the compilation. */
// "allowJs": true, /* Allow javascript files to be compiled. */
@ -12,7 +12,7 @@
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
// "sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */
"outDir": "./build", /* Redirect output structure to the directory. */
"outDir": "./build" /* Redirect output structure to the directory. */,
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
// "composite": true, /* Enable project compilation */
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
@ -23,14 +23,14 @@
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
/* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */
"noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
"strictNullChecks": true, /* Enable strict null checks. */
"strictFunctionTypes": true, /* Enable strict checking of function types. */
"strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
"strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
"noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
"alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
"strict": true /* Enable all strict type-checking options. */,
"noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */,
"strictNullChecks": true /* Enable strict null checks. */,
"strictFunctionTypes": true /* Enable strict checking of function types. */,
"strictBindCallApply": true /* Enable strict 'bind', 'call', and 'apply' methods on functions. */,
"strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */,
"noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */,
"alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */,
/* Additional Checks */
// "noUnusedLocals": true, /* Report errors on unused locals. */
@ -39,7 +39,7 @@
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
/* Module Resolution Options */
"moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
"moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */

Loading…
Cancel
Save