Skip to content

Commit 1e544d4

Browse files
CompuIvesmstijaknicknisi
committed
Community templates (#709)
* Add CxJS template UI * Configure Babel for CxJS template * Load transform-cx-jsx on demand * Removing direct sharp dependency * Update CxJS template * add Dojo 2 as a preset template - add dojo2 template - add temporary project as template to load (github) - add type definition creation to styles transpiler - add dojo 2 to home page - add default loading of dojo template src/index.html and src/main.css * change dojo template url to dojo codesandbox repo * add in temporary API override -- REMOVE COMMIT * set isTypeScript to true for dojo template * remove DojoIcon from dojo template definition * Don't throw error for cxjs if main.css is not found * Remove force of Dojo * Fix check * Update URLs * Add CxJS to homepage * update yarn.lock * Add CxJS cube to the homepage and fix CxJS and Dojo icons (#751) * Force build * Change logo order for consistency with homepage * Clean up transpilation listener on unmount * Add to changelog Co-authored-by: Marko Stijak <[email protected]> Co-authored-by: Nick Nisi <[email protected]>
1 parent c6fa022 commit 1e544d4

File tree

24 files changed

+659
-6
lines changed

24 files changed

+659
-6
lines changed

.editorconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[*.js]
2+
indent_style = space
3+
indent_size = 2
4+
end_of_line = lf

packages/app/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@
106106
"babel-plugin-syntax-jsx": "^6.18.0",
107107
"babel-plugin-system-import": "^1.1.5",
108108
"babel-plugin-system-import-transformer": "3.1.0",
109+
"babel-plugin-transform-cx-jsx": "^17.12.0",
109110
"babel-plugin-transform-async-to-generator": "^6.24.1",
110111
"babel-plugin-transform-decorators-legacy": "^1.3.4",
111112
"babel-plugin-transform-remove-strict-mode": "^0.0.2",

packages/app/src/app/components/CodeEditor/Monaco/index.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { TextOperation } from 'ot';
44
import { debounce } from 'lodash';
55
import { getModulePath } from 'common/sandbox/modules';
66
import { css } from 'glamor';
7+
import { listen } from 'codesandbox-api';
78

89
import getTemplate from 'common/templates';
910
import type {
@@ -134,6 +135,7 @@ class MonacoEditor extends React.Component<Props, State> implements Editor {
134135
editor: any;
135136
monaco: any;
136137
receivingCode: ?boolean = false;
138+
transpilationListener: ?Function;
137139

138140
constructor(props: Props) {
139141
super(props);
@@ -158,6 +160,8 @@ class MonacoEditor extends React.Component<Props, State> implements Editor {
158160
this.onSelectionChangedDebounced,
159161
500
160162
);
163+
164+
this.transpilationListener = this.setupTranspilationListener();
161165
}
162166

163167
shouldComponentUpdate(nextProps: Props) {
@@ -191,6 +195,9 @@ class MonacoEditor extends React.Component<Props, State> implements Editor {
191195
if (this.typingsFetcherWorker) {
192196
this.typingsFetcherWorker.terminate();
193197
}
198+
if (this.transpilationListener) {
199+
this.transpilationListener();
200+
}
194201
clearTimeout(this.sizeProbeInterval);
195202
});
196203

@@ -199,6 +206,18 @@ class MonacoEditor extends React.Component<Props, State> implements Editor {
199206
}
200207
}
201208

209+
setupTranspilationListener() {
210+
return listen(({ type, code, path }) => {
211+
if (type === 'add-extra-lib') {
212+
const dtsPath = `${path}.d.ts`;
213+
this.monaco.languages.typescript.typescriptDefaults._extraLibs[
214+
`file:///${dtsPath}`
215+
] = code;
216+
this.commitLibChanges();
217+
}
218+
});
219+
}
220+
202221
configureEditor = async (editor: any, monaco: any) => {
203222
this.editor = editor;
204223
this.monaco = monaco;

packages/app/src/app/components/NewSandbox/index.js

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ import {
1010
newPreactSandboxUrl,
1111
newVueSandboxUrl,
1212
newAngularSandboxUrl,
13+
newDojoSandboxUrl,
1314
newSvelteSandboxUrl,
15+
newCxJSSandboxUrl,
1416
importFromGitHubUrl,
1517
uploadFromCliUrl,
1618
} from 'common/utils/url-generator';
@@ -21,6 +23,8 @@ import ParcelIcon from 'common/components/logos/Parcel';
2123
import VueIcon from 'common/components/logos/Vue';
2224
import SvelteIcon from 'common/components/logos/Svelte';
2325
import AngularIcon from 'common/components/logos/Angular';
26+
import CxJSIcon from 'common/components/logos/CxJS';
27+
import DojoIcon from 'common/components/logos/Dojo';
2428

2529
import {
2630
Container,
@@ -53,7 +57,6 @@ function NewSandbox({ signals }) {
5357
href={parcelSandboxUrl()}
5458
onClick={() => signals.modalClosed()}
5559
/>
56-
5760
<Logo
5861
Icon={ReactIcon}
5962
width={50}
@@ -62,7 +65,6 @@ function NewSandbox({ signals }) {
6265
href={newSandboxUrl()}
6366
onClick={() => signals.modalClosed()}
6467
/>
65-
6668
<Logo
6769
Icon={VueIcon}
6870
width={50}
@@ -71,7 +73,6 @@ function NewSandbox({ signals }) {
7173
href={newVueSandboxUrl()}
7274
onClick={() => signals.modalClosed()}
7375
/>
74-
7576
<Logo
7677
Icon={AngularIcon}
7778
width={50}
@@ -104,6 +105,22 @@ function NewSandbox({ signals }) {
104105
href={newReactTypeScriptSandboxUrl()}
105106
onClick={() => signals.modalClosed()}
106107
/>
108+
<Logo
109+
Icon={DojoIcon}
110+
width={50}
111+
height={50}
112+
text="Dojo 2"
113+
href={newDojoSandboxUrl()}
114+
onClick={() => signals.closeModal()}
115+
/>
116+
<Logo
117+
Icon={CxJSIcon}
118+
width={50}
119+
height={50}
120+
text="CxJS"
121+
href={newCxJSSandboxUrl()}
122+
onClick={() => signals.closeModal()}
123+
/>
107124
<Logo
108125
Icon={GithubIcon}
109126
width={50}

packages/app/src/sandbox/eval/index.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ import {
77
preact,
88
reactTs,
99
angular,
10+
cxjs,
1011
babel,
12+
dojo,
1113
} from 'common/templates';
1214

1315
import reactPreset from './presets/create-react-app';
@@ -18,6 +20,8 @@ import sveltePreset from './presets/svelte';
1820
import angularPreset from './presets/angular-cli';
1921
import parcelPreset from './presets/parcel';
2022
import babelPreset from './presets/babel-repl';
23+
import cxjsPreset from './presets/cxjs';
24+
import dojoPreset from './presets/dojo';
2125

2226
export default function getPreset(template: string) {
2327
switch (template) {
@@ -37,6 +41,10 @@ export default function getPreset(template: string) {
3741
return parcelPreset();
3842
case babel.name:
3943
return babelPreset();
44+
case cxjs.name:
45+
return cxjsPreset();
46+
case dojo.name:
47+
return dojoPreset();
4048
default:
4149
return reactPreset();
4250
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import babelTranspiler from '../../transpilers/babel';
2+
import jsonTranspiler from '../../transpilers/json';
3+
import stylesTranspiler from '../../transpilers/style';
4+
import sassTranspiler from '../../transpilers/sass';
5+
import rawTranspiler from '../../transpilers/raw';
6+
import stylusTranspiler from '../../transpilers/stylus';
7+
import lessTranspiler from '../../transpilers/less';
8+
import tsTranspiler from '../../transpilers/typescript';
9+
10+
import Preset from '../';
11+
12+
export default function initialize() {
13+
const cxjsPreset = new Preset(
14+
'cxjs',
15+
['js', 'jsx', 'ts', 'tsx', 'json', 'less', 'scss', 'sass', 'styl', 'css'],
16+
{},
17+
{}
18+
);
19+
20+
cxjsPreset.registerTranspiler(module => /\.jsx?$/.test(module.path), [
21+
{
22+
transpiler: babelTranspiler,
23+
options: {
24+
dynamicCSSModules: true,
25+
},
26+
},
27+
]);
28+
29+
cxjsPreset.registerTranspiler(module => /\.tsx?$/.test(module.path), [
30+
{ transpiler: tsTranspiler },
31+
]);
32+
33+
cxjsPreset.registerTranspiler(module => /\.css$/.test(module.path), [
34+
{ transpiler: stylesTranspiler },
35+
]);
36+
37+
cxjsPreset.registerTranspiler(module => /\.json$/.test(module.path), [
38+
{ transpiler: jsonTranspiler },
39+
]);
40+
41+
const sassWithConfig = {
42+
transpiler: sassTranspiler,
43+
options: {},
44+
};
45+
46+
const lessWithConfig = {
47+
transpiler: lessTranspiler,
48+
options: {},
49+
};
50+
51+
const stylusWithConfig = {
52+
transpiler: stylusTranspiler,
53+
options: {},
54+
};
55+
const styles = {
56+
css: [],
57+
scss: [sassWithConfig],
58+
sass: [sassWithConfig],
59+
less: [lessWithConfig],
60+
styl: [stylusWithConfig],
61+
};
62+
63+
/**
64+
* Registers transpilers for all different combinations
65+
*
66+
* @returns
67+
*/
68+
function registerStyleTranspilers() {
69+
return Object.keys(styles).forEach(type => {
70+
cxjsPreset.registerTranspiler(
71+
module => new RegExp(`\\.${type}`).test(module.path),
72+
[...styles[type], { transpiler: stylesTranspiler }]
73+
);
74+
});
75+
}
76+
77+
registerStyleTranspilers();
78+
79+
cxjsPreset.registerTranspiler(() => true, [{ transpiler: rawTranspiler }]);
80+
81+
return cxjsPreset;
82+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { join, absolute } from 'common/utils/path';
2+
import Preset from '../';
3+
4+
import typescriptTranspiler from '../../transpilers/typescript';
5+
import rawTranspiler from '../../transpilers/raw';
6+
import jsonTranspiler from '../../transpilers/json';
7+
import stylesTranspiler from '../../transpilers/style';
8+
import babelTranspiler from '../../transpilers/babel';
9+
10+
export default function initialize() {
11+
const preset = new Preset(
12+
'@dojo/cli-create-app',
13+
['ts', 'tsx', 'js', 'json'],
14+
{},
15+
{
16+
setup: async manager => {
17+
const stylesPath = absolute(join('src', 'main.css'));
18+
try {
19+
const tModule = await manager.resolveTranspiledModuleAsync(
20+
stylesPath,
21+
'/'
22+
);
23+
await tModule.transpile(manager);
24+
tModule.setIsEntry(true);
25+
tModule.evaluate(manager);
26+
} catch (e) {
27+
if (e.type === 'module-not-found') {
28+
// Do nothing
29+
} else {
30+
throw e;
31+
}
32+
}
33+
},
34+
}
35+
);
36+
37+
preset.registerTranspiler(module => /\.tsx?$/.test(module.path), [
38+
{ transpiler: typescriptTranspiler },
39+
]);
40+
41+
preset.registerTranspiler(module => /\.jsx?$/.test(module.path), [
42+
{ transpiler: babelTranspiler },
43+
]);
44+
45+
preset.registerTranspiler(module => /\.json$/.test(module.path), [
46+
{ transpiler: jsonTranspiler },
47+
]);
48+
49+
preset.registerTranspiler(module => /\.m\.css$/.test(module.path), [
50+
{ transpiler: stylesTranspiler, options: { module: true } },
51+
]);
52+
53+
preset.registerTranspiler(module => /\.css$/.test(module.path), [
54+
{ transpiler: stylesTranspiler },
55+
]);
56+
57+
preset.registerTranspiler(() => true, [{ transpiler: rawTranspiler }]);
58+
59+
return preset;
60+
}

packages/app/src/sandbox/eval/transpilers/babel/worker/babel-worker.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,14 @@ self.addEventListener('message', async event => {
274274
) {
275275
const pragmaticPlugin = await import(/* webpackChunkName: 'babel-plugin-jsx-pragmatic' */ 'babel-plugin-jsx-pragmatic');
276276
Babel.registerPlugin('jsx-pragmatic', pragmaticPlugin);
277+
}
278+
279+
if (
280+
flattenedPlugins.indexOf('transform-cx-jsx') > -1 &&
281+
Object.keys(Babel.availablePlugins).indexOf('transform-cx-jsx') === -1
282+
) {
283+
const cxJsxPlugin = await import(/* webpackChunkName: 'transform-cx-jsx' */ 'babel-plugin-transform-cx-jsx');
284+
Babel.registerPlugin('transform-cx-jsx', cxJsxPlugin);
277285
}
278286
}
279287

packages/app/src/sandbox/eval/transpilers/style/index.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// @flow
2+
import { dispatch } from 'codesandbox-api';
23
import Transpiler from '../';
34
import { type LoaderContext } from '../../transpiled-module';
45

@@ -7,6 +8,13 @@ import getModules from './get-modules';
78

89
const getStyleId = id => id + '-css'; // eslint-disable-line
910

11+
function classesToDefinition(classes): string {
12+
return Object.keys(classes).reduce(
13+
(previous, className) => previous + `export const ${className}: string;\n`,
14+
''
15+
);
16+
}
17+
1018
class StyleTranspiler extends Transpiler {
1119
constructor() {
1220
super('style-loader');
@@ -24,12 +32,18 @@ class StyleTranspiler extends Transpiler {
2432

2533
doTranspilation(code: string, loaderContext: LoaderContext) {
2634
const id = getStyleId(loaderContext._module.getId());
35+
const { path } = loaderContext;
2736

2837
if (loaderContext.options.module) {
2938
return getModules(code, loaderContext).then(({ css, exportTokens }) => {
3039
let result = insertCss(id, css);
3140
result += `\nmodule.exports=${JSON.stringify(exportTokens)};`;
3241

42+
dispatch({
43+
type: 'add-extra-lib',
44+
path,
45+
code: classesToDefinition(exportTokens),
46+
});
3347
return Promise.resolve({ transpiledCode: result });
3448
});
3549
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import React from 'react';
2+
3+
import cxjs from './cxjs.svg';
4+
5+
export default props => <img alt="cxjs" src={cxjs} {...props} />;

0 commit comments

Comments
 (0)