Skip to content

Commit a8bd665

Browse files
Adding a new story supporting mgt-samples repo (#1581)
* Adding a new story supporting mgt-samples repo * Refining the filter for the supported manifest URL
1 parent 8217c1a commit a8bd665

File tree

3 files changed

+208
-116
lines changed

3 files changed

+208
-116
lines changed

.storybook/addons/codeEditorAddon/codeAddon.js

Lines changed: 179 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -5,117 +5,180 @@ const mgtScriptName = './mgt.storybook.js';
55

66
// function is used for dragging and moving
77
const setupEditorResize = (first, separator, last, dragComplete) => {
8-
var md; // remember mouse down info
9-
10-
separator.addEventListener('mousedown', e => {
11-
md = {
12-
e,
13-
offsetLeft: separator.offsetLeft,
14-
offsetTop: separator.offsetTop,
15-
firstWidth: first.offsetWidth,
16-
lastWidth: last.offsetWidth,
17-
firstHeight: first.offsetHeight,
18-
lastHeight: last.offsetHeight
19-
};
20-
21-
first.style.pointerEvents = 'none';
22-
last.style.pointerEvents = 'none';
23-
24-
document.addEventListener('mousemove', onMouseMove);
25-
document.addEventListener('mouseup', onMouseUp);
26-
});
8+
var md; // remember mouse down info
9+
10+
separator.addEventListener('mousedown', e => {
11+
md = {
12+
e,
13+
offsetLeft: separator.offsetLeft,
14+
offsetTop: separator.offsetTop,
15+
firstWidth: first.offsetWidth,
16+
lastWidth: last.offsetWidth,
17+
firstHeight: first.offsetHeight,
18+
lastHeight: last.offsetHeight
19+
};
20+
21+
first.style.pointerEvents = 'none';
22+
last.style.pointerEvents = 'none';
23+
24+
document.addEventListener('mousemove', onMouseMove);
25+
document.addEventListener('mouseup', onMouseUp);
26+
});
2727

28-
const onMouseUp = () => {
29-
if (typeof dragComplete === 'function') {
30-
dragComplete();
31-
}
28+
const onMouseUp = () => {
29+
if (typeof dragComplete === 'function') {
30+
dragComplete();
31+
}
3232

33-
first.style.pointerEvents = '';
34-
last.style.pointerEvents = '';
33+
first.style.pointerEvents = '';
34+
last.style.pointerEvents = '';
3535

36-
document.removeEventListener('mousemove', onMouseMove);
37-
document.removeEventListener('mouseup', onMouseUp);
38-
};
36+
document.removeEventListener('mousemove', onMouseMove);
37+
document.removeEventListener('mouseup', onMouseUp);
38+
};
3939

40-
const onMouseMove = e => {
41-
var delta = { x: e.clientX - md.e.x, y: e.clientY - md.e.y };
40+
const onMouseMove = e => {
41+
var delta = { x: e.clientX - md.e.x, y: e.clientY - md.e.y };
4242

43-
if (window.innerWidth > 800) {
44-
// Horizontal
45-
// prevent negative-sized elements
46-
delta.x = Math.min(Math.max(delta.x, -md.firstWidth + 200), md.lastWidth - 200);
43+
if (window.innerWidth > 800) {
44+
// Horizontal
45+
// prevent negative-sized elements
46+
delta.x = Math.min(Math.max(delta.x, -md.firstWidth + 200), md.lastWidth - 200);
4747

48-
first.style.width = md.firstWidth + delta.x - 0.5 + 'px';
49-
last.style.width = md.lastWidth - delta.x - 0.5 + 'px';
50-
} else {
51-
// Vertical
52-
// prevent negative-sized elements
53-
delta.y = Math.min(Math.max(delta.y, -md.firstHeight + 150), md.lastHeight - 150);
48+
first.style.width = md.firstWidth + delta.x - 0.5 + 'px';
49+
last.style.width = md.lastWidth - delta.x - 0.5 + 'px';
50+
} else {
51+
// Vertical
52+
// prevent negative-sized elements
53+
delta.y = Math.min(Math.max(delta.y, -md.firstHeight + 150), md.lastHeight - 150);
5454

55-
first.style.height = md.firstHeight + delta.y - 0.5 + 'px';
56-
last.style.height = md.lastHeight - delta.y - 0.5 + 'px';
57-
}
58-
};
55+
first.style.height = md.firstHeight + delta.y - 0.5 + 'px';
56+
last.style.height = md.lastHeight - delta.y - 0.5 + 'px';
57+
}
58+
};
5959
};
6060

6161
let scriptRegex = /<script\b[^>]*>([\s\S]*?)<\/script>/gm;
6262
let styleRegex = /<style\b[^>]*>([\s\S]*?)<\/style>/gm;
6363

6464
export const withCodeEditor = makeDecorator({
65-
name: `withCodeEditor`,
66-
parameterName: 'myParameter',
67-
skipIfNoParametersOrOptions: false,
68-
wrapper: (getStory, context, { parameters }) => {
69-
let story = getStory(context);
70-
71-
let storyHtml;
72-
const root = document.createElement('div');
73-
let storyElementWrapper = document.createElement('div');
74-
75-
if (story.strings) {
76-
storyHtml = story.strings[0];
77-
} else {
78-
storyHtml = story.innerHTML;
79-
}
80-
81-
let scriptMatches = scriptRegex.exec(storyHtml);
82-
let scriptCode = scriptMatches && scriptMatches.length > 1 ? scriptMatches[1].trim() : '';
83-
84-
let styleMatches = styleRegex.exec(storyHtml);
85-
let styleCode = styleMatches && styleMatches.length > 1 ? styleMatches[1].trim() : '';
65+
name: `withCodeEditor`,
66+
parameterName: 'myParameter',
67+
skipIfNoParametersOrOptions: false,
68+
wrapper: (getStory, context, { parameters }) => {
69+
let story = getStory(context);
70+
71+
let storyHtml;
72+
const root = document.createElement('div');
73+
let storyElementWrapper = document.createElement('div');
74+
75+
if (story.strings) {
76+
storyHtml = story.strings[0];
77+
} else {
78+
storyHtml = story.innerHTML;
79+
}
80+
81+
let scriptMatches = scriptRegex.exec(storyHtml);
82+
let scriptCode = scriptMatches && scriptMatches.length > 1 ? scriptMatches[1].trim() : '';
83+
84+
let styleMatches = styleRegex.exec(storyHtml);
85+
let styleCode = styleMatches && styleMatches.length > 1 ? styleMatches[1].trim() : '';
86+
87+
storyHtml = storyHtml
88+
.replace(styleRegex, '')
89+
.replace(scriptRegex, '')
90+
.replace(/\n?<!---->\n?/g, '')
91+
.trim();
92+
93+
let editor = new EditorElement();
94+
editor.files = {
95+
html: storyHtml,
96+
js: scriptCode,
97+
css: styleCode
98+
};
99+
100+
const getContent = async(url, json) => {
101+
let content = ""
102+
103+
if (url) {
104+
let response = await fetch(url);
105+
106+
if (response.ok) {
107+
if (json) {
108+
content = await response.json();
109+
} else {
110+
content = await response.text();
111+
}
112+
} else {
113+
console.warn(`Can't get content from '${url}'`)
114+
}
115+
}
116+
117+
return content;
118+
}
119+
120+
const isNotIframed = () => {
121+
try {
122+
return window.top.location.href != null || window.top.location.href != undefined;
123+
} catch (err) {
124+
return false;
125+
}
126+
}
127+
128+
const isValid = (manifestUrl) => {
129+
return manifestUrl && manifestUrl.startsWith('https://raw.githubusercontent.com/pnp/mgt-samples/main/');
130+
}
131+
132+
if (context.name === "Editor") {
133+
134+
// If the editor is not iframed (Docs, GE, etc.)
135+
if (isNotIframed()) {
136+
var urlParams = new URLSearchParams(window.top.location.search);
137+
var manifestUrl = urlParams.get('manifest');
138+
139+
if (isValid(manifestUrl)) {
140+
getContent(manifestUrl, true).then((manifest) => {
141+
Promise.all([
142+
getContent(manifest[0].preview.html),
143+
getContent(manifest[0].preview.js),
144+
getContent(manifest[0].preview.css)
145+
]).then((values) => {
146+
//editor.autoFormat = false;
147+
editor.files = {
148+
html: values[0],
149+
js: values[1],
150+
css: values[2]
151+
};
152+
});
153+
});
154+
}
155+
}
86156

87-
storyHtml = storyHtml
88-
.replace(styleRegex, '')
89-
.replace(scriptRegex, '')
90-
.replace(/\n?<!---->\n?/g, '')
91-
.trim();
157+
}
92158

93-
let editor = new EditorElement();
94-
editor.files = {
95-
html: storyHtml,
96-
js: scriptCode,
97-
css: styleCode
98-
};
159+
const loadEditorContent = () => {
160+
let providerInitCode = `
161+
import {Providers, MockProvider} from "${mgtScriptName}";
162+
Providers.globalProvider = new MockProvider(true);
163+
`;
99164

100-
editor.addEventListener('fileUpdated', () => {
101-
const storyElement = document.createElement('iframe');
165+
const storyElement = document.createElement('iframe');
102166

103-
storyElement.addEventListener('load', () => {
104-
let doc = storyElement.contentDocument;
167+
storyElement.addEventListener('load', () => {
168+
let doc = storyElement.contentDocument;
105169

106-
let { html, css, js } = editor.files;
107-
js = js.replace(
108-
/import \{([^\}]+)\}\s+from\s+['"]@microsoft\/mgt['"];/gm,
109-
`import {$1} from '${mgtScriptName}';`
110-
);
170+
let { html, css, js } = editor.files;
171+
js = js.replace(
172+
/import \{([^\}]+)\}\s+from\s+['"]@microsoft\/mgt['"];/gm,
173+
`import {$1} from '${mgtScriptName}';`
174+
);
111175

112-
const docContent = `
176+
const docContent = `
113177
<html>
114178
<head>
115179
<script type="module" src="${mgtScriptName}"></script>
116180
<script type="module">
117-
import {Providers, MockProvider} from "${mgtScriptName}";
118-
Providers.globalProvider = new MockProvider(true);
181+
${providerInitCode}
119182
</script>
120183
<style>
121184
html, body {
@@ -133,37 +196,38 @@ export const withCodeEditor = makeDecorator({
133196
</html>
134197
`;
135198

136-
doc.open();
137-
doc.write(docContent);
138-
doc.close();
139-
});
199+
doc.open();
200+
doc.write(docContent);
201+
doc.close();
202+
});
140203

141-
storyElement.className = 'story-mgt-preview';
142-
storyElement.title = 'story-mgt-preview';
143-
storyElementWrapper.innerHTML = '';
144-
storyElementWrapper.appendChild(storyElement);
145-
});
204+
storyElement.className = 'story-mgt-preview';
205+
storyElementWrapper.innerHTML = '';
206+
storyElementWrapper.appendChild(storyElement);
207+
};
146208

147-
const separator = document.createElement('div');
209+
editor.addEventListener('fileUpdated', loadEditorContent);
148210

149-
setupEditorResize(storyElementWrapper, separator, editor, () => editor.layout());
211+
const separator = document.createElement('div');
150212

151-
root.className = 'story-mgt-root';
152-
storyElementWrapper.className = 'story-mgt-preview-wrapper';
153-
separator.className = 'story-mgt-separator';
154-
editor.className = 'story-mgt-editor';
213+
setupEditorResize(storyElementWrapper, separator, editor, () => editor.layout());
155214

156-
root.appendChild(storyElementWrapper);
157-
root.appendChild(separator);
158-
root.appendChild(editor);
215+
root.className = 'story-mgt-root';
216+
storyElementWrapper.className = 'story-mgt-preview-wrapper';
217+
separator.className = 'story-mgt-separator';
218+
editor.className = 'story-mgt-editor';
159219

160-
window.addEventListener('resize', () => {
161-
storyElementWrapper.style.height = null;
162-
storyElementWrapper.style.width = null;
163-
editor.style.height = null;
164-
editor.style.width = null;
165-
});
220+
root.appendChild(storyElementWrapper);
221+
root.appendChild(separator);
222+
root.appendChild(editor);
166223

167-
return root;
168-
}
169-
});
224+
window.addEventListener('resize', () => {
225+
storyElementWrapper.style.height = null;
226+
storyElementWrapper.style.width = null;
227+
editor.style.height = null;
228+
editor.style.width = null;
229+
});
230+
231+
return root;
232+
}
233+
});

.storybook/addons/codeEditorAddon/editor.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ export class EditorElement extends LitElement {
8383
super();
8484
this.internalFiles = [];
8585
this.fileTypes = ['html', 'js', 'css'];
86+
this.autoFormat = true;
8687

8788
this.editorRoot = document.createElement('div');
8889
this.editorRoot.setAttribute('slot', 'editor');
@@ -190,7 +191,9 @@ export class EditorElement extends LitElement {
190191
this.editor.restoreViewState(this.currentEditorState.state);
191192
}
192193

193-
this.editor.getAction('editor.action.formatDocument').run();
194+
if(this.autoFormat) {
195+
this.editor.getAction('editor.action.formatDocument').run();
196+
}
194197
}
195198

196199
render() {

stories/samples/editor.stories.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* -------------------------------------------------------------------------------------------
3+
* Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
4+
* See License in the project root for license information.
5+
* -------------------------------------------------------------------------------------------
6+
*/
7+
8+
import { html } from 'lit-element';
9+
import { withCodeEditor } from '../../.storybook/addons/codeEditorAddon/codeAddon';
10+
11+
export default {
12+
title: 'Editor',
13+
decorators: [withCodeEditor]
14+
};
15+
16+
export const Editor = () => html`
17+
<!-- Add your own HTML code here -->
18+
19+
<script>
20+
// Add your own JavaScript code here
21+
</script>
22+
<style>
23+
/* Add your own CSS code here */
24+
</style>
25+
`;

0 commit comments

Comments
 (0)