Skip to content

Commit

Permalink
add MoreLinkRoot, strip out current method for opening MorePopover
Browse files Browse the repository at this point in the history
  • Loading branch information
arshaw committed Apr 28, 2021
1 parent ce35cbc commit 5ae2ed9
Show file tree
Hide file tree
Showing 12 changed files with 146 additions and 219 deletions.
2 changes: 2 additions & 0 deletions packages/common/src/api-type-deps.ts
Expand Up @@ -19,6 +19,8 @@ export { ViewComponentType, SpecificViewContentArg, SpecificViewMountArg } from
export { ClassNamesGenerator, CustomContentGenerator, DidMountHandler, WillUnmountHandler } from './common/render-hook'
export { NowIndicatorContentArg, NowIndicatorMountArg } from './common/NowIndicatorRoot'
export { WeekNumberContentArg, WeekNumberMountArg } from './common/WeekNumberRoot'
export { MoreLinkContentArg, MoreLinkMountArg } from './common/MoreLinkRoot'
export * from './common/more-link'
export {
SlotLaneContentArg, SlotLaneMountArg,
SlotLabelContentArg, SlotLabelMountArg,
Expand Down
50 changes: 50 additions & 0 deletions packages/common/src/common/MoreLinkRoot.tsx
@@ -0,0 +1,50 @@
import { createElement } from '../vdom'
import { ViewApi } from '../ViewApi'
import { ViewContext, ViewContextType } from '../ViewContext'
import { MountArg, RenderHook, RenderHookPropsChildren } from './render-hook'

export interface MoreLinkRootProps { // what the MoreLinkRoot component receives
moreCnt: number
buildMoreLinkText: (moreCnt: number) => string
children: RenderHookPropsChildren
}

export interface MoreLinkContentArg { // what the render-hooks receive
num: number
text: string
view: ViewApi
}

export type MoreLinkMountArg = MountArg<MoreLinkContentArg>

export const MoreLinkRoot = (props: MoreLinkRootProps) => (
<ViewContextType.Consumer>
{(context: ViewContext) => {
let { viewApi, options } = context
let hookProps: MoreLinkContentArg = {
num: props.moreCnt,
text: props.buildMoreLinkText(props.moreCnt),
view: viewApi,
}

return (
<RenderHook<MoreLinkContentArg>
hookProps={hookProps}
classNames={options.moreLinkClassNames}
content={options.moreLinkContent}
defaultContent={renderMoreLinkInner}
didMount={options.moreLinkDidMount}
willUnmount={options.moreLinkWillUnmount}
>
{(rootElRef, customClassNames, innerElRef, innerContent) => props.children(
rootElRef, ['fc-event-more'].concat(customClassNames), innerElRef, innerContent,
)}
</RenderHook>
)
}}
</ViewContextType.Consumer>
)

function renderMoreLinkInner(props) {
return props.text
}
@@ -1,4 +1,6 @@
import { EventApi, ViewApi, VUIEvent } from '@fullcalendar/common'
import { EventApi } from '../api/EventApi'
import { VUIEvent } from '../vdom'
import { ViewApi } from '../ViewApi'

export interface EventSegment {
event: EventApi
Expand All @@ -12,11 +14,11 @@ export type MoreLinkAction = MoreLinkSimpleAction | MoreLinkHandler
export type MoreLinkSimpleAction = 'popover' | 'week' | 'day' | 'timeGridWeek' | 'timeGridDay' | string

export interface MoreLinkArg {
date: Date,
allDay: boolean,
allSegs: EventSegment[],
hiddenSegs: EventSegment[],
jsEvent: VUIEvent,
date: Date
allDay: boolean
allSegs: EventSegment[]
hiddenSegs: EventSegment[]
jsEvent: VUIEvent
view: ViewApi
}

Expand Down
1 change: 1 addition & 0 deletions packages/common/src/main.ts
Expand Up @@ -264,6 +264,7 @@ export { DayCellContent, DayCellContentProps } from './common/DayCellContent'
export { EventRoot, MinimalEventProps } from './common/EventRoot'
export { renderFill, BgEvent, BgEventProps } from './common/bg-fill'
export { WeekNumberRoot, WeekNumberRootProps } from './common/WeekNumberRoot'
export { MoreLinkRoot, MoreLinkContentArg, MoreLinkMountArg } from './common/MoreLinkRoot'

export { ViewRoot, ViewRootProps } from './common/ViewRoot'
export { triggerDateSelect, DatePointTransform, DateSpanTransform, DateSelectionApi, getDefaultEventEnd } from './calendar-utils'
9 changes: 9 additions & 0 deletions packages/common/src/options.ts
Expand Up @@ -38,6 +38,9 @@ import {
EventContentArg, EventMountArg,
DatesSetArg,
EventApi, EventAddArg, EventChangeArg, EventRemoveArg,
MoreLinkContentArg,
MoreLinkMountArg,
MoreLinkAction,
} from './api-type-deps'

// base options
Expand Down Expand Up @@ -213,6 +216,12 @@ export const BASE_OPTION_REFINERS = {

// only used by list-view, but languages define the value, so we need it in base options
noEventsText: String,

moreLinkClick: identity as Identity<MoreLinkAction>,
moreLinkClassNames: identity as Identity<ClassNamesGenerator<MoreLinkContentArg>>,
moreLinkContent: identity as Identity<CustomContentGenerator<MoreLinkContentArg>>,
moreLinkDidMount: identity as Identity<DidMountHandler<MoreLinkMountArg>>,
moreLinkWillUnmount: identity as Identity<WillUnmountHandler<MoreLinkMountArg>>,
}

type BuiltInBaseOptionRefiners = typeof BASE_OPTION_REFINERS
Expand Down
109 changes: 3 additions & 106 deletions packages/daygrid/src/Table.tsx
Expand Up @@ -14,16 +14,12 @@ import {
DateRange,
NowTimer,
DateMarker,
EventApi,
DateProfile,
Fragment,
createRef,
} from '@fullcalendar/common'
import { TableSeg, splitSegsByRow, splitInteractionByRow } from './TableSeg'
import { TableRow } from './TableRow'
import { TableCellModel, MoreLinkArg } from './TableCell'
import { MorePopover } from './MorePopover'
import { MoreLinkAction } from './more-link'
import { TableCellModel } from './TableCell'

export interface TableProps {
elRef?: Ref<HTMLDivElement>
Expand All @@ -49,17 +45,7 @@ export interface TableProps {
forPrint: boolean
}

interface TableState {
morePopoverState: MorePopoverState | null
}

interface MorePopoverState extends MoreLinkArg {
currentFgEventSegs: TableSeg[]
fromRow: number
fromCol: number
}

export class Table extends DateComponent<TableProps, TableState> {
export class Table extends DateComponent<TableProps> {
private splitBusinessHourSegs = memoize(splitSegsByRow)
private splitBgEventSegs = memoize(splitSegsByRow)
private splitFgEventSegs = memoize(splitSegsByRow)
Expand All @@ -68,19 +54,13 @@ export class Table extends DateComponent<TableProps, TableState> {
private splitEventResize = memoize(splitInteractionByRow)
private buildBuildMoreLinkText = memoize(buildBuildMoreLinkText)
private rootEl: HTMLElement
private morePopoverRef = createRef<MorePopover>()
private rowRefs = new RefMap<TableRow>()
private rowPositions: PositionCache
private colPositions: PositionCache

state: TableState = {
morePopoverState: null,
}

render() {
let { props } = this
let { dateProfile, dayMaxEventRows, dayMaxEvents, expandRows } = props
let { morePopoverState } = this.state
let rowCnt = props.cells.length

let businessHourSegsByRow = this.splitBusinessHourSegs(props.businessHourSegs, rowCnt)
Expand Down Expand Up @@ -157,34 +137,11 @@ export class Table extends DateComponent<TableProps, TableState> {
clientWidth={props.clientWidth}
clientHeight={props.clientHeight}
buildMoreLinkText={buildMoreLinkText}
onMoreClick={(arg) => {
this.handleMoreLinkClick({ ...arg, fromRow: row })
}}
forPrint={props.forPrint}
/>
))}
</tbody>
</table>
{ // clear popover on event mod
(!props.forPrint && morePopoverState && morePopoverState.currentFgEventSegs === props.fgEventSegs) && (
<MorePopover
ref={this.morePopoverRef}
date={morePopoverState.date}
dateProfile={dateProfile}
segs={morePopoverState.allSegs}
alignmentEl={morePopoverState.dayEl}
topAlignmentEl={rowCnt === 1 ? props.headerAlignElRef.current : null}
onCloseClick={this.handleMorePopoverClose}
selectedInstanceId={props.eventSelection}
hiddenInstances={// yuck
(props.eventDrag ? props.eventDrag.affectedInstances : null) ||
(props.eventResize ? props.eventResize.affectedInstances : null) ||
{}
}
todayRange={todayRange}
/>
)
}
</Fragment>
)}
</NowTimer>
Expand All @@ -197,55 +154,6 @@ export class Table extends DateComponent<TableProps, TableState> {
setRef(this.props.elRef, rootEl)
}

// TODO: bad names "more link click" versus "more click"
handleMoreLinkClick = (arg: MoreLinkArg & {fromRow: number, fromCol: number}) => {
let { context } = this
let { dateEnv } = context
let clickOption = context.options.moreLinkClick

function segForPublic(seg: TableSeg) {
let { def, instance, range } = seg.eventRange

return {
event: new EventApi(context, def, instance),
start: dateEnv.toDate(range.start),
end: dateEnv.toDate(range.end),
isStart: seg.isStart,
isEnd: seg.isEnd,
}
}

if (typeof clickOption === 'function') {
clickOption = clickOption({
date: dateEnv.toDate(arg.date),
allDay: true,
allSegs: arg.allSegs.map(segForPublic),
hiddenSegs: arg.hiddenSegs.map(segForPublic),
jsEvent: arg.ev,
view: context.viewApi,
}) as (MoreLinkAction | undefined) // hack to handle void
}

if (!clickOption || clickOption === 'popover') {
this.setState({
morePopoverState: {
...arg,
currentFgEventSegs: this.props.fgEventSegs,
fromRow: arg.fromRow,
fromCol: arg.fromCol,
},
})
} else if (typeof clickOption === 'string') { // a view name
context.calendarApi.zoomTo(arg.date, clickOption)
}
}

handleMorePopoverClose = () => {
this.setState({
morePopoverState: null,
})
}

// Hit System
// ----------------------------------------------------------------------------------------------------

Expand All @@ -266,18 +174,6 @@ export class Table extends DateComponent<TableProps, TableState> {
}

positionToHit(leftPosition, topPosition) {
let morePopover = this.morePopoverRef.current
let morePopoverHit = morePopover ? morePopover.positionToHit(leftPosition, topPosition, this.rootEl) : null
let { morePopoverState } = this.state

if (morePopoverHit) {
return {
row: morePopoverState.fromRow,
col: morePopoverState.fromCol,
...morePopoverHit,
}
}

let { colPositions, rowPositions } = this
let col = colPositions.leftToIndex(leftPosition)
let row = rowPositions.topToIndex(topPosition)
Expand Down Expand Up @@ -314,6 +210,7 @@ export class Table extends DateComponent<TableProps, TableState> {
}
}

// builds the FUNCTION
function buildBuildMoreLinkText(moreLinkTextInput): (num: number) => string {
if (typeof moreLinkTextInput === 'function') {
return moreLinkTextInput
Expand Down

0 comments on commit 5ae2ed9

Please sign in to comment.