Converted to hooks
This commit is contained in:
parent
3d0700133a
commit
aa008a169a
|
@ -3,90 +3,70 @@ import { css } from "office-ui-fabric-react/lib/Utilities";
|
|||
import * as React from "react";
|
||||
import styles from "./DateBox.module.scss";
|
||||
import { DateBoxSize, IDateBoxProps } from ".";
|
||||
import { IReadonlyTheme } from '@microsoft/sp-component-base';
|
||||
|
||||
/**
|
||||
* Shows a date in a SharePoint-looking date
|
||||
*/
|
||||
export class DateBox extends React.Component<IDateBoxProps, {}> {
|
||||
public render(): React.ReactElement<IDateBoxProps> {
|
||||
// convert start and end date into moments so that we can manipulate them
|
||||
const startMoment: moment.Moment = moment(this.props.startDate);
|
||||
export const DateBox = (props: IDateBoxProps) => {
|
||||
// convert start and end date into moments so that we can manipulate them
|
||||
const startMoment: moment.Moment = moment(props.startDate);
|
||||
|
||||
// event actually ends one second before the end date
|
||||
const endMoment: moment.Moment = moment(this.props.endDate).add(-1, "s");
|
||||
// event actually ends one second before the end date
|
||||
const endMoment: moment.Moment = moment(props.endDate).add(-1, "s");
|
||||
|
||||
// check if both dates are on the same day
|
||||
const isSameDay: boolean = startMoment.isSame(endMoment, "day");
|
||||
|
||||
if (isSameDay) {
|
||||
return this._renderSingleDay(startMoment);
|
||||
} else {
|
||||
return this._renderMultiDay(startMoment, endMoment);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders an event that happens in a single day
|
||||
* @param startMoment
|
||||
*/
|
||||
private _renderSingleDay(startMoment: moment.Moment): JSX.Element {
|
||||
const { className, size, themeVariant } = this.props;
|
||||
// check if both dates are on the same day
|
||||
const isSameDay: boolean = startMoment.isSame(endMoment, "day");
|
||||
|
||||
if (isSameDay) {
|
||||
return (
|
||||
<div className={css(styles.box,
|
||||
styles.boxIsSingleDay,
|
||||
(size === DateBoxSize.Small ? styles.boxIsSmall : styles.boxIsMedium), className)}
|
||||
(props.size === DateBoxSize.Small ? styles.boxIsSmall : styles.boxIsMedium), props.className)}
|
||||
style={
|
||||
themeVariant &&
|
||||
props.themeVariant &&
|
||||
{
|
||||
// KLUDGE: It seems like the themeVariant palette doesn't expose primaryBackground
|
||||
backgroundColor: themeVariant.palette["primaryBackground"],
|
||||
borderColor: themeVariant.semanticColors.bodyDivider
|
||||
backgroundColor: props.themeVariant.palette["primaryBackground"],
|
||||
borderColor: props.themeVariant.semanticColors.bodyDivider
|
||||
}}>
|
||||
<div className={styles.month}
|
||||
style={
|
||||
themeVariant &&
|
||||
{ color: themeVariant.semanticColors.bodyText }}>{startMoment.format("MMM").toUpperCase()}</div>
|
||||
props.themeVariant &&
|
||||
{ color: props.themeVariant.semanticColors.bodyText }}>{startMoment.format("MMM").toUpperCase()}</div>
|
||||
<div className={styles.day}
|
||||
style={
|
||||
themeVariant &&
|
||||
{ color: themeVariant.semanticColors.bodyText }}>{startMoment.format("D")}</div>
|
||||
props.themeVariant &&
|
||||
{ color: props.themeVariant.semanticColors.bodyText }}>{startMoment.format("D")}</div>
|
||||
</div>);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders an event that spans over multiple days
|
||||
* @param startMoment
|
||||
* @param endMoment
|
||||
*/
|
||||
private _renderMultiDay(startMoment: moment.Moment, endMoment: moment.Moment): JSX.Element {
|
||||
const { className, size, themeVariant } = this.props;
|
||||
} else {
|
||||
return (
|
||||
<div
|
||||
className={css(styles.box,
|
||||
styles.boxIsSingleDay,
|
||||
(size === DateBoxSize.Small ? styles.boxIsSmall : styles.boxIsMedium), className)}
|
||||
(props.size === DateBoxSize.Small ? styles.boxIsSmall : styles.boxIsMedium), props.className)}
|
||||
style={
|
||||
themeVariant &&
|
||||
props.themeVariant &&
|
||||
{
|
||||
backgroundColor: themeVariant.palette["primaryBackground"],
|
||||
borderColor: themeVariant.semanticColors.bodyDivider
|
||||
backgroundColor: props.themeVariant.palette["primaryBackground"],
|
||||
borderColor: props.themeVariant.semanticColors.bodyDivider
|
||||
}}>
|
||||
|
||||
<div className={styles.date} style={
|
||||
themeVariant &&
|
||||
{ color: themeVariant.semanticColors.bodyText }}>{startMoment.format("MMM D").toUpperCase()}</div>
|
||||
props.themeVariant &&
|
||||
{ color: props.themeVariant.semanticColors.bodyText }}>{startMoment.format("MMM D").toUpperCase()}</div>
|
||||
<hr className={styles.separator}
|
||||
style={
|
||||
themeVariant &&
|
||||
props.themeVariant &&
|
||||
{
|
||||
borderColor: themeVariant.semanticColors.bodyText
|
||||
borderColor: props.themeVariant.semanticColors.bodyText
|
||||
}}
|
||||
/>
|
||||
<div className={styles.date} style={
|
||||
themeVariant &&
|
||||
{ color: themeVariant.semanticColors.bodyText }}>{endMoment.format("MMM D").toUpperCase()}</div>
|
||||
props.themeVariant &&
|
||||
{ color: props.themeVariant.semanticColors.bodyText }}>{endMoment.format("MMM D").toUpperCase()}</div>
|
||||
</div>);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -8,149 +8,30 @@ import { IEventCardProps } from ".";
|
|||
import { DateBox, DateBoxSize } from "../DateBox";
|
||||
import styles from "./EventCard.module.scss";
|
||||
import { Text } from "@microsoft/sp-core-library";
|
||||
import { IReadonlyTheme } from '@microsoft/sp-component-base';
|
||||
|
||||
import { useCallback } from 'react';
|
||||
/**
|
||||
* Shows an event in a document card
|
||||
*/
|
||||
export class EventCard extends React.Component<IEventCardProps, {}> {
|
||||
public render(): React.ReactElement<IEventCardProps> {
|
||||
const { isNarrow } = this.props;
|
||||
export const EventCard = (props: IEventCardProps) => {
|
||||
const { isNarrow, themeVariant, isEditMode, event } = props;
|
||||
|
||||
if (isNarrow) {
|
||||
return this._renderNarrowCell();
|
||||
} else {
|
||||
return this._renderNormalCell();
|
||||
}
|
||||
}
|
||||
// Get the cell information
|
||||
const { start,
|
||||
end,
|
||||
allDay,
|
||||
title,
|
||||
url,
|
||||
category,
|
||||
location
|
||||
} = event;
|
||||
|
||||
/**
|
||||
* Renders a full width cell
|
||||
*/
|
||||
private _renderNormalCell(): JSX.Element {
|
||||
|
||||
const { themeVariant } = this.props;
|
||||
const { start,
|
||||
end,
|
||||
allDay,
|
||||
title,
|
||||
url,
|
||||
category,
|
||||
// description,
|
||||
location } = this.props.event;
|
||||
const eventDate: moment.Moment = moment(start);
|
||||
const dateString: string = allDay ? eventDate.format(strings.AllDayDateFormat) : eventDate.format(strings.LocalizedTimeFormat);
|
||||
const { isEditMode } = this.props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
className={css(styles.cardWrapper)}
|
||||
style={themeVariant && { backgroundColor: themeVariant.semanticColors.bodyBackground }}
|
||||
data-is-focusable={true}
|
||||
data-is-focus-item={true}
|
||||
role="listitem"
|
||||
aria-label={Text.format(strings.EventCardWrapperArialLabel, title, `${dateString}`)}
|
||||
tabIndex={0}
|
||||
>
|
||||
<DocumentCard
|
||||
className={css(styles.root, !isEditMode && styles.rootIsActionable, styles.normalCard)}
|
||||
type={DocumentCardType.normal}
|
||||
onClickHref={isEditMode ? null : url}
|
||||
style={themeVariant && { borderColor: themeVariant.semanticColors.bodyDivider }}
|
||||
>
|
||||
<FocusZone>
|
||||
<div className={styles.dateBoxContainer} style={{ height: 160 }}>
|
||||
<DateBox
|
||||
className={styles.dateBox}
|
||||
startDate={start}
|
||||
endDate={end}
|
||||
size={DateBoxSize.Medium}
|
||||
themeVariant={themeVariant}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.detailsContainer}>
|
||||
<div className={styles.category} style={themeVariant && { color: themeVariant.semanticColors.bodySubtext}}>{category}</div>
|
||||
<div className={styles.title} style={themeVariant && { color: themeVariant.semanticColors.bodyText}}>{title}</div>
|
||||
<div className={styles.datetime} style={themeVariant && { color: themeVariant.semanticColors.bodySubtext}}>{dateString}</div>
|
||||
<div className={styles.location} style={themeVariant && { color: themeVariant.semanticColors.bodySubtext}}>{location}</div>
|
||||
<ActionButton
|
||||
className={styles.addToMyCalendar}
|
||||
style={themeVariant && { color: themeVariant.semanticColors.bodyText}}
|
||||
iconProps={{ iconName: "AddEvent" }}
|
||||
ariaLabel={strings.AddToCalendarAriaLabel}
|
||||
onClick={this._onAddToMyCalendar}
|
||||
>
|
||||
{strings.AddToCalendarButtonLabel}
|
||||
</ActionButton>
|
||||
</div>
|
||||
</FocusZone>
|
||||
</DocumentCard>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a narrow event card cell
|
||||
*/
|
||||
private _renderNarrowCell(): JSX.Element {
|
||||
|
||||
// Get the cell information
|
||||
const { start,
|
||||
end,
|
||||
allDay,
|
||||
title,
|
||||
url,
|
||||
} = this.props.event;
|
||||
|
||||
const { themeVariant } = this.props;
|
||||
|
||||
// Calculate the date and string format
|
||||
const eventDate: moment.Moment = moment(start);
|
||||
const dateString: string = allDay ? eventDate.format(strings.AllDayDateFormat) : eventDate.format(strings.LocalizedTimeFormat);
|
||||
|
||||
// Define theme variant styles if themevariant was passed
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
className={css(styles.cardWrapper, styles.compactCard, styles.root, styles.rootIsCompact)}
|
||||
style={themeVariant && { backgroundColor: themeVariant.semanticColors.bodyBackground }}
|
||||
data-is-focusable={true}
|
||||
data-is-focus-item={true}
|
||||
role="listitem"
|
||||
aria-label={Text.format(strings.EventCardWrapperArialLabel, title, dateString)}
|
||||
>
|
||||
<DocumentCard
|
||||
className={css(styles.root, styles.rootIsActionable, styles.rootIsCompact)}
|
||||
type={DocumentCardType.compact}
|
||||
style={themeVariant && { backgroundColor: themeVariant.semanticColors.bodyBackground }}
|
||||
onClickHref={url}
|
||||
>
|
||||
<div>
|
||||
<DateBox
|
||||
className={styles.dateBox}
|
||||
startDate={start}
|
||||
endDate={end}
|
||||
size={DateBoxSize.Small}
|
||||
themeVariant={themeVariant}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div className={styles.title} style={themeVariant && { color: themeVariant.semanticColors.bodyText}}>{title}</div>
|
||||
<div className={styles.datetime} style={themeVariant && { color: themeVariant.semanticColors.bodySubtext}}>{dateString}</div>
|
||||
</div>
|
||||
</DocumentCard>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
const eventDate: moment.Moment = moment(start);
|
||||
const dateString: string = allDay ? eventDate.format(strings.AllDayDateFormat) : eventDate.format(strings.LocalizedTimeFormat);
|
||||
|
||||
/**
|
||||
* Handle adding to calendar
|
||||
*/
|
||||
private _onAddToMyCalendar = (): void => {
|
||||
const { event } = this.props;
|
||||
const _onAddToMyCalendar = useCallback((): void => {
|
||||
|
||||
// create a calendar to hold the event
|
||||
const cal: ICS.VCALENDAR = new ICS.VCALENDAR();
|
||||
|
@ -198,5 +79,92 @@ export class EventCard extends React.Component<IEventCardProps, {}> {
|
|||
// my spidey senses are telling me that there are sitaations where this isn't going to work, but none of my tests could prove it.
|
||||
// i suspect we're not encoding events properly
|
||||
window.open("data:text/calendar;charset=utf8," + encodeURIComponent(cal.toString()));
|
||||
}, [event]);
|
||||
|
||||
if (isNarrow) {
|
||||
// Calculate the date and string format
|
||||
|
||||
// Define theme variant styles if themevariant was passed
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
className={css(styles.cardWrapper, styles.compactCard, styles.root, styles.rootIsCompact)}
|
||||
style={themeVariant && { backgroundColor: themeVariant.semanticColors.bodyBackground }}
|
||||
data-is-focusable={true}
|
||||
data-is-focus-item={true}
|
||||
role="listitem"
|
||||
aria-label={Text.format(strings.EventCardWrapperArialLabel, title, dateString)}
|
||||
>
|
||||
<DocumentCard
|
||||
className={css(styles.root, styles.rootIsActionable, styles.rootIsCompact)}
|
||||
type={DocumentCardType.compact}
|
||||
style={themeVariant && { backgroundColor: themeVariant.semanticColors.bodyBackground }}
|
||||
onClickHref={url}
|
||||
>
|
||||
<div>
|
||||
<DateBox
|
||||
className={styles.dateBox}
|
||||
startDate={start}
|
||||
endDate={end}
|
||||
size={DateBoxSize.Small}
|
||||
themeVariant={themeVariant}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div className={styles.title} style={themeVariant && { color: themeVariant.semanticColors.bodyText }}>{title}</div>
|
||||
<div className={styles.datetime} style={themeVariant && { color: themeVariant.semanticColors.bodySubtext }}>{dateString}</div>
|
||||
</div>
|
||||
</DocumentCard>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
className={css(styles.cardWrapper)}
|
||||
style={themeVariant && { backgroundColor: themeVariant.semanticColors.bodyBackground }}
|
||||
data-is-focusable={true}
|
||||
data-is-focus-item={true}
|
||||
role="listitem"
|
||||
aria-label={Text.format(strings.EventCardWrapperArialLabel, title, `${dateString}`)}
|
||||
tabIndex={0}
|
||||
>
|
||||
<DocumentCard
|
||||
className={css(styles.root, !isEditMode && styles.rootIsActionable, styles.normalCard)}
|
||||
type={DocumentCardType.normal}
|
||||
onClickHref={isEditMode ? null : url}
|
||||
style={themeVariant && { borderColor: themeVariant.semanticColors.bodyDivider }}
|
||||
>
|
||||
<FocusZone>
|
||||
<div className={styles.dateBoxContainer} style={{ height: 160 }}>
|
||||
<DateBox
|
||||
className={styles.dateBox}
|
||||
startDate={start}
|
||||
endDate={end}
|
||||
size={DateBoxSize.Medium}
|
||||
themeVariant={themeVariant}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.detailsContainer}>
|
||||
<div className={styles.category} style={themeVariant && { color: themeVariant.semanticColors.bodySubtext }}>{category}</div>
|
||||
<div className={styles.title} style={themeVariant && { color: themeVariant.semanticColors.bodyText }}>{title}</div>
|
||||
<div className={styles.datetime} style={themeVariant && { color: themeVariant.semanticColors.bodySubtext }}>{dateString}</div>
|
||||
<div className={styles.location} style={themeVariant && { color: themeVariant.semanticColors.bodySubtext }}>{location}</div>
|
||||
<ActionButton
|
||||
className={styles.addToMyCalendar}
|
||||
style={themeVariant && { color: themeVariant.semanticColors.bodyText }}
|
||||
iconProps={{ iconName: "AddEvent" }}
|
||||
ariaLabel={strings.AddToCalendarAriaLabel}
|
||||
onClick={_onAddToMyCalendar}
|
||||
>
|
||||
{strings.AddToCalendarButtonLabel}
|
||||
</ActionButton>
|
||||
</div>
|
||||
</FocusZone>
|
||||
</DocumentCard>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -5,84 +5,72 @@ import * as React from "react";
|
|||
import { IPaginationProps } from ".";
|
||||
import styles from "./Pagination.module.scss";
|
||||
import * as strings from "CalendarFeedSummaryWebPartStrings";
|
||||
import { useCallback } from 'react';
|
||||
|
||||
/**
|
||||
* A custom pagination control designed to look & feel like Office UI Fabric
|
||||
*/
|
||||
export class Pagination extends React.Component<IPaginationProps, {}> {
|
||||
public render(): React.ReactElement<IPaginationProps> {
|
||||
export const Pagination = (props: IPaginationProps) => {
|
||||
const { currentPage, totalItems, itemsCountPerPage } = props;
|
||||
|
||||
const { currentPage } = this.props;
|
||||
// calculate the page situation
|
||||
const numberOfPages: number = Math.round(totalItems / itemsCountPerPage);
|
||||
|
||||
// calculate the page situation
|
||||
const numberOfPages: number = this._getNumberOfPages();
|
||||
// we disable the previous button if we're on page 1
|
||||
const prevDisabled: boolean = currentPage <= 1;
|
||||
|
||||
// we disable the previous button if we're on page 1
|
||||
const prevDisabled: boolean = currentPage <= 1;
|
||||
// we disable the next button if we're on the last page
|
||||
const nextDisabled: boolean = currentPage >= numberOfPages;
|
||||
|
||||
// we disable the next button if we're on the last page
|
||||
const nextDisabled: boolean = currentPage >= numberOfPages;
|
||||
|
||||
return (
|
||||
<div className={css(styles.Pagination, this.props.showPageNum ? null : styles.noPageNum)}>
|
||||
<ActionButton className={styles.prev}
|
||||
data-automation-id="previousPage"
|
||||
onRenderIcon={(_props: IButtonProps) => {
|
||||
// we use the render custom icon method to render the icon consistently with the right icon
|
||||
return (
|
||||
<Icon iconName="ChevronLeft" />
|
||||
);
|
||||
}}
|
||||
disabled={prevDisabled}
|
||||
onClick={this._prevPage}
|
||||
ariaLabel={strings.PrevButtonAriaLabel}
|
||||
>
|
||||
{strings.PrevButtonLabel}
|
||||
</ActionButton>
|
||||
{/* NOT IMPLEMENTED: Page numbers aren't shown here, but we'll need them if we want this control to be reusable */}
|
||||
<ActionButton className={styles.next}
|
||||
data-automation-id="nextPage"
|
||||
disabled={nextDisabled}
|
||||
onRenderMenuIcon={(props: IButtonProps) => {
|
||||
// we use the render custom menu icon method to render the icon to the right of the text
|
||||
return (
|
||||
<Icon iconName="ChevronRight" />
|
||||
);
|
||||
}}
|
||||
onClick={this._nextPage}
|
||||
ariaLabel={strings.NextButtonAriaLabel}
|
||||
>
|
||||
{strings.NextButtonLabel}
|
||||
</ActionButton>
|
||||
</div>
|
||||
);
|
||||
/**
|
||||
* Increments the page number unless we're on the last page
|
||||
*/
|
||||
const _nextPage = useCallback((): void => {
|
||||
if (props.currentPage < numberOfPages) {
|
||||
props.onPageUpdate(props.currentPage + 1);
|
||||
}
|
||||
}, [props, numberOfPages]);
|
||||
|
||||
/**
|
||||
* Increments the page number unless we're on the last page
|
||||
*/
|
||||
private _nextPage = (): void => {
|
||||
const numberOfPages: number = this._getNumberOfPages();
|
||||
if (this.props.currentPage < numberOfPages) {
|
||||
this.props.onPageUpdate(this.props.currentPage + 1);
|
||||
}
|
||||
/**
|
||||
* Decrements the page number unless we're on the first page
|
||||
*/
|
||||
const _prevPage = useCallback((): void => {
|
||||
if (props.currentPage > 1) {
|
||||
props.onPageUpdate(props.currentPage - 1);
|
||||
}
|
||||
}, [props]);
|
||||
|
||||
/**
|
||||
* Decrements the page number unless we're on the first page
|
||||
*/
|
||||
private _prevPage = (): void => {
|
||||
if (this.props.currentPage > 1) {
|
||||
this.props.onPageUpdate(this.props.currentPage - 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates how many pages there will be
|
||||
*/
|
||||
private _getNumberOfPages(): number {
|
||||
const { totalItems, itemsCountPerPage } = this.props;
|
||||
let numPages: number = Math.round(totalItems / itemsCountPerPage);
|
||||
return numPages;
|
||||
}
|
||||
}
|
||||
return (
|
||||
<div className={css(styles.Pagination, props.showPageNum ? null : styles.noPageNum)}>
|
||||
<ActionButton className={styles.prev}
|
||||
onRenderIcon={(_props: IButtonProps) => {
|
||||
// we use the render custom icon method to render the icon consistently with the right icon
|
||||
return (
|
||||
<Icon iconName="ChevronLeft" />
|
||||
);
|
||||
}}
|
||||
disabled={prevDisabled}
|
||||
onClick={_prevPage}
|
||||
ariaLabel={strings.PrevButtonAriaLabel}
|
||||
>
|
||||
{strings.PrevButtonLabel}
|
||||
</ActionButton>
|
||||
{/* NOT IMPLEMENTED: Page numbers aren't shown here, but we'll need them if we want this control to be reusable */}
|
||||
<ActionButton className={styles.next}
|
||||
data-automation-id="nextPage"
|
||||
disabled={nextDisabled}
|
||||
onRenderMenuIcon={(_props: IButtonProps) => {
|
||||
// we use the render custom menu icon method to render the icon to the right of the text
|
||||
return (
|
||||
<Icon iconName="ChevronRight" />
|
||||
);
|
||||
}}
|
||||
onClick={_nextPage}
|
||||
ariaLabel={strings.NextButtonAriaLabel}
|
||||
>
|
||||
{strings.NextButtonLabel}
|
||||
</ActionButton>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -16,14 +16,12 @@ function useBreakpoints(currentWidth: number, breakpoints: number[]) {
|
|||
* Presents the child compoments as a slick slide
|
||||
*/
|
||||
export const FilmstripLayout = (props: { children: any; clientWidth: number; themeVariant?: IReadonlyTheme, ariaLabel?: string; }) => {
|
||||
|
||||
let ref: React.MutableRefObject<HTMLDivElement> = useRef<HTMLDivElement>(null);
|
||||
// // the slick slider used in normal views
|
||||
let _slider: React.MutableRefObject<Slider> = useRef<Slider>(null);
|
||||
|
||||
SPComponentLoader.loadCss('https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.css');
|
||||
SPComponentLoader.loadCss('https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick-theme.min.css');
|
||||
|
||||
let topElem: React.MutableRefObject<HTMLDivElement> = useRef<HTMLDivElement>(null);
|
||||
let _slider: React.MutableRefObject<Slider> = useRef<Slider>(null);
|
||||
|
||||
const [isSmall, isMedium] = useBreakpoints(props.clientWidth, [696, 928]);
|
||||
|
||||
let numSlides: number = 3;
|
||||
|
@ -88,7 +86,7 @@ export const FilmstripLayout = (props: { children: any; clientWidth: number; the
|
|||
</style>
|
||||
}
|
||||
<div>
|
||||
<div className={css(styles.filmstripLayout, styles.filmStrip)} aria-label={props.ariaLabel} ref={ref}>
|
||||
<div className={css(styles.filmstripLayout, styles.filmStrip)} aria-label={props.ariaLabel} ref={topElem}>
|
||||
<Slider ref={_slider} {...settings}>
|
||||
{props.children}
|
||||
</Slider>
|
||||
|
|
|
@ -19,6 +19,16 @@ const sampleEvents: ICalendarEvent[] = [
|
|||
location: "Barrie, ON",
|
||||
description: "This is a description"
|
||||
},
|
||||
{
|
||||
title: "This is a UTC event",
|
||||
start: moment().add(1, "d").utc(false).toDate(),
|
||||
end: moment().add(1, "d").add(1, "h").utc(false).toDate(),
|
||||
url: "https://www.contoso.com/news-events/events/1UTC/",
|
||||
allDay: false,
|
||||
category: "Meeting",
|
||||
location: "Barrie, ON",
|
||||
description: "This is a description for a UTC event"
|
||||
},
|
||||
{
|
||||
title: "This event will be in one week",
|
||||
start: moment().add(1, "w").toDate(),
|
||||
|
|
Loading…
Reference in New Issue