Skip to content

Commit

Permalink
Community templates (#709)
Browse files Browse the repository at this point in the history
* 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 <mstijak@gmail.com>
Co-authored-by: Nick Nisi <nick@nisi.org>
  • Loading branch information
3 people committed Apr 25, 2018
1 parent c6fa022 commit 1e544d4
Show file tree
Hide file tree
Showing 24 changed files with 659 additions and 6 deletions.
4 changes: 4 additions & 0 deletions .editorconfig
@@ -0,0 +1,4 @@
[*.js]
indent_style = space
indent_size = 2
end_of_line = lf
1 change: 1 addition & 0 deletions packages/app/package.json
Expand Up @@ -106,6 +106,7 @@
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-system-import": "^1.1.5",
"babel-plugin-system-import-transformer": "3.1.0",
"babel-plugin-transform-cx-jsx": "^17.12.0",
"babel-plugin-transform-async-to-generator": "^6.24.1",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-plugin-transform-remove-strict-mode": "^0.0.2",
Expand Down
19 changes: 19 additions & 0 deletions packages/app/src/app/components/CodeEditor/Monaco/index.js
Expand Up @@ -4,6 +4,7 @@ import { TextOperation } from 'ot';
import { debounce } from 'lodash';
import { getModulePath } from 'common/sandbox/modules';
import { css } from 'glamor';
import { listen } from 'codesandbox-api';

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

constructor(props: Props) {
super(props);
Expand All @@ -158,6 +160,8 @@ class MonacoEditor extends React.Component<Props, State> implements Editor {
this.onSelectionChangedDebounced,
500
);

this.transpilationListener = this.setupTranspilationListener();
}

shouldComponentUpdate(nextProps: Props) {
Expand Down Expand Up @@ -191,6 +195,9 @@ class MonacoEditor extends React.Component<Props, State> implements Editor {
if (this.typingsFetcherWorker) {
this.typingsFetcherWorker.terminate();
}
if (this.transpilationListener) {
this.transpilationListener();
}
clearTimeout(this.sizeProbeInterval);
});

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

setupTranspilationListener() {
return listen(({ type, code, path }) => {
if (type === 'add-extra-lib') {
const dtsPath = `${path}.d.ts`;
this.monaco.languages.typescript.typescriptDefaults._extraLibs[
`file:///${dtsPath}`
] = code;
this.commitLibChanges();
}
});
}

configureEditor = async (editor: any, monaco: any) => {
this.editor = editor;
this.monaco = monaco;
Expand Down
23 changes: 20 additions & 3 deletions packages/app/src/app/components/NewSandbox/index.js
Expand Up @@ -10,7 +10,9 @@ import {
newPreactSandboxUrl,
newVueSandboxUrl,
newAngularSandboxUrl,
newDojoSandboxUrl,
newSvelteSandboxUrl,
newCxJSSandboxUrl,
importFromGitHubUrl,
uploadFromCliUrl,
} from 'common/utils/url-generator';
Expand All @@ -21,6 +23,8 @@ import ParcelIcon from 'common/components/logos/Parcel';
import VueIcon from 'common/components/logos/Vue';
import SvelteIcon from 'common/components/logos/Svelte';
import AngularIcon from 'common/components/logos/Angular';
import CxJSIcon from 'common/components/logos/CxJS';
import DojoIcon from 'common/components/logos/Dojo';

import {
Container,
Expand Down Expand Up @@ -53,7 +57,6 @@ function NewSandbox({ signals }) {
href={parcelSandboxUrl()}
onClick={() => signals.modalClosed()}
/>

<Logo
Icon={ReactIcon}
width={50}
Expand All @@ -62,7 +65,6 @@ function NewSandbox({ signals }) {
href={newSandboxUrl()}
onClick={() => signals.modalClosed()}
/>

<Logo
Icon={VueIcon}
width={50}
Expand All @@ -71,7 +73,6 @@ function NewSandbox({ signals }) {
href={newVueSandboxUrl()}
onClick={() => signals.modalClosed()}
/>

<Logo
Icon={AngularIcon}
width={50}
Expand Down Expand Up @@ -104,6 +105,22 @@ function NewSandbox({ signals }) {
href={newReactTypeScriptSandboxUrl()}
onClick={() => signals.modalClosed()}
/>
<Logo
Icon={DojoIcon}
width={50}
height={50}
text="Dojo 2"
href={newDojoSandboxUrl()}
onClick={() => signals.closeModal()}
/>
<Logo
Icon={CxJSIcon}
width={50}
height={50}
text="CxJS"
href={newCxJSSandboxUrl()}
onClick={() => signals.closeModal()}
/>
<Logo
Icon={GithubIcon}
width={50}
Expand Down
8 changes: 8 additions & 0 deletions packages/app/src/sandbox/eval/index.js
Expand Up @@ -7,7 +7,9 @@ import {
preact,
reactTs,
angular,
cxjs,
babel,
dojo,
} from 'common/templates';

import reactPreset from './presets/create-react-app';
Expand All @@ -18,6 +20,8 @@ import sveltePreset from './presets/svelte';
import angularPreset from './presets/angular-cli';
import parcelPreset from './presets/parcel';
import babelPreset from './presets/babel-repl';
import cxjsPreset from './presets/cxjs';
import dojoPreset from './presets/dojo';

export default function getPreset(template: string) {
switch (template) {
Expand All @@ -37,6 +41,10 @@ export default function getPreset(template: string) {
return parcelPreset();
case babel.name:
return babelPreset();
case cxjs.name:
return cxjsPreset();
case dojo.name:
return dojoPreset();
default:
return reactPreset();
}
Expand Down
82 changes: 82 additions & 0 deletions packages/app/src/sandbox/eval/presets/cxjs/index.js
@@ -0,0 +1,82 @@
import babelTranspiler from '../../transpilers/babel';
import jsonTranspiler from '../../transpilers/json';
import stylesTranspiler from '../../transpilers/style';
import sassTranspiler from '../../transpilers/sass';
import rawTranspiler from '../../transpilers/raw';
import stylusTranspiler from '../../transpilers/stylus';
import lessTranspiler from '../../transpilers/less';
import tsTranspiler from '../../transpilers/typescript';

import Preset from '../';

export default function initialize() {
const cxjsPreset = new Preset(
'cxjs',
['js', 'jsx', 'ts', 'tsx', 'json', 'less', 'scss', 'sass', 'styl', 'css'],
{},
{}
);

cxjsPreset.registerTranspiler(module => /\.jsx?$/.test(module.path), [
{
transpiler: babelTranspiler,
options: {
dynamicCSSModules: true,
},
},
]);

cxjsPreset.registerTranspiler(module => /\.tsx?$/.test(module.path), [
{ transpiler: tsTranspiler },
]);

cxjsPreset.registerTranspiler(module => /\.css$/.test(module.path), [
{ transpiler: stylesTranspiler },
]);

cxjsPreset.registerTranspiler(module => /\.json$/.test(module.path), [
{ transpiler: jsonTranspiler },
]);

const sassWithConfig = {
transpiler: sassTranspiler,
options: {},
};

const lessWithConfig = {
transpiler: lessTranspiler,
options: {},
};

const stylusWithConfig = {
transpiler: stylusTranspiler,
options: {},
};
const styles = {
css: [],
scss: [sassWithConfig],
sass: [sassWithConfig],
less: [lessWithConfig],
styl: [stylusWithConfig],
};

/**
* Registers transpilers for all different combinations
*
* @returns
*/
function registerStyleTranspilers() {
return Object.keys(styles).forEach(type => {
cxjsPreset.registerTranspiler(
module => new RegExp(`\\.${type}`).test(module.path),
[...styles[type], { transpiler: stylesTranspiler }]
);
});
}

registerStyleTranspilers();

cxjsPreset.registerTranspiler(() => true, [{ transpiler: rawTranspiler }]);

return cxjsPreset;
}
60 changes: 60 additions & 0 deletions packages/app/src/sandbox/eval/presets/dojo/index.js
@@ -0,0 +1,60 @@
import { join, absolute } from 'common/utils/path';
import Preset from '../';

import typescriptTranspiler from '../../transpilers/typescript';
import rawTranspiler from '../../transpilers/raw';
import jsonTranspiler from '../../transpilers/json';
import stylesTranspiler from '../../transpilers/style';
import babelTranspiler from '../../transpilers/babel';

export default function initialize() {
const preset = new Preset(
'@dojo/cli-create-app',
['ts', 'tsx', 'js', 'json'],
{},
{
setup: async manager => {
const stylesPath = absolute(join('src', 'main.css'));
try {
const tModule = await manager.resolveTranspiledModuleAsync(
stylesPath,
'/'
);
await tModule.transpile(manager);
tModule.setIsEntry(true);
tModule.evaluate(manager);
} catch (e) {
if (e.type === 'module-not-found') {
// Do nothing
} else {
throw e;
}
}
},
}
);

preset.registerTranspiler(module => /\.tsx?$/.test(module.path), [
{ transpiler: typescriptTranspiler },
]);

preset.registerTranspiler(module => /\.jsx?$/.test(module.path), [
{ transpiler: babelTranspiler },
]);

preset.registerTranspiler(module => /\.json$/.test(module.path), [
{ transpiler: jsonTranspiler },
]);

preset.registerTranspiler(module => /\.m\.css$/.test(module.path), [
{ transpiler: stylesTranspiler, options: { module: true } },
]);

preset.registerTranspiler(module => /\.css$/.test(module.path), [
{ transpiler: stylesTranspiler },
]);

preset.registerTranspiler(() => true, [{ transpiler: rawTranspiler }]);

return preset;
}
Expand Up @@ -274,6 +274,14 @@ self.addEventListener('message', async event => {
) {
const pragmaticPlugin = await import(/* webpackChunkName: 'babel-plugin-jsx-pragmatic' */ 'babel-plugin-jsx-pragmatic');
Babel.registerPlugin('jsx-pragmatic', pragmaticPlugin);
}

if (
flattenedPlugins.indexOf('transform-cx-jsx') > -1 &&
Object.keys(Babel.availablePlugins).indexOf('transform-cx-jsx') === -1
) {
const cxJsxPlugin = await import(/* webpackChunkName: 'transform-cx-jsx' */ 'babel-plugin-transform-cx-jsx');
Babel.registerPlugin('transform-cx-jsx', cxJsxPlugin);
}
}

Expand Down
14 changes: 14 additions & 0 deletions packages/app/src/sandbox/eval/transpilers/style/index.js
@@ -1,4 +1,5 @@
// @flow
import { dispatch } from 'codesandbox-api';
import Transpiler from '../';
import { type LoaderContext } from '../../transpiled-module';

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

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

function classesToDefinition(classes): string {
return Object.keys(classes).reduce(
(previous, className) => previous + `export const ${className}: string;\n`,
''
);
}

class StyleTranspiler extends Transpiler {
constructor() {
super('style-loader');
Expand All @@ -24,12 +32,18 @@ class StyleTranspiler extends Transpiler {

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

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

dispatch({
type: 'add-extra-lib',
path,
code: classesToDefinition(exportTokens),
});
return Promise.resolve({ transpiledCode: result });
});
}
Expand Down
5 changes: 5 additions & 0 deletions packages/common/components/logos/CxJS.js
@@ -0,0 +1,5 @@
import React from 'react';

import cxjs from './cxjs.svg';

export default props => <img alt="cxjs" src={cxjs} {...props} />;

0 comments on commit 1e544d4

Please sign in to comment.