make pokemon active from list

This commit is contained in:
Jeff Colombo 2019-01-18 15:28:59 -05:00
parent 68dba3005d
commit 790df65780
7 changed files with 47 additions and 2 deletions

View File

@ -19,6 +19,7 @@
"@babel/preset-env": "^7.2.3", "@babel/preset-env": "^7.2.3",
"@babel/preset-react": "^7.0.0", "@babel/preset-react": "^7.0.0",
"@babel/preset-typescript": "^7.1.0", "@babel/preset-typescript": "^7.1.0",
"@types/classnames": "^2.2.7",
"@types/node": "^10.12.18", "@types/node": "^10.12.18",
"@types/react": "^16.7.18", "@types/react": "^16.7.18",
"@types/react-dom": "^16.0.11", "@types/react-dom": "^16.0.11",
@ -56,6 +57,7 @@
"webpack-shell-plugin": "^0.5.0" "webpack-shell-plugin": "^0.5.0"
}, },
"dependencies": { "dependencies": {
"classnames": "^2.2.6",
"pokemongo-json-pokedex": "^3.4.6", "pokemongo-json-pokedex": "^3.4.6",
"prop-types": "^15.6.2", "prop-types": "^15.6.2",
"react": "^16.7.0", "react": "^16.7.0",

View File

@ -25,10 +25,19 @@ class PokemonApp extends React.Component<IConnectedPokemonAppProps> {
} }
public render() { public render() {
const { pokemonSelectListState } = this.props;
return ( return (
<PokemonSelectList pokemonList={ this.props.pokemonSelectListState.pokemonList } /> <PokemonSelectList
activePokemonIndex={ pokemonSelectListState.activePokemonIndex }
pokemonList={ pokemonSelectListState.pokemonList }
onActivatePokemon={ this.onActivatePokemon }
/>
); );
} }
private readonly onActivatePokemon = (pokemonIndex : number) => {
this.props.dispatch(ActionsPokemonSelectList.setActivePokemonIndex(pokemonIndex));
}
} }
const mapStateToProps = (state : ReturnType<typeof appReducers>) : PokemonAppProps => { const mapStateToProps = (state : ReturnType<typeof appReducers>) : PokemonAppProps => {

View File

@ -2,10 +2,15 @@ import React from 'react';
import { ContentRect, default as Measure } from 'react-measure'; import { ContentRect, default as Measure } from 'react-measure';
import { FixedSizeList } from 'react-window'; import { FixedSizeList } from 'react-window';
import classNames from 'classnames';
import { IPokemon } from 'app/models/Pokemon'; import { IPokemon } from 'app/models/Pokemon';
export interface IPokemonSelectListProps { export interface IPokemonSelectListProps {
activePokemonIndex : number;
pokemonList : Array<IPokemon>; pokemonList : Array<IPokemon>;
onActivatePokemon : (index : number) => void;
} }
interface IState { interface IState {
@ -68,6 +73,10 @@ export class PokemonSelectList extends React.Component<IPokemonSelectListProps,
private rowFactory({ index, style } : IRowFactory) { private rowFactory({ index, style } : IRowFactory) {
const pokemon = this.props.pokemonList[index]; const pokemon = this.props.pokemonList[index];
return <div key={ index } style={ style }>{ pokemon.name }</div>; const css = classNames({
active: this.props.activePokemonIndex === index
});
const onClick = () => this.props.onActivatePokemon(index);
return <div key={ index } style={ style } className={ css } onClick={ onClick }>{ pokemon.name }</div>;
} }
} }

View File

@ -6,6 +6,8 @@ import { PokemonSelectListActionTypes, ThunkResult } from './types';
export const setPokemonList = (pokemonList : Array<IPokemon>) => action(PokemonSelectListActionTypes.SET_POKEMON_LIST, { pokemonList }); export const setPokemonList = (pokemonList : Array<IPokemon>) => action(PokemonSelectListActionTypes.SET_POKEMON_LIST, { pokemonList });
export const setActivePokemonIndex = (activePokemonIndex : number) => action(PokemonSelectListActionTypes.SET_ACTIVE_POKEMON_INDEX, { activePokemonIndex });
export const fetchPokemonList = ( export const fetchPokemonList = (
) : ThunkResult<Promise<void>> => { ) : ThunkResult<Promise<void>> => {
return (dispatch, getState, extraArguments) => { return (dispatch, getState, extraArguments) => {

View File

@ -4,6 +4,7 @@ import * as Actions from './actions';
import { IPokemonSelectListState, PokemonSelectListActionTypes } from './types'; import { IPokemonSelectListState, PokemonSelectListActionTypes } from './types';
export const initialState : IPokemonSelectListState = { export const initialState : IPokemonSelectListState = {
activePokemonIndex: -1,
pokemonList: [], pokemonList: [],
pokemonListFiltered: [], pokemonListFiltered: [],
}; };
@ -16,6 +17,14 @@ const reduceSetPokemonList = (
pokemonList: action.payload.pokemonList, pokemonList: action.payload.pokemonList,
}); });
const reduceSetActivePokemonIndex = (
state : IPokemonSelectListState,
action : ReturnType<typeof Actions.setActivePokemonIndex>
) : IPokemonSelectListState => ({
...state,
activePokemonIndex: action.payload.activePokemonIndex,
});
export const PokemonSelectListReducers : Reducer<IPokemonSelectListState> = ( export const PokemonSelectListReducers : Reducer<IPokemonSelectListState> = (
state : IPokemonSelectListState = initialState, state : IPokemonSelectListState = initialState,
action, action,
@ -23,6 +32,8 @@ export const PokemonSelectListReducers : Reducer<IPokemonSelectListState> = (
switch (action.type) { switch (action.type) {
case PokemonSelectListActionTypes.SET_POKEMON_LIST: case PokemonSelectListActionTypes.SET_POKEMON_LIST:
return reduceSetPokemonList(state, action as ReturnType<typeof Actions.setPokemonList>); return reduceSetPokemonList(state, action as ReturnType<typeof Actions.setPokemonList>);
case PokemonSelectListActionTypes.SET_ACTIVE_POKEMON_INDEX:
return reduceSetActivePokemonIndex(state, action as ReturnType<typeof Actions.setActivePokemonIndex>);
default: default:
return state; return state;
} }

View File

@ -8,6 +8,7 @@ import { PokemonService } from 'api/PokemonService';
import { IPokemon } from 'app/models/Pokemon'; import { IPokemon } from 'app/models/Pokemon';
export interface IPokemonSelectListState { export interface IPokemonSelectListState {
activePokemonIndex : number;
pokemonList : Array<IPokemon>; pokemonList : Array<IPokemon>;
pokemonListFiltered : Array<IPokemon>; pokemonListFiltered : Array<IPokemon>;
} }
@ -29,4 +30,5 @@ export type ThunkDispatchPokemonSelectList = ThunkDispatch<IPokemonSelectListSto
export const PokemonSelectListActionTypes = { export const PokemonSelectListActionTypes = {
SET_POKEMON_LIST: 'POKEMON_SELECT_LIST/SET_POKEMON_LIST', SET_POKEMON_LIST: 'POKEMON_SELECT_LIST/SET_POKEMON_LIST',
SET_ACTIVE_POKEMON_INDEX: 'POKEMON_SELECT_LIST/SET_ACTIVE_POKEMON_INDEX',
}; };

View File

@ -726,6 +726,11 @@
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b"
integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==
"@types/classnames@^2.2.7":
version "2.2.7"
resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.2.7.tgz#fb68cc9be8487e6ea5b13700e759bfbab7e0fefd"
integrity sha512-rzOhiQ55WzAiFgXRtitP/ZUT8iVNyllEpylJ5zHzR4vArUvMB39GTk+Zon/uAM0JxEFAWnwsxC2gH8s+tZ3Myg==
"@types/json5@^0.0.29": "@types/json5@^0.0.29":
version "0.0.29" version "0.0.29"
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
@ -1641,6 +1646,11 @@ class-utils@^0.3.5:
isobject "^3.0.0" isobject "^3.0.0"
static-extend "^0.1.1" static-extend "^0.1.1"
classnames@^2.2.6:
version "2.2.6"
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==
cliui@^3.2.0: cliui@^3.2.0:
version "3.2.0" version "3.2.0"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d"