aboutsummaryrefslogtreecommitdiff
path: root/users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/icon-picker.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/icon-picker.jsx')
-rwxr-xr-xusers/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/icon-picker.jsx130
1 files changed, 130 insertions, 0 deletions
diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/icon-picker.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/icon-picker.jsx
new file mode 100755
index 0000000..ca3bdab
--- /dev/null
+++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/icon-picker.jsx
@@ -0,0 +1,130 @@
1import * as Uebersicht from "uebersicht";
2import * as Icons from "../icons/icons.jsx";
3import { SuspenseIcon } from "../icons/icon.jsx";
4
5const { React } = Uebersicht;
6
7/**
8 * IconPicker component allows users to select an icon from a list of available icons.
9 *
10 * @param {Object} props - The component props.
11 * @param {Function} props.callback - The callback function to be called when an icon is selected.
12 * @param {number} props.index - The index of the icon picker.
13 * @param {string} props.selectedIcon - The initially selected icon.
14 * @returns {JSX.Element} The IconPicker component.
15 */
16export default function IconPicker({ callback, index, selectedIcon }) {
17 // State to manage the open/close state of the icon picker dropdown
18 const [open, setOpen] = React.useState(false);
19 // State to manage the currently selected icon
20 const [selected, setSelected] = React.useState(selectedIcon);
21 // State to manage the search term for filtering icons
22 const [searchTerm, setSearchTerm] = React.useState("");
23
24 // Get the selected icon component
25 const Icon = Icons[selected];
26 // Get the list of all available icon keys
27 const keys = Object.keys(Icons);
28
29 // Filter icons based on search term
30 const filteredKeys = React.useMemo(() => {
31 if (!searchTerm.trim()) {
32 return keys;
33 }
34 return keys.filter((key) =>
35 key.toLowerCase().includes(searchTerm.toLowerCase()),
36 );
37 }, [keys, searchTerm]);
38
39 /**
40 * Toggles the open state of the icon picker dropdown.
41 */
42 const onClick = () => setOpen(!open);
43
44 /**
45 * Handles search input changes.
46 *
47 * @param {React.ChangeEvent<HTMLInputElement>} e - The input change event.
48 */
49 const onSearchChange = (e) => {
50 setSearchTerm(e.target.value);
51 };
52
53 /**
54 * Clears the search term.
55 */
56 const clearSearch = () => {
57 setSearchTerm("");
58 };
59
60 return (
61 <div className="icon-picker">
62 <button className="icon-picker__button" onClick={onClick}>
63 <SuspenseIcon>
64 <Icon />
65 </SuspenseIcon>
66 </button>
67 {open && (
68 <div className="icon-picker__dropdown">
69 <div
70 className="icon-picker__search"
71 onClick={(e) => e.stopPropagation()}
72 >
73 <button
74 className="icon-picker__back"
75 onClick={() => setOpen(false)}
76 type="button"
77 >
78 <Icons.ChevronLeft />
79 Back
80 </button>
81 <input
82 type="text"
83 placeholder="Search icons..."
84 value={searchTerm}
85 onChange={onSearchChange}
86 className="icon-picker__search-input"
87 autoFocus
88 />
89 {searchTerm && (
90 <button
91 className="icon-picker__search-clear"
92 onClick={clearSearch}
93 type="button"
94 >
95
96 </button>
97 )}
98 </div>
99 <div className="icon-picker__icons" onClick={() => setOpen(false)}>
100 {filteredKeys.length > 0 ? (
101 filteredKeys.map((key) => {
102 /**
103 * Handles the icon selection.
104 *
105 * @param {React.MouseEvent} e - The click event.
106 */
107 const onClick = (e) => {
108 e.stopPropagation();
109 setSelected(key);
110 callback?.(index, "icon", key);
111 setOpen(false);
112 };
113 const Icon = Icons[key];
114 return (
115 <button key={key} onClick={onClick} title={key}>
116 <Icon />
117 </button>
118 );
119 })
120 ) : (
121 <div className="icon-picker__no-results">
122 No icons found for "{searchTerm}"
123 </div>
124 )}
125 </div>
126 </div>
127 )}
128 </div>
129 );
130}