Skip to content

Commit

Permalink
Merge pull request #57 from Travelopia/feature/add-responsive-attribu…
Browse files Browse the repository at this point in the history
…te-tp-slider

TP-Slider: Add Responsive Settings
  • Loading branch information
junaidbhura authored Mar 14, 2024
2 parents 66aca02 + f238470 commit 043dcdc
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 12 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@travelopia/web-components",
"version": "0.5.24",
"version": "0.5.25",
"description": "Accessible web components for the modern web",
"files": [
"dist"
Expand Down
50 changes: 41 additions & 9 deletions src/slider/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,47 @@ slider.setCurrentSlide( 2 );

## Attributes

| Attribute | Required | Values | Notes |
|---------------------|----------|-----------------|--------------------------------------------------------------------------------------------------------|
| flexible-height | No | `yes` | Whether the height of the slider changes depending on the content inside the slides |
| infinite | No | `yes` | Go back to the first slide at the end of all slides, and open the last slide when navigating backwards |
| swipe | No | `yes` | Whether to add support for swiping gestures on touch devices |
| behaviour | No | `fade`, `slide` | The default behaviour is to slide between slides. This can be updated to fade. |
| auto-slide-interval | No | <interval> | Interval in milliseconds. |
| per-view | No | <per-view> | Handles slider behavior having more than 1 slides. Default value is 1. |
| step | No | <step> | Steps number of slides on next and previous transition. Default value is 1. |
| Attribute | Required | Values | Notes |
|---------------------|----------|-----------------------|-----------------------------------------------------------------------------------------------------------------|
| flexible-height | No | `yes` | Whether the height of the slider changes depending on the content inside the slides |
| infinite | No | `yes` | Go back to the first slide at the end of all slides, and open the last slide when navigating backwards |
| swipe | No | `yes` | Whether to add support for swiping gestures on touch devices |
| behaviour | No | `fade`, `slide` | The default behaviour is to slide between slides. This can be updated to fade. |
| auto-slide-interval | No | <interval> | Interval in milliseconds. |
| per-view | No | <per-view> | Handles slider behavior having more than 1 slides. No. of slides to show in one view. Default value is 1. |
| step | No | <step> | Steps number of slides on next and previous transition. No. of slides to step to at a time. Default value is 1. |
| responsive | No | <responsive-settings> | Responsive settings to be passed in a JSON string format. |

* `responsive` attribute value data shape.
- When passing the settings, JSON stringy it before passing it to responsive attribute.
- If you pass the responsive attribute, then it will take precedence over any the directly passed attributes values at the given breakpoints.
Be sure to pass the default attributes outside the responsive attribute too, this is because there are CSS attached to those attributes and it may cause CLS
issue if the default attributes ( e.g. flexible-height, infinite etc are not passed )

```javascript
[
{
'media' : '(min-width: 600px)',
'flexible-height' : 'yes',
'infinite' : 'yes',
'swipe' : 'yes',
'behaviour' : 'fade',
'auto-slide-interval': 3000,
'per-view' : 2,
'step' : 2,
},
{
'media' : '(min-width: 300px)',
'flexible-height' : 'no',
'infinite' : 'no',
'swipe' : 'yes',
'behaviour' : 'slide',
'auto-slide-interval': 2000,
'per-view' : 1,
'step' : 1,
},
]
```

## Events

Expand Down
4 changes: 2 additions & 2 deletions src/slider/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
</head>
<body>
<main>
<!--Slider that slides horizontally-->
<tp-slider flexible-height="yes" infinite="yes" swipe="yes">
<!--Slider that slides horizontally with responsive settings.-->
<tp-slider flexible-height="yes" infinite="yes" swipe="yes" responsive='[{"media":"(min-width: 600px)","flexible-height":"yes","infinite":"no","swipe":"yes","auto-slide-interval":2000,"per-view":1,"step":2},{"media":"(min-width: 300px)","flexible-height":"yes","infinite":"no","swipe":"yes","behaviour":"fade","auto-slide-interval":2000,"per-view":1,"step":1}]'>
<tp-slider-arrow direction="previous"><button>&laquo; Previous</button></tp-slider-arrow>
<tp-slider-arrow direction="next"><button>Next &raquo;</button></tp-slider-arrow>
<tp-slider-track>
Expand Down
57 changes: 57 additions & 0 deletions src/slider/tp-slider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,17 @@ export class TPSliderElement extends HTMLElement {
* Properties.
*/
protected touchStartX: number = 0;
protected responsiveSettings: { [ key: string ]: any };
protected allowedResponsiveKeys: string[] = [
'flexible-height',
'infinite',
'swipe',
'behaviour',
'auto-slide-interval',
'per-view',
'step',
'responsive',
];

/**
* Constructor.
Expand All @@ -32,6 +43,10 @@ export class TPSliderElement extends HTMLElement {
this.autoSlide();
this.setAttribute( 'initialized', 'yes' );

// Responsive Settings.
const responsiveSettingsJSON: string = this.getAttribute( 'responsive' ) || '';
this.responsiveSettings = responsiveSettingsJSON ? JSON.parse( responsiveSettingsJSON ) : [];

// Event listeners.
if ( ! ( 'ResizeObserver' in window ) ) {
// We set the resize observer in `tp-slider-slide`
Expand Down Expand Up @@ -430,6 +445,11 @@ export class TPSliderElement extends HTMLElement {
* @protected
*/
handleResize(): void {
// Update responsive settings. We are using setTimeout for INP( Interaction for Next Paint ).
setTimeout( () => {
this.updateAttributesResponsively();
}, 0 );

// Check if we're already resizing.
if ( this.getAttribute( 'resizing' ) ) {
return;
Expand All @@ -445,6 +465,43 @@ export class TPSliderElement extends HTMLElement {
this.removeAttribute( 'resizing' );
}

/**
* Update attributes responsive settings.
*/
updateAttributesResponsively(): void {
// Check if responsiveSettings exist.
if ( ! this.responsiveSettings.length ) {
// Early Return.
return;
}

// Step 2: First remove all the allowed responsive keys.
this.allowedResponsiveKeys.forEach( ( key: string ) => {
this.removeAttribute( key );
} );

// Step 3: Loop through responsiveSettings and check if the media query is matched.
this.responsiveSettings.every( ( settings: { [ key: string ]: any } ) => {
// Check if media query is matched.
if ( window.matchMedia( settings.media ).matches ) {
// If yes, loop through the settings at this media breakpoint.
for ( const settingKey in settings ) {
// Check if the setting key is not media.
if ( 'media' !== settingKey && this.allowedResponsiveKeys.includes( settingKey ) ) {
// Set those keys as attributes.
this.setAttribute( settingKey, settings[ settingKey ] );
}
}

// Return false to break out of the loop.
return false;
}

// Return true so that the loop continues, if it does not break above.
return true;
} );
}

/**
* Detect touch start event, and store the starting location.
*
Expand Down

0 comments on commit 043dcdc

Please sign in to comment.