aboutsummaryrefslogtreecommitdiff
path: root/users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/icon-picker.jsx
blob: ca3bdab1461d6d4b5d56cfea3db2d7db17ee80dd (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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import * as Uebersicht from "uebersicht";
import * as Icons from "../icons/icons.jsx";
import { SuspenseIcon } from "../icons/icon.jsx";

const { React } = Uebersicht;

/**
 * IconPicker component allows users to select an icon from a list of available icons.
 *
 * @param {Object} props - The component props.
 * @param {Function} props.callback - The callback function to be called when an icon is selected.
 * @param {number} props.index - The index of the icon picker.
 * @param {string} props.selectedIcon - The initially selected icon.
 * @returns {JSX.Element} The IconPicker component.
 */
export default function IconPicker({ callback, index, selectedIcon }) {
  // State to manage the open/close state of the icon picker dropdown
  const [open, setOpen] = React.useState(false);
  // State to manage the currently selected icon
  const [selected, setSelected] = React.useState(selectedIcon);
  // State to manage the search term for filtering icons
  const [searchTerm, setSearchTerm] = React.useState("");

  // Get the selected icon component
  const Icon = Icons[selected];
  // Get the list of all available icon keys
  const keys = Object.keys(Icons);

  // Filter icons based on search term
  const filteredKeys = React.useMemo(() => {
    if (!searchTerm.trim()) {
      return keys;
    }
    return keys.filter((key) =>
      key.toLowerCase().includes(searchTerm.toLowerCase()),
    );
  }, [keys, searchTerm]);

  /**
   * Toggles the open state of the icon picker dropdown.
   */
  const onClick = () => setOpen(!open);

  /**
   * Handles search input changes.
   *
   * @param {React.ChangeEvent<HTMLInputElement>} e - The input change event.
   */
  const onSearchChange = (e) => {
    setSearchTerm(e.target.value);
  };

  /**
   * Clears the search term.
   */
  const clearSearch = () => {
    setSearchTerm("");
  };

  return (
    <div className="icon-picker">
      <button className="icon-picker__button" onClick={onClick}>
        <SuspenseIcon>
          <Icon />
        </SuspenseIcon>
      </button>
      {open && (
        <div className="icon-picker__dropdown">
          <div
            className="icon-picker__search"
            onClick={(e) => e.stopPropagation()}
          >
            <button
              className="icon-picker__back"
              onClick={() => setOpen(false)}
              type="button"
            >
              <Icons.ChevronLeft />
              Back
            </button>
            <input
              type="text"
              placeholder="Search icons..."
              value={searchTerm}
              onChange={onSearchChange}
              className="icon-picker__search-input"
              autoFocus
            />
            {searchTerm && (
              <button
                className="icon-picker__search-clear"
                onClick={clearSearch}
                type="button"
              >
                
              </button>
            )}
          </div>
          <div className="icon-picker__icons" onClick={() => setOpen(false)}>
            {filteredKeys.length > 0 ? (
              filteredKeys.map((key) => {
                /**
                 * Handles the icon selection.
                 *
                 * @param {React.MouseEvent} e - The click event.
                 */
                const onClick = (e) => {
                  e.stopPropagation();
                  setSelected(key);
                  callback?.(index, "icon", key);
                  setOpen(false);
                };
                const Icon = Icons[key];
                return (
                  <button key={key} onClick={onClick} title={key}>
                    <Icon />
                  </button>
                );
              })
            ) : (
              <div className="icon-picker__no-results">
                No icons found for "{searchTerm}"
              </div>
            )}
          </div>
        </div>
      )}
    </div>
  );
}