Skip to content

Commit

Permalink
#14: Remove MUI dependencies from Marks
Browse files Browse the repository at this point in the history
  • Loading branch information
netzwerg committed Apr 7, 2022
1 parent 1b97d16 commit e2b6e68
Show file tree
Hide file tree
Showing 21 changed files with 75 additions and 90 deletions.
8 changes: 3 additions & 5 deletions src/Timeline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,21 @@ import React, { useCallback } from 'react'

import { Domain, EventComponentFactory, LaneDisplayMode, TimelineEvent, TimelineLane } from './model'

import { TimelineTheme } from './theme'
import { TimelineTheme } from './theme/model'
import { TimelineThemeProvider } from './theme/TimelineThemeProvider'

import { useEvents, useTimeline, useTimelineAnimation } from './hooks'

import { noOp } from './utils'

import { defaultOrderedZoomLevels, ZoomLevels } from './shared/ZoomScale'

import { GridLines } from './layers/GridLines'
import { ExpandedMarks } from './layers/ExpandedMarks'
import { Interaction } from './layers/interaction'
import { Interaction } from './layers/interaction/Interaction'
import { CollapsedMarks } from './layers/CollapsedMarks'
import { EventClusters } from './layers/EventClusters'
import { Axes } from './layers/Axes'
import { Axis } from './layers/Axis'
import { TimelineLayer } from '.'
import { defaultOrderedZoomLevels, TimelineLayer, ZoomLevels } from '.'

export interface TimelineProps<EID extends string, LID extends string, E extends TimelineEvent<EID, LID>> {
width: number
Expand Down
6 changes: 4 additions & 2 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export * from './model'
export * from './Timeline'
export * from './layers/Marks'
export * from './layers/interaction'
export * from './layers/interaction/model'
export * from './layers/interaction/Interaction'
export * from './shared/ZoomScale'
export { TimelineTheme, createTimelineTheme } from './theme'
export { TimelineTheme } from './theme/model'
export { createTimelineTheme } from './theme/createTimelineTheme'
2 changes: 1 addition & 1 deletion src/layers/Axes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ScaleBand } from 'd3-scale'
import { TimelineLane } from '../model'
import { Axis } from './Axis'
import { defaultLaneColor } from '../utils'
import { useTimelineTheme } from '../theme'
import { useTimelineTheme } from '../theme/useTimelineTheme'

