Skip to content

Commit

Permalink
stickyHeader/stickyFooter
Browse files Browse the repository at this point in the history
  • Loading branch information
arshaw committed Apr 9, 2020
1 parent 49e9b17 commit d1125d8
Show file tree
Hide file tree
Showing 8 changed files with 305 additions and 38 deletions.
121 changes: 121 additions & 0 deletions examples/timegrid-sticky-header.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<link href='../packages/bundle/dist/main.css' rel='stylesheet' />
<script src='../packages/bundle/dist/main.js'></script>
<script>

document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');

var calendar = new FullCalendar.Calendar(calendarEl, {
height: 'auto', // enough to active sticky headers

slotDuration: '00:05:00',
defaultDate: '2020-02-12',
defaultView: 'timeGridWeek',
nowIndicator: true,
header: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
},
navLinks: true, // can click day/week names to navigate views
editable: true,
selectable: true,
selectMirror: true,
dayMaxEvents: true, // allow "more" link when too many events
events: [
{
title: 'All Day Event',
start: '2020-02-01',
},
{
title: 'Long Event',
start: '2020-02-07',
end: '2020-02-10'
},
{
groupId: 999,
title: 'Repeating Event',
start: '2020-02-09T16:00:00'
},
{
groupId: 999,
title: 'Repeating Event',
start: '2020-02-16T16:00:00'
},
{
title: 'Conference',
start: '2020-02-11',
end: '2020-02-13'
},
{
title: 'Meeting',
start: '2020-02-12T10:30:00',
end: '2020-02-12T12:30:00'
},
{
title: 'Lunch',
start: '2020-02-12T12:00:00'
},
{
title: 'Meeting',
start: '2020-02-12T14:30:00'
},
{
title: 'Happy Hour',
start: '2020-02-12T17:30:00'
},
{
title: 'Dinner',
start: '2020-02-12T20:00:00'
},
{
title: 'Birthday Party',
start: '2020-02-13T07:00:00'
},
{
title: 'Click for Google',
url: 'http://google.com/',
start: '2020-02-28'
}
]
});

calendar.render();
});

</script>
<style>

body {
margin: 40px 10px;
padding: 0;
font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
font-size: 14px;
text-align: center;
}

#calendar {
max-width: 900px;
margin: 0 auto;
}

</style>
</head>
<body>

<p style='margin-bottom: 5em'>
Demo for sticky header. Also, the bottom scrollbars stick.
</p>

<div id='calendar'></div>

<p style='margin-top: 5em'>
Cool, right?
</p>

</body>
</html>
136 changes: 136 additions & 0 deletions examples/timeline-sticky-header.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<link href='../packages-premium/bundle/dist/main.css' rel='stylesheet' />
<script src='../packages-premium/bundle/dist/main.js'></script>
<script>

document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');

