Skip to content

Commit 2a18c7c

Browse files
committed
CarouselImage is ready
1 parent fa28d90 commit 2a18c7c

5 files changed

Lines changed: 80 additions & 33 deletions

File tree

src/controls/carousel/Carousel.tsx

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { ProcessingState } from "./ICarouselState";
1111
import { Spinner } from "office-ui-fabric-react/lib/Spinner";
1212
import { isArray } from "@pnp/common";
1313
import * as telemetry from '../../common/telemetry';
14+
import CarouselImage from "./CarouselImage";
1415

1516
export class Carousel extends React.Component<ICarouselProps, ICarouselState> {
1617
constructor(props: ICarouselProps) {
@@ -62,7 +63,7 @@ export class Carousel extends React.Component<ICarouselProps, ICarouselState> {
6263
return (
6364
<div className={this.getMergedStyles(styles.container, containerStyles)}>
6465
<div className={this.getMergedStyles(this.getButtonContainerStyles(), containerButtonsStyles)}
65-
onClick={() => { if (!prevButtonDisabled) { this.onCarouselButtonClicked(false); } }} >
66+
onClick={() => { if (!prevButtonDisabled) { this.onCarouselButtonClicked(false); } }} >
6667
<IconButton
6768
className={this.getMergedStyles(this.getButtonStyles(false), prevButtonStyles)}
6869
iconProps={{ iconName: prevButtonIconName }}
@@ -86,7 +87,7 @@ export class Carousel extends React.Component<ICarouselProps, ICarouselState> {
8687
</div>
8788

8889
<div className={this.getMergedStyles(this.getButtonContainerStyles(), containerButtonsStyles)}
89-
onClick={() => { if (!nextButtonDisabled) { this.onCarouselButtonClicked(true); } }}>
90+
onClick={() => { if (!nextButtonDisabled) { this.onCarouselButtonClicked(true); } }}>
9091
<IconButton
9192
className={this.getMergedStyles(this.getButtonStyles(true), nextButtonStyles)}
9293
iconProps={{ iconName: nextButtonIconName }}
@@ -261,15 +262,21 @@ export class Carousel extends React.Component<ICarouselProps, ICarouselState> {
261262
private getElementToDisplay = (): JSX.Element => {
262263
const { element } = this.props;
263264
const currentIndex = this.state.currentIndex;
264-
let result : JSX.Element = null;
265+
let result: JSX.Element = null;
266+
let arrayLen: number;
265267

266268
// If no element has been provided.
267269
if (!element) {
268270
result = null;
269271
}
270-
// Retrieve proper element from the array
271-
else if (isArray(element) && currentIndex >= 0 && (element as JSX.Element[]).length > currentIndex) {
272-
result = element[currentIndex];
272+
else if (isArray(element) && (arrayLen = (element as any[]).length) > 0) {
273+
// Retrieve proper element from the array
274+
if (currentIndex >= 0 && arrayLen > currentIndex) {
275+
const arrayEl = element[currentIndex];
276+
277+
result = 'props' in arrayEl ? arrayEl as JSX.Element :
278+
<CarouselImage {...arrayEl} />;
279+
}
273280
}
274281
else {
275282
result = element as JSX.Element;

src/controls/carousel/CarouselImage.module.scss

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@import "~office-ui-fabric-react/dist/sass/References.scss";
2+
13
.carouselImage {
24
overflow: hidden;
35
width: 100%;
@@ -6,6 +8,22 @@
68

79
.image {
810
width: 100%;
11+
height: 100%;
12+
}
13+
14+
&.dynamicDetails {
15+
16+
&:hover {
17+
.details {
18+
top: 60%;
19+
}
20+
}
21+
}
22+
23+
&.staticDetails {
24+
.details {
25+
top: 60%;
26+
}
927
}
1028

1129
.details {
@@ -17,6 +35,13 @@
1735
padding: 15px;
1836
position: absolute;
1937
right: 0;
20-
top: 60%;
38+
top: 100%;
39+
transition: all 0.5s ease;
40+
41+
.title {
42+
display: block;
43+
@include ms-fontSize-l;
44+
padding-bottom: 5px;
45+
}
2146
}
2247
}

src/controls/carousel/CarouselImage.tsx

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as React from 'react';
22
import styles from './CarouselImage.module.scss';
33
import { Image, ImageFit } from 'office-ui-fabric-react/lib/Image';
4+
import { css } from 'office-ui-fabric-react/lib/Utilities';
45

56
export interface ICarouselImageProps {
67
imageSrc: string;
@@ -10,14 +11,16 @@ export interface ICarouselImageProps {
1011
description?: string | JSX.Element;
1112
target?: '_blank' | '_self';
1213
showDetailsOnHover?: boolean;
13-
detailsBackgroundColor?: string;
14-
detailsColor?: string;
1514
className?: string;
1615
style?: React.CSSProperties;
1716
imgClassName?: string;
1817
imgStyle?: React.CSSProperties;
1918
detailsClassName?: string;
2019
detailsStyle?: React.CSSProperties;
20+
titleClassName?: string;
21+
titleStyle?: React.CSSProperties;
22+
descriptionClassName?: string;
23+
descriptionStyle?: React.CSSProperties;
2124
}
2225

2326
export interface ICarouselImageState { }
@@ -32,14 +35,16 @@ export default class CarouselImage extends React.Component<ICarouselImageProps,
3235
description,
3336
target = '_blank',
3437
showDetailsOnHover,
35-
detailsBackgroundColor,
36-
detailsColor,
3738
className,
3839
style,
3940
imgClassName,
4041
imgStyle,
4142
detailsClassName,
42-
detailsStyle
43+
detailsStyle,
44+
titleClassName,
45+
titleStyle,
46+
descriptionClassName,
47+
descriptionStyle
4348
} = this.props;
4449

4550
let details: JSX.Element | null = null;
@@ -49,14 +54,14 @@ export default class CarouselImage extends React.Component<ICarouselImageProps,
4954
let descriptionEl: JSX.Element | null;
5055
if (description) {
5156
if (typeof(description) === 'string') {
52-
descriptionEl = <span>{description}</span>;
57+
descriptionEl = <span className={descriptionClassName} style={descriptionStyle}>{description}</span>;
5358
}
5459
else {
5560
descriptionEl = description;
5661
}
5762
}
58-
const detailsContent = <div className={styles.details}>
59-
{!!title && <span>{title}</span>}
63+
const detailsContent = <div className={css(styles.details, detailsClassName)} style={detailsStyle}>
64+
{!!title && <span className={css(styles.title, titleClassName)} style={titleStyle}>{title}</span>}
6065
{descriptionEl}
6166
</div>;
6267

@@ -69,8 +74,8 @@ export default class CarouselImage extends React.Component<ICarouselImageProps,
6974
}
7075

7176
return (
72-
<div className={styles.carouselImage}>
73-
<Image className={styles.image} imageFit={imageFit} src={imageSrc} />
77+
<div className={css(styles.carouselImage, className, showDetailsOnHover ? styles.dynamicDetails : styles.staticDetails)} style={style}>
78+
<Image className={css(styles.image, imgClassName)} style={imgStyle} imageFit={imageFit} src={imageSrc} />
7479
{details}
7580
</div>
7681
);

src/controls/carousel/ICarouselProps.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { ICssInput } from "@uifabric/utilities/lib";
2+
import { ICarouselImageProps } from "./CarouselImage";
23

34
/**
45
* Provides options for carousel buttons location.
@@ -96,7 +97,7 @@ export interface ICarouselProps {
9697
* Fixed array of elemenets to be displayed in carousel - if triggerPageEvent is not used.
9798
* In case triggerPageEvent is in use, JSX.Element has to be provided. Elements are distinguished based on the 'key' property.
9899
*/
99-
element: JSX.Element | JSX.Element[];
100+
element: JSX.Element | JSX.Element[] | ICarouselImageProps[];
100101
/**
101102
* Allows to inject custom component when the carousel is in processing state. If not provided, Spinner is displayed.
102103
*/

src/webparts/controlsTest/components/ControlsTest.tsx

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,21 +1047,30 @@ export default class ControlsTest extends React.Component<IControlsTestProps, IC
10471047
isInfinite={true}
10481048

10491049
element={[
1050-
<CarouselImage
1051-
imageSrc={'https://images.unsplash.com/photo-1588614959060-4d144f28b207?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3078&q=80'}
1052-
title={'Colosseum'}
1053-
description={'This is Colosseum'}
1054-
url={'https://en.wikipedia.org/wiki/Colosseum'} />,
1055-
<CarouselImage
1056-
imageSrc={'https://images.unsplash.com/photo-1588614959060-4d144f28b207?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3078&q=80'}
1057-
title={'Colosseum'}
1058-
description={'This is Colosseum'}
1059-
url={'https://en.wikipedia.org/wiki/Colosseum'} />,
1060-
<CarouselImage
1061-
imageSrc={'https://images.unsplash.com/photo-1588614959060-4d144f28b207?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3078&q=80'}
1062-
title={'Colosseum'}
1063-
description={'This is Colosseum'}
1064-
url={'https://en.wikipedia.org/wiki/Colosseum'} />
1050+
{
1051+
imageSrc: 'https://images.unsplash.com/photo-1588614959060-4d144f28b207?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3078&q=80',
1052+
title: 'Colosseum',
1053+
description: 'This is Colosseum',
1054+
url: 'https://en.wikipedia.org/wiki/Colosseum',
1055+
showDetailsOnHover: true,
1056+
imageFit: ImageFit.cover
1057+
},
1058+
{
1059+
imageSrc: 'https://images.unsplash.com/photo-1588614959060-4d144f28b207?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3078&q=80',
1060+
title: 'Colosseum',
1061+
description: 'This is Colosseum',
1062+
url: 'https://en.wikipedia.org/wiki/Colosseum',
1063+
showDetailsOnHover: true,
1064+
imageFit: ImageFit.cover
1065+
},
1066+
{
1067+
imageSrc: 'https://images.unsplash.com/photo-1588614959060-4d144f28b207?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3078&q=80',
1068+
title: 'Colosseum',
1069+
description: 'This is Colosseum',
1070+
url: 'https://en.wikipedia.org/wiki/Colosseum',
1071+
showDetailsOnHover: true,
1072+
imageFit: ImageFit.cover
1073+
}
10651074
]}
10661075
onMoveNextClicked={(index: number) => { console.log(`Next button clicked: ${index}`); }}
10671076
onMovePrevClicked={(index: number) => { console.log(`Prev button clicked: ${index}`); }}

0 commit comments

Comments
 (0)