###*
Tooltips
========
Up.js comes with a basic tooltip implementation.
You can an [`up-tooltip`](/up-tooltip) attribute to any HTML tag to show a tooltip whenever
the user hovers over the element:
Decks
\#\#\#\# Styling
The [default styles](https://github.com/makandra/upjs/blob/master/lib/assets/stylesheets/up/tooltip.css.sass)
show a simple tooltip with white text on a gray background.
A gray triangle points to the element.
To change the styling, simply override CSS rules for the `.up-tooltip` selector and its `:after`
selector that is used the triangle.
The HTML of a tooltip element is simply this:
Show all decks
The tooltip element is appended to the end of ``.
@class up.tooltip
###
up.tooltip = (($) ->
u = up.util
###*
Sets default options for future tooltips.
@property up.tooltip.config
@param {String} [config.position]
The default position of tooltips relative to the element.
Can be either `"top"` or `"bottom"`.
@param {String} [config.openAnimation='fade-in']
The animation used to open a tooltip.
@param {String} [config.closeAnimation='fade-out']
The animation used to close a tooltip.
@stable
###
config = u.config
position: 'top'
openAnimation: 'fade-in'
closeAnimation: 'fade-out'
reset = ->
config.reset()
setPosition = ($link, $tooltip, position) ->
linkBox = u.measure($link)
tooltipBox = u.measure($tooltip)
css = switch position
when "top"
left: linkBox.left + 0.5 * (linkBox.width - tooltipBox.width)
top: linkBox.top - tooltipBox.height
when "bottom"
left: linkBox.left + 0.5 * (linkBox.width - tooltipBox.width)
top: linkBox.top + linkBox.height
else
u.error("Unknown position %o", position)
$tooltip.attr('up-position', position)
$tooltip.css(css)
createElement = (options) ->
$element = u.$createElementFromSelector('.up-tooltip')
if u.isGiven(options.text)
$element.text(options.text)
else
$element.html(options.html)
$element.appendTo(document.body)
$element
###*
Opens a tooltip over the given element.
up.tooltip.attach('.help', {
html: 'Enter multiple words or phrases'
});
@function up.tooltip.attach
@param {Element|jQuery|String} elementOrSelector
@param {String} [options.html]
The HTML to display in the tooltip.
@param {String} [options.position='top']
The position of the tooltip. Known values are `top` and `bottom`.
@param {String} [options.animation]
The animation to use when opening the tooltip.
@return {Promise}
A promise that will be resolved when the tooltip's opening animation has finished.
@stable
###
attach = (linkOrSelector, options = {}) ->
$link = $(linkOrSelector)
html = u.option(options.html, $link.attr('up-tooltip-html'))
text = u.option(options.text, $link.attr('up-tooltip'))
position = u.option(options.position, $link.attr('up-position'), config.position)
animation = u.option(options.animation, u.castedAttr($link, 'up-animation'), config.openAnimation)
animateOptions = up.motion.animateOptions(options, $link)
close()
$tooltip = createElement(text: text, html: html)
setPosition($link, $tooltip, position)
up.animate($tooltip, animation, animateOptions)
###*
Closes a currently shown tooltip.
Does nothing if no tooltip is currently shown.
@function up.tooltip.close
@param {Object} options
See options for [`up.animate`](/up.animate).
@stable
###
close = (options) ->
$tooltip = $('.up-tooltip')
if $tooltip.length
options = u.options(options, animation: config.closeAnimation)
options = u.merge(options, up.motion.animateOptions(options))
up.destroy($tooltip, options)
###*
Displays a tooltip with text content when hovering the mouse over this element:
Decks
To make the tooltip appear below the element instead of above the element,
add an `up-position` attribute:
Decks
@selector [up-tooltip]
@param {String} [up-animation]
The animation used to open the tooltip.
Defaults to [`up.tooltip.config.openAnimation`](/up.tooltip.config).
@param {String} [up-position]
The default position of tooltips relative to the element.
Can be either `"top"` or `"bottom"`.
Defaults to [`up.tooltip.config.position`](/up.tooltip.config).
@stable
###
###*
Displays a tooltip with HTML content when hovering the mouse over this element:
Decks
@selector [up-tooltip-html]
@stable
###
up.compiler('[up-tooltip], [up-tooltip-html]', ($link) ->
# Don't register these events on document since *every*
# mouse move interaction bubbles up to the document.
$link.on('mouseover', -> attach($link))
$link.on('mouseout', -> close())
)
# Close the tooltip when someone clicks anywhere.
up.on('click', 'body', (event, $body) ->
close()
)
# The framework is reset between tests, so also close
# a currently open tooltip.
up.on 'up:framework:reset', close
# Close the tooltip when the user presses ESC.
up.bus.onEscape(-> close())
# The framework is reset between tests
up.on 'up:framework:reset', reset
attach: attach
close: close
open: -> u.error('up.tooltip.open no longer exists. Use up.tooltip.attach instead.')
)(jQuery)