Skip to content

Commit

Permalink
feat(toolbar): add tooltips
Browse files Browse the repository at this point in the history
  • Loading branch information
markchou0225 committed Feb 25, 2024
1 parent dea5ea4 commit d879004
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 3 deletions.
22 changes: 22 additions & 0 deletions packages/core/src/components/axes/toolbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export class Toolbar extends Component {
.merge(toolbarControls as any)
.classed('disabled', (d: any) => d.shouldBeDisabled())
.attr('aria-disabled', (d: any) => d.shouldBeDisabled())
.attr('role', 'button')
.attr('aria-label', (d: any) => d.title)
.html((d: any) => {
return `
Expand All @@ -100,12 +101,33 @@ export class Toolbar extends Component {
.each(function (d: any, index: number) {
select(this)
.select('svg')
.style('pointer-events', 'none')
.style('will-change', 'transform')
.style('width', d.iconSVG.width !== undefined ? d.iconSVG.width : '20px')
.style('height', d.iconSVG.height !== undefined ? d.iconSVG.height : '20px')

select(this)
.select('button')
.on('mouseover focus', function (event: MouseEvent) {
const hoveredElement = select(this)
hoveredElement.classed('hovered', true)
self.services.events.dispatchEvent(Events.Tooltip.SHOW, {
event,
hoveredElement,
content: d.title,
placement: 'top'
})
})
.on('mousemove focusin', function (event: MouseEvent) {
self.services.events.dispatchEvent(Events.Tooltip.MOVE, {
event,
content: d.title,
placement: 'top'
})
})
.on('mouseout blur', function () {
self.services.events.dispatchEvent(Events.Tooltip.HIDE)
})
.on('click', (event: CustomEvent<MouseEvent>) => {
if (!d.shouldBeDisabled()) {
self.triggerFunctionAndEvent(d, event, this)
Expand Down
37 changes: 35 additions & 2 deletions packages/core/src/components/essentials/tooltip.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { select, pointer } from 'd3'
import Position, { PLACEMENTS } from '@carbon/utils-position' // position service
import Position, { PLACEMENTS, defaultPositions } from '@carbon/utils-position' // position service
import { getProperty, truncateLabel } from '@/tools'
import { zoomBar as zoomBarConfigs, tooltips as tooltipConfigs } from '@/configuration'
import { carbonPrefix } from '@/configuration-non-customizable' // CSS prefix
Expand Down Expand Up @@ -238,13 +238,47 @@ export class Tooltip extends Component {
}
}

getOffsetByPlacement(position: any, placement: string, offset: number) {
const newOffset = Object.assign({}, position)
if (placement == PLACEMENTS.LEFT) {
newOffset.left -= offset
} else if (placement == PLACEMENTS.RIGHT) {
newOffset.left += offset
} else if (placement == PLACEMENTS.TOP) {
newOffset.top -= offset
} else if (placement == PLACEMENTS.BOTTOM) {
newOffset.top += offset
}
return newOffset
}

positionTooltip(e: CustomEvent) {
const holder = this.services.domUtils.getHolder()
const target = this.tooltip.node()
const options = this.getOptions()
const isTopZoomBarEnabled = getProperty(options, 'zoomBar', 'top', 'enabled')

let { horizontalOffset, defaultOffsetSmall } = tooltipConfigs
let mouseRelativePos = getProperty(e, 'detail', 'mousePosition')
const customPlacement: PLACEMENTS | undefined | null = getProperty(e, 'detail', 'placement')

// set Tooltip based on custom placement relative to the triggered dom
if (customPlacement) {
const hovered = getProperty(e, 'detail', 'event', 'target')
const hoveredRect = hovered.getBoundingClientRect()
const position = defaultPositions[customPlacement](
this.getOffsetByPlacement(
this.services.domUtils.getElementOffset(hovered),
customPlacement,
defaultOffsetSmall
),
target,
hoveredRect
)
this.positionService.setElement(target, position)
return ;
}
// set Tooltip based on mouse position
if (!mouseRelativePos) {
mouseRelativePos = pointer(getProperty(e, 'detail', 'event'), holder)
} else {
Expand Down Expand Up @@ -288,7 +322,6 @@ export class Tooltip extends Component {
)
}

let { horizontalOffset } = tooltipConfigs
if (bestPlacementOption === PLACEMENTS.LEFT) {
horizontalOffset *= -1
}
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/configuration-non-customizable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,9 @@ export const spacers = {
}

export const tooltips = {
horizontalOffset: 10
horizontalOffset: 10,
defaultOffsetSmall: 4,
defaultOffsetNormal: 8,
}

/**
Expand Down
16 changes: 16 additions & 0 deletions packages/core/src/services/essentials/dom-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,22 @@ export class DOMUtils extends Service {
return this.chartID
}

getElementOffset(element: HTMLElement) {
// get relative position { left, top } of the chart holder
const elementOffset = { left: 0, top: 0 }
const childRect = element.getBoundingClientRect()
const baseRect = this.getHolder().getBoundingClientRect()

try {
elementOffset.left = childRect.left - baseRect.left
elementOffset.top = childRect.top - baseRect.top
} catch (e) {
console.error(e)
}

return elementOffset
}

generateElementIDString(originalID: string | number) {
return `chart-${this.chartID}-${originalID}`
}
Expand Down

0 comments on commit d879004

Please sign in to comment.