var calendar = new FullCalendar.Calendar(calendarEl, {
height: 'auto', // enough to active sticky headers
// stickyHeader: false,
// stickyFooter: false,

now: '2020-02-07',
scrollTime: '00:00', // undo default 6am scrollTime
editable: true, // enable draggable events
selectable: true,
aspectRatio: 1.8,
header: {
left: 'today prev,next',
center: 'title',
right: 'resourceTimelineDay,resourceTimelineThreeDays,timeGridWeek,dayGridMonth,listWeek'
},
defaultView: 'resourceTimelineDay',
views: {
resourceTimelineThreeDays: {
type: 'resourceTimeline',
duration: { days: 3 },
buttonText: '3 days'
}
},
resourceAreaHeaderContent: 'Rooms',
resources: [
{ id: 'a', title: 'Auditorium A' },
{ id: 'b', title: 'Auditorium B', eventColor: 'green' },
{ id: 'c', title: 'Auditorium C', eventColor: 'orange' },
{ id: 'd', title: 'Auditorium D', children: [
{ id: 'd1', title: 'Room D1' },
{ id: 'd2', title: 'Room D2' }
] },
{ id: 'e', title: 'Auditorium E' },
{ id: 'f', title: 'Auditorium F', eventColor: 'red' },
{ id: 'g', title: 'Auditorium G' },
{ id: 'h', title: 'Auditorium H' },
{ id: 'i', title: 'Auditorium I' },
{ id: 'j', title: 'Auditorium J' },
{ id: 'k', title: 'Auditorium K' },
{ id: 'l', title: 'Auditorium L' },
{ id: 'm', title: 'Auditorium M' },
{ id: 'n', title: 'Auditorium N' },
{ id: 'o', title: 'Auditorium O' },
{ id: 'p', title: 'Auditorium P' },
{ id: 'q', title: 'Auditorium Q' },
{ id: 'r', title: 'Auditorium R' },
{ id: 's', title: 'Auditorium S' },
{ id: 't', title: 'Auditorium T' },
{ id: 'u', title: 'Auditorium U' },
{ id: 'v', title: 'Auditorium V' },
{ id: 'w', title: 'Auditorium W' },
{ id: 'x', title: 'Auditorium X' },
{ id: 'y', title: 'Auditorium Y' },
{ id: 'z', title: 'Auditorium Z' },
{ id: 'a2', title: 'Auditorium A2' },
{ id: 'b2', title: 'Auditorium B2' },
{ id: 'c2', title: 'Auditorium C2' },
{ id: 'd2', title: 'Auditorium D2' },
{ id: 'e2', title: 'Auditorium E2' },
{ id: 'f2', title: 'Auditorium F2' },
{ id: 'g2', title: 'Auditorium G2' },
{ id: 'h2', title: 'Auditorium H2' },
{ id: 'i2', title: 'Auditorium I2' },
{ id: 'j2', title: 'Auditorium J2' },
{ id: 'k2', title: 'Auditorium K2' },
{ id: 'l2', title: 'Auditorium L2' },
{ id: 'm2', title: 'Auditorium M2' },
{ id: 'n2', title: 'Auditorium N2' },
{ id: 'o2', title: 'Auditorium O2' },
{ id: 'p2', title: 'Auditorium P2' },
{ id: 'q2', title: 'Auditorium Q2' },
{ id: 'r2', title: 'Auditorium R2' },
{ id: 's2', title: 'Auditorium S2' },
{ id: 't2', title: 'Auditorium T2' },
{ id: 'u2', title: 'Auditorium U2' },
{ id: 'v2', title: 'Auditorium V2' },
{ id: 'w2', title: 'Auditorium W2' },
{ id: 'x2', title: 'Auditorium X2' },
{ id: 'y2', title: 'Auditorium Y2' },
{ id: 'z2', title: 'Auditorium Z2' }
],
events: [
{ id: '1', resourceId: 'b', start: '2020-02-07T02:00:00', end: '2020-02-07T07:00:00', title: 'event 1' },
{ id: '2', resourceId: 'c', start: '2020-02-07T05:00:00', end: '2020-02-07T22:00:00', title: 'event 2' },
{ id: '3', resourceId: 'd', start: '2020-02-06', end: '2020-02-08', title: 'event 3' },
{ id: '4', resourceId: 'e', start: '2020-02-07T03:00:00', end: '2020-02-07T08:00:00', title: 'event 4' },
{ id: '5', resourceId: 'f', start: '2020-02-07T00:30:00', end: '2020-02-07T02:30:00', title: 'event 5' }
]
});

calendar.render();
});

</script>
<style>

body {
margin: 0;
padding: 0;
font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
font-size: 14px;
text-align: center;
}

#calendar {
max-width: 900px;
margin: 50px auto;
}

</style>
</head>
<body>

<p style='margin-bottom: 5em'>
Demo for sticky header. Also, the bottom scrollbars stick.
</p>

<div id='calendar'></div>

<p style='margin-top: 5em'>
Did you see how the bottom scrollbars stuck?
</p>

