Update to Hero webpart

Following updates applied:

- Updated to automatically detect how many items are being displayed and adjust the display layout based on this
- Updated design to show the title on all images
- Updated description area on hover
- Updated hover effect of image to show a zoom effect when hovering over an item
- General cleaning up of CSS and code
This commit is contained in:
Omar 2021-07-28 02:11:33 +01:00
parent 0fbb1b6f4c
commit 087a2a16ce
5 changed files with 114 additions and 89 deletions

View File

@ -25,7 +25,8 @@
"isPaginated":false,
"hideFirstPageJump":false,
"hideLastPageJump":false,
"showAllHero":false
"showAllHero":false,
"totalShow":5
}
}]
}

View File

@ -12,6 +12,7 @@ import HeroWebpart from './components/HeroWebpart';
import { IHeroWebpartProps } from './components/IHeroWebpartProps';
import { PropertyFieldToggleWithCallout } from '@pnp/spfx-property-controls/lib/PropertyFieldToggleWithCallout';
import { PropertyFieldSliderWithCallout } from '@pnp/spfx-property-controls/lib/PropertyFieldSliderWithCallout';
import { CalloutTriggers } from '@pnp/spfx-property-controls/lib/PropertyFieldHeader';
import { PropertyFieldCollectionData, CustomCollectionFieldType } from '@pnp/spfx-property-controls/lib/PropertyFieldCollectionData';
@ -105,27 +106,27 @@ export default class HeroWebpartWebPart extends BaseClientSideWebPart<IHeroWebpa
title: "Select File",
type: CustomCollectionFieldType.custom,
onCustomRender: (field, value, onUpdate, item, itemId, onError) => {
return (
React.createElement(FilePicker, {
key: itemId,
context: this.context,
buttonLabel:"Select File",
onChange: (selectedFile: IFilePickerResult[]) => {
onUpdate(field.id, selectedFile);
return (
React.createElement(FilePicker, {
key: itemId,
context: this.context,
buttonLabel:"Select File",
onChange: (selectedFile: IFilePickerResult[]) => {
onUpdate(field.id, selectedFile);
return Event;
},
onSave: (filePickerResult: IFilePickerResult[]) => {
// write code to save file to SharePoint doc library
// if you are uploading the file via the upload tab which I've not implemented here
onUpdate(field.id, filePickerResult);
return Event;
},
onSave: (filePickerResult: IFilePickerResult[]) => {
// write code to save file to SharePoint doc library
// if you are uploading the file via the upload tab which I've not implemented here
onUpdate(field.id, filePickerResult);
return Event;
},
hideLocalUploadTab: true,
hideLocalMultipleUploadTab: true,
hideLinkUploadTab: true
})
);
}
},
hideLocalUploadTab: true,
hideLocalMultipleUploadTab: true,
hideLinkUploadTab: true
})
);
}
}
],
disabled: false

View File

