Add icon support to tooltip and add SpellTooltip component
This commit is contained in:
@@ -6,22 +6,24 @@ interface Props {
|
||||
name?: string
|
||||
size?: 'small' | 'medium' | 'large'
|
||||
golden?: boolean
|
||||
className?: string
|
||||
}
|
||||
|
||||
const NOT_FOUND_ICON = 'inv_misc_questionmark'
|
||||
|
||||
export const Icon: FC<Props> = ({ name: defaultName, size = 'medium', golden = false, children }) => {
|
||||
export const Icon: FC<Props> = (props) => {
|
||||
const { name: defaultName, size = 'medium', golden = false, children } = props
|
||||
const [hasLoadedImage, setLoadedImage] = useState(false)
|
||||
const [fadeIn, setFadeIn] = useState(false)
|
||||
const [name, setName] = useState(defaultName)
|
||||
|
||||
const bgSize = size !== 'small' ? 'large' : 'medium'
|
||||
const url = `https://wow.zamimg.com/images/wow/icons/${bgSize}/${name}.jpg`
|
||||
const url = name && `https://wow.zamimg.com/images/wow/icons/${bgSize}/${name}.jpg`
|
||||
|
||||
const start = Date.now()
|
||||
|
||||
useEffect(() => {
|
||||
if (!name) return
|
||||
if (!url) return
|
||||
const img = new Image()
|
||||
img.onload = () => {
|
||||
const loadTime = Date.now() - start
|
||||
@@ -32,9 +34,9 @@ export const Icon: FC<Props> = ({ name: defaultName, size = 'medium', golden = f
|
||||
}
|
||||
img.onerror = () => setName(NOT_FOUND_ICON)
|
||||
img.src = url
|
||||
}, [name, url, start])
|
||||
}, [url, start])
|
||||
|
||||
const className = classNames('icon', `icon--${size}`, {
|
||||
const className = classNames('icon', `icon--${size}`, props.className, {
|
||||
'icon--golden': golden,
|
||||
'icon--loaded': hasLoadedImage,
|
||||
'icon--fade-in': fadeIn,
|
||||
@@ -42,7 +44,7 @@ export const Icon: FC<Props> = ({ name: defaultName, size = 'medium', golden = f
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
{name &&
|
||||
{url &&
|
||||
<div className="icon__bg" style={{ backgroundImage: `url(${url})` }} />
|
||||
}
|
||||
<div className="icon__frame" />
|
||||
|
||||
@@ -6,4 +6,10 @@
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.playground-section__spelltooltip {
|
||||
.tooltip {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,8 @@ import { Tooltip } from './Tooltip'
|
||||
import { Talent } from './Talent'
|
||||
import { talentsById } from '../data/talents'
|
||||
import { Map } from 'immutable'
|
||||
import { SpellTooltip } from './SpellTooltip';
|
||||
import classNames from 'classnames'
|
||||
|
||||
interface Props extends RouteComponentProps {
|
||||
//
|
||||
@@ -38,7 +40,7 @@ const DEEP_WOUNDS = <Tooltip title="Deep Wounds" fixed>
|
||||
|
||||
const Section: FC<any> = (props) => {
|
||||
return <div className="playground-section">
|
||||
<div className="container">
|
||||
<div className={classNames('container', `playground-section__${props.title.toLowerCase()}`)}>
|
||||
<h2>{props.title}</h2>
|
||||
|
||||
{props.children}
|
||||
@@ -152,6 +154,11 @@ export class Playground extends React.PureComponent<Props> {
|
||||
And even <a href="/warrior">link</a> to exciting places!
|
||||
</Tooltip>
|
||||
|
||||
<h3>With title and icon</h3>
|
||||
<Tooltip title="Strongest Class in the World" icon="inv_pet_babymurlocs_blue">
|
||||
<p className="yellow">And some description text here</p>
|
||||
</Tooltip>
|
||||
|
||||
<h3>Fixed width</h3>
|
||||
{DEEP_WOUNDS}
|
||||
|
||||
@@ -165,6 +172,12 @@ export class Playground extends React.PureComponent<Props> {
|
||||
fixed: false
|
||||
})}
|
||||
</Section>
|
||||
|
||||
<Section title="SpellTooltip">
|
||||
<SpellTooltip id={29086} />
|
||||
<SpellTooltip id={20501} />
|
||||
<SpellTooltip id={17793} />
|
||||
</Section>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import React, { FC } from 'react'
|
||||
import { Tooltip } from './Tooltip'
|
||||
import spells from '../data/spells.json'
|
||||
|
||||
interface Props {
|
||||
id: number
|
||||
}
|
||||
|
||||
export const SpellTooltip: FC<Props> = ({ id }) => {
|
||||
const spell: SpellData = spells[id.toString()]
|
||||
if (!spell) {
|
||||
return <Tooltip fixed>Spell not found :(</Tooltip>
|
||||
}
|
||||
|
||||
return <Tooltip fixed title={spell.name} icon={spell.icon}>
|
||||
{spell.rank &&
|
||||
<p className="tight">Rank {spell.rank}</p>
|
||||
}
|
||||
<p className="yellow">{spell.description}</p>
|
||||
</Tooltip>
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
height: 40px;
|
||||
border-radius: 5px;
|
||||
transition: filter .1s linear;
|
||||
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, .75);
|
||||
box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, .75);
|
||||
filter: none;
|
||||
cursor: pointer;
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@ import './TalentTree.scss'
|
||||
import React, { useCallback } from 'react'
|
||||
import { Map } from 'immutable'
|
||||
import { Talent } from './Talent';
|
||||
import { getPointsInSpec, canLearnTalent, calcMeetsRequirements, SORT_TALENTS_DESC } from '../lib/tree';
|
||||
import { talentsBySpec, specNames, talentsById, talentToSpec } from '../data/talents'
|
||||
import { getPointsInSpec, canLearnTalent, SORT_TALENTS_DESC } from '../lib/tree';
|
||||
import { talentsBySpec, specNames, talentsById } from '../data/talents'
|
||||
import { Arrow } from './Arrow'
|
||||
|
||||
interface Props {
|
||||
@@ -36,9 +36,8 @@ export const TalentTree: React.FC<Props> = ({ specId, knownTalents, availablePoi
|
||||
const points = knownTalents.get(talent.id, 0)
|
||||
const canLearn = canLearnTalent(knownTalents, talent)
|
||||
|
||||
return <React.Fragment>
|
||||
<Talent
|
||||
key={talent.id}
|
||||
return <React.Fragment key={talent.id}>
|
||||
<Talent
|
||||
talent={talent}
|
||||
points={points}
|
||||
onClick={handleClick}
|
||||
@@ -47,8 +46,7 @@ export const TalentTree: React.FC<Props> = ({ specId, knownTalents, availablePoi
|
||||
/>
|
||||
|
||||
{!!talent.requires.length &&
|
||||
<Arrow
|
||||
key={`arrow-${talent.id}`}
|
||||
<Arrow
|
||||
from={talentsById[talent.requires[0].id]}
|
||||
to={talent}
|
||||
active={points > 0 || canLearn}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
&__body {
|
||||
min-height: 2px;
|
||||
padding: 8px 4px 2px 10px;
|
||||
padding: 8px 3px 2px 9px;
|
||||
background: url('../images/tooltip-background.png');
|
||||
background-position: top left;
|
||||
}
|
||||
@@ -50,16 +50,17 @@
|
||||
|
||||
.tooltip {
|
||||
@include tooltip-base;
|
||||
display: flex;
|
||||
|
||||
&--inline {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
&--fixed {
|
||||
width: 320px;
|
||||
|
||||
|
||||
.tooltip__inner {
|
||||
width: 100%;
|
||||
width: 320px;
|
||||
}
|
||||
|
||||
.tooltip__body {
|
||||
@@ -67,10 +68,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
&__icon {
|
||||
margin-right: .25em;
|
||||
transform: translateY(2px);
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-size: 14px;
|
||||
line-height: 1.3;
|
||||
// margin-bottom: 1px;
|
||||
}
|
||||
|
||||
&__body {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import './Tooltip.scss'
|
||||
import React, { FC } from 'react'
|
||||
import classNames from 'classnames'
|
||||
import { Icon } from './Icon'
|
||||
|
||||
interface Props {
|
||||
title?: string
|
||||
@@ -10,6 +11,8 @@ interface Props {
|
||||
fixed?: boolean
|
||||
/** Display tooltip inline */
|
||||
inline?: boolean
|
||||
/** Icon to show next to tooltip */
|
||||
icon?: string
|
||||
}
|
||||
|
||||
export const Tooltip: FC<Props> = (props) => {
|
||||
@@ -24,8 +27,11 @@ export const Tooltip: FC<Props> = (props) => {
|
||||
width: props.width
|
||||
}
|
||||
|
||||
return <div className={cn} style={style}>
|
||||
<div className="tooltip__inner">
|
||||
return <div className={cn}>
|
||||
{props.icon &&
|
||||
<Icon className="tooltip__icon" name={props.icon} />
|
||||
}
|
||||
<div className="tooltip__inner" style={style}>
|
||||
<div className="tooltip__top">
|
||||
<div className="tooltip__body">
|
||||
{title && <div className="tooltip__title tight">{title}</div>}
|
||||
|
||||
Reference in New Issue
Block a user