export interface AxesProps<LID extends string> {
lanes: ReadonlyArray<TimelineLane<LID>>
Expand Down
2 changes: 1 addition & 1 deletion src/layers/Axis.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react'
import { useTimelineTheme } from '../theme'
import { useTimelineTheme } from '../theme/useTimelineTheme'

export const Axis = ({ y }: { y: number }) => {
const theme = useTimelineTheme()
Expand Down
2 changes: 1 addition & 1 deletion src/layers/EventClusters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ScaleBand, ScaleLinear, scaleSqrt } from 'd3-scale'
import { TimelineEventCluster } from '../model'
import { defaultClusterColor, defaultSingleEventMarkHeight } from '../utils'
import { extent } from 'd3-array'
import { useTimelineTheme } from '../theme'
import { useTimelineTheme } from '../theme/useTimelineTheme'

const useCircleStyle = () => {
const theme = useTimelineTheme()
Expand Down
2 changes: 1 addition & 1 deletion src/layers/GridLines.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { monthDuration, weekDuration, yearDuration, ZoomLevels } from '../shared
import { addMonths, addWeeks, endOfMonth, endOfWeek, isBefore, isEqual, startOfWeek } from 'date-fns'
import { Domain } from '../model'
import { range } from '../utils'
import { useTimelineTheme } from '../theme'
import { useTimelineTheme } from '../theme/useTimelineTheme'
import { XAxisTheme } from '../theme/model'
import { CSSProperties } from 'react'

Expand Down
23 changes: 6 additions & 17 deletions src/layers/Marks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { ScaleLinear } from 'd3-scale'
import { Theme } from '@material-ui/core'
import { EventComponentFactory, EventComponentRole, TimelineEvent } from '../model'
import useTheme from '@material-ui/core/styles/useTheme'
import { EventTooltip, TooltipClasses, useTooltipStyle } from '../tooltip'
import { useTimelineTheme } from '../theme'
import { EventTooltip } from '../tooltip/EventTooltip'
import { useTimelineTheme } from '../theme/useTimelineTheme'

const useEventBackgroundStyle = () => {
const theme = useTimelineTheme().base
Expand Down Expand Up @@ -68,12 +68,10 @@ export const Marks = <EID extends string, LID extends string, E extends Timeline
props: Props<EID, LID, E>
) => {
const { events, height } = props
const timelineTheme = useTimelineTheme()
const eventBackgroundStyle = useEventBackgroundStyle()
const eventPeriodStyle = useEventPeriodStyle()
const eventCircleStyle = useEventCircleStyle()
const eventSelectedStyle = useEventSelectedStyle()
const tooltipClasses = useTooltipStyle(timelineTheme.tooltip)
const { eventComponent, timeScale, y } = props

// shorter periods on top of longer ones
Expand Down Expand Up @@ -109,7 +107,7 @@ export const Marks = <EID extends string, LID extends string, E extends Timeline
const backgroundMarks = useMemo(
() =>
events.map((e: E) => (
<InteractiveEventMark key={e.eventId} event={e} tooltipClasses={tooltipClasses} {...props}>
<InteractiveEventMark key={e.eventId} event={e} {...props}>
{eventComponentFactory(e, 'background', timeScale, y)}
</InteractiveEventMark>
)),
Expand All @@ -122,7 +120,7 @@ export const Marks = <EID extends string, LID extends string, E extends Timeline
.filter((_) => true)
.sort(sortByEventDuration)
.map((e: E) => (
<InteractiveEventMark key={e.eventId} event={e} tooltipClasses={tooltipClasses} {...props}>
<InteractiveEventMark key={e.eventId} event={e} {...props}>
{eventComponentFactory(e, 'foreground', timeScale, y)}
</InteractiveEventMark>
)),
Expand All @@ -135,7 +133,7 @@ export const Marks = <EID extends string, LID extends string, E extends Timeline
.filter((e) => e.isSelected || e.isPinned)
.sort(sortByEventDuration)
.map((e: E) => (
<InteractiveEventMark key={e.eventId} event={e} tooltipClasses={tooltipClasses} {...props}>
<InteractiveEventMark key={e.eventId} event={e} {...props}>
{eventComponentFactory(e, 'foreground', timeScale, y)}
</InteractiveEventMark>
)),
Expand All @@ -158,7 +156,6 @@ interface InteractiveGroupProps<EID extends string, LID extends string, E extend
onEventHover?: (eventId: EID) => void
onEventUnhover?: (eventId: EID) => void
onEventClick?: (eventId: EID) => void
tooltipClasses: TooltipClasses
children: React.ReactNode
}

Expand All @@ -169,7 +166,6 @@ const InteractiveEventMark = <EID extends string, LID extends string, E extends
onEventClick = noOp,
onEventHover = noOp,
onEventUnhover = noOp,
tooltipClasses,
children,
}: InteractiveGroupProps<EID, LID, E>) => {
const eventId = event.eventId
Expand All @@ -194,14 +190,7 @@ const InteractiveEventMark = <EID extends string, LID extends string, E extends
>
<g ref={triggerRef}>{children}</g>
{event.tooltip ? (
<EventTooltip
type={tooltipType}
y={y}
parentWidth={parentWidth}
triggerRef={triggerRef}
text={event.tooltip}
classes={tooltipClasses}
/>
<EventTooltip type={tooltipType} y={y} parentWidth={parentWidth} triggerRef={triggerRef} text={event.tooltip} />
) : (
<g />
)}
Expand Down
2 changes: 1 addition & 1 deletion src/layers/interaction/CursorLabel.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { CSSProperties } from 'react'
import { useTimelineTheme } from '../../theme'
import { useTimelineTheme } from '../../theme/useTimelineTheme'

const useTextStyle = (fill?: string): CSSProperties => {
const theme = useTimelineTheme()
Expand Down
8 changes: 5 additions & 3 deletions src/layers/interaction/Interaction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ import React from 'react'
import { ScaleLinear } from 'd3-scale'

import { Domain } from '../../model'
import { ZoomLevels, getDomainSpan } from '../../shared/ZoomScale'
import { InteractionHandling } from './InteractionHandling'
import { MouseAwareSvg, SvgCoordinates } from './MouseAwareSvg'
import { MouseCursor } from './MouseCursor'
import { Trimmer, TrimRange, useTrimming } from './trimmer'
import { useZoom } from '../../hooks'
import { ZoomLevels, getDomainSpan } from '../../shared/ZoomScale'
import { InteractionHandling } from './InteractionHandling'
import { useTrimming } from './trimmer/useTrimming'
import { TrimRange } from './trimmer/TrimRange'
import { Trimmer } from './trimmer/Trimmer'

export interface InteractionProps {
width: number
Expand Down
4 changes: 2 additions & 2 deletions src/layers/interaction/MouseCursor.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import * as React from 'react'
import { ZoomScale } from '../../shared/ZoomScale'
import { Cursor } from '../../model'
import { InteractionMode } from '.'
import { CursorLabel } from './CursorLabel'
import { useTimelineTheme } from '../../theme'
import { useTimelineTheme } from '../../theme/useTimelineTheme'
import { InteractionMode } from './model'

const useCursorStyle = () => {
const theme = useTimelineTheme().mouseCursor
Expand Down
2 changes: 0 additions & 2 deletions src/layers/interaction/index.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/layers/interaction/trimmer/TrimHandle.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { CSSProperties } from 'react'
import { CursorLabel } from '../CursorLabel'
import { useTimelineTheme } from '../../../theme'
import { useTimelineTheme } from '../../../theme/useTimelineTheme'

const useTrimHandleStyle = (): CSSProperties => {
const theme = useTimelineTheme().trimmer
Expand Down
2 changes: 1 addition & 1 deletion src/layers/interaction/trimmer/TrimRange.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { CSSProperties } from 'react'
import { useTimelineTheme } from '../../../theme'
import { useTimelineTheme } from '../../../theme/useTimelineTheme'

const useTrimRangeStyle = (): CSSProperties => {
const theme = useTimelineTheme().trimmer
Expand Down
4 changes: 2 additions & 2 deletions src/layers/interaction/trimmer/Trimmer.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from 'react'
import { makeStyles } from '@material-ui/core'
import { ScaleLinear } from 'd3-scale'
import { TrimHover, TrimNone } from '..'
import TrimHandle from './TrimHandle'
import Triangle, { TriangleDirection } from '../../../shared/Triangle'
import { useTimelineTheme } from '../../../theme'
import { useTimelineTheme } from '../../../theme/useTimelineTheme'
import { TrimmerTheme } from '../../../theme/model'
import { TrimHover, TrimNone } from '../model'

const useStyles = makeStyles(() => ({
trimmerArea: (trimmerTheme: TrimmerTheme) => ({
Expand Down
3 changes: 0 additions & 3 deletions src/layers/interaction/trimmer/index.ts

This file was deleted.

2 changes: 2 additions & 0 deletions src/theme/createTimelineTheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ export const createTimelineTheme = (theme: MaterialTheme, options?: TimelineThem
},
tooltip: {
backgroundColor: theme.palette.text.secondary,
fontSize: 14,
fontFamily: theme.typography.caption.fontFamily,
},
trimmer: {
trimHandleColor: ORANGE_DEFAULT,
Expand Down
3 changes: 0 additions & 3 deletions src/theme/index.ts

This file was deleted.

2 changes: 2 additions & 0 deletions src/theme/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ export interface LaneTheme {
}

export interface TooltipTheme {
readonly fontSize: number
readonly fontFamily: React.CSSProperties['fontFamily']
readonly backgroundColor: string
}

Expand Down
59 changes: 42 additions & 17 deletions src/tooltip/EventTooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,44 @@ import * as React from 'react'
import TextSize from '../shared/TextSize'
import { Tooltip } from 'react-svg-tooltip'
import { scaleLinear } from 'd3-scale'
import { TooltipClasses, TOOLTIP_FONT_SIZE } from './useTooltipStyle'
import { CSSProperties } from 'react'
import { useTimelineTheme } from '../theme/useTimelineTheme'

const useTooltipRootSvgStyle = (): CSSProperties => ({
textAlign: 'left',
})

const useBackgroundStyle = (): CSSProperties => {
const theme = useTimelineTheme().tooltip
return { fill: theme.backgroundColor, strokeWidth: 0 }
}

const useTooltipTextStyle = (): CSSProperties => {
const theme = useTimelineTheme().tooltip
return {
fill: 'white',
dominantBaseline: 'middle',
textAnchor: 'middle',
fontFamily: theme.fontFamily,
fontSize: theme.fontSize,
}
}

interface Props {
readonly type: { singleEventX: number } | 'period'
readonly y: number
readonly parentWidth: number
readonly text: string
readonly triggerRef: React.RefObject<SVGElement>
readonly classes: TooltipClasses
}

export const EventTooltip = ({ type, y, parentWidth, text, triggerRef, classes }: Props) => {
const { textLines, tooltipWidth, tooltipHeight, baseHeight } = getTooltipDimensions(text)
export const EventTooltip = ({ type, y, parentWidth, text, triggerRef }: Props) => {
const tooltipRootSvgStyle = useTooltipRootSvgStyle()
const tooltipBackgroundStyle = useBackgroundStyle()
const tooltipTextStyle = useTooltipTextStyle()
const tooltipFontSize = useTimelineTheme().tooltip.fontSize

const { textLines, tooltipWidth, tooltipHeight, baseHeight } = getTooltipDimensions(text, tooltipFontSize)

return (
<Tooltip triggerRef={triggerRef}>
Expand Down Expand Up @@ -43,16 +68,16 @@ export const EventTooltip = ({ type, y, parentWidth, text, triggerRef, classes }

return (
<g>
<svg x={svgX} y={svgY} width={tooltipWidth} height={tooltipHeight} className={classes.svg}>
<rect width="100%" height="100%" rx={3} ry={3} className={classes.background} />
<svg style={tooltipRootSvgStyle} x={svgX} y={svgY} width={tooltipWidth} height={tooltipHeight}>
<rect style={tooltipBackgroundStyle} width="100%" height="100%" rx={3} ry={3} />
<TooltipText
style={tooltipTextStyle}
textLines={textLines}
tooltipHeight={tooltipHeight}
tooltipWidth={tooltipWidth}
className={classes.text}
/>
</svg>
<ArrowDown tipX={tooltipX} baseY={baseY} dimension={arrowDimension} className={classes.background} />)
<ArrowDown style={tooltipBackgroundStyle} tipX={tooltipX} baseY={baseY} dimension={arrowDimension} />)
</g>
)
}}
Expand All @@ -64,10 +89,10 @@ interface ArrowDownProps {
readonly tipX: number
readonly baseY: number
readonly dimension: number
readonly className: string
readonly style: CSSProperties
}

const ArrowDown = ({ tipX, baseY, dimension, className }: ArrowDownProps) => {
const ArrowDown = ({ tipX, baseY, dimension, style }: ArrowDownProps) => {
return (
<svg
x={tipX - dimension / 2}
Expand All @@ -76,15 +101,15 @@ const ArrowDown = ({ tipX, baseY, dimension, className }: ArrowDownProps) => {
width={dimension}
height={dimension}
>
<path className={className} d={`M0 2.5 l 5 5 5-5z`} />
<path style={style} d={`M0 2.5 l 5 5 5-5z`} />
</svg>
)
}

/**
* Calculates the `width` and `height` of the passed tooltip text.
*/
const getTooltipDimensions = (inputText: string) => {
const getTooltipDimensions = (inputText: string, fontSize: number) => {
const text = inputText || ''
const textLines = text.split('\n')
const numLinesInText = textLines.length
Expand All @@ -98,12 +123,12 @@ const getTooltipDimensions = (inputText: string) => {
if (isMultiLineText) {
let maxWidth = 0
textLines.forEach((textLine) => {
const textLineWidth = TextSize.getTextWidth(textLine, TOOLTIP_FONT_SIZE)
const textLineWidth = TextSize.getTextWidth(textLine, fontSize)
maxWidth = Math.max(textLineWidth, maxWidth)
})
width = maxWidth + horizontalPadding * 2
} else {
width = TextSize.getTextWidth(text, TOOLTIP_FONT_SIZE) + horizontalPadding * 2
width = TextSize.getTextWidth(text, fontSize) + horizontalPadding * 2
}

const singleLineHeight = 30
Expand All @@ -119,14 +144,14 @@ const getTooltipDimensions = (inputText: string) => {

interface TooltipTextProps {
readonly textLines: string[]
readonly className: string
readonly style: CSSProperties
readonly tooltipWidth: number
readonly tooltipHeight: number
}

const TooltipText = ({ textLines, className, tooltipWidth, tooltipHeight }: TooltipTextProps) => {
const TooltipText = ({ textLines, style, tooltipWidth, tooltipHeight }: TooltipTextProps) => {
return (
<text className={className} width={tooltipWidth} height={tooltipHeight}>
<text style={style} width={tooltipWidth} height={tooltipHeight}>
{textLines.map((textLine, index) => {
return (
<tspan dy="1.2em" x="10" key={index} textAnchor="start">
Expand Down
2 changes: 0 additions & 2 deletions src/tooltip/index.ts

This file was deleted.

Loading

0 comments on commit e2b6e68

Please sign in to comment.