@ -11,12 +11,15 @@ export default class Hero extends React.Component<IHeroLayoutProps> {
public render(): React.ReactElement<IHeroLayoutProps> {
//const classTotal = "itemShow"+this.props.totalShow;
const items = this.props.items;
const viewType = items.length==1 ? "heroOne" : items.length==2 ? "heroTwo" : items.length==3 ? "heroThree" :
items.length==4 ? "heroFour" : items.length==5 ? "heroFive" : "heroFive";
var arr = [];
arr.push(items);
return (
<div role="group">
<div role="group" className={viewType}>
<List
role="presentation"
className={styles.heroItem}
@ -46,7 +49,8 @@ export default class Hero extends React.Component<IHeroLayoutProps> {
<div className={styles["flexitems"]}>
<a href={firstItemUrl}>
<img src={firstItem.filePicker[0].fileNameWithoutExtension=='blankEntry154873'?firstItem.filePicker[0].fileAbsoluteUrl:thumbRend+firstItem.filePicker[0].fileAbsoluteUrl+"&w=960"}/>
<div className={styles.description}><div className={styles.heroTitle}>{firstItem.Title}</div>{firstItem.Description ? firstItem.Description.length>150 ? firstItem.Description.substring(0, 150)+".." : firstItem.Description : "Description coming soon"}</div>
<div className={styles.heroTitle}>{firstItem.Title}</div>
<div className={styles.description}><div className={styles.heroTitleHover}>{firstItem.Title}</div><div className={styles.info}>{firstItem.Description ? firstItem.Description.length>150 ? firstItem.Description.substring(0, 150)+".." : firstItem.Description : "Description coming soon"}</div></div>
</a>
</div>
</div>
@ -57,7 +61,8 @@ export default class Hero extends React.Component<IHeroLayoutProps> {
<div className={styles["flexitems"]}>
<a href={smalltemUrl}>
<img src={item.filePicker[0].fileNameWithoutExtension=='blankEntry154873'?item.filePicker[0].fileAbsoluteUrl:thumbRend+item.filePicker[0].fileAbsoluteUrl+"&w=960"}/>
<div className={styles.description}><div className={styles.heroTitle}>{item.Title}</div>{item.Description ? item.Description.length>150 ? item.Description.substring(0, 150)+".." : item.Description : "Description coming soon"}</div>
<div className={styles.heroTitle}>{item.Title}</div>
<div className={styles.description}><div className={styles.heroTitleHover}>{item.Title}</div><div className={styles.info}>{item.Description ? item.Description.length>150 ? item.Description.substring(0, 150)+".." : item.Description : "Description coming soon"}</div></div>
</a>
</div>
))}

View File

@ -87,76 +87,62 @@
height:530px;
}
.carouselContentOne{
:global(.ms-List-page .ms-List-cell){
width: 100%!important;
padding:0%
}
:global(.ms-List-page .ms-List-cell div) {
width: 100%!important;
}
}
.carouselContentTwo {
:global(.ms-List-page .ms-List-cell){
width: 46%!important;
padding:2%
}
:global(.ms-List-page .ms-List-cell div) {
width: 100%!important;
}
}
.carouselContentThree{
:global(.ms-List-page .ms-List-cell){
width: 29%!important;
padding:2%
}
:global(.ms-List-page .ms-List-cell div) {
width: 100%!important;
}
}
.carouselContentFour{
:global(.ms-List-page .ms-List-cell){
width: 24%!important;
padding:1%
}
:global(.ms-List-page .ms-List-cell div) {
width: 100%!important;
}
}
.heroTitle{
.heroTitleHover{
@include ms-font-xl;
padding-bottom: 10px;
font-weight: 600;
}
.heroTitle{
@include ms-fontColor-white;
font-size: 26px;
font-weight: 600;
position: absolute;
bottom: 5px;
width: 100%;
padding: 30px 0px;;
text-align: center;
background-image: linear-gradient(180deg,transparent 15%,rgba(0,0,0,.7));
height: fit-content!important;
}
.info,.heroTitleHover{
opacity: 0;
}
.heroItem {
flex: auto;
flex-grow: 0;
flex-shrink: 0;
display: flex;
.flexcontainer .flexitems:hover img{
transform: scale(1.1);
transition: .4s ease;
}
.flexcontainer .flexitems:hover .heroTitle{
opacity: 0;
}
.flexcontainer .flexitems:hover .description {
opacity: 1;
background: rgba(0, 0, 0, 0.9);
.info,.heroTitleHover{
opacity: 1;
}
}
.flexcontainer .flexitems .description{
@include ms-fontColor-white;
position: absolute;
bottom: 5px;
background: rgba(0, 0, 0, 0.9);
color: #f1f1f1;
width: calc(100% - 40px);
transition: .5s ease;
opacity: 0;
color: white;
font-size: 16px;
padding: 20px 0px;;
text-align: center;
}
@include ms-fontColor-white;
position: absolute;
bottom: 0px;
background: rgba(0, 0, 0, 0);
width: calc(100% - 40px);
transition: .5s ease;
font-size: 18px;
padding: 20px 0px;;
text-align: center;
}
.flexcontainer .flexitems{
overflow: hidden;
@ -164,10 +150,14 @@
.flexcontainer:nth-child(1){
flex: auto;
flex-basis: 40%;
flex-basis: 50%;
flex-shrink: 1;
padding-right:5px;
padding-bottom: 7px;
padding-bottom: 5px;
.heroTitle{
width: 100%;
}
*{
height: 100%;
@ -201,33 +191,67 @@
.flexcontainer:nth-child(2) {
flex: auto;
flex-basis: 60%;
flex-basis: 50%;
flex-grow: 0;
flex-shrink: 0;
display: flex;
display: flex;
flex-direction: row;
flex-wrap: wrap;
.heroTitle{
width: calc(100% - 5px);
}
img{
width:100%;
height:100%;
}
.description {
width: calc(100% - 5px);
width: 100%;
}
.flexitems{
padding-right:5px;
flex-basis: calc(50% - 5px);
flex-shrink: 1;
flex-grow: 1;
align-self: auto;
position: relative;
padding-bottom: 5px;
min-height: 200px;
}
.flexitems:hover{
margin-bottom: 5px;
}
}
}
:global(.heroThree) .heroItem {
.flexcontainer:nth-child(1){
flex-basis: 60%;
.focusItem .flexitems{
padding-bottom: 5px;
}
}
.flexcontainer:nth-child(2)
{
flex-basis: 40%;
.flexitems {
flex-basis: 50%;
flex-direction: column;
}
}
}
:global(.heroFive) .heroItem {
.flexcontainer:nth-child(1){
min-height: 400px;
}
}
@media all and (max-width: 768px) {
.heroItem {
@ -278,7 +302,6 @@
.subGroup ~ .subGroup a{
display:inline-block;
width: 48%!important;
float: left;
}
}
:global(.ms-List-page .ms-List-cell){

View File

@ -2,10 +2,7 @@ import * as React from 'react';
import styles from './HeroWebpart.module.scss';
import { IHeroWebpartProps } from './IHeroWebpartProps';
import {IHeroState} from './IHeroWebpartState';
import { escape } from '@microsoft/sp-lodash-subset';
import { Pagination } from "@pnp/spfx-controls-react/lib/pagination";
import { PnPClientStorage } from "@pnp/common";
import { IHeroLayoutProps } from './IHeroLayoutProps';
import Hero from './HeroLayout';
import { sp } from '@pnp/sp';
import { Stack, IStackProps, IStackTokens } from 'office-ui-fabric-react/lib/Stack';
@ -25,8 +22,6 @@ const tokens = {
},
};
const storage = new PnPClientStorage();
export default class HeroWebpart extends React.Component<IHeroWebpartProps, IHeroState> {
constructor(props: IHeroWebpartProps) {