diff --git a/docs/Gruntfile.js b/docs/Gruntfile.js
new file mode 100644
index 0000000000..3e3383a927
--- /dev/null
+++ b/docs/Gruntfile.js
@@ -0,0 +1,62 @@
+module.exports = function(grunt) {
+
+ // Project configuration.
+ grunt.initConfig({
+ pkg: grunt.file.readJSON('../package.json')
+ });
+
+ function writeToLiveSampleJS(matchedJS) {
+
+ grunt.file.write('js/cookbook/' + componentName + '.js', liveEditJS);
+ }
+
+ function readFromCookbookEntry(abspath, rootdir, subdir, filename) {
+
+ var markdown = grunt.file.read(abspath),
+
+ // read markdown file for code sample
+ matchedJS = markdown.match(/`{3}[\s\S]*?`{3}/g),
+ trimmedJS,
+ componentName,
+ componentNameCamelCase,
+ componentNameUpperCase,
+ liveEditJS;
+
+ // File has no code sample
+ if (matchedJS === null) {
+ return;
+ };
+
+ matchedJS = matchedJS[0];
+
+ // Remove markdown syntax
+ matchedJS = matchedJS.slice(5, -3);
+
+ // remove file extension
+ componentName = filename.slice(0, -3);
+
+
+ componentNameCamelCase = componentName;
+
+ componentNameUpperCase = componentName.toUpperCase().replace("-","_");
+
+ componentNameCamelCase = componentNameCamelCase.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase() });
+
+ // Add code sample to live edit
+ liveEditJS = '/**\n * @jsx React.DOM\n */\n\n var ' + componentNameUpperCase + '_COMPONENT = "' + matchedJS + '";\n React.renderComponent(\n ReactPlayground( {codeText:' + componentNameUpperCase + '_COMPONENT} ),\n document.getElementById("' + componentNameCamelCase + 'Example")\n );'
+
+ writeToLiveSampleJS(liveEditJS, componentName);
+ }
+
+ grunt.registerTask('makeLiveSamples', 'Out live edit JS file for code samples in React Cookbook entries', function() {
+ var rootdir = 'cookbook/';
+
+ // Recurse through cookbook directory
+ grunt.file.recurse(rootdir, readFromCookbookEntry);
+
+ });
+
+ // Default task(s).
+ grunt.registerTask('default', ['makeLiveSamples']);
+
+};
\ No newline at end of file
diff --git a/docs/extractCode.js b/docs/extractCode.js
index b5714e3cb0..8728776b97 100644
--- a/docs/extractCode.js
+++ b/docs/extractCode.js
@@ -16,21 +16,24 @@ function main(dest, filenames) {
if (!dest) {
throw new Error('no dest provided');
}
+ console.log(filenames);
+
filenames.map(function (filename) {
- var content = fs.readFileSync(filename).toString('utf8');
- var codeSamples = content.match(CODE_SAMPLE);
+ var content = fs.readFileSync(filename).toString('utf8');
+ var codeSamples = content.match(CODE_SAMPLE);
- codeSamples.map(function (codeSample) {
- // Do a little jank preprocessing
- codeSample = codeSample.replace('', '');
- var extracted = codeSample.match(PARTS);
- if (!extracted) {
- throw new Error('Code sample did not match correct format in ' + filename + ': ' + truncate(codeSample));
- }
- var filename = extracted[1];
- var content = extracted[2].replace(/\*\*/g, '');
- fs.writeFileSync(argv.dest + '/' + filename, content);
- });
+
+ codeSamples.map(function (codeSample) {
+ // Do a little jank preprocessing
+ codeSample = codeSample.replace('', '');
+ var extracted = codeSample.match(PARTS);
+ if (!extracted) {
+ throw new Error('Code sample did not match correct format in ' + filename + ': ' + truncate(codeSample));
+ }
+ var filename = extracted[1];
+ var content = extracted[2].replace(/\*\*/g, '');
+ fs.writeFileSync(argv.dest + '/' + filename, content);
+ });
});
}
diff --git a/docs/js/cookbook/cb-02-inline-styles tip.js b/docs/js/cookbook/cb-02-inline-styles tip.js
new file mode 100644
index 0000000000..d66547de48
--- /dev/null
+++ b/docs/js/cookbook/cb-02-inline-styles tip.js
@@ -0,0 +1,19 @@
+/**
+ * @jsx React.DOM
+ */
+
+ var CB_02-INLINE-STYLES TIP_COMPONENT = "
+/** @jsx React.DOM */
+
+var divStyle = {
+ color: 'white',
+ backgroundImage: 'url(' + imgUrl + ')',
+ WebkitTransition: 'all' // note the capital 'W' here
+};
+
+React.renderComponent(
Hello World!
, mountNode);
+";
+ React.renderComponent(
+ ReactPlayground( {codeText:CB_02-INLINE-STYLES TIP_COMPONENT} ),
+ document.getElementById("cb-02InlineStyles tipExample")
+ );
\ No newline at end of file
diff --git a/docs/js/cookbook/cb-02-inline-styles.js b/docs/js/cookbook/cb-02-inline-styles.js
new file mode 100644
index 0000000000..8d38ca134c
--- /dev/null
+++ b/docs/js/cookbook/cb-02-inline-styles.js
@@ -0,0 +1,19 @@
+/**
+ * @jsx React.DOM
+ */
+
+ var CB_02-INLINE-STYLES_COMPONENT = "
+/** @jsx React.DOM */
+
+var divStyle = {
+ color: 'white',
+ backgroundImage: 'url(' + imgUrl + ')',
+ WebkitTransition: 'all' // note the capital 'W' here
+};
+
+React.renderComponent(
Hello World!
, mountNode);
+";
+ React.renderComponent(
+ ReactPlayground( {codeText:CB_02-INLINE-STYLES_COMPONENT} ),
+ document.getElementById("cb-02InlineStylesExample")
+ );
\ No newline at end of file
diff --git a/docs/js/cookbook/cb-03-if-else-in-JSX tip.js b/docs/js/cookbook/cb-03-if-else-in-JSX tip.js
new file mode 100644
index 0000000000..4726ee18c0
--- /dev/null
+++ b/docs/js/cookbook/cb-03-if-else-in-JSX tip.js
@@ -0,0 +1,16 @@
+/**
+ * @jsx React.DOM
+ */
+
+ var CB_03-IF-ELSE-IN-JSX TIP_COMPONENT = "
+/** @jsx React.DOM */
+
+// this
+React.renderComponent(
Hello World!
, mountNode);
+// is the same as this
+React.renderComponent(React.DOM.div({id:"msg"}, "Hello World!"), mountNode);
+";
+ React.renderComponent(
+ ReactPlayground( {codeText:CB_03-IF-ELSE-IN-JSX TIP_COMPONENT} ),
+ document.getElementById("cb-03IfElseIn-JSX tipExample")
+ );
\ No newline at end of file
diff --git a/docs/js/cookbook/cb-03-if-else-in-JSX.js b/docs/js/cookbook/cb-03-if-else-in-JSX.js
new file mode 100644
index 0000000000..f229ce335a
--- /dev/null
+++ b/docs/js/cookbook/cb-03-if-else-in-JSX.js
@@ -0,0 +1,16 @@
+/**
+ * @jsx React.DOM
+ */
+
+ var CB_03-IF-ELSE-IN-JSX_COMPONENT = "
+/** @jsx React.DOM */
+
+// this
+React.renderComponent(
Hello World!
, mountNode);
+// is the same as this
+React.renderComponent(React.DOM.div({id:"msg"}, "Hello World!"), mountNode);
+";
+ React.renderComponent(
+ ReactPlayground( {codeText:CB_03-IF-ELSE-IN-JSX_COMPONENT} ),
+ document.getElementById("cb-03IfElseIn-JSXExample")
+ );
\ No newline at end of file
diff --git a/docs/js/cookbook/cb-06-style-prop-value-px tip.js b/docs/js/cookbook/cb-06-style-prop-value-px tip.js
new file mode 100644
index 0000000000..6bfcda2cee
--- /dev/null
+++ b/docs/js/cookbook/cb-06-style-prop-value-px tip.js
@@ -0,0 +1,14 @@
+/**
+ * @jsx React.DOM
+ */
+
+ var CB_06-STYLE-PROP-VALUE-PX TIP_COMPONENT = "
+/** @jsx React.DOM */
+
+var divStyle = {height: 10}; // rendered as "height:10px"
+React.renderComponent(
Hello World!
, mountNode);
+";
+ React.renderComponent(
+ ReactPlayground( {codeText:CB_06-STYLE-PROP-VALUE-PX TIP_COMPONENT} ),
+ document.getElementById("cb-06StylePropValuePx tipExample")
+ );
\ No newline at end of file
diff --git a/docs/js/cookbook/cb-06-style-prop-value-px.js b/docs/js/cookbook/cb-06-style-prop-value-px.js
new file mode 100644
index 0000000000..d80cfd4055
--- /dev/null
+++ b/docs/js/cookbook/cb-06-style-prop-value-px.js
@@ -0,0 +1,14 @@
+/**
+ * @jsx React.DOM
+ */
+
+ var CB_06-STYLE-PROP-VALUE-PX_COMPONENT = "
+/** @jsx React.DOM */
+
+var divStyle = {height: 10}; // rendered as "height:10px"
+React.renderComponent(
Hello World!
, mountNode);
+";
+ React.renderComponent(
+ ReactPlayground( {codeText:CB_06-STYLE-PROP-VALUE-PX_COMPONENT} ),
+ document.getElementById("cb-06StylePropValuePxExample")
+ );
\ No newline at end of file
diff --git a/docs/js/cookbook/cb-08-controlled-input-null-value tip.js b/docs/js/cookbook/cb-08-controlled-input-null-value tip.js
new file mode 100644
index 0000000000..2351da9acb
--- /dev/null
+++ b/docs/js/cookbook/cb-08-controlled-input-null-value tip.js
@@ -0,0 +1,17 @@
+/**
+ * @jsx React.DOM
+ */
+
+ var CB_08-CONTROLLED-INPUT-NULL-VALUE TIP_COMPONENT = "
+/** @jsx React.DOM */
+
+React.renderComponent(, mountNode);
+
+setTimeout(function() {
+ React.renderComponent(, mountNode);
+}, 2000);
+";
+ React.renderComponent(
+ ReactPlayground( {codeText:CB_08-CONTROLLED-INPUT-NULL-VALUE TIP_COMPONENT} ),
+ document.getElementById("cb-08ControlledInputNullValue tipExample")
+ );
\ No newline at end of file
diff --git a/docs/js/cookbook/cb-08-controlled-input-null-value.js b/docs/js/cookbook/cb-08-controlled-input-null-value.js
new file mode 100644
index 0000000000..18e37c5956
--- /dev/null
+++ b/docs/js/cookbook/cb-08-controlled-input-null-value.js
@@ -0,0 +1,17 @@
+/**
+ * @jsx React.DOM
+ */
+
+ var CB_08-CONTROLLED-INPUT-NULL-VALUE_COMPONENT = "
+/** @jsx React.DOM */
+
+React.renderComponent(, mountNode);
+
+setTimeout(function() {
+ React.renderComponent(, mountNode);
+}, 2000);
+";
+ React.renderComponent(
+ ReactPlayground( {codeText:CB_08-CONTROLLED-INPUT-NULL-VALUE_COMPONENT} ),
+ document.getElementById("cb-08ControlledInputNullValueExample")
+ );
\ No newline at end of file
diff --git a/docs/js/cookbook/inline-styles.js b/docs/js/cookbook/inline-styles.js
new file mode 100644
index 0000000000..0f6110ae20
--- /dev/null
+++ b/docs/js/cookbook/inline-styles.js
@@ -0,0 +1,19 @@
+/**
+ * @jsx React.DOM
+ */
+
+ var INLINE_STYLES_COMPONENT = "
+/** @jsx React.DOM */
+
+var divStyle = {
+ color: 'white',
+ backgroundImage: 'url(' + imgUrl + ')',
+ WebkitTransition: 'all' // note the capital 'W' here
+};
+
+React.renderComponent(
Hello World!
, mountNode);
+";
+ React.renderComponent(
+ ReactPlayground( {codeText:INLINE_STYLES_COMPONENT} ),
+ document.getElementById("inlineStylesExample")
+ );
\ No newline at end of file