Added Collage Feature
- At the request of another user a option has been added to allow a collage of images to be shown in a flex grid layout - Added in placeholder configuration screen - Fixed webpart not loading the 5 temporary items on first adding webpart to new page in local workbench - General maintenance to remove unused imports - Updated CSS to add in collage feature
This commit is contained in:
parent
51eebc82de
commit
47ddd9bcfa
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "hero-webpart",
|
||||
"version": "0.0.1",
|
||||
"version": "1.2.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"id": "71d58a4f-1896-46aa-94a5-dbef33d14166",
|
||||
"alias": "HeroWebpartWebPart",
|
||||
"componentType": "WebPart",
|
||||
"version": "0.0.1",
|
||||
"version": "1.2.0",
|
||||
"manifestVersion": 2,
|
||||
"requiresCustomScript": false,
|
||||
"supportedHosts": [
|
||||
|
|
|
@ -12,13 +12,13 @@ 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';
|
||||
import { PropertyFieldFilePicker, IPropertyFieldFilePickerProps, IFilePickerResult } from "@pnp/spfx-property-controls/lib/PropertyFieldFilePicker";
|
||||
import { FilePicker , IFilePickerProps } from '@pnp/spfx-controls-react/lib/FilePicker';
|
||||
import { IFilePickerResult } from "@pnp/spfx-property-controls/lib/PropertyFieldFilePicker";
|
||||
import { FilePicker } from '@pnp/spfx-controls-react/lib/FilePicker';
|
||||
import { PropertyPaneWebPartInformation } from '@pnp/spfx-property-controls/lib/PropertyPaneWebPartInformation';
|
||||
import { DisplayMode } from '@microsoft/sp-core-library';
|
||||
|
||||
export interface IHeroWebpartWebPartProps {
|
||||
title: string;
|
||||
|
@ -26,9 +26,11 @@ export interface IHeroWebpartWebPartProps {
|
|||
hideFirstPageJump: boolean;
|
||||
hideLastPageJump: boolean;
|
||||
showAllHero: boolean;
|
||||
showCollage: boolean;
|
||||
collectionData: any[];
|
||||
filePickerResult: IFilePickerResult;
|
||||
pageLimit:number;
|
||||
displayMode: DisplayMode;
|
||||
}
|
||||
|
||||
export default class HeroWebpartWebPart extends BaseClientSideWebPart<IHeroWebpartWebPartProps> {
|
||||
|
@ -42,9 +44,11 @@ export default class HeroWebpartWebPart extends BaseClientSideWebPart<IHeroWebpa
|
|||
hideFirstPageJump:this.properties.hideFirstPageJump,
|
||||
hideLastPageJump:this.properties.hideLastPageJump,
|
||||
spfxContext: this.context,
|
||||
showAllHero: this.properties.showAllHero,
|
||||
showAllHero: this.properties.showAllHero?this.properties.showAllHero:false,
|
||||
showCollage: this.properties.showCollage?this.properties.showCollage:false,
|
||||
pageLimit:5,
|
||||
items:this.properties.collectionData?this.properties.collectionData:[]
|
||||
items:this.properties.collectionData?this.properties.collectionData:[],
|
||||
displayMode: this.displayMode,
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -132,11 +136,20 @@ export default class HeroWebpartWebPart extends BaseClientSideWebPart<IHeroWebpa
|
|||
],
|
||||
disabled: false
|
||||
}),
|
||||
PropertyFieldToggleWithCallout('showCollage', {
|
||||
calloutTrigger: CalloutTriggers.Hover,
|
||||
key: 'showCollage',
|
||||
label: 'Show collage of all images?',
|
||||
calloutContent: React.createElement('p', {}, 'Enabling this will show all images in a collage view'),
|
||||
onText: 'ON',
|
||||
offText: 'OFF',
|
||||
checked: this.properties.showCollage,
|
||||
}),
|
||||
PropertyFieldToggleWithCallout('showAllHero', {
|
||||
calloutTrigger: CalloutTriggers.Hover,
|
||||
key: 'showAllHeroFieldId',
|
||||
label: 'Show all courses in Hero view?',
|
||||
calloutContent: React.createElement('p', {}, 'Enabling this will show all courses in the Hero view'),
|
||||
label: 'Show all images in Hero view?',
|
||||
calloutContent: React.createElement('p', {}, 'Enabling this will show all images in the Hero view'),
|
||||
onText: 'ON',
|
||||
offText: 'OFF',
|
||||
checked: this.properties.showAllHero,
|
||||
|
|
|
@ -11,9 +11,8 @@ 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" :
|
||||
const viewType = this.props.isCollage ? "heroCollage" : 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);
|
||||
|
@ -25,7 +24,7 @@ export default class Hero extends React.Component<IHeroLayoutProps> {
|
|||
className={styles.heroItem}
|
||||
items={arr}
|
||||
getItemCountForPage={this._getItemCountForPage}
|
||||
onRenderCell={this._onRenderHeroItem}
|
||||
onRenderCell={this.props.isCollage?this._onRenderHeroCollage:this._onRenderHeroItem}
|
||||
{...this.props.listProps}
|
||||
/>
|
||||
</div>
|
||||
|
@ -70,4 +69,25 @@ export default class Hero extends React.Component<IHeroLayoutProps> {
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private _onRenderHeroCollage = (items: any, index: number | undefined): JSX.Element => {
|
||||
const thumbRend = "https://media.akamai.odsp.cdn.office.net/uksouth1-mediap.svc.ms/transform/thumbnail?provider=url&inputFormat=jpg&docid=";
|
||||
var smalltemUrl;
|
||||
return(
|
||||
<div className={styles["collageContainer"]}>
|
||||
{items.map((item) => (
|
||||
smalltemUrl= item.Hyperlink ? item.Hyperlink : "#",
|
||||
<div className={styles["collageitem"]}>
|
||||
<div className={styles["collageItemInner"]}>
|
||||
<a href={smalltemUrl}>
|
||||
<img src={item.filePicker[0].fileNameWithoutExtension=='blankEntry154873'?item.filePicker[0].fileAbsoluteUrl:thumbRend+item.filePicker[0].fileAbsoluteUrl+"&w=960"}/>
|
||||
<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>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -284,6 +284,65 @@
|
|||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
:global(.heroCollage) .collageContainer
|
||||
{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
|
||||
.collageitem {
|
||||
overflow: hidden;
|
||||
flex-shrink: 1;
|
||||
padding: 6px;
|
||||
width: calc(33% - 12px);
|
||||
a{
|
||||
width: 100%;
|
||||
}
|
||||
img{
|
||||
width: inherit;
|
||||
}
|
||||
.heroTitle {
|
||||
font-size: 14px;
|
||||
width: calc(33% - 12px);
|
||||
margin: -80px 0px 0px 0px;
|
||||
position: absolute;
|
||||
bottom: unset;
|
||||
}
|
||||
.heroTitleHover{
|
||||
font-size: 16px;
|
||||
}
|
||||
.info{
|
||||
font-size: 12px;
|
||||
}
|
||||
.description{
|
||||
@include ms-fontColor-white;
|
||||
position: absolute;
|
||||
margin: -90px 0px 0px 0px;
|
||||
bottom: unset;
|
||||
background: rgba(0, 0, 0, 0);
|
||||
width: calc(33% - 12px);
|
||||
transition: .5s ease;
|
||||
font-size: 18px;
|
||||
padding: 20px 0px;;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.collageItemInner:hover {
|
||||
.description {
|
||||
background: rgba(0, 0, 0, 0.9);
|
||||
width: calc(33% - 12px);
|
||||
position: absolute;
|
||||
margin: -90px 0px 0px 0px;
|
||||
bottom: unset;
|
||||
.info,.heroTitleHover{
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media all and (max-width: 768px) {
|
||||
|
|
|
@ -8,6 +8,8 @@ import { sp } from '@pnp/sp';
|
|||
import { Stack, IStackProps, IStackTokens } from 'office-ui-fabric-react/lib/Stack';
|
||||
import { Label } from 'office-ui-fabric-react/lib/Label';
|
||||
import { Spinner, SpinnerSize } from 'office-ui-fabric-react/lib/Spinner';
|
||||
import { Placeholder } from "@pnp/spfx-controls-react/lib/Placeholder";
|
||||
import { DisplayMode } from '@microsoft/sp-core-library';
|
||||
|
||||
const stackTokens: IStackTokens = { childrenGap: 20 };
|
||||
|
||||
|
@ -87,11 +89,17 @@ export default class HeroWebpart extends React.Component<IHeroWebpartProps, IHer
|
|||
<Stack {...rowProps} tokens={tokens.spinnerStack}>
|
||||
<Label>Loading</Label>
|
||||
<Spinner size={SpinnerSize.large} />
|
||||
</Stack>
|
||||
</Stack> &&
|
||||
<Placeholder iconName='Edit'
|
||||
iconText='Configure your web part'
|
||||
description='Please configure the web part.'
|
||||
buttonLabel='Configure'
|
||||
hideButton={this.props.displayMode === DisplayMode.Read}
|
||||
onConfigure={this._onConfigure} />
|
||||
);
|
||||
}else{
|
||||
var itemList:any[];
|
||||
this.props.showAllHero ? itemList = this.state.itemsPaginated : itemList = this.state.items;
|
||||
var itemList:any[] = this.state.items;
|
||||
this.props.showAllHero && !this.props.showCollage ? itemList = this.state.itemsPaginated : itemList = this.state.items;
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -99,9 +107,10 @@ export default class HeroWebpart extends React.Component<IHeroWebpartProps, IHer
|
|||
<div className={styles.titleHead}>
|
||||
{this.props.title}
|
||||
</div>
|
||||
<Hero items={this.props.showAllHero ? this.state.itemsPaginated : this.state.items.slice(0, 5)}/>
|
||||
{this.props.showAllHero ?
|
||||
<Pagination
|
||||
{this.props.showAllHero &&
|
||||
<>
|
||||
<Hero items={this.props.showAllHero ? this.state.itemsPaginated : this.state.items.slice(0, 5)} isCollage={this.props.showCollage}/>
|
||||
<Pagination
|
||||
currentPage={this.state.currentPage}
|
||||
totalPages={this.state.totalPages}
|
||||
onChange={(page) => this._getPage(page)}
|
||||
|
@ -109,10 +118,20 @@ export default class HeroWebpart extends React.Component<IHeroWebpartProps, IHer
|
|||
hideFirstPageJump={this.props.hideFirstPageJump} // Optional
|
||||
hideLastPageJump={this.props.hideLastPageJump} // Optional
|
||||
limiterIcon={"Emoji12"} // Optional
|
||||
/> : "" }
|
||||
</div>
|
||||
/>
|
||||
</>
|
||||
}
|
||||
{!this.props.showAllHero &&
|
||||
<Hero items={this.state.items} isCollage={this.props.showCollage}/>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private _onConfigure() {
|
||||
// Context of the web part
|
||||
this.props.spfxContext.propertyPane.open();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -4,4 +4,5 @@ import { IListProps } from 'office-ui-fabric-react/lib/List';
|
|||
export interface IHeroLayoutProps {
|
||||
items:any[];
|
||||
listProps?: Partial<IListProps>;
|
||||
isCollage:boolean;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { WebPartContext } from '@microsoft/sp-webpart-base';
|
||||
import { DisplayMode } from '@microsoft/sp-core-library';
|
||||
|
||||
export interface IHeroWebpartProps {
|
||||
title: string;
|
||||
|
@ -8,5 +9,7 @@ export interface IHeroWebpartProps {
|
|||
hideFirstPageJump: boolean;
|
||||
hideLastPageJump: boolean;
|
||||
showAllHero: boolean;
|
||||
showCollage: boolean;
|
||||
items:any[];
|
||||
displayMode: DisplayMode;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue