Add active/inactive styling to ClassPicker

This commit is contained in:
Melvin Valster
2019-07-21 22:36:46 +02:00
parent 431f944b50
commit 8302af7504
7 changed files with 73 additions and 48 deletions
+2 -2
View File
@@ -1,10 +1,10 @@
# TODO # TODO
- [ ] Add redux - [ ] Add redux
- [ ] Prevent reducing talent points on a talent that is a requirement for another talent with points in it
- [ ] Talent tooltips - [ ] Talent tooltips
- [ ] Generate URL for chosen talents - [ ] Generate URL for chosen talents
- [ ] Responsive on mobile - [ ] Responsive on mobile
- [ ] Pretty ClassPicker - [ ] Pretty ClassPicker
- [x] Add react-router - [x] Add react-router
- [x] Prevent reducing talent points on a row when it is a dependency for points already spent in the next row - [x] Prevent reducing talent points on a row when it is a dependency for points already spent in the next row
- [x] Prevent reducing talent points on a talent that is a requirement for another talent with points in it
+16 -6
View File
@@ -3,7 +3,6 @@ body {
} }
.calculator { .calculator {
&__points { &__points {
color: white; color: white;
text-align: center; text-align: center;
@@ -40,15 +39,26 @@ body {
.class-picker { .class-picker {
display: flex; display: flex;
justify-content: center;
&__class { &__class {
margin-right: 2em; margin-right: 2em;
} opacity: .8;
// TODO: Make BEM &:hover {
a { opacity: 1;
&.active { }
font-weight: bold;
&--active {
opacity: 1;
}
&--inactive {
opacity: .4;
&:hover {
opacity: .6;
}
} }
} }
} }
+29 -8
View File
@@ -1,18 +1,39 @@
import React from 'react' import React from 'react'
import { NavLink } from 'react-router-dom' import { NavLink, Link } from 'react-router-dom'
import { classByName } from '../data/classes' import { classByName } from '../data/classes'
import { Icon } from './Icon'
import classNames from 'classnames'
interface Props { interface Props {
/** Name of the selected class, lowercase */
selected?: string
} }
export const ClassPicker: React.FC<Props> = () => { const classNameForItem = (c: ClassData, selected: string) => classNames('class-picker__class', {
return ( 'class-picker__class--active': c.name.toLowerCase() === selected,
<ul className="class-picker"> 'class-picker__class--inactive': !!selected && c.name.toLowerCase() !== selected
})
export class ClassPicker extends React.PureComponent<Props> {
static whyDidYouRender = true
render() {
const { selected } = this.props
const cn = classNames('class-picker', {
'class-picker--has-selection': !!selected
})
return (
<ul className={cn}>
{Object.values(classByName).map((c) => {Object.values(classByName).map((c) =>
<li key={c.id} className="class-picker__class"> <li key={c.id} className={classNameForItem(c, selected)}>
<NavLink to={`/${c.name.toLowerCase()}`}>{c.name}</NavLink> <Link to={`/${c.name.toLowerCase()}`} title={c.name}>
<Icon name={c.icon} />
</Link>
</li> </li>
)} )}
</ul> </ul>
) )
} }
}
+10 -14
View File
@@ -1,33 +1,29 @@
import React from 'react' import React from 'react'
import { Calculator } from './Calculator' import { Calculator } from './Calculator'
import { ClassPicker } from './ClassPicker' import { ClassPicker } from './ClassPicker'
import { match } from 'react-router-dom'
import { RouteComponentProps } from 'react-router'
interface Props { interface Props extends RouteComponentProps {
pointString?: string // e.g. 2305302300--001 match: match<{
match: any selectedClass: string
history: any pointString: string
}>
} }
export class IndexRoute extends React.PureComponent<Props> { export class IndexRoute extends React.PureComponent<Props> {
static whyDidYouRender = true static whyDidYouRender = true
render() { render() {
const { match, history } = this.props const { match } = this.props
const { selectedClass, pointString } = match.params const { selectedClass, pointString } = match.params
if (!selectedClass) {
history.replace('/warlock')
return null
}
return ( return (
<div className="index"> <div className="index">
<ClassPicker /> <ClassPicker selected={selectedClass} />
{selectedClass && {selectedClass &&
<Calculator <Calculator selectedClass={selectedClass} />
selectedClass={selectedClass}
/>
} }
</div> </div>
) )
-7
View File
@@ -1,10 +1,3 @@
interface ClassData {
id: number
name: string
icon: string
specs: number[]
}
export const classes: ClassData[] = [ export const classes: ClassData[] = [
{ {
id: 1, id: 1,
+9 -11
View File
@@ -25,9 +25,9 @@ export function calcMeetsRequirements(talent: TalentData, known: Map<number, num
if (talent.requires.length === 0) { if (talent.requires.length === 0) {
return true return true
} }
return talent.requires.reduce((prev, current) => { return talent.requires.reduce((prev, req) => {
if (!prev) return false if (!prev) return false
return known.get(current.id, 0) >= current.qty return known.get(req.id, 0) >= req.qty
}, true) }, true)
} }
@@ -74,11 +74,14 @@ export const removeTalentPoint = (known: Map<number, number>, talent: TalentData
return known return known
} }
let isDependency = false
let highestRow = 0 let highestRow = 0
let cumulativePointsPerRow = {} let cumulativePointsPerRow = {}
known.forEach((points, talentId) => { known.forEach((points, talentId) => {
const t = talentsBySpec[specId][talentId] const t = talentsBySpec[specId][talentId]
if (t) { if (t) {
isDependency = isDependency || t.requires.some((req) => req.id === talent.id)
highestRow = t.row > highestRow ? t.row : highestRow highestRow = t.row > highestRow ? t.row : highestRow
for (let row = t.row; row < MAX_ROWS; row++) { for (let row = t.row; row < MAX_ROWS; row++) {
cumulativePointsPerRow[row] = (cumulativePointsPerRow[row] || 0) + points cumulativePointsPerRow[row] = (cumulativePointsPerRow[row] || 0) + points
@@ -93,15 +96,10 @@ export const removeTalentPoint = (known: Map<number, number>, talent: TalentData
return known return known
} }
// TODO: Prevent if another talent depends on this // Prevent if another talent depends on this
// const isDependency = known.reduce((prev, current, key) => { if (isDependency) {
// if (prev) return prev return known
// const t = talentsBySpec[specId][key] }
// if (t.requires.length === 0) {
// return false
// }
// t.requires.map((d) => d.id === talent.id ? d : undefined)
// }, false)
return currentPoints === 1 return currentPoints === 1
? known.remove(talent.id) ? known.remove(talent.id)
+7
View File
@@ -5,6 +5,13 @@ interface TalentTree {
talents: Talent[] talents: Talent[]
} }
interface ClassData {
id: number
name: string
icon: string
specs: number[]
}
interface TalentData { interface TalentData {
/** ID for the Talent */ /** ID for the Talent */
id: number id: number