@bigbinary/neeto-editor 0.2.1 → 0.2.5

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 (78) hide show
  1. package/index.js +9 -9
  2. package/package.json +2 -3
  3. package/tailwind.config.js +13 -9
  4. package/webpack.config.js +5 -3
  5. package/webpack.dev.config.js +5 -3
  6. package/public/favicon.ico +0 -0
  7. package/public/index.html +0 -28
  8. package/public/robots.txt +0 -3
  9. package/src/App.js +0 -8
  10. package/src/Common/Avatar.js +0 -168
  11. package/src/Common/Button.js +0 -95
  12. package/src/Common/CodeBlock.js +0 -11
  13. package/src/Common/Description.js +0 -8
  14. package/src/Common/Dropdown/index.js +0 -122
  15. package/src/Common/Heading.js +0 -13
  16. package/src/Common/HighlightText.js +0 -7
  17. package/src/Common/Icons/HashtagFilled.js +0 -59
  18. package/src/Common/Icons/TextColor.js +0 -35
  19. package/src/Common/Icons/index.js +0 -2
  20. package/src/Common/Input.js +0 -70
  21. package/src/Common/Label.js +0 -45
  22. package/src/Common/ListItems.js +0 -17
  23. package/src/Common/Modal.js +0 -91
  24. package/src/Common/Tab.js +0 -79
  25. package/src/Common/ToolTip.js +0 -37
  26. package/src/Editor/CustomExtensions/BubbleMenu/index.js +0 -92
  27. package/src/Editor/CustomExtensions/CodeBlock/CodeBlockComponent.js +0 -12
  28. package/src/Editor/CustomExtensions/CodeBlock/ExtensionConfig.js +0 -10
  29. package/src/Editor/CustomExtensions/Embeds.js +0 -72
  30. package/src/Editor/CustomExtensions/FixedMenu/FontSizeOption.js +0 -32
  31. package/src/Editor/CustomExtensions/FixedMenu/TextColorOption.js +0 -29
  32. package/src/Editor/CustomExtensions/FixedMenu/constants.js +0 -3
  33. package/src/Editor/CustomExtensions/FixedMenu/index.js +0 -183
  34. package/src/Editor/CustomExtensions/Image/ExtensionConfig.js +0 -47
  35. package/src/Editor/CustomExtensions/Image/LinkUploader/URLForm.js +0 -39
  36. package/src/Editor/CustomExtensions/Image/LocalUploader.js +0 -21
  37. package/src/Editor/CustomExtensions/Image/ProgressBar.js +0 -34
  38. package/src/Editor/CustomExtensions/Image/Uploader.js +0 -82
  39. package/src/Editor/CustomExtensions/Image/constants.js +0 -5
  40. package/src/Editor/CustomExtensions/Mention/ExtensionConfig.js +0 -66
  41. package/src/Editor/CustomExtensions/Mention/MentionList.js +0 -96
  42. package/src/Editor/CustomExtensions/Mention/helpers.js +0 -23
  43. package/src/Editor/CustomExtensions/Placeholder/ExtensionConfig.js +0 -81
  44. package/src/Editor/CustomExtensions/Placeholder/helpers.js +0 -18
  45. package/src/Editor/CustomExtensions/SlashCommands/Commands.js +0 -20
  46. package/src/Editor/CustomExtensions/SlashCommands/CommandsList.js +0 -109
  47. package/src/Editor/CustomExtensions/SlashCommands/ExtensionConfig.js +0 -209
  48. package/src/Editor/CustomExtensions/Variable/ExtensionConfig.js +0 -208
  49. package/src/Editor/CustomExtensions/Variable/VariableList.js +0 -45
  50. package/src/Editor/CustomExtensions/Variable/VariableSuggestion.js +0 -20
  51. package/src/Editor/CustomExtensions/Variable/helpers.js +0 -31
  52. package/src/Editor/CustomExtensions/Variable/index.js +0 -35
  53. package/src/Editor/CustomExtensions/useCustomExtensions.js +0 -88
  54. package/src/Editor/index.js +0 -104
  55. package/src/Editor/sharedState.js +0 -8
  56. package/src/constants/regexp.js +0 -1
  57. package/src/examples/constants.js +0 -95
  58. package/src/examples/index.js +0 -186
  59. package/src/hooks/useOutsideClick.js +0 -19
  60. package/src/hooks/useTabBar.js +0 -9
  61. package/src/index.js +0 -10
  62. package/src/index.scss +0 -46
  63. package/src/styles/abstracts/_mixins.scss +0 -20
  64. package/src/styles/abstracts/_neeto-ui-variables.scss +0 -107
  65. package/src/styles/abstracts/_variables.scss +0 -13
  66. package/src/styles/components/_avatar.scss +0 -105
  67. package/src/styles/components/_button.scss +0 -161
  68. package/src/styles/components/_codeblock.scss +0 -16
  69. package/src/styles/components/_command-list.scss +0 -19
  70. package/src/styles/components/_dropdown.scss +0 -69
  71. package/src/styles/components/_editor-variables.scss +0 -12
  72. package/src/styles/components/_editor.scss +0 -102
  73. package/src/styles/components/_fixed-menu.scss +0 -17
  74. package/src/styles/components/_image-uploader.scss +0 -109
  75. package/src/styles/components/_input.scss +0 -165
  76. package/src/styles/components/_tab.scss +0 -74
  77. package/src/styles/components/_tooltip.scss +0 -152
  78. package/src/utils/common.js +0 -13
@@ -1,20 +0,0 @@
1
- import { Extension } from "@tiptap/core";
2
- import { PluginKey } from "prosemirror-state";
3
- import Suggestion from "@tiptap/suggestion";
4
-
5
- export const CommandsPluginKey = new PluginKey("commands");
6
-
7
- export default Extension.create({
8
- name: "commands",
9
-
10
- defaultOptions: {},
11
-
12
- addProseMirrorPlugins() {
13
- return [
14
- Suggestion({
15
- editor: this.editor,
16
- ...this.options.suggestion,
17
- }),
18
- ];
19
- },
20
- });
@@ -1,109 +0,0 @@
1
- import React from "react";
2
- import classnames from "classnames";
3
-
4
- class CommandsList extends React.Component {
5
- constructor(props) {
6
- super(props);
7
-
8
- this.state = {
9
- selectedIndex: 0,
10
- };
11
- }
12
-
13
- componentDidUpdate(oldProps) {
14
- if (this.props.items !== oldProps.items) {
15
- this.setState({
16
- selectedIndex: 0,
17
- });
18
- }
19
- }
20
-
21
- onKeyDown = ({ event }) => {
22
- if (event.key === "ArrowUp") {
23
- this.upHandler();
24
- return true;
25
- }
26
-
27
- if (event.key === "ArrowDown") {
28
- this.downHandler();
29
- return true;
30
- }
31
-
32
- if (event.key === "Enter") {
33
- this.enterHandler();
34
- return true;
35
- }
36
-
37
- return false;
38
- };
39
-
40
- upHandler = () => {
41
- this.setState({
42
- selectedIndex:
43
- (this.state.selectedIndex + this.props.items.length - 1) %
44
- this.props.items.length,
45
- });
46
- };
47
-
48
- downHandler = () => {
49
- this.setState({
50
- selectedIndex: (this.state.selectedIndex + 1) % this.props.items.length,
51
- });
52
- };
53
-
54
- enterHandler = () => {
55
- this.selectItem(this.state.selectedIndex);
56
- };
57
-
58
- selectItem = (index) => {
59
- const item = this.props.items[index];
60
-
61
- if (item) {
62
- const { editor, range } = this.props;
63
- item.command({ editor, range });
64
- }
65
- };
66
-
67
- render() {
68
- return (
69
- <div className="relative p-3 space-y-2 overflow-hidden rounded shadow editor-command-list--root">
70
- {this.props.items.map((item, index) => (
71
- <Item
72
- key={item.title}
73
- item={item}
74
- index={index}
75
- selectedIndex={this.state.selectedIndex}
76
- selectItem={() => this.selectItem(index)}
77
- />
78
- ))}
79
- </div>
80
- );
81
- }
82
- }
83
-
84
- const Item = ({ item, selectedIndex, index, selectItem }) => {
85
- const Icon = item.Icon;
86
- return (
87
- <div
88
- className={classnames(
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",
90
- {
91
- selected_item: index === selectedIndex,
92
- }
93
- )}
94
- onClick={() => selectItem(index)}
95
- >
96
- {Icon && (
97
- <div className="p-1 text-gray-100 rounded-sm">
98
- <Icon size={18} />
99
- </div>
100
- )}
101
- <div className="flex flex-col text-gray-100">
102
- <span className="text-sm font-semibold">{item.title}</span>
103
- <span className="text-xs text-gray-300">{item.description}</span>
104
- </div>
105
- </div>
106
- );
107
- };
108
-
109
- export default CommandsList;
@@ -1,209 +0,0 @@
1
- import { Extension } from "@tiptap/core";
2
- import CommandsList from "./CommandsList";
3
- import { PluginKey } from "prosemirror-state";
4
- import Suggestion from "@tiptap/suggestion";
5
- import tippy from "tippy.js";
6
- import { ReactRenderer } from "@tiptap/react";
7
- import {
8
- Paragraph,
9
- TextH1,
10
- TextH2,
11
- ListDot,
12
- ListNumber,
13
- Blockquote,
14
- Image,
15
- Video,
16
- Code,
17
- } from "@bigbinary/neeto-icons";
18
-
19
- export const CommandsPluginKey = new PluginKey("commands");
20
-
21
- export default {
22
- configure: ({ setImageUploadVisible }) =>
23
- Extension.create({
24
- addOptions() {
25
- return {
26
- HTMLAttributes: {
27
- class: "commands",
28
- },
29
- suggestion: {
30
- char: "/",
31
- startOfLine: false,
32
- pluginKey: CommandsPluginKey,
33
- command: ({ editor, range, props }) => {
34
- props.command({ editor, range });
35
- },
36
-
37
- items: () => {
38
- return [
39
- {
40
- title: "Paragraph",
41
- description: "Add a plain text block",
42
- Icon: Paragraph,
43
- command: ({ editor, range }) => {
44
- editor
45
- .chain()
46
- .focus()
47
- .deleteRange(range)
48
- .setNode("paragraph")
49
- .run();
50
- },
51
- },
52
- {
53
- title: "H1",
54
- description: "Add a big heading",
55
- Icon: TextH1,
56
- command: ({ editor, range }) => {
57
- editor
58
- .chain()
59
- .focus()
60
- .deleteRange(range)
61
- .setNode("heading", { level: 1 })
62
- .run();
63
- },
64
- },
65
- {
66
- title: "H2",
67
- description: "Add a sub-heading",
68
- Icon: TextH2,
69
- command: ({ editor, range }) => {
70
- editor
71
- .chain()
72
- .focus()
73
- .deleteRange(range)
74
- .setNode("heading", { level: 2 })
75
- .run();
76
- },
77
- },
78
- {
79
- title: "Numbered list",
80
- description: "Add a list with numbering",
81
- Icon: ListNumber,
82
- command: ({ editor, range }) => {
83
- editor
84
- .chain()
85
- .focus()
86
- .deleteRange(range)
87
- .toggleOrderedList()
88
- .run();
89
- },
90
- },
91
- {
92
- title: "Bulleted list",
93
- description: "Add an list bullets",
94
- Icon: ListDot,
95
- command: ({ editor, range }) => {
96
- editor
97
- .chain()
98
- .focus()
99
- .deleteRange(range)
100
- .toggleBulletList()
101
- .run();
102
- },
103
- },
104
- {
105
- title: "Blockquote",
106
- description: "Add a quote",
107
- Icon: Blockquote,
108
- command: ({ editor, range }) => {
109
- editor
110
- .chain()
111
- .focus()
112
- .deleteRange(range)
113
- .toggleBlockquote()
114
- .run();
115
- },
116
- },
117
- {
118
- title: "Image",
119
- description: "Add an image",
120
- Icon: Image,
121
- command: ({ editor, range }) => {
122
- setImageUploadVisible(true);
123
- editor.chain().focus().deleteRange(range).run();
124
- },
125
- },
126
- {
127
- title: "Youtube/Vimeo",
128
- description: "Embed a video from major services",
129
- Icon: Video,
130
- command: ({ editor, range }) => {
131
- const embedURL = prompt(
132
- "Please enter Youtube/Vimeo embed URL"
133
- );
134
- editor
135
- .chain()
136
- .focus()
137
- .deleteRange(range)
138
- .setExternalVideo({ src: embedURL })
139
- .run();
140
- },
141
- },
142
- {
143
- title: "Code block",
144
- description: "Add a code block with syntax highlighting",
145
- Icon: Code,
146
- command: ({ editor, range }) => {
147
- editor
148
- .chain()
149
- .focus()
150
- .deleteRange(range)
151
- .toggleCodeBlock()
152
- .run();
153
- },
154
- },
155
- ];
156
- },
157
-
158
- render: () => {
159
- let reactRenderer;
160
- let popup;
161
-
162
- return {
163
- onStart: (props) => {
164
- reactRenderer = new ReactRenderer(CommandsList, {
165
- props,
166
- editor: props.editor,
167
- });
168
-
169
- popup = tippy("body", {
170
- getReferenceClientRect: props.clientRect,
171
- appendTo: () => document.body,
172
- content: reactRenderer.element,
173
- showOnCreate: true,
174
- interactive: true,
175
- trigger: "manual",
176
- placement: "bottom-start",
177
- arrow: false,
178
- });
179
- },
180
- onUpdate(props) {
181
- reactRenderer.updateProps(props);
182
-
183
- popup[0].setProps({
184
- getReferenceClientRect: props.clientRect,
185
- });
186
- },
187
- onKeyDown(props) {
188
- return reactRenderer.ref?.onKeyDown(props);
189
- },
190
- onExit() {
191
- popup[0].destroy();
192
- reactRenderer.destroy();
193
- },
194
- };
195
- },
196
- },
197
- };
198
- },
199
-
200
- addProseMirrorPlugins() {
201
- return [
202
- Suggestion({
203
- editor: this.editor,
204
- ...this.options.suggestion,
205
- }),
206
- ];
207
- },
208
- }),
209
- };
@@ -1,208 +0,0 @@
1
- import tippy from "tippy.js";
2
- import Suggestion from "@tiptap/suggestion";
3
- import { Node, mergeAttributes } from "@tiptap/core";
4
- import { ReactRenderer } from "@tiptap/react";
5
- import { PluginKey } from "prosemirror-state";
6
-
7
- import VariableSuggestion from "./VariableSuggestion";
8
-
9
- export const VariablePluginKey = new PluginKey("variables");
10
-
11
- const Variable = Node.create({
12
- name: "variable",
13
-
14
- addOptions() {
15
- return {
16
- HTMLAttributes: { class: "variable__text" },
17
- charOpen: "{{",
18
- charClose: "}}",
19
- renderLabel({ options, node }) {
20
- return `${options.charOpen}${node.attrs.label || node.attrs.id}${
21
- options.charClose
22
- }`;
23
- },
24
- suggestion: {},
25
- };
26
- },
27
-
28
- group: "inline",
29
-
30
- inline: true,
31
-
32
- selectable: false,
33
-
34
- atom: true,
35
-
36
- addAttributes() {
37
- return {
38
- id: {
39
- default: null,
40
- parseHTML: (element) => element.getAttribute("data-id"),
41
- renderHTML: (attributes) => {
42
- if (!attributes.id) {
43
- return {};
44
- }
45
-
46
- return {
47
- "data-id": attributes.id,
48
- };
49
- },
50
- },
51
-
52
- label: {
53
- default: null,
54
- parseHTML: (element) => element.getAttribute("data-label"),
55
- renderHTML: (attributes) => {
56
- if (!attributes.label) {
57
- return {};
58
- }
59
-
60
- return {
61
- "data-label": attributes.label,
62
- };
63
- },
64
- },
65
- };
66
- },
67
-
68
- parseHTML() {
69
- return [
70
- {
71
- tag: "span[data-variable]",
72
- },
73
- ];
74
- },
75
-
76
- renderHTML({ node, HTMLAttributes }) {
77
- return [
78
- "span",
79
- mergeAttributes(
80
- { "data-variable": "" },
81
- this.options.HTMLAttributes,
82
- HTMLAttributes
83
- ),
84
- this.options.renderLabel({
85
- options: this.options,
86
- node,
87
- }),
88
- ];
89
- },
90
-
91
- renderText({ node }) {
92
- return this.options.renderLabel({
93
- options: this.options,
94
- node,
95
- });
96
- },
97
-
98
- addCommands() {
99
- return {
100
- setVariable:
101
- (attributes) =>
102
- ({ chain }) => {
103
- chain()
104
- .focus()
105
- .insertContent([
106
- {
107
- type: this.name,
108
- attrs: attributes,
109
- },
110
- {
111
- type: "text",
112
- text: " ",
113
- },
114
- ])
115
- .run();
116
- },
117
- };
118
- },
119
-
120
- addKeyboardShortcuts() {
121
- return {
122
- Backspace: () =>
123
- this.editor.commands.command(({ tr, state }) => {
124
- let isVariable = false;
125
- const { selection } = state;
126
- const { empty, anchor } = selection;
127
-
128
- if (!empty) {
129
- return false;
130
- }
131
-
132
- state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {
133
- if (node.type.name === this.name) {
134
- isVariable = true;
135
- tr.insertText("", pos, pos + node.nodeSize);
136
-
137
- return false;
138
- }
139
- });
140
-
141
- return isVariable;
142
- }),
143
- };
144
- },
145
-
146
- addProseMirrorPlugins() {
147
- return [
148
- Suggestion({
149
- editor: this.editor,
150
- ...this.options.suggestion,
151
- }),
152
- ];
153
- },
154
- });
155
-
156
- const suggestionConfig = {
157
- char: "{{",
158
- startOfLine: false,
159
- pluginKey: VariablePluginKey,
160
- command: ({ editor, range, props }) => {
161
- editor.chain().focus().deleteRange(range).setVariable(props).run();
162
- },
163
-
164
- items: () => [],
165
- render: () => {
166
- let reactRenderer;
167
- let popup;
168
-
169
- return {
170
- onStart: (props) => {
171
- reactRenderer = new ReactRenderer(VariableSuggestion, {
172
- props,
173
- editor: props.editor,
174
- });
175
-
176
- popup = tippy("body", {
177
- getReferenceClientRect: props.clientRect,
178
- appendTo: () => document.body,
179
- content: reactRenderer.element,
180
- showOnCreate: true,
181
- interactive: true,
182
- trigger: "manual",
183
- placement: "bottom-start",
184
- });
185
- },
186
- onUpdate(props) {
187
- reactRenderer.updateProps(props);
188
-
189
- popup[0].setProps({
190
- getReferenceClientRect: props.clientRect,
191
- });
192
- },
193
-
194
- onExit() {
195
- popup[0].destroy();
196
- reactRenderer.destroy();
197
- },
198
- };
199
- },
200
- };
201
-
202
- export default {
203
- configure: ({ suggestion = {} }) => {
204
- return Variable.configure({
205
- suggestion: { ...suggestionConfig, ...suggestion },
206
- });
207
- },
208
- };
@@ -1,45 +0,0 @@
1
- import React from "react";
2
-
3
- import { parseVariables } from "./helpers";
4
-
5
- const VariableList = ({ onClickVariable, variables }) => {
6
- const parsedVariables = parseVariables(variables);
7
-
8
- if (!(variables && variables.length)) {
9
- return null;
10
- }
11
-
12
- return (
13
- <div className="p-3 bg-white">
14
- {parsedVariables.map(({ label, variables }) => (
15
- <VariableCategory
16
- key={label}
17
- title={label}
18
- variables={variables}
19
- onClickItem={onClickVariable}
20
- />
21
- ))}
22
- </div>
23
- );
24
- };
25
-
26
- export default VariableList;
27
-
28
- const VariableCategory = ({ title, variables, onClickItem }) => {
29
- return (
30
- <div className="my-3">
31
- {title ? <p className="text-xs font-semibold">{title}</p> : null}
32
- <div className="mt-1 space-x-2">
33
- {variables.map((item) => (
34
- <button
35
- onClick={() => onClickItem(item)}
36
- key={`${item.label}--${item.value}`}
37
- className="px-2 py-1 text-xs text-white bg-blue-400 rounded-sm"
38
- >
39
- {item.label}
40
- </button>
41
- ))}
42
- </div>
43
- </div>
44
- );
45
- };
@@ -1,20 +0,0 @@
1
- import React from "react";
2
-
3
- import VariableList from "./VariableList";
4
-
5
- const VariableSuggestion = ({ items, command }) => {
6
- return (
7
- <div className="shadow-md">
8
- <VariableList
9
- variables={items}
10
- onClickVariable={(variable) => {
11
- const { category_key, key } = variable;
12
- const variableName = category_key ? `${category_key}.${key}` : key;
13
- command({ label: variableName, id: variableName });
14
- }}
15
- />
16
- </div>
17
- );
18
- };
19
-
20
- export default VariableSuggestion;
@@ -1,31 +0,0 @@
1
- /* Helper function that accepts an array of variables and injects category to each item in the group
2
- And also performs grouping of indvidual variables under common category as 'Others'. */
3
-
4
- export const parseVariables = (variableArr = []) => {
5
- const uncategorized = [];
6
- const groupedVariables = [];
7
- variableArr.forEach((variable) => {
8
- const { category_key, category_label, variables } = variable;
9
- if (category_key && variables) {
10
- const parsedVariables = variables.map((categoryVariable) => ({
11
- ...categoryVariable,
12
- category_key,
13
- }));
14
- groupedVariables.push({
15
- label: category_label,
16
- variables: parsedVariables,
17
- });
18
- } else uncategorized.push(variable);
19
- });
20
-
21
- /* If there are other categorised variables already present, group all uncategorized variables under title 'Others'.
22
- otherwise, if all available variables are uncategorised, do not render 'Others' title */
23
-
24
- if (uncategorized.length) {
25
- groupedVariables.push({
26
- label: groupedVariables.length ? "Others" : null,
27
- variables: uncategorized,
28
- });
29
- }
30
- return groupedVariables;
31
- };
@@ -1,35 +0,0 @@
1
- import React from "react";
2
-
3
- import VariableList from "./VariableList";
4
- import Dropdown from "common/Dropdown";
5
- import { HashtagFilled } from "common/Icons";
6
-
7
- import { MENU_ICON_SIZE } from "../FixedMenu/constants";
8
-
9
- const Variables = ({ editor, variables }) => {
10
- const handleClickItem = (item) => {
11
- const { category_key, key } = item;
12
- const variableName = category_key ? `${category_key}.${key}` : key;
13
- editor.chain().focus().setVariable({ label: variableName }).run();
14
- };
15
-
16
- if (!(variables && variables.length)) {
17
- return null;
18
- }
19
-
20
- return (
21
- <Dropdown
22
- customTarget={() => (
23
- <button className="relative h-full p-3 editor-fixed-menu--item variable-selection-popup">
24
- <HashtagFilled size={MENU_ICON_SIZE} />
25
- </button>
26
- )}
27
- >
28
- <div className="items-container">
29
- <VariableList onClickVariable={handleClickItem} variables={variables} />
30
- </div>
31
- </Dropdown>
32
- );
33
- };
34
-
35
- export default Variables;