@vonaffenfels/slate-editor 1.0.49 → 1.0.52

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,20 +1,21 @@
1
1
  {
2
2
  "name": "@vonaffenfels/slate-editor",
3
- "version": "1.0.49",
3
+ "version": "1.0.52",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
7
7
  "prepublish": "yarn run build",
8
8
  "test": "echo \"Error: no test specified\" && exit 1",
9
9
  "build": "rm -rf dist && webpack --config webpack.config.build.js",
10
- "buildWatch": "rm -rf dist && webpack --config webpack.config.build.js --watch",
10
+ "buildWatch": "rm -rf dist && webpack --config webpack.config.watch.js --watch",
11
11
  "dev": "webpack serve --config webpack.config.dev.js --open"
12
12
  },
13
13
  "author": "",
14
14
  "license": "ISC",
15
15
  "peerDependencies": {
16
- "react": "17.0.2",
17
- "react-dom": "17.0.2"
16
+ "next": "^12.3.4",
17
+ "react": "^18",
18
+ "react-dom": "^18"
18
19
  },
19
20
  "devDependencies": {
20
21
  "@babel/core": "^7.20.12",
@@ -43,13 +44,12 @@
43
44
  "graphql": "16.5.0",
44
45
  "html-webpack-plugin": "^5.3.1",
45
46
  "mini-css-extract-plugin": "^1.5.0",
46
- "next": "^12.3.4",
47
47
  "path-browserify": "^1.0.1",
48
48
  "postcss": "8.4.14",
49
49
  "postcss-import": "^15.1.0",
50
50
  "postcss-loader": "^5.2.0",
51
- "react": "18.2.0",
52
- "react-dom": "18.2.0",
51
+ "react": "^18.2.0",
52
+ "react-dom": "^18.2.0",
53
53
  "sass": "^1.32.11",
54
54
  "sass-loader": "^10.0.1",
55
55
  "shortid": "^2.2.16",
@@ -71,7 +71,7 @@
71
71
  "cssnano": "^5.0.1",
72
72
  "escape-html": "^1.0.3"
73
73
  },
74
- "gitHead": "b9487e3c2407021c202cb464a6073bb11ccb6bb4",
74
+ "gitHead": "41eb9767f8c80645382c0d77eae03bcefaac6fe4",
75
75
  "publishConfig": {
76
76
  "access": "public"
77
77
  }
package/scss/editor.scss CHANGED
@@ -161,7 +161,7 @@
161
161
  }
162
162
 
163
163
  .arrow-list li::before {
164
- content: none !important;
164
+ content: none !important;
165
165
  }
166
166
 
167
167
  div[data-slate-editor="true"] {
@@ -303,21 +303,15 @@
303
303
  }
304
304
  }
305
305
 
306
- .layout-block-auto-fill {
307
- grid-template-columns: auto 1fr;
308
- }
309
-
310
- .layout-block-fill-auto {
311
- grid-template-columns: 1fr auto;
306
+ .layout-block-grid {
307
+ display: grid;
312
308
  }
313
309
 
314
- .layout-block-auto-fill-auto {
315
- grid-template-columns: auto 1fr auto;
310
+ .layout-block-flex {
311
+ display: flex;
316
312
  }
317
313
 
318
314
  .layout-block {
319
- display: grid;
320
-
321
315
  &.article-width {
322
316
  width: 44.44444444435556%;
323
317
  }
@@ -359,6 +353,15 @@
359
353
  display: inline-block;
360
354
  }
361
355
  }
356
+
357
+ &.layout-slot-grid-fill {
358
+ flex-grow: 1;
359
+ }
360
+
361
+ &.layout-slot-grid-auto {
362
+ flex-grow: 0;
363
+ width: auto;
364
+ }
362
365
  }
363
366
 
364
367
  @media only screen and (max-width: 360px) {
@@ -407,4 +410,24 @@
407
410
  .button.button--secondary:active {
408
411
  background-color: #0262C9 !important;
409
412
  color: #FFFFFF !important;
413
+ }
414
+
415
+ .resizable {
416
+ .resizable-left {
417
+ position: relative;
418
+ }
419
+ .resizable-right {
420
+ position: relative;
421
+ }
422
+ .resizable-x-handle {
423
+ cursor: ew-resize;
424
+ content: "";
425
+ position: absolute;
426
+ height: 100%;
427
+ width: 10px;
428
+ text-align: center;
429
+ top: 0;
430
+ left: -2px;
431
+ background-color: transparent;
432
+ }
410
433
  }
@@ -17,15 +17,15 @@
17
17
  * {
18
18
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !important;
19
19
  }
20
-
20
+
21
21
  p, label, b, span {
22
22
  color: rgb(90, 101, 124);
23
23
  }
24
-
24
+
25
25
  label {
26
26
  margin: 0 0 2px 0 !important;
27
27
  }
28
-
28
+
29
29
  input[type="text"],
30
30
  input[type="number"],
31
31
  input[type="color"],
@@ -48,46 +48,47 @@
48
48
  height: 42px;
49
49
  max-height: 200px;
50
50
  }
51
-
51
+
52
52
  input[type="color"] {
53
53
  padding: 4px !important;
54
54
  }
55
-
55
+
56
56
  input[type="range"] {
57
57
  display: block;
58
58
  width: 100%;
59
59
  }
60
-
60
+
61
61
  input[type="radio"],
62
62
  input[type="checkbox"] {
63
63
  margin-right: 8px;
64
+ margin-left: 4px;
64
65
  }
65
66
 
66
67
  option[disabled] {
67
68
  color: rgba(0, 0, 0, 0.3)
68
69
  }
69
-
70
+
70
71
  /* button[data-test-id="cf-ui-button"] span {
71
72
  color: #036fe3 !important;
72
73
  }
73
-
74
+
74
75
  button[data-test-id="cf-ui-button"] svg {
75
76
  fill: #036fe3 !important;
76
77
  }
77
-
78
+
78
79
  button[data-test-id="cf-ui-button"]:hover span {
79
80
  color: #FFFFFF !important;
80
81
  }
81
-
82
+
82
83
  button[data-test-id="cf-ui-button"]:hover svg {
83
84
  fill: #FFFFFF !important;
84
85
  } */
85
-
86
+
86
87
  .inline-check-wrapper {
87
88
  display: inline-block;
88
89
  margin-right: 8px;
89
90
  }
90
-
91
+
91
92
  details {
92
93
  display: block;
93
94
  font-size: 0.875rem !important;
@@ -19,6 +19,7 @@ import ErrorBoundary from "../src/Blocks/ErrorBoundary";
19
19
  import SidebarEditor from './SidebarEditor';
20
20
  import {Spinner} from '@contentful/forma-36-react-components';
21
21
  import {ObjectId} from "./ObjectId";
22
+ import {Resizable} from "./SidebarEditor/Resizable";
22
23
 
23
24
  export default function BlockEditor({
24
25
  onChange,
@@ -262,63 +263,68 @@ export default function BlockEditor({
262
263
 
263
264
  return (
264
265
  <div className={classNames({"block-editor-wrapper h-full": true})}>
265
- <div className="slate-editor h-full">
266
- <Slate
267
- editor={editor}
268
- value={value}
269
- onChange={onSlateChange}
270
- >
271
- <div>
272
- <Toolbar
273
- hover={false}
274
- onSaveClick={onSaveClick}
275
- storybookStories={loadedStorybookStories}
276
- isLoadingStories={isLoadingStories}
277
- editor={editor}
278
- sdk={contentfulSdk}/>
279
- </div>
280
- <div className="relative h-full max-h-full overflow-scroll px-8 py-4" ref={scrollContainer}>
281
- {isLoading && (
282
- <div className="pointer-events-none fixed left-0 top-0 z-50" style={{padding: "61px 0 0 16px"}}>
283
- <Spinner color={window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? "white" : "default"} />
284
- </div>
285
- )}
286
- <ErrorBoundary
287
- name="editor"
288
- fallback={(
289
- <>
290
- Invalid Content! Call Support!
291
- </>
292
- )}>
293
- <Editable
294
- renderLeaf={renderLeaf}
295
- renderElement={renderElement}
296
- onKeyDown={(event) => {
297
- if (event.code === "Backspace") {
298
- // event.preventDefault();
299
- // return false;
300
- }
301
-
302
- if (!ListItemPlugin.onKeyDown(event, editor)) {
303
- SoftBreakPlugin.onKeyDown(event, editor);
304
- }
305
- }}
306
- />
307
- </ErrorBoundary>
308
- </div>
309
- </Slate>
310
- </div>
311
- {!!selectedStorybookElement && <SidebarEditor
312
- sdk={contentfulSdk}
313
- storybookElement={selectedStorybookElement}
314
- onChange={handleSidebarEditorChange}
315
- storybookStories={loadedStorybookStories}
316
- isLoading={isLoadingStories}
317
- onClose={handleSidebarClose}
318
- onDelete={handleSidebarDeleteClick}
319
- onMove={handleSidebarMoveClick}
320
- editor={editor}/>
321
- }
266
+ <Resizable
267
+ left={<div className="slate-editor h-full">
268
+ <Slate
269
+ editor={editor}
270
+ value={value}
271
+ onChange={onSlateChange}
272
+ >
273
+ <div>
274
+ <Toolbar
275
+ hover={false}
276
+ onSaveClick={onSaveClick}
277
+ storybookStories={loadedStorybookStories}
278
+ isLoadingStories={isLoadingStories}
279
+ editor={editor}
280
+ sdk={contentfulSdk}/>
281
+ </div>
282
+ <div className="relative h-full max-h-full overflow-scroll px-8 py-4" ref={scrollContainer}>
283
+ {isLoading && (
284
+ <div
285
+ className="pointer-events-none fixed left-0 top-0 z-50"
286
+ style={{padding: "61px 0 0 16px"}}>
287
+ <Spinner
288
+ color={window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? "white" : "default"}/>
289
+ </div>
290
+ )}
291
+ <ErrorBoundary
292
+ name="editor"
293
+ fallback={(
294
+ <>
295
+ Invalid Content! Call Support!
296
+ </>
297
+ )}>
298
+ <Editable
299
+ renderLeaf={renderLeaf}
300
+ renderElement={renderElement}
301
+ onKeyDown={(event) => {
302
+ if (event.code === "Backspace") {
303
+ // event.preventDefault();
304
+ // return false;
305
+ }
306
+
307
+ if (!ListItemPlugin.onKeyDown(event, editor)) {
308
+ SoftBreakPlugin.onKeyDown(event, editor);
309
+ }
310
+ }}
311
+ />
312
+ </ErrorBoundary>
313
+ </div>
314
+ </Slate>
315
+ </div>}
316
+ right={!!selectedStorybookElement && <SidebarEditor
317
+ sdk={contentfulSdk}
318
+ storybookElement={selectedStorybookElement}
319
+ onChange={handleSidebarEditorChange}
320
+ storybookStories={loadedStorybookStories}
321
+ isLoading={isLoadingStories}
322
+ onClose={handleSidebarClose}
323
+ onDelete={handleSidebarDeleteClick}
324
+ onMove={handleSidebarMoveClick}
325
+ editor={editor}/>
326
+ }
327
+ />
322
328
  </div>
323
329
  );
324
330
  }
@@ -190,7 +190,15 @@ export const LayoutBlock = ({
190
190
  }, {at: fromPath});
191
191
  };
192
192
 
193
- console.log({element});
193
+ let isGrid = true;
194
+
195
+ if (Array.isArray(element?.children)) {
196
+ element.children.forEach(child => {
197
+ if (child.type === "layout-slot" && ["grid-auto", "grid-fill"].includes(child.attributes.name)) {
198
+ isGrid = false;
199
+ }
200
+ });
201
+ }
194
202
 
195
203
  return <div className="options-wrapper" onClick={() => onElementClick(element)}>
196
204
  <div className="options-container">
@@ -239,7 +247,9 @@ export const LayoutBlock = ({
239
247
  <ToolMargin margin={element?.attributes?.margin} onChange={onMarginChange}/>
240
248
  </div>
241
249
  <div
242
- className={`layout-block layout-grid layout-grid-cols-${children.length} ${element?.attributes?.className || ""} ` + classNames({
250
+ className={`layout-block layout-grid layout-grid-cols-${children.length} ` + classNames({
251
+ "layout-block-flex": !isGrid,
252
+ "layout-block-grid": isGrid,
243
253
  [classNameArticle + " article-width"]: element?.attributes?.width === "article" || !element?.attributes?.width,
244
254
  [classNameSite + " site-width"]: element?.attributes?.width === "full",
245
255
  "block-editor-table-border-wrapper": element?.attributes?.tableBorder,
@@ -30,7 +30,7 @@ export const LayoutSlot = ({
30
30
 
31
31
  return <div
32
32
  className={classNames({
33
- ["layout-slot"]: true,
33
+ ["layout-slot layout-slot-" + element.attributes.name]: true,
34
34
  "editor-mt-4": element?.attributes?.margin?.top,
35
35
  "editor-mr-4": element?.attributes?.margin?.right,
36
36
  "editor-mb-4": element?.attributes?.margin?.bottom,
@@ -22,7 +22,7 @@ export const StorybookDisplay = (props) => {
22
22
 
23
23
  const interval = setInterval(() => {
24
24
  // innerText for regular elements, img for inline images and such :)
25
- if (elRef.current && !elRef.current.innerText && !elRef.current.querySelector("img, svg, iframe, video, audio, picture, frame")) {
25
+ if (elRef.current && !elRef.current.innerText && !elRef.current.querySelector("img, svg, iframe, video, audio, picture, frame, input")) {
26
26
  elRef.current.classList.add("storybook-element-display-empty");
27
27
  elRef.current.dataset.content = `Leeres Element :: ${element.block}`;
28
28
  } else if (elRef.current) {
@@ -126,19 +126,37 @@ export function Serializer({
126
126
 
127
127
  return <Wrapper><StorybookDisplay {...storyProps} /></Wrapper>;
128
128
  }
129
- case 'layout':
129
+ case 'layout': {
130
+ let isGrid = true;
131
+
132
+ if (Array.isArray(props.children)) {
133
+ props.children.forEach(child => {
134
+ if (child.type === "layout-slot" && ["grid-auto", "grid-fill"].includes(child.attributes.name)) {
135
+ isGrid = false;
136
+ }
137
+ });
138
+ }
139
+
130
140
  return <Wrapper>
131
141
  <div
132
142
  data-cols={props.children.length}
133
- className={classNames(props?.attributes?.className || "", {
134
- "block-editor-layout": true,
143
+ className={classNames("block-editor-layout", {
144
+ "block-editor-layout-grid": isGrid,
145
+ "block-editor-layout-flex": !isGrid,
146
+ "block-editor-table-border-wrapper": props?.attributes?.tableBorder,
147
+ "md:grid-cols-1": props.children.length === 1,
148
+ "md:grid-cols-2": props.children.length === 2,
149
+ "md:grid-cols-3": props.children.length === 3,
150
+ "md:grid-cols-4": props.children.length === 4,
151
+ "md:grid-cols-5": props.children.length === 5,
152
+ "grid-cols-1": props?.attributes?.mobileColumnSpan === 1,
153
+ "grid-cols-2": props?.attributes?.mobileColumnSpan === 2,
135
154
  "md:space-x-4": props.attributes?.spacing,
136
155
  "mt-16": props?.attributes?.margin?.top,
137
156
  "mr-16": props?.attributes?.margin?.right,
138
157
  "mb-16": props?.attributes?.margin?.bottom,
139
158
  "ml-16": props?.attributes?.margin?.left,
140
- "block-editor-table-border-wrapper": props?.attributes?.tableBorder,
141
- "mx-auto": props?.attributes?.justifyCenter,
159
+ "justify-center": props?.attributes?.justifyCenter,
142
160
  [typeProps.classNameSite + " site-width"]: !isInSlot && (props.attributes?.width === "site" || props.attributes?.width === "full"),
143
161
  [typeProps.classNameArticle + " article-width"]: !isInSlot && (props.attributes?.width === "article" || !props.attributes?.width),
144
162
  })}
@@ -146,6 +164,7 @@ export function Serializer({
146
164
  {props.children.map((v, i) => <Fragment key={"layout-pos-" + i}>{serializeNode(v, i, isInSlot)}</Fragment>)}
147
165
  </div>
148
166
  </Wrapper>;
167
+ }
149
168
  case 'layout-slot':
150
169
  return <Wrapper>
151
170
  <div
@@ -0,0 +1,72 @@
1
+ import {useEffect, useRef} from "react";
2
+
3
+ export const Resizable = ({left, right}) => {
4
+ const containerRef = useRef();
5
+ const leftRef = useRef();
6
+ const handleRef = useRef();
7
+ const rightRef = useRef();
8
+
9
+ const checkWidth = (width) => {
10
+ if (!containerRef.current || !width) {
11
+ return width;
12
+ }
13
+
14
+ if (width < 300) {
15
+ return 300;
16
+ } else if (containerRef.current.getBoundingClientRect().width - width < 300) {
17
+ return containerRef.current.getBoundingClientRect().width - 300
18
+ }
19
+
20
+ return width;
21
+ }
22
+
23
+ useEffect(() => {
24
+ if (rightRef.current) {
25
+ const savedWidth = localStorage.getItem("slate-editor-resizable-width");
26
+
27
+ if (checkWidth(savedWidth)) {
28
+ rightRef.current.style.width = savedWidth + 'px';
29
+ }
30
+
31
+ const onMouseDown = (e) => {
32
+ rightRef.current.resizingStartWidth = rightRef.current.getBoundingClientRect().width;
33
+ rightRef.current.resizingStartMouseX = e.pageX;
34
+ rightRef.current.resizing = true;
35
+ };
36
+ const onMouseMove = (e) => {
37
+ if (!rightRef.current.resizing) {
38
+ return;
39
+ }
40
+
41
+ let newWidth = rightRef.current.resizingStartWidth - (e.pageX - rightRef.current.resizingStartMouseX)
42
+
43
+ newWidth = checkWidth(newWidth);
44
+
45
+ localStorage.setItem("slate-editor-resizable-width", newWidth);
46
+
47
+ rightRef.current.style.width = newWidth + 'px';
48
+ }
49
+ const onMouseUp = (e) => {
50
+ rightRef.current.resizing = false;
51
+ }
52
+
53
+ rightRef.current.addEventListener("mousedown", onMouseDown);
54
+ document.addEventListener("mousemove", onMouseMove);
55
+ document.addEventListener("mouseup", onMouseUp);
56
+
57
+ return () => {
58
+ rightRef.current.removeEventListener("mousedown", onMouseDown);
59
+ document.removeEventListener("mousemove", onMouseMove);
60
+ document.removeEventListener("mouseup", onMouseUp);
61
+ }
62
+ }
63
+ }, [right, left]);
64
+
65
+ return <div className="w-full flex resizable" ref={containerRef}>
66
+ <div ref={leftRef} className="resizable-left flex-grow">{left}</div>
67
+ {right && <div ref={rightRef} className="resizable-right">
68
+ <div ref={handleRef} className="resizable-x-handle"/>
69
+ {right}
70
+ </div>}
71
+ </div>
72
+ }
@@ -31,7 +31,7 @@ const SidebarEditor = ({
31
31
 
32
32
  const story = storybookStories?.find(v => storybookElement.block?.toLowerCase() === v.id?.toLowerCase());
33
33
 
34
- if (story) {
34
+ if (story?.argTypes) {
35
35
  Object.keys(story.argTypes).forEach(key => {
36
36
  const argType = story.argTypes[key];
37
37
 
@@ -225,7 +225,7 @@ const SidebarEditor = ({
225
225
  <hr className="my-4" style={{borderColor: "#cfd9e0"}}/>
226
226
  </div>
227
227
  )}
228
- {!!story && (
228
+ {!!story && !!fields.fields && (
229
229
  <>
230
230
  {Object.keys(fields.fields).map(key => {
231
231
  const field = fields.fields[key];
@@ -392,11 +392,11 @@ const BlockSelect = ({
392
392
  const result = {};
393
393
 
394
394
  array.forEach(item => {
395
- if (!item.id) {
395
+ if (!item?.id) {
396
396
  return;
397
397
  }
398
398
 
399
- let splitStoryContext = storyContext.split(",");
399
+ let splitStoryContext = String(storyContext || "").split(",");
400
400
  let isItemInContext = splitStoryContext.find(context => {
401
401
  return Array.isArray(item.storyContext) ? item.storyContext.includes(context) : context === item.storyContext;
402
402
  });
@@ -273,7 +273,6 @@ export const InsertGridButton = () => {
273
273
  </InsertLayoutButton>
274
274
  <InsertLayoutButton insert={{
275
275
  "type": "layout",
276
- "attributes": {"className": "layout-block-auto-fill"},
277
276
  "children": [
278
277
  {
279
278
  "type": "layout-slot",
@@ -305,7 +304,6 @@ export const InsertGridButton = () => {
305
304
  </InsertLayoutButton>
306
305
  <InsertLayoutButton insert={{
307
306
  "type": "layout",
308
- "attributes": {"className": "layout-block-fill-auto"},
309
307
  "children": [
310
308
  {
311
309
  "type": "layout-slot",
@@ -337,7 +335,6 @@ export const InsertGridButton = () => {
337
335
  </InsertLayoutButton>
338
336
  <InsertLayoutButton insert={{
339
337
  "type": "layout",
340
- "attributes": {"className": "layout-block-auto-fill-auto"},
341
338
  "children": [
342
339
  {
343
340
  "type": "layout-slot",
@@ -90,7 +90,7 @@ export const Toolbar = ({
90
90
  el.removeAttribute('style');
91
91
  el.classList.remove("active");
92
92
  }
93
- });
93
+ }, [hover, ref, editor]);
94
94
 
95
95
  function renderMenu() {
96
96
  return <Menu
@@ -147,7 +147,9 @@ export const Toolbar = ({
147
147
  />
148
148
  </div>
149
149
  </div>
150
- {!!onSaveClick && <button className="!w-auto !border-0 !bg-green-600 !text-xs font-bold text-white hover:!bg-green-700" onClick={onSaveClick}>Änderungen speichern</button>}
150
+ {!!onSaveClick && <button
151
+ className="!w-auto !border-0 !bg-green-600 !text-xs font-bold text-white hover:!bg-green-700"
152
+ onClick={onSaveClick}>Änderungen speichern</button>}
151
153
  </div>
152
154
  </Menu>;
153
155
  }
@@ -167,18 +169,16 @@ const ElementAutocomplete = ({
167
169
  storybookStories,
168
170
  isLoading,
169
171
  editor,
170
- storyContext,
172
+ storyContext = "",
171
173
  }) => {
172
- const [filteredItems, setFilteredItems] = React.useState(items);
173
-
174
174
  const items = (storybookStories || []).map(story => {
175
- let storyTitleSplit = story.title.split("/");
175
+ let storyTitleSplit = String(story.title || "").split("/");
176
176
 
177
177
  if (!story.id) {
178
178
  return;
179
179
  }
180
180
 
181
- let splitStoryContext = storyContext.split(",");
181
+ let splitStoryContext = String(storyContext || "").split(",");
182
182
  let isItemInContext = splitStoryContext.find(context => {
183
183
  return Array.isArray(story.storyContext) ? story.storyContext.includes(context) : context === story.storyContext;
184
184
  });
@@ -194,6 +194,8 @@ const ElementAutocomplete = ({
194
194
  };
195
195
  }).filter(Boolean);
196
196
 
197
+ const [filteredItems, setFilteredItems] = useState(items);
198
+
197
199
  useEffect(() => {
198
200
  setFilteredItems(items);
199
201
  }, [storybookStories]);
@@ -226,7 +228,7 @@ const ElementAutocomplete = ({
226
228
  items={filteredItems}
227
229
  onQueryChange={handleQueryChange}
228
230
  isLoading={isLoading}
229
- placeholder={'Suchen...'}
231
+ placeholder={'Element hinzufügen'}
230
232
  emptyListMessage={'Keine Komponenten gefunden'}
231
233
  noMatchesMessage={'Keine Ergebnisse gefunden'}
232
234
  dropdownProps={{isFullWidth: true}}
package/src/index.js CHANGED
@@ -1,3 +1,5 @@
1
+ import "../scss/editor.scss";
2
+
1
3
  import BlockEditor from "./BlockEditor";
2
4
  import Renderer from "./Renderer";
3
5
  import {HtmlSerializer} from "./Serializer";
package/storyLoader.js CHANGED
@@ -8,6 +8,7 @@ module.exports = async function storiesLoader() {
8
8
  globs: ["**/*.stories.js", "**/*.stories.jsx", "**/*.stories.ts"],
9
9
  });
10
10
 
11
+ this.addContextDependency(options.storiesRoot);
11
12
  console.log(`Found ${files.length} stories in ${options.storiesRoot}`);
12
13
 
13
14
  return `
@@ -4,6 +4,7 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin');
4
4
 
5
5
  config.externals = {
6
6
  react: "react",
7
+ next: "next",
7
8
  "react-dom": "react-dom",
8
9
  "prop-types": "prop-types",
9
10
  };
@@ -0,0 +1,5 @@
1
+ const config = require("./webpack.config.build");
2
+
3
+ config.mode = "development";
4
+
5
+ module.exports = config;