浏览代码

Improvements to dropdown logic

Kirk Trombley 5 年之前
父节点
当前提交
82f1ad096c

+ 27 - 6
client/src/components/util/GameCreationForm/Dropdown.jsx

@@ -1,18 +1,39 @@
-import React, { useRef } from 'react';
+import React, { useRef, useState, useCallback, useEffect } from 'react';
 import { CSSTransition } from 'react-transition-group';
 import styles from './Dropdown.module.css';
 
-export const Item = ({ value, onSelect, children }) => (
-  <div className={styles.item} onClick={() => onSelect(value)}>
+export const Item = ({ value, display, onSelect, children }) => (
+  <div className={styles.item} onClick={() => onSelect(value, display ?? value)}>
     {children}
   </div>
 );
 
-export const Dropdown = ({ open, selected, onSelect, onClick, children }) => {
+export const Dropdown = ({ open, onSelect, onClick, children }) => {
   const transitionRef = useRef(null);
+  const [ displayed, setDisplayed ] = useState(null);
+  const onSelectCallback = useCallback((value, display) => { 
+    setDisplayed(display); 
+    onSelect(value); 
+  }, [onSelect]);
+  useEffect(() => {
+    if (displayed) {
+      return;
+    }
+    let found = null;
+    children.forEach(element => {
+      if (!React.isValidElement(element) || found) {
+        return;
+      }
+      if (element.props['default']) {
+        const { value, display } = element.props;
+        found = display ?? value;
+      }
+    });
+    setDisplayed(found);
+  }, [children, displayed])
   return (
     <div className={styles.container}>
-      <div className={styles.button} onClick={onClick}>{selected}</div>
+      <div className={styles.button} onClick={onClick}>{displayed}</div>
       <CSSTransition nodeRef={transitionRef} in={open} timeout={200} mountOnEnter unmountOnExit classNames={{
         enter: styles['list-enter'],
         enterActive: styles['list-enter-active'],
@@ -20,7 +41,7 @@ export const Dropdown = ({ open, selected, onSelect, onClick, children }) => {
         exitActive: styles['list-exit-active'],
       }}>
         <div className={styles.list} ref={transitionRef}>
-          {children.map((child, key) => React.cloneElement(child, { onSelect, key }))}
+          {children.map((child, key) => React.cloneElement(child, { onSelect: onSelectCallback, key }))}
         </div>
       </CSSTransition>
     </div>

+ 24 - 33
client/src/components/util/GameCreationForm/GameCreationForm.jsx

@@ -31,59 +31,50 @@ export default ({ afterCreate }) => {
   return (
     <div className={styles.form}>
       <div className={styles.dropdowns}>
-        <Dropdown 
-          selected={ms(timer * 1000)} 
-          onSelect={v => { setTimer(v); setOpen(null); }} 
-          open={open === 'timer'} 
+        <Dropdown
+          onSelect={v => { setTimer(v); setOpen(null); }}
+          open={open === 'timer'}
           onClick={() => setOpen(o => o === 'timer' ? null : 'timer')}
         >
-          <Item value={30}>30 Seconds</Item>
-          <Item value={120}>2 Minutes</Item>
-          <Item value={300}>5 Minutes</Item>
-          <Item value={3600}>1 Hour</Item>
+          <Item value={30} display={ms(30 * 1000)}>30 Seconds</Item>
+          <Item value={120} display={ms(2 * 60 * 1000)}>2 Minutes</Item>
+          <Item value={300} display={ms(5 * 60 * 1000)} default>5 Minutes</Item>
+          <Item value={3600} display={ms(60 * 60 * 1000)}>1 Hour</Item>
         </Dropdown>
-        <Dropdown 
-          selected={rounds} 
-          onSelect={v => { setRounds(v); setOpen(null); }} 
-          open={open === 'rounds'} 
+        <Dropdown
+          onSelect={v => { setRounds(v); setOpen(null); }}
+          open={open === 'rounds'}
           onClick={() => setOpen(o => o === 'rounds' ? null : 'rounds')}
         >
           <Item value={1}>1 Round</Item>
           <Item value={3}>3 Rounds</Item>
-          <Item value={5}>5 Rounds</Item>
+          <Item value={5} default>5 Rounds</Item>
           <Item value={10}>10 Rounds</Item>
         </Dropdown>
-        <Dropdown 
-          selected={onlyAmerica ? '🇺🇸' : '🌎'} 
-          onSelect={v => { setOnlyAmerica(v); setOpen(null); }} 
-          open={open === 'america'} 
+        <Dropdown
+          onSelect={v => { setOnlyAmerica(v); setOpen(null); }}
+          open={open === 'america'}
           onClick={() => setOpen(o => o === 'america' ? null : 'america')}
         >
-          <Item value={false}>All Countries</Item>
-          <Item value={true}>Just America</Item>
+          <Item value={false} display='🌎' default>All Countries</Item>
+          <Item value={true} display='🇺🇸'>Just America</Item>
         </Dropdown>
         <Dropdown
-          selected={
-            genMethod === MAP_CRUNCH
-              ? 'MC'
-              : genMethod === RANDOM_STREET_VIEW ? 'RSV' : '🏙️'
-            }
-            onSelect={v => { setGenMethod(v); setOpen(null); }} 
-            open={open === 'gen'} 
-            onClick={() => setOpen(o => o === 'gen' ? null : 'gen')}
+          onSelect={v => { setGenMethod(v); setOpen(null); }}
+          open={open === 'gen'}
+          onClick={() => setOpen(o => o === 'gen' ? null : 'gen')}
         >
-          <Item value={MAP_CRUNCH}>Map Crunch</Item>
-          <Item value={RANDOM_STREET_VIEW}>Random Street View</Item>
-          <Item value={URBAN}>Urban Centers</Item>
+          <Item value={MAP_CRUNCH} display='MC' default>Map Crunch</Item>
+          <Item value={RANDOM_STREET_VIEW} display='RSV'>Random Street View</Item>
+          <Item value={URBAN} display='🏙️'>Urban Centers</Item>
         </Dropdown>
         <Dropdown
-          selected={ruleSet === NORMAL ? '⏰' : '🏦'}
           onSelect={v => { setRuleSet(v); setOpen(null); }}
           open={open === 'rule'}
           onClick={() => setOpen(o => o === 'rule' ? null : 'rule')}
         >
-          <Item value={NORMAL}>Normal</Item>
-          <Item value={TIME_BANK}>Time Bank</Item>
+          <Item value={NORMAL} display='⏰' default>Normal</Item>
+          <Item value={TIME_BANK} display='🏦'>Time Bank</Item>
         </Dropdown>
       </div>
       <button className={styles.start} onClick={onCreateGame}>