Skip to content

Commit

Permalink
feat(ui5-carousel): Allow different number of items per page based on…
Browse files Browse the repository at this point in the history
… component width (#1434)
  • Loading branch information
vladitasev committed Apr 6, 2020
1 parent 0089db4 commit dec0d4d
Show file tree
Hide file tree
Showing 3 changed files with 210 additions and 12 deletions.
2 changes: 1 addition & 1 deletion packages/main/src/Carousel.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
></div>
{{/each}}
{{else}}
<ui5-label>{{currenlySelectedIndexToShow}}&nbsp;{{ofText}}&nbsp;{{pages.length}}</ui5-label>
<ui5-label>{{selectedIndexToShow}}&nbsp;{{ofText}}&nbsp;{{pages.length}}</ui5-label>
{{/if}}
</div>

Expand Down
79 changes: 72 additions & 7 deletions packages/main/src/Carousel.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
getI18nBundle,
} from "@ui5/webcomponents-base/dist/i18nBundle.js";
import ScrollEnablement from "@ui5/webcomponents-base/dist/delegate/ScrollEnablement.js";
import ResizeHandler from "@ui5/webcomponents-base/dist/delegate/ResizeHandler.js";
import { isDesktop } from "@ui5/webcomponents-base/dist/Device.js";
import AnimationMode from "@ui5/webcomponents-base/dist/types/AnimationMode.js";
import { getAnimationMode } from "@ui5/webcomponents-base/dist/config/AnimationMode.js";
Expand Down Expand Up @@ -40,17 +41,39 @@ const metadata = {
* @defaultvalue false
* @public
*/
cycling: {
cyclic: {
type: Boolean,
},

/**
* Sets the amount of items per page. If this property is set, on mobile devices it will always fallback to 1.
* Sets the number of items per page on small size (up to 640px). One item per page shown by default.
* @type {Integer}
* @defaultvalue 1
* @public
*/
itemsPerPage: {
itemsPerPageS: {
type: Integer,
defaultValue: 1,
},

/**
* Sets the number of items per page on medium size (from 640px to 1024px). One item per page shown by default.
* @type {Integer}
* @defaultvalue 1
* @public
*/
itemsPerPageM: {
type: Integer,
defaultValue: 1,
},

/**
* Sets the number of items per page on large size (more than 1024px). One item per page shown by default.
* @type {Integer}
* @defaultvalue 1
* @public
*/
itemsPerPageL: {
type: Integer,
defaultValue: 1,
},
Expand Down Expand Up @@ -96,6 +119,14 @@ const metadata = {
type: CarouselArrowsPlacement,
defaultValue: CarouselArrowsPlacement.Content,
},

/**
* Defines the carousel width in pixels
* @private
*/
_width: {
type: Integer,
},
},
managedSlots: true,
slots: /** @lends sap.ui.webcomponents.main.Carousel.prototype */ {
Expand Down Expand Up @@ -177,12 +208,38 @@ class Carousel extends UI5Element {
});

this.i18nBundle = getI18nBundle("@ui5/webcomponents");
this._onResizeBound = this._onResize.bind(this);
}

onAfterRendering() {
this._scrollEnablement.scrollContainer = this.getDomRef();
}

onEnterDOM() {
ResizeHandler.register(this, this._onResizeBound);
}

onExitDOM() {
ResizeHandler.deregister(this, this._onResizeBound);
}

_onResize() {
const oldItemsPerPage = this.effectiveItemsPerPage;

// Change transitively effectiveItemsPerPage by modifying _width
this._width = this.offsetWidth;

// Items per page did not change, therefore page index does not need to be re-adjusted
if (this.effectiveItemsPerPage === oldItemsPerPage) {
return;
}

// Whenever the number of items per page changes, the selected index needs to be re-adjusted so that the items
// that were visible before, can be visible as much as possible afterwards.
const adjustment = oldItemsPerPage / this.effectiveItemsPerPage;
this.selectedIndex = Math.round(this.selectedIndex * adjustment);
}

_updateScrolling(event) {
if (!event) {
return;
Expand All @@ -209,7 +266,7 @@ class Carousel extends UI5Element {

navigateLeft() {
if (this.selectedIndex - 1 < 0) {
if (this.cycling) {
if (this.cyclic) {
this.selectedIndex = this.pages.length - 1;
}
} else {
Expand All @@ -219,7 +276,7 @@ class Carousel extends UI5Element {

navigateRight() {
if (this.selectedIndex + 1 > this.pages.length - 1) {
if (this.cycling) {
if (this.cyclic) {
this.selectedIndex = 0;
}
} else {
Expand Down Expand Up @@ -261,7 +318,15 @@ class Carousel extends UI5Element {
}

get effectiveItemsPerPage() {
return isDesktop() ? this.itemsPerPage : 1;
if (this._width <= 640) {
return this.itemsPerPageS;
}

if (this._width <= 1024) {
return this.itemsPerPageM;
}

return this.itemsPerPageL;
}

get styles() {
Expand Down Expand Up @@ -316,7 +381,7 @@ class Carousel extends UI5Element {
return this.i18nBundle.getText(CAROUSEL_OF_TEXT);
}

get currenlySelectedIndexToShow() {
get selectedIndexToShow() {
return this.selectedIndex + 1;
}

Expand Down
141 changes: 137 additions & 4 deletions packages/main/test/pages/Carousel.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
}
</style>

<ui5-carousel items-per-page="3">
<ui5-carousel items-per-page-s="3" items-per-page-m="3" items-per-page-l="3">
<ui5-card
id="card"
status="4 of 10"
Expand Down Expand Up @@ -157,7 +157,140 @@
</ui5-carousel>


<ui5-carousel id="carousel1" cycling="true">
<ui5-carousel items-per-page-s="1" items-per-page-m="2" items-per-page-l="3">
<ui5-card
id="card"
status="Item 1"
heading="Quick Links"
subheading="quick links"
header-interactive
class="myCard">
<ui5-list id="myList3" separators="Inner">
<ui5-li icon="horizontal-bullet-chart" >Template Based Segmentation</ui5-li>
<ui5-li icon="opportunity" >Segmentation Models</ui5-li>
<ui5-li icon="line-charts" >Marketing plans</ui5-li>
</ui5-list>

<ui5-input id="field" value="0"></ui5-input>
</ui5-card>

<ui5-card
id="card2"
status="Item 2"
heading="Quick Links"
subheading="quick links"
class="myCard">
<ui5-icon name="group" slot="avatar"></ui5-icon>
<ui5-list id="myList3" separators="Inner">
<ui5-li icon="horizontal-bullet-chart" >Template Based Segmentation</ui5-li>
<ui5-li icon="opportunity" >Segmentation Models</ui5-li>
</ui5-list>
</ui5-card>

<ui5-card heading="Quick Links" status="Item 3" subheading="quick links" class="myCard">
<ui5-list id="myList3" separators="Inner">
<ui5-li icon="horizontal-bullet-chart" >Template Based Segmentation</ui5-li>
<ui5-li icon="opportunity" >Segmentation Models</ui5-li>
</ui5-list>
</ui5-card>

<ui5-card
id="card"
status="Item 4"
heading="Quick Links"
subheading="quick links"
header-interactive
class="myCard">
<ui5-list id="myList3" separators="Inner">
<ui5-li icon="horizontal-bullet-chart" >Template Based Segmentation</ui5-li>
<ui5-li icon="opportunity" >Segmentation Models</ui5-li>
<ui5-li icon="line-charts" >Marketing plans</ui5-li>
</ui5-list>

<ui5-input id="field" value="0"></ui5-input>
</ui5-card>

<ui5-card
id="card2"
status="Item 5"
heading="Quick Links"
subheading="quick links"
class="myCard">
<ui5-icon name="group" slot="avatar"></ui5-icon>
<ui5-list id="myList3" separators="Inner">
<ui5-li icon="horizontal-bullet-chart" >Template Based Segmentation</ui5-li>
<ui5-li icon="opportunity" >Segmentation Models</ui5-li>
</ui5-list>
</ui5-card>

<ui5-card heading="Quick Links" status="Item 6" subheading="quick links" class="myCard">
<ui5-list id="myList3" separators="Inner">
<ui5-li icon="horizontal-bullet-chart" >Template Based Segmentation</ui5-li>
<ui5-li icon="opportunity" >Segmentation Models</ui5-li>
</ui5-list>
</ui5-card>

<ui5-card
id="card"
status="Item 7"
heading="Quick Links"
subheading="quick links"
header-interactive
class="myCard">
<ui5-list id="myList3" separators="Inner">
<ui5-li icon="horizontal-bullet-chart" >Template Based Segmentation</ui5-li>
<ui5-li icon="opportunity" >Segmentation Models</ui5-li>
<ui5-li icon="line-charts" >Marketing plans</ui5-li>
</ui5-list>

<ui5-input id="field" value="0"></ui5-input>
</ui5-card>

<ui5-card
id="card2"
status="Item 8"
heading="Quick Links"
subheading="quick links"
class="myCard">
<ui5-icon name="group" slot="avatar"></ui5-icon>
<ui5-list id="myList3" separators="Inner">
<ui5-li icon="horizontal-bullet-chart" >Template Based Segmentation</ui5-li>
<ui5-li icon="opportunity" >Segmentation Models</ui5-li>
</ui5-list>
</ui5-card>

<ui5-card heading="Quick Links" status="Item 9" subheading="quick links" class="myCard">
<ui5-list id="myList3" separators="Inner">
<ui5-li icon="horizontal-bullet-chart" >Template Based Segmentation</ui5-li>
<ui5-li icon="opportunity" >Segmentation Models</ui5-li>
</ui5-list>
</ui5-card>

<ui5-card
id="card2"
status="Item 10"
heading="Quick Links"
subheading="quick links"
class="myCard">
<ui5-icon name="group" slot="avatar"></ui5-icon>
<ui5-list id="myList3" separators="Inner">
<ui5-li icon="horizontal-bullet-chart" >Template Based Segmentation</ui5-li>
<ui5-li icon="opportunity" >Segmentation Models</ui5-li>
</ui5-list>
</ui5-card>

<ui5-card heading="Quick Links" status="Item 11" subheading="quick links" class="myCard">
<ui5-list id="myList3" separators="Inner">
<ui5-li icon="horizontal-bullet-chart" >Template Based Segmentation</ui5-li>
<ui5-li icon="opportunity" >Segmentation Models</ui5-li>
</ui5-list>
</ui5-card>

</ui5-carousel>



<ui5-carousel id="carousel1" cyclic="true">
<ui5-button>Button 1</ui5-button>
<ui5-button>Button 2</ui5-button>
<ui5-button>Button 3</ui5-button>
Expand Down Expand Up @@ -215,7 +348,7 @@
</ui5-list>
</ui5-carousel>

<ui5-carousel id="carousel5" items-per-page="4">
<ui5-carousel id="carousel5" items-per-page-m="4" items-per-page-l="4">
<ui5-button>Button 1</ui5-button>
<ui5-button>Button 2</ui5-button>
<ui5-button>Button 3</ui5-button>
Expand All @@ -229,7 +362,7 @@
<ui5-title>Carousel with one page</ui5-title>
<ui5-label>The arrows and dots are not displayed</ui5-label>

<ui5-carousel id="carousel6" items-per-page="3">
<ui5-carousel id="carousel6" items-per-page-m="3" items-per-page-l="4">
<ui5-button>Button 1</ui5-button>
<ui5-button>Button 2</ui5-button>
<ui5-button>Button 3</ui5-button>
Expand Down

0 comments on commit dec0d4d

Please sign in to comment.