aboutsummaryrefslogtreecommitdiffhomepage
path: root/app/src/Keyboard/LayerSelector.js
blob: 147ea5c805a2298be27ad8f63a01f7df141addb4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import PropTypes from 'prop-types'
import { useEffect, useMemo, useRef, useState } from 'react'

import Icon from '../Common/Icon'
import styles from './styles.module.css'

function LayerSelector(props) {
  const ref = useRef(null)
  const { activeLayer, layers } = props
  const { onSelect, onNewLayer, onRenameLayer, onDeleteLayer } = props
  const [renaming, setRenaming] = useState(false)
  const [editing, setEditing] = useState('')

  const handleSelect = useMemo(() => function(layer) {
    if (layer === activeLayer) {
      setRenaming(true)
      return
    }

    setRenaming(false)
    onSelect(layer)
  }, [activeLayer, setRenaming, onSelect])

  const handleAdd = useMemo(() => function() {
    onNewLayer()
  }, [onNewLayer])

  const handleDelete = useMemo(() => function(layerIndex, layerName) {
    const confirmation = `Really delete layer: ${layerName}?`
    window.confirm(confirmation) && onDeleteLayer(layerIndex)
  }, [onDeleteLayer])

  const handleClickOutside = useMemo(() => function(event) {
    const clickedOutside = ref.current && ref.current.contains(event.target)
    if (clickedOutside || !renaming) {
      return
    }

    setEditing('')
    setRenaming(false)
    onRenameLayer(editing)
  }, [
    ref,
    editing,
    renaming,
    onRenameLayer,
    setEditing,
    setRenaming
  ])

  useEffect(() => {
    document.addEventListener('click', handleClickOutside)
    return () => document.removeEventListener('click', handleClickOutside)
  }, [handleClickOutside])

  return (
    <div
      className={styles['layer-selector']}
      data-renaming={renaming}
      ref={ref}
    >
      <p>Layers:</p>
      <ul>
        {layers.map((name, i) => (
          <li
            key={`layer-${i}`}
            className={activeLayer === i ? 'active' : ''}
            data-layer={i}
            onClick={() => handleSelect(i)}
          >
            <span className={styles.index}>{i}</span>
            {(activeLayer === i && renaming) ? (
              <input
                className={styles.name}
                onChange={e => setEditing(e.target.value)}
                value={
                  (activeLayer === i && renaming)
                    ? editing
                    : layers[i]
                }
              />
            ) : (
              <span className={styles.name}>
                {name}
                <Icon
                  name="times-circle"
                  className={styles.delete}
                  onClick={() => handleDelete(i, name)}
                />
              </span>
            )}
          </li>
        ))}
        <li onClick={handleAdd}>
          <Icon className={styles.index} name="plus" />
          <span className={styles.name}>Add Layer</span>
        </li>
      </ul>
    </div>
  )
}

LayerSelector.propTypes = {
  layers: PropTypes.array.isRequired,
  activeLayer: PropTypes.number.isRequired,
  onSelect: PropTypes.func.isRequired,
  onNewLayer: PropTypes.func.isRequired,
  onRenameLayer: PropTypes.func.isRequired,
  onDeleteLayer: PropTypes.func.isRequired
}

export default LayerSelector