</body>
</html>
3 changes: 1 addition & 2 deletions examples/vertical-resource-view.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@
var calendar = new FullCalendar.Calendar(calendarEl, {

// // for testing sticky
// viewHeaderSticky: true,
// height: 'auto',
// height: 'auto', // enough to active sticky headers
// slotDuration: '00:10:00',

// resourceLabelContent: function(arg) { console.log('resourceLabelContent', arg); return 'label' },
Expand Down
2 changes: 1 addition & 1 deletion packages-premium
4 changes: 3 additions & 1 deletion packages/core/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,9 @@ export {
sanitizeShrinkWidth,
ChunkConfigRowContent, ChunkConfigContent,
isColPropsEqual,
renderScrollShim
renderScrollShim,
getStickyFooter,
getStickyHeader
} from './scrollgrid/util'
export { default as Scroller, ScrollerProps, OverflowValue } from './scrollgrid/Scroller'
export { getScrollbarWidths } from './util/scrollbar-width'
Expand Down
22 changes: 22 additions & 0 deletions packages/core/src/scrollgrid/util.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -198,3 +198,25 @@ export function renderScrollShim(arg: ChunkContentCallbackArgs) {
}} />
)
}


export function getStickyHeader(options) {
let { stickyHeader } = options

if (stickyHeader == null || stickyHeader === 'auto') {
stickyHeader = options.height === 'auto' || options.viewHeight === 'auto'
}

return stickyHeader
}


export function getStickyFooter(options) {
let { stickyFooter } = options

if (stickyFooter == null || stickyFooter === 'auto') {
stickyFooter = options.height === 'auto' || options.viewHeight === 'auto'
}

return stickyFooter
}
32 changes: 12 additions & 20 deletions packages/daygrid/src/TableView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import {
DateComponent,
ViewProps,
RefObject,
renderScrollShim
renderScrollShim,
getStickyHeader,
getStickyFooter
} from '@fullcalendar/core'


Expand All @@ -28,14 +30,14 @@ export default abstract class TableView<State={}> extends DateComponent<ViewProp
headerRowContent: VNode | null,
bodyContent: (contentArg: ChunkContentCallbackArgs) => VNode
) {
let { props } = this
let { props, context } = this
let sections: SimpleScrollGridSection[] = []
let { viewHeaderSticky } = this.context.options
let stickyHeader = getStickyHeader(context.options)

if (headerRowContent) {
sections.push({
type: 'head',
isSticky: viewHeaderSticky,
isSticky: stickyHeader,
chunk: {
elRef: this.headerElRef,
tableClassName: 'fc-col-header',
Expand All @@ -47,20 +49,9 @@ export default abstract class TableView<State={}> extends DateComponent<ViewProp
sections.push({
type: 'body',
liquid: true,
chunk: {
content: bodyContent
}
chunk: { content: bodyContent }
})

if (viewHeaderSticky) {
sections.push({
type: 'foot',
chunk: {
content: renderScrollShim
}
})
}

return (
<ViewRoot viewSpec={props.viewSpec}>
{(rootElRef, classNames) => (
Expand Down Expand Up @@ -90,14 +81,15 @@ export default abstract class TableView<State={}> extends DateComponent<ViewProp
throw new Error('No ScrollGrid implementation')
}

let { props } = this
let { viewHeaderSticky } = this.context.options
let { props, context } = this
let stickyHeader = getStickyHeader(context.options)
let stickyFooter = getStickyFooter(context.options)
let sections: ScrollGridSectionConfig[] = []

if (headerRowContent) {
sections.push({
type: 'head',
isSticky: viewHeaderSticky,
isSticky: stickyHeader,
chunks: [{
elRef: this.headerElRef,
tableClassName: 'fc-col-header',
Expand All @@ -114,7 +106,7 @@ export default abstract class TableView<State={}> extends DateComponent<ViewProp
}]
})

if (viewHeaderSticky) {
if (stickyFooter) {
sections.push({
type: 'foot',
isSticky: true,
Expand Down

0 comments on commit d1125d8

Please sign in to comment.