@vonaffenfels/slate-editor 1.0.26 → 1.0.28

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vonaffenfels/slate-editor",
3
- "version": "1.0.26",
3
+ "version": "1.0.28",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -62,7 +62,7 @@
62
62
  "url-loader": "^4.1.1",
63
63
  "util": "^0.12.5",
64
64
  "walk-sync": "^3.0.0",
65
- "webpack": "5.73.0",
65
+ "webpack": "5.88.2",
66
66
  "webpack-cli": "^4.6.0",
67
67
  "webpack-dev-server": "4.7.4"
68
68
  },
@@ -71,7 +71,7 @@
71
71
  "cssnano": "^5.0.1",
72
72
  "escape-html": "^1.0.3"
73
73
  },
74
- "gitHead": "7089b60e41691c2c382e25c8447f74d0bd031aaa",
74
+ "gitHead": "fe5a1e14e437b67a1aa58fa6781b9ae134914750",
75
75
  "publishConfig": {
76
76
  "access": "public"
77
77
  }
@@ -17,6 +17,8 @@ import "../scss/editor.scss";
17
17
  import {ListItemPlugin} from "./plugins/ListItem";
18
18
  import ErrorBoundary from "../src/Blocks/ErrorBoundary";
19
19
  import SidebarEditor from './SidebarEditor';
20
+ import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
21
+ import {faSpinner} from '@fortawesome/free-solid-svg-icons';
20
22
 
21
23
  export default function BlockEditor({
22
24
  onChange,
@@ -27,6 +29,7 @@ export default function BlockEditor({
27
29
  storybookComponentDataLoader,
28
30
  storybookStories,
29
31
  onSaveClick,
32
+ isLoading,
30
33
  }) {
31
34
  const scrollContainer = useRef(null);
32
35
  const [selectedStorybookElement, setSelectedStorybookElement] = useState(null);
@@ -231,7 +234,12 @@ export default function BlockEditor({
231
234
  <div>
232
235
  <Toolbar hover={false} onSaveClick={onSaveClick}/>
233
236
  </div>
234
- <div className="h-full max-h-full overflow-scroll px-8 py-4" ref={scrollContainer}>
237
+ <div className="relative h-full max-h-full overflow-scroll px-8 py-4" ref={scrollContainer}>
238
+ {isLoading && (
239
+ <div className='pointer-events-none fixed left-0 top-0 z-50 text-black dark:text-white' style={{padding: "61px 0 0 16px"}}>
240
+ <FontAwesomeIcon icon={faSpinner} pulse />
241
+ </div>
242
+ )}
235
243
  <ErrorBoundary
236
244
  name="editor"
237
245
  fallback={(
@@ -1,6 +1,7 @@
1
1
  import React from "react";
2
2
  import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
3
3
  import {
4
+ faAlignCenter,
4
5
  faArrowDown, faArrowUp, faBorderAll, faBorderNone, faCompress, faTimes,
5
6
  } from "@fortawesome/free-solid-svg-icons";
6
7
  import {Transforms} from "slate";
@@ -119,6 +120,44 @@ export const LayoutBlock = ({
119
120
  }, {at: fromPath});
120
121
  };
121
122
 
123
+ const switchCenter = (e) => {
124
+ let node = ReactEditor.toSlateNode(editor, attributes.ref.current);
125
+ let fromPath = ReactEditor.findPath(editor, node);
126
+
127
+ if (!fromPath) {
128
+ return;
129
+ }
130
+
131
+ let justifyCenter = !(element?.attributes?.justifyCenter);
132
+
133
+ Transforms.setNodes(editor, {
134
+ type: "layout",
135
+ attributes: {
136
+ ...(element.attributes || {}),
137
+ justifyCenter,
138
+ },
139
+ }, {at: fromPath});
140
+ };
141
+
142
+ const switchBorder = (e) => {
143
+ let node = ReactEditor.toSlateNode(editor, attributes.ref.current);
144
+ let fromPath = ReactEditor.findPath(editor, node);
145
+
146
+ if (!fromPath) {
147
+ return;
148
+ }
149
+
150
+ let tableBorder = !(element?.attributes?.tableBorder);
151
+
152
+ Transforms.setNodes(editor, {
153
+ type: "layout",
154
+ attributes: {
155
+ ...(element.attributes || {}),
156
+ tableBorder,
157
+ },
158
+ }, {at: fromPath});
159
+ };
160
+
122
161
  const onMarginChange = (value) => {
123
162
  let node = ReactEditor.toSlateNode(editor, attributes.ref.current);
124
163
  let path = ReactEditor.findPath(editor, node);
@@ -159,12 +198,28 @@ export const LayoutBlock = ({
159
198
  <FontAwesomeIcon icon={faBorderAll} size="lg"/>
160
199
  )}
161
200
  </span>
201
+ <span className="options-container-option options-container-option-expand" onClick={switchCenter}>
202
+ {!element?.attributes?.justifyCenter ? (
203
+ <FontAwesomeIcon icon={faAlignCenter} size="lg"/>
204
+ ) : (
205
+ <FontAwesomeIcon icon={faAlignCenter} color="#3490f3" size="lg"/>
206
+ )}
207
+ </span>
208
+ <span className="options-container-option options-container-option-expand-text mx-2" onClick={switchBorder}>
209
+ {!element?.attributes?.tableBorder ? (
210
+ <span>Kein Rahmen</span>
211
+ ) : (
212
+ <span>Rahmen</span>
213
+ )}
214
+ </span>
162
215
  <ToolMargin margin={element?.attributes?.margin} onChange={onMarginChange}/>
163
216
  </div>
164
217
  <div
165
218
  className={`layout-block layout-grid layout-grid-cols-${children.length} ` + classNames({
166
219
  [classNameArticle + " article-width"]: element?.attributes?.width === "article" || !element?.attributes?.width,
167
220
  [classNameSite + " site-width"]: element?.attributes?.width === "full",
221
+ "block-editor-table-border-wrapper": element?.attributes?.tableBorder,
222
+ "justify-center": element?.attributes?.justifyCenter,
168
223
  "space-x-4": element?.attributes?.spacing,
169
224
  "editor-mt-large": element?.attributes?.margin?.top,
170
225
  "editor-mr-large": element?.attributes?.margin?.right,
@@ -137,6 +137,8 @@ export function Serializer({
137
137
  "mr-16": props?.attributes?.margin?.right,
138
138
  "mb-16": props?.attributes?.margin?.bottom,
139
139
  "ml-16": props?.attributes?.margin?.left,
140
+ "block-editor-table-border-wrapper": props?.attributes?.tableBorder,
141
+ "justify-center": props?.attributes?.justifyCenter,
140
142
  [typeProps.classNameSite + " site-width"]: !isInSlot && (props.attributes?.width === "site" || props.attributes?.width === "full"),
141
143
  [typeProps.classNameArticle + " article-width"]: !isInSlot && (props.attributes?.width === "article" || !props.attributes?.width),
142
144
  })}
@@ -107,6 +107,22 @@ export const Asset = ({
107
107
  return null;
108
108
  }
109
109
 
110
+ let assetType = "image";
111
+
112
+ if (title?.endsWith(".mp3")) {
113
+ assetType = "audio";
114
+ }
115
+
116
+ const renderMedia = () => {
117
+ switch (assetType) {
118
+ case "audio":
119
+ return <audio src={mediaUrl} className="mt-2 w-full" controls />;
120
+ case "image":
121
+ default:
122
+ return <img src={mediaUrl} width="100%" className="mt-2 rounded-md" />;
123
+ }
124
+ };
125
+
110
126
  return (
111
127
  <div className="flex flex-col">
112
128
  <div className="flex">
@@ -126,7 +142,7 @@ export const Asset = ({
126
142
  <IconButton size="small" onClick={onDeleteClick}>⨯</IconButton>
127
143
  </div>
128
144
  </div>
129
- {!!mediaUrl && <img src={mediaUrl} width="100%" className="mt-2 rounded-md" />}
145
+ {!!mediaUrl && renderMedia()}
130
146
  </div>
131
147
  );
132
148
  };
@@ -122,8 +122,8 @@ export const SidebarEditorField = ({
122
122
  case "object":
123
123
  return (
124
124
  <textarea
125
- value={value || ""}
126
- onChange={e => onChange(fieldKey, e.target.value)} />
125
+ value={typeof value === "object" ? JSON.stringify(value, null, 2) || "" : value}
126
+ onChange={e => onChange(fieldKey, isJson(e.target.value) ? JSON.parse(e.target.value) : e.target.value)} />
127
127
  );
128
128
  case "radio":
129
129
  return (
@@ -379,8 +379,17 @@ export const SidebarEditorField = ({
379
379
 
380
380
  return (
381
381
  <div key={`${field.name}`} className="mb-2">
382
- <label className="block">{field.name}</label>
382
+ <label className="block">{field.name || fieldKey}</label>
383
383
  {inputField}
384
384
  </div>
385
385
  );
386
+ };
387
+
388
+ const isJson = (str) => {
389
+ try {
390
+ JSON.parse(str);
391
+ } catch (e) {
392
+ return false;
393
+ }
394
+ return true;
386
395
  };
@@ -26,7 +26,7 @@ const SidebarEditor = ({
26
26
  tables: {},
27
27
  };
28
28
 
29
- const story = storybookStories.find(v => storybookElement.block === v.id);
29
+ const story = storybookStories?.find(v => storybookElement.block === v.id);
30
30
 
31
31
  if (story) {
32
32
  Object.keys(story.argTypes).forEach(key => {
@@ -73,8 +73,23 @@ export const toggleBlock = (editor, format, attributes) => {
73
73
 
74
74
  export const isBlockActive = (editor, format, attributes) => {
75
75
  const {selection} = editor;
76
+
76
77
  if (selection) {
77
- const selectedNodes = [editor.children[selection.anchor.path[0]]];
78
+ let selected = editor;
79
+
80
+ let reducedPath = selection.anchor.path.slice(0, -1);
81
+
82
+ for (let i = 0; i < reducedPath.length; i++) {
83
+ let path = reducedPath[i];
84
+
85
+ selected = selected.children[path];
86
+
87
+ if (LIST_TYPES.includes(selected.type)) {
88
+ break;
89
+ }
90
+ }
91
+
92
+ const selectedNodes = [selected];
78
93
 
79
94
  return !!selectedNodes.find(v => {
80
95
  if (Editor.isEditor(v)) {
@@ -204,6 +204,73 @@ export const InsertGridButton = () => {
204
204
  }}>
205
205
  <span>1 | 1 | 1 | 1</span>
206
206
  </InsertLayoutButton>
207
+ <InsertLayoutButton insert={{
208
+ "type": "layout",
209
+ "children": [
210
+ {
211
+ "type": "layout-slot",
212
+ "attributes": {"name": "grid-1"},
213
+ "children": [
214
+ {
215
+ "type": "paragraph",
216
+ "children": [
217
+ {"text": ""},
218
+ ],
219
+ },
220
+ ],
221
+ },
222
+ {
223
+ "type": "layout-slot",
224
+ "attributes": {"name": "grid-1"},
225
+ "children": [
226
+ {
227
+ "type": "paragraph",
228
+ "children": [
229
+ {"text": ""},
230
+ ],
231
+ },
232
+ ],
233
+ },
234
+ {
235
+ "type": "layout-slot",
236
+ "attributes": {"name": "grid-1"},
237
+ "children": [
238
+ {
239
+ "type": "paragraph",
240
+ "children": [
241
+ {"text": ""},
242
+ ],
243
+ },
244
+ ],
245
+ },
246
+ {
247
+ "type": "layout-slot",
248
+ "attributes": {"name": "grid-1"},
249
+ "children": [
250
+ {
251
+ "type": "paragraph",
252
+ "children": [
253
+ {"text": ""},
254
+ ],
255
+ },
256
+ ],
257
+ },
258
+ {
259
+ "type": "layout-slot",
260
+ "attributes": {"name": "grid-1"},
261
+ "children": [
262
+ {
263
+ "type": "paragraph",
264
+ "children": [
265
+ {"text": ""},
266
+ ],
267
+ },
268
+ ],
269
+ },
270
+ ],
271
+ }}>
272
+ <span>1 | 1 | 1 | 1 | 1</span>
273
+ </InsertLayoutButton>
207
274
  <InsertLayoutButton insert={{
208
275
  "type": "layout",
209
276
  "children": [
@@ -21,9 +21,9 @@ export const ListItemPlugin = {
21
21
  event.preventDefault();
22
22
  Transforms.insertNodes(editor, {
23
23
  at: editor.selection.anchor.path,
24
- match: node => {
25
- return node.type === "list-item";
26
- },
24
+ // match: node => {
25
+ // return node.type === "list-item";
26
+ // },
27
27
  type: "list-item",
28
28
  children: [{text: ""}],
29
29
  });