@bigbinary/neeto-editor 0.1.17 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/index.js +16 -14
  2. package/package.json +12 -1
  3. package/src/App.js +5 -28
  4. package/src/Common/Avatar.js +168 -0
  5. package/src/Common/CodeBlock.js +11 -0
  6. package/src/Common/Description.js +12 -0
  7. package/src/Common/Dropdown/index.js +118 -0
  8. package/src/Common/Heading.js +13 -0
  9. package/src/Common/HighlightText.js +7 -0
  10. package/src/Common/Icons/HashtagFilled.js +59 -0
  11. package/src/Common/Icons/TextColor.js +35 -0
  12. package/src/Common/Icons/index.js +2 -0
  13. package/src/Common/ListItems.js +17 -0
  14. package/src/Editor/CustomExtensions/BubbleMenu/index.js +33 -26
  15. package/src/Editor/CustomExtensions/Embeds.js +5 -3
  16. package/src/Editor/CustomExtensions/FixedMenu/FontSizeOption.js +32 -0
  17. package/src/Editor/CustomExtensions/FixedMenu/TextColorOption.js +29 -0
  18. package/src/Editor/CustomExtensions/FixedMenu/constants.js +3 -0
  19. package/src/Editor/CustomExtensions/FixedMenu/index.js +186 -0
  20. package/src/Editor/CustomExtensions/Mention/ExtensionConfig.js +67 -0
  21. package/src/Editor/CustomExtensions/Mention/MentionList.js +96 -0
  22. package/src/Editor/CustomExtensions/Mention/helpers.js +23 -0
  23. package/src/Editor/CustomExtensions/Placeholder/ExtensionConfig.js +81 -0
  24. package/src/Editor/CustomExtensions/Placeholder/helpers.js +18 -0
  25. package/src/Editor/CustomExtensions/SlashCommands/Commands.js +5 -10
  26. package/src/Editor/CustomExtensions/SlashCommands/CommandsList.js +15 -16
  27. package/src/Editor/CustomExtensions/SlashCommands/ExtensionConfig.js +191 -150
  28. package/src/Editor/CustomExtensions/Variable/ExtensionConfig.js +208 -0
  29. package/src/Editor/CustomExtensions/Variable/VariableList.js +45 -0
  30. package/src/Editor/CustomExtensions/Variable/VariableSuggestion.js +20 -0
  31. package/src/Editor/CustomExtensions/Variable/helpers.js +31 -0
  32. package/src/Editor/CustomExtensions/Variable/index.js +35 -0
  33. package/src/Editor/CustomExtensions/useCustomExtensions.js +87 -0
  34. package/src/Editor/index.js +42 -37
  35. package/src/examples/constants.js +95 -0
  36. package/src/examples/index.js +186 -0
  37. package/src/hooks/useOutsideClick.js +19 -0
  38. package/src/index.scss +27 -12
  39. package/src/styles/abstracts/_mixins.scss +20 -0
  40. package/src/styles/abstracts/_neeto-ui-variables.scss +36 -0
  41. package/src/styles/abstracts/_variables.scss +10 -0
  42. package/src/styles/components/_avatar.scss +105 -0
  43. package/src/styles/components/_codeblock.scss +16 -0
  44. package/src/{Editor/styles/CommandsList.scss → styles/components/_command-list.scss} +12 -1
  45. package/src/styles/components/_dropdown.scss +69 -0
  46. package/src/styles/components/_editor-variables.scss +12 -0
  47. package/src/{Editor/styles/EditorStyles.scss → styles/components/_editor.scss} +29 -7
  48. package/src/styles/components/_fixed-menu.scss +13 -0
  49. package/src/utils/common.js +13 -0
  50. package/public/logo192.png +0 -0
  51. package/public/logo512.png +0 -0
  52. package/src/logo.svg +0 -1
@@ -0,0 +1,32 @@
1
+ import React from "react";
2
+
3
+ import { TextSize } from "@bigbinary/neeto-icons";
4
+
5
+ import { ICON_COLOR_ACTIVE, MENU_ICON_SIZE } from "./constants";
6
+ import Dropdown from "../../../Common/Dropdown";
7
+
8
+ const FontSizeOption = ({ onChange }) => {
9
+ const options = [
10
+ { label: <h2 className="text-xl font-medium">Large</h2>, value: "large" },
11
+ { label: <h3 className="text-lg">Medium</h3>, value: "medium" },
12
+ { label: <span className="text-sm">Normal</span>, value: "normal" },
13
+ ];
14
+
15
+ return (
16
+ <Dropdown
17
+ customTarget={() => (
18
+ <button className="p-3 transition-colors editor-fixed-menu--item">
19
+ <TextSize size={MENU_ICON_SIZE} color={ICON_COLOR_ACTIVE} />
20
+ </button>
21
+ )}
22
+ >
23
+ {options.map(({ label, className, value }) => (
24
+ <li className={className} onClick={() => onChange(value)}>
25
+ {label}
26
+ </li>
27
+ ))}
28
+ </Dropdown>
29
+ );
30
+ };
31
+
32
+ export default FontSizeOption;
@@ -0,0 +1,29 @@
1
+ import React, { useRef } from "react";
2
+
3
+ import { TextColor } from "../../../Common/Icons";
4
+ import { ICON_COLOR_ACTIVE, MENU_ICON_SIZE } from "./constants";
5
+
6
+ const TextColorOption = ({ color = "#000", onChange }) => {
7
+ const colorInputRef = useRef();
8
+
9
+ return (
10
+ <div
11
+ onClick={() => colorInputRef.current?.click()}
12
+ className="flex items-center justify-center p-3 transition-colors cursor-pointer editor-fixed-menu--item"
13
+ >
14
+ <TextColor
15
+ size={MENU_ICON_SIZE}
16
+ underlineColor={color}
17
+ color={ICON_COLOR_ACTIVE}
18
+ />
19
+ <input
20
+ ref={colorInputRef}
21
+ type="color"
22
+ className="invisible w-0 h-0"
23
+ onChange={(event) => onChange && onChange(event.target.value)}
24
+ />
25
+ </div>
26
+ );
27
+ };
28
+
29
+ export default TextColorOption;
@@ -0,0 +1,3 @@
1
+ export const MENU_ICON_SIZE = 24;
2
+ export const ICON_COLOR_ACTIVE = "#2F3941";
3
+ export const ICON_COLOR_INACTIVE = "#87929D";
@@ -0,0 +1,186 @@
1
+ import React from "react";
2
+ import {
3
+ TextBold,
4
+ TextItalic,
5
+ Underline,
6
+ TextCross,
7
+ Link,
8
+ Code,
9
+ ListDot,
10
+ ListNumber,
11
+ Image,
12
+ Quote,
13
+ Undo,
14
+ Redo,
15
+ } from "@bigbinary/neeto-icons";
16
+
17
+ import TextColorOption from "./TextColorOption";
18
+ import FontSizeOption from "./FontSizeOption";
19
+
20
+ import { ICON_COLOR_ACTIVE, ICON_COLOR_INACTIVE } from "./constants";
21
+ import sharedState from "../../sharedState";
22
+ import Variables from "../Variable";
23
+
24
+ const FixedMenu = ({ editor, variables }) => {
25
+ if (!editor) {
26
+ return null;
27
+ }
28
+
29
+ const fontStyleOptions = [
30
+ {
31
+ Icon: TextBold,
32
+ command: () => editor.chain().focus().toggleBold().run(),
33
+ active: editor.isActive("bold"),
34
+ optionName: "bold",
35
+ },
36
+ {
37
+ Icon: TextItalic,
38
+ command: () => editor.chain().focus().toggleItalic().run(),
39
+ active: editor.isActive("italic"),
40
+ optionName: "italic",
41
+ },
42
+ {
43
+ Icon: Underline,
44
+ command: () => editor.chain().focus().toggleUnderline().run(),
45
+ active: editor.isActive("underline"),
46
+ optionName: "underline",
47
+ size: 27,
48
+ },
49
+ {
50
+ Icon: TextCross,
51
+ command: () => editor.chain().focus().toggleStrike().run(),
52
+ active: editor.isActive("strike"),
53
+ optionName: "strike",
54
+ },
55
+ ];
56
+
57
+ const blockStyleOptions = [
58
+ {
59
+ Icon: Link,
60
+ command: () => {
61
+ if (editor.isActive("link")) {
62
+ editor.chain().focus().unsetLink().run();
63
+ } else {
64
+ const url = window.prompt("Please enter your URL");
65
+ editor.chain().focus().setLink({ href: url }).run();
66
+ }
67
+ },
68
+ active: editor.isActive("link"),
69
+ optionName: "link",
70
+ },
71
+ {
72
+ Icon: Quote,
73
+ command: () => editor.chain().focus().toggleBlockquote().run(),
74
+ active: editor.isActive("blockquote"),
75
+ optionName: "block-quote",
76
+ },
77
+ {
78
+ Icon: Code,
79
+ command: () => editor.chain().focus().toggleCode().run(),
80
+ active: editor.isActive("code"),
81
+ optionName: "code",
82
+ },
83
+ {
84
+ Icon: Image,
85
+ command: ({ editor, range }) => {
86
+ sharedState.showImageUpload = true;
87
+ sharedState.range = range;
88
+ editor.chain().focus().deleteRange(range).run();
89
+ },
90
+ optionName: "image-upload",
91
+ },
92
+ ];
93
+
94
+ const listStyleOptions = [
95
+ {
96
+ Icon: ListDot,
97
+ command: () => editor.chain().focus().toggleBulletList().run(),
98
+ active: editor.isActive("bulletList"),
99
+ optionName: "bullet-list",
100
+ },
101
+ {
102
+ Icon: ListNumber,
103
+ command: () => editor.chain().focus().toggleOrderedList().run(),
104
+ active: editor.isActive("orderedList"),
105
+ optionName: "ordered-list",
106
+ },
107
+ ];
108
+
109
+ const editorOptions = [
110
+ {
111
+ Icon: Undo,
112
+ command: () => editor.chain().focus().undo().run(),
113
+ optionName: "undo",
114
+ disabled: !editor.can().undo(),
115
+ active: editor.can().undo(),
116
+ },
117
+ {
118
+ Icon: Redo,
119
+ command: () => editor.chain().focus().redo().run(),
120
+ optionName: "redo",
121
+ disabled: !editor.can().redo(),
122
+ active: editor.can().redo(),
123
+ },
124
+ ];
125
+
126
+ const handleTextSizeChange = (value) => {
127
+ switch (value) {
128
+ case "large": {
129
+ editor.chain().focus().setHeading({ level: 2 }).run();
130
+ break;
131
+ }
132
+ case "medium": {
133
+ editor.chain().focus().setHeading({ level: 3 }).run();
134
+ break;
135
+ }
136
+ case "normal": {
137
+ editor.chain().focus().setParagraph().run();
138
+ break;
139
+ }
140
+ }
141
+ };
142
+
143
+ const renderOptionButton = ({
144
+ Icon,
145
+ command,
146
+ active,
147
+ optionName,
148
+ disabled,
149
+ ...rest
150
+ }) => (
151
+ <button
152
+ disabled={disabled}
153
+ onClick={command}
154
+ key={optionName}
155
+ className="p-3 transition-colors cursor-pointer editor-fixed-menu--item"
156
+ >
157
+ <Icon
158
+ color={active ? ICON_COLOR_ACTIVE : ICON_COLOR_INACTIVE}
159
+ {...rest}
160
+ />
161
+ </button>
162
+ );
163
+
164
+ return (
165
+ <div className="flex items-center space-x-6 border-t border-l border-r editor-fixed-menu--root">
166
+ <div className="flex">
167
+ <TextColorOption
168
+ color={editor.getAttributes("textStyle").color}
169
+ onChange={(color) => editor.chain().focus().setColor(color).run()}
170
+ />
171
+ <FontSizeOption onChange={handleTextSizeChange} />
172
+ {fontStyleOptions.map(renderOptionButton)}
173
+ </div>
174
+ {[blockStyleOptions, listStyleOptions, editorOptions].map(
175
+ (optionGroup) => (
176
+ <div className="flex">{optionGroup.map(renderOptionButton)}</div>
177
+ )
178
+ )}
179
+ <div className="flex justify-end flex-1">
180
+ <Variables editor={editor} variables={variables} />
181
+ </div>
182
+ </div>
183
+ );
184
+ };
185
+
186
+ export default FixedMenu;
@@ -0,0 +1,67 @@
1
+ import Mention from "@tiptap/extension-mention";
2
+ import tippy from "tippy.js";
3
+ import { ReactRenderer } from "@tiptap/react";
4
+
5
+ import { MentionList } from "./MentionList";
6
+
7
+ import { createMentionSuggestions } from "./helpers";
8
+
9
+ const suggestion = {
10
+ render: () => {
11
+ let reactRenderer;
12
+ let popup;
13
+
14
+ return {
15
+ onStart: (props) => {
16
+ console.log({ props });
17
+ reactRenderer = new ReactRenderer(MentionList, {
18
+ props,
19
+ editor: props.editor,
20
+ });
21
+
22
+ popup = tippy("body", {
23
+ getReferenceClientRect: props.clientRect,
24
+ appendTo: () => document.body,
25
+ content: reactRenderer.element,
26
+ showOnCreate: true,
27
+ interactive: true,
28
+ trigger: "manual",
29
+ placement: "bottom-start",
30
+ });
31
+ },
32
+
33
+ onUpdate(props) {
34
+ reactRenderer.updateProps(props);
35
+
36
+ popup[0].setProps({
37
+ getReferenceClientRect: props.clientRect,
38
+ });
39
+ },
40
+
41
+ onKeyDown(props) {
42
+ if (props.event.key === "Escape") {
43
+ popup[0].hide();
44
+
45
+ return true;
46
+ }
47
+
48
+ return reactRenderer.ref?.onKeyDown(props);
49
+ },
50
+
51
+ onExit() {
52
+ popup[0].destroy();
53
+ reactRenderer.destroy();
54
+ },
55
+ };
56
+ },
57
+ };
58
+
59
+ export default {
60
+ configure: ({ suggestion: suggestionConfig = {}, ...otherConfig }) =>
61
+ Mention.configure({
62
+ ...otherConfig,
63
+ suggestion: { ...suggestion, ...suggestionConfig },
64
+ }),
65
+ };
66
+
67
+ export { createMentionSuggestions };
@@ -0,0 +1,96 @@
1
+ import React from "react";
2
+ import classNames from "classnames";
3
+
4
+ import Avatar from "../../../Common/Avatar";
5
+
6
+ export class MentionList extends React.Component {
7
+ state = { selectedIndex: 0 };
8
+
9
+ componentDidUpdate(prevProps) {
10
+ const { items } = this.props;
11
+ if (items !== prevProps.items) {
12
+ this.setState({ selectedIndex: 0 });
13
+ }
14
+ }
15
+
16
+ selectItem = (index) => {
17
+ const { items, command } = this.props;
18
+ const item = items[index];
19
+
20
+ if (item) {
21
+ command({ label: item.label, id: item.key });
22
+ }
23
+ };
24
+
25
+ upHandler = () => {
26
+ const { items } = this.props;
27
+ this.setState((prevState) => {
28
+ const { selectedIndex } = prevState;
29
+ const nextSelectedIndex =
30
+ (selectedIndex + items.length - 1) % items.length;
31
+ return {
32
+ selectedIndex: nextSelectedIndex,
33
+ };
34
+ });
35
+ };
36
+
37
+ downHandler = () => {
38
+ const { items } = this.props;
39
+ this.setState((prevState) => {
40
+ const { selectedIndex } = prevState;
41
+ const nextSelectedIndex = (selectedIndex + 1) % items.length;
42
+ return {
43
+ selectedIndex: nextSelectedIndex,
44
+ };
45
+ });
46
+ };
47
+
48
+ enterHandler = () => {
49
+ const { selectedIndex } = this.state;
50
+ this.selectItem(selectedIndex);
51
+ };
52
+
53
+ onKeyDown = ({ event }) => {
54
+ const keyDownHandlers = {
55
+ ArrowUp: this.upHandler,
56
+ ArrowDown: this.downHandler,
57
+ Enter: this.enterHandler,
58
+ };
59
+
60
+ if (keyDownHandlers.hasOwnProperty(event.key)) {
61
+ keyDownHandlers[event.key]();
62
+ return true;
63
+ }
64
+
65
+ return false;
66
+ };
67
+
68
+ render() {
69
+ const { selectedIndex } = this.state;
70
+ const { items } = this.props;
71
+
72
+ const containerClassName =
73
+ "relative p-2 space-y-1 overflow-hidden rounded shadow editor-command-list--root";
74
+ const itemClassName =
75
+ "flex items-center w-full px-4 py-2 transition-all duration-100 ease-in-out cursor-pointer text-xs text-white rounded editor-command-list--item";
76
+
77
+ return (
78
+ <div className={containerClassName}>
79
+ {items.map(({ label, imageUrl, showImage }, index) => (
80
+ <button
81
+ className={classNames(itemClassName, {
82
+ selected_item: index === selectedIndex,
83
+ })}
84
+ key={label}
85
+ onClick={() => this.selectItem(index)}
86
+ >
87
+ {showImage ? (
88
+ <Avatar user={{ name: label, imageUrl }} className="mr-2" />
89
+ ) : null}
90
+ <span>{label}</span>
91
+ </button>
92
+ ))}
93
+ </div>
94
+ );
95
+ }
96
+ }
@@ -0,0 +1,23 @@
1
+ export const createMentionSuggestions = (
2
+ items = [],
3
+ { limit = 5, showImage = false } = {}
4
+ ) => {
5
+ const allSuggestions = items.map((item) => {
6
+ let suggestionObj;
7
+ if (typeof item === "string") {
8
+ suggestionObj = { key: item, label: item };
9
+ } else if (typeof item === "object") {
10
+ suggestionObj = { ...item };
11
+ }
12
+ suggestionObj.showImage = showImage;
13
+
14
+ return suggestionObj;
15
+ });
16
+
17
+ return ({ query }) =>
18
+ allSuggestions
19
+ .filter((suggestion) =>
20
+ suggestion.label.toLowerCase().startsWith(query.toLowerCase())
21
+ )
22
+ .slice(0, limit);
23
+ };
@@ -0,0 +1,81 @@
1
+ import { Extension } from "@tiptap/core";
2
+ import { Decoration, DecorationSet } from "prosemirror-view";
3
+ import { Plugin } from "prosemirror-state";
4
+
5
+ import { placeholderGenerator } from "./helpers";
6
+
7
+ export default Extension.create({
8
+ name: "placeholder",
9
+
10
+ addOptions() {
11
+ return {
12
+ excludeNodeTypes: ["variable"],
13
+ emptyEditorClass: "is-editor-empty",
14
+ emptyNodeClass: "is-empty",
15
+ placeholder: "Write something …",
16
+ showOnlyWhenEditable: true,
17
+ showOnlyCurrent: true,
18
+ includeChildren: false,
19
+ };
20
+ },
21
+
22
+ addProseMirrorPlugins() {
23
+ return [
24
+ new Plugin({
25
+ props: {
26
+ decorations: ({ doc, selection }) => {
27
+ const active =
28
+ this.editor.isEditable || !this.options.showOnlyWhenEditable;
29
+ const { anchor } = selection;
30
+ const decorations = [];
31
+
32
+ if (!active) {
33
+ return;
34
+ }
35
+
36
+ doc.descendants((node, pos) => {
37
+ const hasAnchor = anchor >= pos && anchor <= pos + node.nodeSize;
38
+ const isEmpty = !node.isLeaf && !node.childCount;
39
+
40
+ const isExcluded = this.options.excludeNodeTypes.includes(
41
+ node.type.name
42
+ );
43
+
44
+ if (
45
+ (hasAnchor || !this.options.showOnlyCurrent) &&
46
+ !isExcluded &&
47
+ isEmpty
48
+ ) {
49
+ const classes = [this.options.emptyNodeClass];
50
+
51
+ if (this.editor.isEmpty) {
52
+ classes.push(this.options.emptyEditorClass);
53
+ }
54
+
55
+ const decoration = Decoration.node(pos, pos + node.nodeSize, {
56
+ class: classes.join(" "),
57
+ "data-placeholder":
58
+ typeof this.options.placeholder === "function"
59
+ ? this.options.placeholder({
60
+ editor: this.editor,
61
+ node,
62
+ pos,
63
+ })
64
+ : this.options.placeholder,
65
+ });
66
+
67
+ decorations.push(decoration);
68
+ }
69
+
70
+ return this.options.includeChildren;
71
+ });
72
+
73
+ return DecorationSet.create(doc, decorations);
74
+ },
75
+ },
76
+ }),
77
+ ];
78
+ },
79
+ });
80
+
81
+ export { placeholderGenerator };
@@ -0,0 +1,18 @@
1
+ import isPlainObject from "lodash.isplainobject";
2
+
3
+ export const placeholderGenerator = (placeholder) => {
4
+ const type = typeof placeholder;
5
+
6
+ if (type === "string" || type === "funtion") {
7
+ return placeholder;
8
+ }
9
+
10
+ if (isPlainObject(placeholder)) {
11
+ return ({ node }) => {
12
+ const { name } = node.type;
13
+ return placeholder[name];
14
+ };
15
+ }
16
+
17
+ return "";
18
+ };
@@ -1,18 +1,13 @@
1
1
  import { Extension } from "@tiptap/core";
2
+ import { PluginKey } from "prosemirror-state";
2
3
  import Suggestion from "@tiptap/suggestion";
3
4
 
5
+ export const CommandsPluginKey = new PluginKey("commands");
6
+
4
7
  export default Extension.create({
5
- name: "mention",
8
+ name: "commands",
6
9
 
7
- defaultOptions: {
8
- suggestion: {
9
- char: "/",
10
- startOfLine: false,
11
- command: ({ editor, range, props }) => {
12
- props.command({ editor, range });
13
- },
14
- },
15
- },
10
+ defaultOptions: {},
16
11
 
17
12
  addProseMirrorPlugins() {
18
13
  return [
@@ -1,6 +1,5 @@
1
1
  import React from "react";
2
2
  import classnames from "classnames";
3
- import "../../styles/CommandsList.scss";
4
3
 
5
4
  class CommandsList extends React.Component {
6
5
  constructor(props) {
@@ -19,7 +18,7 @@ class CommandsList extends React.Component {
19
18
  }
20
19
  }
21
20
 
22
- onKeyDown({ event }) {
21
+ onKeyDown = ({ event }) => {
23
22
  if (event.key === "ArrowUp") {
24
23
  this.upHandler();
25
24
  return true;
@@ -36,45 +35,45 @@ class CommandsList extends React.Component {
36
35
  }
37
36
 
38
37
  return false;
39
- }
38
+ };
40
39
 
41
- upHandler() {
40
+ upHandler = () => {
42
41
  this.setState({
43
42
  selectedIndex:
44
43
  (this.state.selectedIndex + this.props.items.length - 1) %
45
44
  this.props.items.length,
46
45
  });
47
- }
46
+ };
48
47
 
49
- downHandler() {
48
+ downHandler = () => {
50
49
  this.setState({
51
50
  selectedIndex: (this.state.selectedIndex + 1) % this.props.items.length,
52
51
  });
53
- }
52
+ };
54
53
 
55
- enterHandler() {
54
+ enterHandler = () => {
56
55
  this.selectItem(this.state.selectedIndex);
57
- }
56
+ };
58
57
 
59
- selectItem(index) {
58
+ selectItem = (index) => {
60
59
  const item = this.props.items[index];
61
60
 
62
61
  if (item) {
63
62
  const { editor, range } = this.props;
64
63
  item.command({ editor, range });
65
64
  }
66
- }
65
+ };
67
66
 
68
67
  render() {
69
68
  return (
70
- <div className="relative py-2 overflow-hidden bg-gray-900 rounded shadow">
69
+ <div className="relative p-3 space-y-2 overflow-hidden rounded shadow editor-command-list--root">
71
70
  {this.props.items.map((item, index) => (
72
71
  <Item
73
72
  key={item.title}
74
73
  item={item}
75
74
  index={index}
76
75
  selectedIndex={this.state.selectedIndex}
77
- selectItem={this.selectItem}
76
+ selectItem={() => this.selectItem(index)}
78
77
  />
79
78
  ))}
80
79
  </div>
@@ -87,15 +86,15 @@ const Item = ({ item, selectedIndex, index, selectItem }) => {
87
86
  return (
88
87
  <div
89
88
  className={classnames(
90
- "flex items-center w-full px-4 py-2 space-x-4 transition-all duration-100",
89
+ "flex items-center w-full px-4 py-2 space-x-4 transition-all duration-100 ease-in-out editor-command-list--item cursor-pointer rounded",
91
90
  {
92
- "bg-gray-800": index === selectedIndex,
91
+ selected_item: index === selectedIndex,
93
92
  }
94
93
  )}
95
94
  onClick={() => selectItem(index)}
96
95
  >
97
96
  {Icon && (
98
- <div className="p-1 text-gray-100 bg-gray-800 rounded-sm">
97
+ <div className="p-1 text-gray-100 rounded-sm">
99
98
  <Icon size={18} />
100
99
  </div>
101
100
  )}