├── packages ├── website │ ├── README.md │ ├── src │ │ ├── examples │ │ │ ├── schema │ │ │ │ ├── schema_docs.md │ │ │ │ └── schema_thumbnail.png │ │ │ ├── form │ │ │ │ ├── form_thumbnail.png │ │ │ │ └── form_docs.md │ │ │ ├── list │ │ │ │ ├── list_thumbnail.png │ │ │ │ └── list_docs.md │ │ │ ├── dynamic │ │ │ │ ├── dynamic_thumbnail.png │ │ │ │ └── dynamic_docs.md │ │ │ ├── examples.js │ │ │ └── examples.json │ │ ├── img │ │ │ ├── forms.png │ │ │ └── github.png │ │ ├── index.js │ │ ├── components │ │ │ ├── Highlighter.js │ │ │ ├── Guide.js │ │ │ ├── Example.js │ │ │ ├── API.js │ │ │ └── APIDoc.js │ │ ├── index.css │ │ ├── guides │ │ │ ├── guides.js │ │ │ └── intro.md │ │ ├── renderers.js │ │ ├── App.js │ │ ├── Header.js │ │ ├── App.css │ │ ├── styles.js │ │ └── Sidebar.js │ ├── forms.png │ ├── public │ │ ├── favicon.ico │ │ ├── manifest.json │ │ └── index.html │ ├── .gitignore │ └── package.json └── react-dynamic-forms │ ├── README.md │ ├── .eslintrc │ ├── .babelrc │ ├── public │ ├── favicon.ico │ └── index.html │ ├── lib │ ├── css │ │ ├── textedit.css │ │ ├── textarea.css │ │ ├── group.css │ │ ├── chooser.css │ │ ├── icon.css │ │ ├── dateedit.css │ │ ├── tagsedit.css │ │ └── list.css │ ├── js │ │ └── constants.js │ ├── index.js │ └── components │ │ ├── Schema.js │ │ └── View.js │ ├── src │ ├── css │ │ ├── textedit.css │ │ ├── textarea.css │ │ ├── group.css │ │ ├── chooser.css │ │ ├── icon.css │ │ ├── dateedit.css │ │ ├── tagsedit.css │ │ └── list.css │ ├── js │ │ ├── constants.js │ │ └── formList.js │ ├── components │ │ ├── View.js │ │ ├── Schema.js │ │ ├── Field.js │ │ ├── RadioButtons.js │ │ ├── CheckBoxes.js │ │ ├── TagsEdit.js │ │ ├── DateEdit.js │ │ ├── TextArea.js │ │ └── TextEdit.js │ └── index.js │ ├── tests │ ├── components_test │ │ ├── TextEditExamples.js │ │ └── ChooserExamples.js │ ├── TextEditTests.js │ ├── ChooserTests.js │ ├── __snapshots__ │ │ └── textedit.test.js.snap │ └── textedit.test.js │ ├── CONTRIBUTING.md │ ├── LICENSE │ └── package.json ├── docs ├── static │ └── media │ │ ├── schema_docs.01abfc75.md │ │ ├── forms.aec5c7b8.png │ │ ├── glyphicons-halflings-regular.448c34a5.woff2 │ │ ├── glyphicons-halflings-regular.e18bbf61.ttf │ │ ├── glyphicons-halflings-regular.f4769f9b.eot │ │ ├── glyphicons-halflings-regular.fa277232.woff │ │ ├── intro.fda87512.md │ │ ├── list_docs.12101c16.md │ │ ├── form_docs.c680d6e1.md │ │ └── dynamic_docs.c45dd5e7.md ├── favicon.ico ├── manifest.json ├── asset-manifest.json ├── index.html └── service-worker.js ├── .vscode └── settings.json ├── .gitignore ├── .travis.yml ├── lerna.json ├── .npmignore ├── package.json └── LICENSE /packages/website/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/static/media/schema_docs.01abfc75.md: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------------- /packages/react-dynamic-forms/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /packages/website/src/examples/schema/schema_docs.md: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "git.ignoreLimitWarning": true 3 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | .DS_Store 4 | npm-debug.log 5 | examples-bundle.js -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/esnet/react-dynamic-forms/HEAD/docs/favicon.ico -------------------------------------------------------------------------------- /packages/react-dynamic-forms/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["react-app", "prettier", "prettier/react"] 3 | } 4 | -------------------------------------------------------------------------------- /packages/website/forms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/esnet/react-dynamic-forms/HEAD/packages/website/forms.png -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - "0.12" 5 | notifications: 6 | email: false 7 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "lerna": "2.0.0", 3 | "packages": [ 4 | "packages/*" 5 | ], 6 | "version": "independent" 7 | } 8 | -------------------------------------------------------------------------------- /docs/static/media/forms.aec5c7b8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/esnet/react-dynamic-forms/HEAD/docs/static/media/forms.aec5c7b8.png -------------------------------------------------------------------------------- /packages/website/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/esnet/react-dynamic-forms/HEAD/packages/website/public/favicon.ico -------------------------------------------------------------------------------- /packages/website/src/img/forms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/esnet/react-dynamic-forms/HEAD/packages/website/src/img/forms.png -------------------------------------------------------------------------------- /packages/website/src/img/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/esnet/react-dynamic-forms/HEAD/packages/website/src/img/github.png -------------------------------------------------------------------------------- /packages/react-dynamic-forms/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-0", "react"], 3 | "plugins": ["transform-class-properties"] 4 | } -------------------------------------------------------------------------------- /packages/react-dynamic-forms/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/esnet/react-dynamic-forms/HEAD/packages/react-dynamic-forms/public/favicon.ico -------------------------------------------------------------------------------- /packages/website/src/examples/form/form_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/esnet/react-dynamic-forms/HEAD/packages/website/src/examples/form/form_thumbnail.png -------------------------------------------------------------------------------- /packages/website/src/examples/list/list_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/esnet/react-dynamic-forms/HEAD/packages/website/src/examples/list/list_thumbnail.png -------------------------------------------------------------------------------- /packages/website/src/examples/schema/schema_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/esnet/react-dynamic-forms/HEAD/packages/website/src/examples/schema/schema_thumbnail.png -------------------------------------------------------------------------------- /docs/static/media/glyphicons-halflings-regular.448c34a5.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/esnet/react-dynamic-forms/HEAD/docs/static/media/glyphicons-halflings-regular.448c34a5.woff2 -------------------------------------------------------------------------------- /docs/static/media/glyphicons-halflings-regular.e18bbf61.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/esnet/react-dynamic-forms/HEAD/docs/static/media/glyphicons-halflings-regular.e18bbf61.ttf -------------------------------------------------------------------------------- /docs/static/media/glyphicons-halflings-regular.f4769f9b.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/esnet/react-dynamic-forms/HEAD/docs/static/media/glyphicons-halflings-regular.f4769f9b.eot -------------------------------------------------------------------------------- /docs/static/media/glyphicons-halflings-regular.fa277232.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/esnet/react-dynamic-forms/HEAD/docs/static/media/glyphicons-halflings-regular.fa277232.woff -------------------------------------------------------------------------------- /packages/website/src/examples/dynamic/dynamic_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/esnet/react-dynamic-forms/HEAD/packages/website/src/examples/dynamic/dynamic_thumbnail.png -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | src/ 2 | examples/ 3 | screenshots/ 4 | docs/ 5 | bin/ 6 | build/global 7 | index.html 8 | .eslintrc 9 | .gitignore 10 | CONTRIBUTING.md 11 | examples-bundle.js 12 | examples-bundle.js.map 13 | *.config.js 14 | .DS_Store 15 | npm-debug.log 16 | -------------------------------------------------------------------------------- /packages/website/src/index.js: -------------------------------------------------------------------------------- 1 | import App from "./App"; 2 | import React from "react"; 3 | import ReactDOM from "react-dom"; 4 | import "bootstrap/dist/css/bootstrap.css"; 5 | import "bootstrap/dist/css/bootstrap-theme.css"; 6 | import "./index.css"; 7 | 8 | ReactDOM.render(, document.getElementById('root')); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "start": "cd packages/website && npm run start", 4 | "build-website": 5 | "echo \"*** Building website\n\" && rm -rf docs && cd packages/website && npm run build && mv build ../../docs" 6 | }, 7 | "devDependencies": { 8 | "lerna": "^2.5.1" 9 | }, 10 | "dependencies": {} 11 | } -------------------------------------------------------------------------------- /docs/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /packages/website/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /packages/website/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /packages/react-dynamic-forms/lib/css/textedit.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 - present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | datepicker__input.has-error { 12 | border-color: "green" 13 | } -------------------------------------------------------------------------------- /packages/react-dynamic-forms/src/css/textedit.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 - present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | datepicker__input.has-error { 12 | border-color: "green" 13 | } -------------------------------------------------------------------------------- /packages/website/src/components/Highlighter.js: -------------------------------------------------------------------------------- 1 | export default { 2 | highlightCodeBlocks() { 3 | const els = document.querySelectorAll("pre code"); 4 | for (let i = 0; i < els.length; i++) { 5 | if (!els[i].classList.contains("hljs")) { 6 | window.hljs.highlightBlock(els[i]); 7 | } 8 | } 9 | }, 10 | 11 | componentDidMount() { 12 | this.highlightCodeBlocks(); 13 | }, 14 | 15 | componentDidUpdate() { 16 | this.highlightCodeBlocks(); 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /packages/react-dynamic-forms/lib/css/textarea.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 - present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | textarea.form-control { 12 | font-size: 12px; 13 | padding-left: 10px; 14 | } 15 | -------------------------------------------------------------------------------- /packages/react-dynamic-forms/src/css/textarea.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 - present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | textarea.form-control { 12 | font-size: 12px; 13 | padding-left: 10px; 14 | } 15 | -------------------------------------------------------------------------------- /packages/website/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: sans-serif; 5 | } 6 | 7 | pre { 8 | display: block; 9 | margin: 0 0 10px; 10 | padding: 0px; 11 | font-size: 13px; 12 | line-height: 1.42857143; 13 | word-break: break-all; 14 | word-wrap: break-word; 15 | color: #333333; 16 | background-color: #f8f8f8; 17 | border-style: none; 18 | border-radius: 0px; 19 | border-left-color: #64a0af; 20 | border-left-style: solid; 21 | border-left-width: 3px; 22 | padding-left: 10px; 23 | } -------------------------------------------------------------------------------- /packages/website/src/guides/guides.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2016-present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | import intro from "./intro.md"; 12 | import start from "./getting_started.md"; 13 | 14 | export default { 15 | intro, 16 | start, 17 | }; 18 | -------------------------------------------------------------------------------- /packages/react-dynamic-forms/lib/css/group.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 - present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | .group-required { 12 | color: orange; 13 | font-size: larger; 14 | } 15 | 16 | .group-label { 17 | text-align: right; 18 | padding-right: 0px; 19 | text-transform: uppercase; 20 | font-size: smaller; 21 | } -------------------------------------------------------------------------------- /packages/react-dynamic-forms/src/css/group.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 - present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | .group-required { 12 | color: orange; 13 | font-size: larger; 14 | } 15 | 16 | .group-label { 17 | text-align: right; 18 | padding-right: 0px; 19 | text-transform: uppercase; 20 | font-size: smaller; 21 | } -------------------------------------------------------------------------------- /packages/website/src/examples/examples.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2016-present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | // 12 | // Export all of the examples 13 | // 14 | 15 | import dynamic from "./dynamic/Index"; 16 | import form from "./form/Index"; 17 | import list from "./list/Index"; 18 | import schema from "./schema/Index"; 19 | 20 | export default { 21 | ...dynamic, 22 | ...form, 23 | ...list, 24 | ...schema 25 | }; 26 | -------------------------------------------------------------------------------- /packages/react-dynamic-forms/tests/components_test/TextEditExamples.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 - present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | import React from "react"; 12 | import TextEdit from "../../src/components/TextEdit"; 13 | 14 | export class TestBasic extends React.Component { 15 | render() { 16 | const attr = { 17 | name: "Basic" 18 | }; 19 | return ; 20 | } 21 | }; -------------------------------------------------------------------------------- /packages/website/src/examples/examples.json: -------------------------------------------------------------------------------- 1 | { 2 | "dynamic": { 3 | "title": "Dynamic", 4 | "description": "This example demonstrates the use of a Dynamic Form", 5 | "tags": ["Form"], 6 | "link": "DynamicExample" 7 | }, 8 | "form": { 9 | "title": "Form", 10 | "description": "This example demonstrates the use of a Basic Form", 11 | "tags": ["Form"], 12 | "link": "FormExample" 13 | }, 14 | "list": { 15 | "title": "List", 16 | "description": "This example demonstrates the use of a List", 17 | "tags": ["List"], 18 | "link": "LinkExample" 19 | }, 20 | "schema": { 21 | "title": "Schema", 22 | "description": "This example demonstrates the use of a Schema", 23 | "tags": ["Schema"], 24 | "link": "SchemaExample" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/react-dynamic-forms/lib/css/chooser.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 - present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | .Select-control { 12 | height: 30px; 13 | } 14 | 15 | .Select-value { 16 | line-height: 26px !important; 17 | } 18 | 19 | .Select-value-label { 20 | line-height: 26px; 21 | font-size: 12px; 22 | } 23 | 24 | .Select-menu-outer { 25 | font-size: 12px; 26 | } 27 | 28 | .Select-input { 29 | height: 26px; 30 | } 31 | 32 | .Select-placeholder { 33 | line-height: 20px; 34 | font-size: 12px; 35 | padding-top: 5px; 36 | } 37 | 38 | .Select.is-missing > .Select-control { 39 | background: floralwhite; 40 | } -------------------------------------------------------------------------------- /packages/react-dynamic-forms/src/css/chooser.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 - present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | .Select-control { 12 | height: 30px; 13 | } 14 | 15 | .Select-value { 16 | line-height: 26px !important; 17 | } 18 | 19 | .Select-value-label { 20 | line-height: 26px; 21 | font-size: 12px; 22 | } 23 | 24 | .Select-menu-outer { 25 | font-size: 12px; 26 | } 27 | 28 | .Select-input { 29 | height: 26px; 30 | } 31 | 32 | .Select-placeholder { 33 | line-height: 20px; 34 | font-size: 12px; 35 | padding-top: 5px; 36 | } 37 | 38 | .Select.is-missing > .Select-control { 39 | background: floralwhite; 40 | } -------------------------------------------------------------------------------- /packages/website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "website", 3 | "version": "1.0.3", 4 | "homepage": "http://software.es.net/react-dynamic-forms", 5 | "private": true, 6 | "dependencies": { 7 | "bootstrap": "^3.3.7", 8 | "chance": "^1.0.6", 9 | "flexbox-react": "^4.4.0", 10 | "immutable": "^3.8.2", 11 | "lodash": "^4.17.5", 12 | "prismjs": "^1.12.0", 13 | "react": "^16.2.0", 14 | "react-bootstrap": "^0.32.1", 15 | "react-dom": "^16.2.0", 16 | "react-dynamic-forms": "^1.0.3", 17 | "react-markdown": "^3.1.4", 18 | "react-overlays": "^0.8.3", 19 | "react-router-dom": "^4.2.2", 20 | "react-scripts": "1.1.1", 21 | "underscore": "^1.8.3" 22 | }, 23 | "scripts": { 24 | "start": "react-scripts start", 25 | "build": "react-scripts build", 26 | "test": "react-scripts test --env=jsdom", 27 | "eject": "react-scripts eject" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/react-dynamic-forms/lib/css/icon.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 - present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | .icon { 12 | cursor: pointer; 13 | font-size: 9px; 14 | padding-bottom: 10px; 15 | color: steelblue; 16 | padding-top: 3px; 17 | } 18 | 19 | .hostile_icon { 20 | cursor: pointer; 21 | font-size: 9px; 22 | padding-bottom: 10px; 23 | color: #b94a48; 24 | padding-top: 3px; 25 | } 26 | 27 | .delete-action:hover { 28 | color: #b94a48; 29 | } 30 | 31 | .edit-action:hover { 32 | color: steelblue; 33 | } 34 | 35 | .edit-action.active { 36 | color: steelblue; 37 | } 38 | 39 | .add-action:hover { 40 | color: green; 41 | } 42 | -------------------------------------------------------------------------------- /packages/react-dynamic-forms/src/css/icon.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 - present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | .icon { 12 | cursor: pointer; 13 | font-size: 9px; 14 | padding-bottom: 10px; 15 | color: steelblue; 16 | padding-top: 3px; 17 | } 18 | 19 | .hostile_icon { 20 | cursor: pointer; 21 | font-size: 9px; 22 | padding-bottom: 10px; 23 | color: #b94a48; 24 | padding-top: 3px; 25 | } 26 | 27 | .delete-action:hover { 28 | color: #b94a48; 29 | } 30 | 31 | .edit-action:hover { 32 | color: steelblue; 33 | } 34 | 35 | .edit-action.active { 36 | color: steelblue; 37 | } 38 | 39 | .add-action:hover { 40 | color: green; 41 | } 42 | -------------------------------------------------------------------------------- /packages/react-dynamic-forms/src/js/constants.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 - present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | import keymirror from "keymirror"; 12 | 13 | module.exports = { 14 | /** 15 | * At Form can either: 16 | * * ALL - Always show edit state for all of its fields 17 | * * SELECTION - Show edit icons next to items, selecting one show edit state for that item 18 | * * NEVER - Never show edit state for the items (view only) 19 | */ 20 | FormEditStates: keymirror({ 21 | ALWAYS: null, 22 | SELECTED: null, 23 | NEVER: null, 24 | TABLE: null 25 | }), 26 | 27 | FormGroupLayout: keymirror({ 28 | ROW: null, 29 | COLUMN: null, 30 | INLINE: null 31 | }) 32 | }; 33 | -------------------------------------------------------------------------------- /packages/website/src/renderers.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | import _ from "lodash"; 12 | import React from "react"; 13 | 14 | import { codeStyle } from "./styles"; 15 | 16 | export function codeRenderer(props) { 17 | const availableLinks = []; 18 | return _.includes(availableLinks, props.literal) ? ( 19 | 20 | {props.literal} 21 | 22 | ) : ( 23 | {props.literal} 24 | ); 25 | } 26 | 27 | export function codeBlockRenderer(props) { 28 | return ( 29 |
30 |             {props.literal}
31 |         
32 | ); 33 | } 34 | -------------------------------------------------------------------------------- /packages/react-dynamic-forms/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | React Dynamic Forms 12 | 13 | 14 | 15 | 16 | 20 | 21 | 22 | 23 |
24 |
25 |
26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /docs/asset-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "main.css": "static/css/main.1d316427.css", 3 | "main.css.map": "static/css/main.1d316427.css.map", 4 | "main.js": "static/js/main.f2da4b7a.js", 5 | "main.js.map": "static/js/main.f2da4b7a.js.map", 6 | "static/media/dynamic_docs.md": "static/media/dynamic_docs.c45dd5e7.md", 7 | "static/media/form_docs.md": "static/media/form_docs.c680d6e1.md", 8 | "static/media/forms.png": "static/media/forms.aec5c7b8.png", 9 | "static/media/getting_started.md": "static/media/getting_started.2be5c59d.md", 10 | "static/media/glyphicons-halflings-regular.eot": "static/media/glyphicons-halflings-regular.f4769f9b.eot", 11 | "static/media/glyphicons-halflings-regular.svg": "static/media/glyphicons-halflings-regular.89889688.svg", 12 | "static/media/glyphicons-halflings-regular.ttf": "static/media/glyphicons-halflings-regular.e18bbf61.ttf", 13 | "static/media/glyphicons-halflings-regular.woff": "static/media/glyphicons-halflings-regular.fa277232.woff", 14 | "static/media/glyphicons-halflings-regular.woff2": "static/media/glyphicons-halflings-regular.448c34a5.woff2", 15 | "static/media/intro.md": "static/media/intro.fda87512.md", 16 | "static/media/list_docs.md": "static/media/list_docs.12101c16.md", 17 | "static/media/schema_docs.md": "static/media/schema_docs.01abfc75.md" 18 | } -------------------------------------------------------------------------------- /packages/react-dynamic-forms/lib/js/constants.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var _keymirror = require("keymirror"); 4 | 5 | var _keymirror2 = _interopRequireDefault(_keymirror); 6 | 7 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 8 | 9 | module.exports = { 10 | /** 11 | * At Form can either: 12 | * * ALL - Always show edit state for all of its fields 13 | * * SELECTION - Show edit icons next to items, selecting one show edit state for that item 14 | * * NEVER - Never show edit state for the items (view only) 15 | */ 16 | FormEditStates: (0, _keymirror2.default)({ 17 | ALWAYS: null, 18 | SELECTED: null, 19 | NEVER: null, 20 | TABLE: null 21 | }), 22 | 23 | FormGroupLayout: (0, _keymirror2.default)({ 24 | ROW: null, 25 | COLUMN: null, 26 | INLINE: null 27 | }) 28 | }; /** 29 | * Copyright (c) 2017 - present, The Regents of the University of California, 30 | * through Lawrence Berkeley National Laboratory (subject to receipt 31 | * of any required approvals from the U.S. Dept. of Energy). 32 | * All rights reserved. 33 | * 34 | * This source code is licensed under the BSD-style license found in the 35 | * LICENSE file in the root directory of this source tree. 36 | */ -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | React Dynamic Forms
-------------------------------------------------------------------------------- /packages/react-dynamic-forms/src/components/View.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 - present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | import React from "react"; 12 | 13 | import formGroup from "../js/formGroup"; 14 | 15 | class View extends React.Component { 16 | render() { 17 | const text = this.props.value; 18 | const view = this.props.view; 19 | let color = ""; 20 | let background = ""; 21 | const style = { 22 | color, 23 | background, 24 | // height: 23, 25 | height: "100%", 26 | width: "100%", 27 | paddingLeft: 3 28 | }; 29 | if (!view) { 30 | return ( 31 |
32 | {text} 33 |
34 | ); 35 | } else { 36 | return ( 37 |
38 | {view(text)} 39 |
40 | ); 41 | } 42 | } 43 | } 44 | 45 | export default formGroup(View, true); -------------------------------------------------------------------------------- /packages/react-dynamic-forms/src/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 - present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | import Form from "./components/Form"; 12 | import Schema from "./components/Schema"; 13 | import Field from "./components/Field"; 14 | import formGroup from "./js/formGroup"; 15 | import formList from "./js/formList"; 16 | import List from "./components/List"; 17 | import TextEdit from "./components/TextEdit"; 18 | import TextArea from "./components/TextArea"; 19 | import Chooser from "./components/Chooser.js"; 20 | import DateEdit from "./components/DateEdit"; 21 | import TagsEdit from "./components/TagsEdit"; 22 | import RadioButtons from "./components/RadioButtons"; 23 | import CheckBoxes from "./components/CheckBoxes"; 24 | import View from "./components/View"; 25 | import { FormEditStates, FormGroupLayout } from "./js/constants"; 26 | 27 | export { Form }; 28 | export { Schema }; 29 | export { Field }; 30 | export { formGroup }; 31 | export { formList }; 32 | export { List }; 33 | export { TextEdit }; 34 | export { TextArea }; 35 | export { Chooser }; 36 | export { DateEdit }; 37 | export { TagsEdit }; 38 | export { RadioButtons }; 39 | export { CheckBoxes }; 40 | export { View }; 41 | export { FormEditStates, FormGroupLayout }; -------------------------------------------------------------------------------- /packages/react-dynamic-forms/lib/css/dateedit.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 - present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | input.datepicker__input.rdf { 12 | font-size: 12px; 13 | height: 30px; 14 | margin-bottom: 10px; 15 | border-radius: 3px; 16 | padding-left: 6px; 17 | color: #555555; 18 | background-color: #ffffff; 19 | background-image: none; 20 | border: 1px solid #cccccc; 21 | border-radius: 4px; 22 | -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); 23 | box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); 24 | -webkit-transition: border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s; 25 | -o-transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s; 26 | transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s; 27 | } 28 | 29 | input.datepicker__input.rdf:focus { 30 | border-color: #66afe9; 31 | outline: 0; 32 | -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6); 33 | box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6); 34 | } 35 | 36 | input.datepicker__input.has-error { 37 | border-color: #B94A48; 38 | } 39 | 40 | input.datepicker__input.is-missing { 41 | background-color: floralwhite; 42 | } 43 | -------------------------------------------------------------------------------- /packages/react-dynamic-forms/src/css/dateedit.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 - present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | input.datepicker__input.rdf { 12 | font-size: 12px; 13 | height: 30px; 14 | margin-bottom: 10px; 15 | border-radius: 3px; 16 | padding-left: 6px; 17 | color: #555555; 18 | background-color: #ffffff; 19 | background-image: none; 20 | border: 1px solid #cccccc; 21 | border-radius: 4px; 22 | -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); 23 | box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); 24 | -webkit-transition: border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s; 25 | -o-transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s; 26 | transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s; 27 | } 28 | 29 | input.datepicker__input.rdf:focus { 30 | border-color: #66afe9; 31 | outline: 0; 32 | -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6); 33 | box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6); 34 | } 35 | 36 | input.datepicker__input.has-error { 37 | border-color: #B94A48; 38 | } 39 | 40 | input.datepicker__input.is-missing { 41 | background-color: floralwhite; 42 | } 43 | -------------------------------------------------------------------------------- /packages/website/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | React Dynamic Forms 16 | 17 | 18 | 19 | 20 | 29 | 30 | 31 | 32 | 33 | 36 | 37 |
38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /packages/react-dynamic-forms/src/components/Schema.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 - present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | import invariant from "invariant"; 12 | 13 | /** 14 | * A schema can be specified using JSX to define the rules for 15 | * each form field. As an example, here is a Form that will take the 16 | * first name, last name and email of a contact. We can define also 17 | * that the email should be of format `email` and that the first and 18 | * last names are `required`: 19 | * 20 | * ``` 21 | * const schema = ( 22 | * 23 | * 25 | * 27 | * 29 | * 30 | * ); 31 | * ``` 32 | * 33 | * See also `Field`. 34 | */ 35 | export default class Schema { 36 | render() { 37 | invariant( 38 | false, 39 | `${this.constructor 40 | .name} elements are for schema configuration only and should not be rendered` 41 | ); 42 | return; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /packages/react-dynamic-forms/lib/css/tagsedit.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 - present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | .Select-control { 12 | height: 26px; 13 | } 14 | 15 | .Select-value { 16 | line-height: 26px !important; 17 | } 18 | 19 | .Select-value-label { 20 | line-height: 24px; 21 | font-size: 12px; 22 | } 23 | 24 | .Select-menu-outer { 25 | font-size: 12px; 26 | } 27 | 28 | .Select-input { 29 | height: 26px; 30 | } 31 | 32 | .Select.is-missing > .Select-control { 33 | background: floralwhite; 34 | } 35 | 36 | .Select--multi .Select-value { 37 | height: 26px; 38 | height: 24px; 39 | margin-top: 1px; 40 | border-color: #ccc 41 | } 42 | 43 | .Select--multi .Select-value-label { 44 | line-height: 22px; 45 | font-size: 12px; 46 | padding: 0px; 47 | margin-top: -6px; 48 | padding-left: 5px; 49 | padding-right: 5px; 50 | background: #DDD; 51 | color: #555555; 52 | border-color: #555; 53 | } 54 | 55 | .Select--multi .Select-value-icon { 56 | line-height: 22px; 57 | font-size: 12px; 58 | padding: 0px; 59 | margin-top: -6px; 60 | padding-left: 5px; 61 | padding-right: 5px; 62 | background: #DDD; 63 | color: #555555; 64 | border-right-color: #ccc; 65 | } 66 | 67 | .Select--multi .Select-value-icon:hover { 68 | background: #DFDFDF; 69 | color: #b94a48; 70 | } 71 | 72 | .Select.missing.Select--multi.is-searchable > .Select-control { 73 | background: floralwhite; 74 | } -------------------------------------------------------------------------------- /packages/react-dynamic-forms/src/css/tagsedit.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 - present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | .Select-control { 12 | height: 26px; 13 | } 14 | 15 | .Select-value { 16 | line-height: 26px !important; 17 | } 18 | 19 | .Select-value-label { 20 | line-height: 24px; 21 | font-size: 12px; 22 | } 23 | 24 | .Select-menu-outer { 25 | font-size: 12px; 26 | } 27 | 28 | .Select-input { 29 | height: 26px; 30 | } 31 | 32 | .Select.is-missing > .Select-control { 33 | background: floralwhite; 34 | } 35 | 36 | .Select--multi .Select-value { 37 | height: 26px; 38 | height: 24px; 39 | margin-top: 1px; 40 | border-color: #ccc 41 | } 42 | 43 | .Select--multi .Select-value-label { 44 | line-height: 22px; 45 | font-size: 12px; 46 | padding: 0px; 47 | margin-top: -6px; 48 | padding-left: 5px; 49 | padding-right: 5px; 50 | background: #DDD; 51 | color: #555555; 52 | border-color: #555; 53 | } 54 | 55 | .Select--multi .Select-value-icon { 56 | line-height: 22px; 57 | font-size: 12px; 58 | padding: 0px; 59 | margin-top: -6px; 60 | padding-left: 5px; 61 | padding-right: 5px; 62 | background: #DDD; 63 | color: #555555; 64 | border-right-color: #ccc; 65 | } 66 | 67 | .Select--multi .Select-value-icon:hover { 68 | background: #DFDFDF; 69 | color: #b94a48; 70 | } 71 | 72 | .Select.missing.Select--multi.is-searchable > .Select-control { 73 | background: floralwhite; 74 | } -------------------------------------------------------------------------------- /packages/react-dynamic-forms/tests/TextEditTests.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | import React from "react"; 12 | import { 13 | TestBasic // TextEditDisabled, // TextEditPlaceholder, 14 | } from // TextEditPassword, 15 | // TextEditRequired1, 16 | // TextEditRequired2, 17 | // TextEditRequired3, 18 | // TextEditValidate, 19 | // TextEditValidateInt 20 | "./components_test/TextEditExamples"; 21 | 22 | export default React.createClass({ 23 | render() { 24 | return ( 25 |
26 |
27 |
28 |

TextEdit Tests

29 | TextEdit initial value 30 | 31 | {/*} 32 | Diabled TextEdit 33 | 34 | With a placeholder 35 | 36 | Password type 37 | 38 | Required field (with showRequired turned ON): 39 | 40 | Required field (with showRequired turned OFF): 41 | 42 | Required field (with showRequired turned ON and initial value): 43 | 44 | Validated field (email address) 45 | 46 | Validated field (integer) 47 | */} 48 |
49 |
50 |
51 | ); 52 | } 53 | }); 54 | -------------------------------------------------------------------------------- /packages/website/src/App.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | import "./App.css"; 12 | import React, { Component } from "react"; 13 | import { HashRouter as Router, Route, Switch } from "react-router-dom"; 14 | 15 | import Prism from "prismjs"; // eslint-disable-line 16 | import "prismjs/components/prism-typescript"; 17 | import "prismjs/themes/prism.css"; 18 | 19 | import Header from "./Header"; 20 | import Sidebar from "./Sidebar"; 21 | import Guide from "./components/Guide"; 22 | import Example from "./components/Example"; 23 | import API from "./components/API"; 24 | 25 | import { bodyStyle, mainStyle, contentStyle } from "./styles"; 26 | 27 | class Page extends Component { 28 | render() { 29 | return ( 30 |
31 |
32 | {" "} 33 | 34 | 35 | 36 | 37 | 38 | 39 |
40 | 41 |
42 | ); 43 | } 44 | } 45 | 46 | class App extends Component { 47 | render() { 48 | return ( 49 | 50 |
51 |
52 | 53 |
54 |
55 | ); 56 | } 57 | } 58 | 59 | export default App; 60 | -------------------------------------------------------------------------------- /packages/react-dynamic-forms/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute to ESnet React Forms 2 | 3 | In general we follow the "fork & pull" model as outlined in the 4 | [GitHub docs](https://help.github.com/articles/using-pull-requests/). 5 | 6 | Here are a few additional thoughts on how to make the contribution process as 7 | painless as possible for yourself and for the developers. 8 | 9 | 1. *Communicate.* please create an GitHub issue in the appropriate GitHub 10 | project communicating your plans. This allows coordination -- it's possible 11 | someone else has ideas about this topic and it can save a lot of time if 12 | things are disucssed before you dive in. When you submit your pull request 13 | please include the issue number with the discussion relevant to this pull 14 | request. 15 | 16 | 2. *Work on a branch.* Work on a branch in a fork of the project code. *DO NOT 17 | WORK ON `master` or `develop`.* 18 | 19 | 3. *Follow the style of the code.* All code must follow the style of the 20 | project. We generally adhere to the [Google JavaScript style 21 | guide](https://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml). 22 | Please lint your code with a reasonable linting tool. 23 | 24 | 4. *Create examples.* All new features must have appropriate examples in the 25 | examples directory. If you are adding a major feature you may wish to create a 26 | new example page. If you are adding a smaller feature you may just wish to 27 | augment one of the existing examples. 28 | 29 | 5. *Tests.* We currently evaluating how to test this library. In the mean time 30 | please be sure to check that all of the examples continue to work before 31 | submitting your pull request. If you have suggestions on how to build tests 32 | we'd love to hear them. 33 | 34 | The [jQuery guidlines](http://contribute.jquery.org/commits-and-pull-requests/) 35 | have some good suggestions for rectifying common Git mistakes 36 | 37 | Once you have you are ready to share your code go ahead and follow the 38 | instructions in the [GitHub 39 | docs](https://help.github.com/articles/using-pull-requests/) to submit your 40 | pull request. 41 | -------------------------------------------------------------------------------- /packages/react-dynamic-forms/tests/ChooserTests.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | import React from "react"; 12 | import { 13 | ChooserBasic, 14 | ChooserWider, 15 | ChooserSortedList, 16 | ChooserInitialValue, 17 | ChooserInitialNull, 18 | ChooserSortedInitial, 19 | ChooserDisabled, 20 | ChooserSearchDisabled, 21 | ChooserSingleDeselect, 22 | ChooserLongList 23 | } from "./components_test/ChooserExamples"; 24 | 25 | export default React.createClass({ 26 | render() { 27 | return ( 28 |
29 |
30 |
31 |

Chooser Tests

32 | Chooser with simple list 33 | 34 | Wider chooser 35 | 36 | Chooser with a sorted list 37 | 38 | Chooser with initial value 39 | 40 | Chooser with a null initial value 41 | 42 | Chooser with sorted list and initial value 43 | 44 | Disabled chooser 45 | 46 | Chooser with no search 47 | 48 | Chooser allowing clearing single selection 49 | 50 | Chooser with a very long list 51 | 52 |
53 |
54 |
55 | ); 56 | } 57 | }); 58 | -------------------------------------------------------------------------------- /packages/react-dynamic-forms/src/components/Field.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 - present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | import React from "react"; 12 | import invariant from "invariant"; 13 | import PropTypes from "prop-types"; 14 | 15 | /** 16 | * A `Field` is a part of the JSX definition of a `Schema`. Each `Field` describes 17 | * the rules and meta data associated with a field on the `Form`. 18 | * 19 | * For example, here is an `Field` which will input the users email address, defining 20 | * a user friendly label "Email", a placeholder and a validation rule that expects 21 | * the field to be a valid email address. The field is also required to be filled in. 22 | * 23 | * ``` 24 | * 25 | * ... 26 | * 32 | * ... 33 | * 34 | * ``` 35 | */ 36 | export default class Field extends React.Component { 37 | render() { 38 | invariant( 39 | false, 40 | `${this.constructor.name} elements are for schema configuration only and should not be rendered` 41 | ); 42 | return; 43 | } 44 | } 45 | 46 | Field.propTypes = { 47 | /** 48 | * name - The name of the field, or basically how it is referenced when rendering the field 49 | */ 50 | name: PropTypes.string, 51 | 52 | /** 53 | * label - The UI fieldly name of the field, used when constructing a `Group`. 54 | */ 55 | label: PropTypes.string, 56 | 57 | /** 58 | * placeholder - If appropiate to the widget, displays placeholder text. 59 | */ 60 | placeholder: PropTypes.string, 61 | 62 | /** 63 | * validation* - See [Revalidator](https://github.com/flatiron/revalidator) for possible formats 64 | * for the validation property. 65 | */ 66 | validation: PropTypes.object 67 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | "ESnet React Forms Library, Copyright (c) 2015-2017, The Regents of the 2 | University of California, through Lawrence Berkeley National Laboratory 3 | (subject to receipt of any required approvals from the U.S. Dept. of Energy). 4 | All rights reserved." 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | (1) Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | (2) Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation and/ 14 | or other materials provided with the distribution. 15 | 16 | (3) Neither the name of the University of California, Lawrence Berkeley 17 | National Laboratory, U.S. Dept. of Energy nor the names of its contributors may 18 | be used to endorse or promote products derived from this software without 19 | specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 22 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 25 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 28 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | You are under no obligation whatsoever to provide any bug fixes, patches, or 33 | upgrades to the features, functionality or performance of the source code 34 | ("Enhancements") to anyone; however, if you choose to make your Enhancements 35 | available either publicly, or directly to Lawrence Berkeley National 36 | Laboratory, without imposing a separate written license agreement for such 37 | Enhancements, then you hereby grant the following license: a non-exclusive, 38 | royalty-free perpetual license to install, use, modify, prepare derivative 39 | works, incorporate into other computer software, distribute, and sublicense 40 | such enhancements or derivative works thereof, in binary and source code form. -------------------------------------------------------------------------------- /packages/react-dynamic-forms/LICENSE: -------------------------------------------------------------------------------- 1 | "ESnet React Forms Library, Copyright (c) 2015-2017, The Regents of the 2 | University of California, through Lawrence Berkeley National Laboratory 3 | (subject to receipt of any required approvals from the U.S. Dept. of Energy). 4 | All rights reserved." 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | (1) Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | (2) Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation and/ 14 | or other materials provided with the distribution. 15 | 16 | (3) Neither the name of the University of California, Lawrence Berkeley 17 | National Laboratory, U.S. Dept. of Energy nor the names of its contributors may 18 | be used to endorse or promote products derived from this software without 19 | specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 22 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 25 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 28 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | You are under no obligation whatsoever to provide any bug fixes, patches, or 33 | upgrades to the features, functionality or performance of the source code 34 | ("Enhancements") to anyone; however, if you choose to make your Enhancements 35 | available either publicly, or directly to Lawrence Berkeley National 36 | Laboratory, without imposing a separate written license agreement for such 37 | Enhancements, then you hereby grant the following license: a non-exclusive, 38 | royalty-free perpetual license to install, use, modify, prepare derivative 39 | works, incorporate into other computer software, distribute, and sublicense 40 | such enhancements or derivative works thereof, in binary and source code form. -------------------------------------------------------------------------------- /packages/website/src/components/Guide.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2016-present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | import React, {Component} from "react"; 12 | import Markdown from "react-markdown"; 13 | import Prism from "prismjs"; 14 | 15 | import Guides from "../guides/guides"; 16 | import { codeRenderer, codeBlockRenderer } from "../renderers"; 17 | 18 | export default class extends Component { 19 | constructor(props) { 20 | super(props); 21 | this.state = { 22 | markdown: null 23 | }; 24 | } 25 | 26 | componentDidMount() { 27 | window.scrollTo(0, 0); 28 | Prism.highlightAll(); 29 | const guideName = this.props.match.params.doc || "intro"; 30 | const markdownFile = Guides[guideName]; 31 | fetch(markdownFile) 32 | .then(response => { 33 | return response.text(); 34 | }) 35 | .then(markdown => { 36 | this.setState({ markdown }); 37 | }); 38 | this.setState({ markdown: null }); 39 | } 40 | 41 | componentWillReceiveProps(nextProps) { 42 | window.scrollTo(0, 0); 43 | const guideName = nextProps.match.params.doc || "intro"; 44 | const markdownFile = Guides[guideName]; 45 | fetch(markdownFile) 46 | .then(response => { 47 | return response.text(); 48 | }) 49 | .then(markdown => { 50 | this.setState({ markdown }); 51 | }); 52 | this.setState({ markdown: null }); 53 | } 54 | 55 | componentDidUpdate() { 56 | Prism.highlightAll(); 57 | } 58 | 59 | render() { 60 | if (this.state.markdown !== null) { 61 | return ( 62 |
63 |
64 |
65 | 69 |
70 |
71 |
72 | ); 73 | } else { 74 | return ( 75 |
76 |
77 |
78 | ); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /packages/react-dynamic-forms/lib/css/list.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 - present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | /* 12 | * The container includes the whole list, but not the [+] at the bottom 13 | */ 14 | .esnet-forms-listeditview-container { 15 | padding-left: 0px; 16 | list-style-type: none; 17 | margin-bottom: 0px; 18 | } 19 | 20 | .esnet-forms-listeditview-container:last-child { 21 | margin-bottom: 0; 22 | } 23 | 24 | /* 25 | * The inner LI of the container is each item, including the [-] control 26 | */ 27 | 28 | .esnet-forms-listeditview-container li { 29 | margin-left: 0px; 30 | } 31 | 32 | /* 33 | * The main styling for each item 34 | */ 35 | 36 | .esnet-forms-listeditview-edit-item { 37 | width: 95%; 38 | margin-bottom: 10px; 39 | padding-top: 2px; 40 | } 41 | 42 | .esnet-forms-listeditview-edit-item.no-controls { 43 | width: 95%; 44 | } 45 | 46 | /* 47 | .esnet-forms-minus-action-box { 48 | float: left; 49 | margin-top: 5px; 50 | vertical-align: top; 51 | width: 28px; 52 | height: 28px; 53 | background: #EDEDED; 54 | margin-left: -5px; 55 | z-index: 10; 56 | border: #E5E5E5; 57 | border-style: solid; 58 | border-width: 1px; 59 | border-radius: 2px; 60 | }*/ 61 | 62 | .esnet-forms-plus-action-box-dialog { 63 | clear: both; 64 | border-width: 1px; 65 | border-color: #cef4d2; 66 | border-style: solid; 67 | border-radius: 4px; 68 | padding: 10px; 69 | height: 70px; 70 | width: 95%; 71 | background: #efe; 72 | } 73 | 74 | /* 75 | List transitions 76 | */ 77 | 78 | .esnet-forms-list { 79 | font-size: 12px; 80 | } 81 | 82 | /** start of entering and end of leaving **/ 83 | li.esnet-forms-list-item-enter, 84 | li.esnet-forms-list-item-leave.esnet-forms-list-item-leave-active { 85 | opacity: 0.01; 86 | max-height: 0px; 87 | } 88 | 89 | /** start of leaving and end of entering **/ 90 | li.esnet-forms-list-item-leave, 91 | li.esnet-forms-list-item-enter.esnet-forms-list-item-enter-active { 92 | opacity: 1; 93 | max-height: 100px; 94 | /*max-height: 50px;*/ 95 | } 96 | 97 | /** ease in out quint **/ 98 | li.esnet-forms-list-item-enter, 99 | li.esnet-forms-list-item-leave { 100 | -moz-transition: all 100ms ease 0s; 101 | -webkit-transition: all 100ms ease 0s; 102 | transition: all 100ms ease 0s; 103 | } 104 | -------------------------------------------------------------------------------- /packages/react-dynamic-forms/src/css/list.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 - present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | /* 12 | * The container includes the whole list, but not the [+] at the bottom 13 | */ 14 | .esnet-forms-listeditview-container { 15 | padding-left: 0px; 16 | list-style-type: none; 17 | margin-bottom: 0px; 18 | } 19 | 20 | .esnet-forms-listeditview-container:last-child { 21 | margin-bottom: 0; 22 | } 23 | 24 | /* 25 | * The inner LI of the container is each item, including the [-] control 26 | */ 27 | 28 | .esnet-forms-listeditview-container li { 29 | margin-left: 0px; 30 | } 31 | 32 | /* 33 | * The main styling for each item 34 | */ 35 | 36 | .esnet-forms-listeditview-edit-item { 37 | width: 95%; 38 | margin-bottom: 10px; 39 | padding-top: 2px; 40 | } 41 | 42 | .esnet-forms-listeditview-edit-item.no-controls { 43 | width: 95%; 44 | } 45 | 46 | /* 47 | .esnet-forms-minus-action-box { 48 | float: left; 49 | margin-top: 5px; 50 | vertical-align: top; 51 | width: 28px; 52 | height: 28px; 53 | background: #EDEDED; 54 | margin-left: -5px; 55 | z-index: 10; 56 | border: #E5E5E5; 57 | border-style: solid; 58 | border-width: 1px; 59 | border-radius: 2px; 60 | }*/ 61 | 62 | .esnet-forms-plus-action-box-dialog { 63 | clear: both; 64 | border-width: 1px; 65 | border-color: #cef4d2; 66 | border-style: solid; 67 | border-radius: 4px; 68 | padding: 10px; 69 | height: 70px; 70 | width: 95%; 71 | background: #efe; 72 | } 73 | 74 | /* 75 | List transitions 76 | */ 77 | 78 | .esnet-forms-list { 79 | font-size: 12px; 80 | } 81 | 82 | /** start of entering and end of leaving **/ 83 | li.esnet-forms-list-item-enter, 84 | li.esnet-forms-list-item-leave.esnet-forms-list-item-leave-active { 85 | opacity: 0.01; 86 | max-height: 0px; 87 | } 88 | 89 | /** start of leaving and end of entering **/ 90 | li.esnet-forms-list-item-leave, 91 | li.esnet-forms-list-item-enter.esnet-forms-list-item-enter-active { 92 | opacity: 1; 93 | max-height: 100px; 94 | /*max-height: 50px;*/ 95 | } 96 | 97 | /** ease in out quint **/ 98 | li.esnet-forms-list-item-enter, 99 | li.esnet-forms-list-item-leave { 100 | -moz-transition: all 100ms ease 0s; 101 | -webkit-transition: all 100ms ease 0s; 102 | transition: all 100ms ease 0s; 103 | } 104 | -------------------------------------------------------------------------------- /docs/static/media/intro.fda87512.md: -------------------------------------------------------------------------------- 1 | ## Introduction 2 | 3 | --- 4 | 5 | This repository contains a set of React based forms components which are used within ESnet for our network database application (ESDB), but could be used by any React based project needing to build complex forms. 6 | 7 | Our approach is to treat a form as a controlled input, essentially an input with many inputs (which may have many inputs, and so on...) You maintain your form's state however you want, you pass that state down into the form as its value prop. If the form is edited, a callback is called and you can update your form state. When it comes time to save the form, that's up to you, you always have your form's state. On top of this the form has a schema defining rules. Therefore, you can also listen to changes in the count of either missing values or errors. With this information it is simple to control if the user can submit the form as well. 8 | 9 | The library is built on Immutable.js, so form state should be passed into the form as an Immutable.Map. This allows efficient operations on your form data, minimizing copying while ensuring safety as the form state is mutated. 10 | 11 | While part of defining a form is to specify a schema for your form, you still maintain complete control over the layout in the form in your `render()` method, just like any other react app. The schema and presentation are entirely separate. This React friendly approach makes it easy to build forms which dynamically change values or structure based on the current state of the form. 12 | 13 | This library contains: 14 | 15 | * Low level forms control wrappers that communicate errors and missing values to parent components and style themselves appropriately for errors and missing value state. You can write your own in the same way. Supplied standard form controls: 16 | * Textedit 17 | * TextArea 18 | * Checkboxes 19 | * RadioButtons 20 | * Chooser (internally we use react-select) 21 | * TagsEdit (again using react-select) 22 | * DateEdit (react-datepicker) 23 | * A `` component that lets you define the rules for each field. Each field is specified in a `` component 24 | * A `` component that acts as a top level controlled input for all of the form state, to assemble controls together and track state change, errors and missing values and enabling dynamic forms with via a declarative schema 25 | * Higher Order Components: 26 | * for grouping of controls with their labels, required state and editing control 27 | * building lists of forms 28 | * Inline editing 29 | * List editing 30 | 31 | The library is built on several other open source libraries, especially: 32 | 33 | * react 34 | * immutable.js 35 | * revalidator 36 | * react-bootstrap 37 | * react-select 38 | * react-virtualized 39 | * react-datepicker 40 | 41 | Please browse the examples for a feel for the library, or read on to get started. 42 | -------------------------------------------------------------------------------- /packages/website/src/guides/intro.md: -------------------------------------------------------------------------------- 1 | ## Introduction 2 | 3 | --- 4 | 5 | This repository contains a set of React based forms components which are used within ESnet for our network database application (ESDB), but could be used by any React based project needing to build complex forms. 6 | 7 | Our approach is to treat a form as a controlled input, essentially an input with many inputs (which may have many inputs, and so on...) You maintain your form's state however you want, you pass that state down into the form as its value prop. If the form is edited, a callback is called and you can update your form state. When it comes time to save the form, that's up to you, you always have your form's state. On top of this the form has a schema defining rules. Therefore, you can also listen to changes in the count of either missing values or errors. With this information it is simple to control if the user can submit the form as well. 8 | 9 | The library is built on Immutable.js, so form state should be passed into the form as an Immutable.Map. This allows efficient operations on your form data, minimizing copying while ensuring safety as the form state is mutated. 10 | 11 | While part of defining a form is to specify a schema for your form, you still maintain complete control over the layout in the form in your `render()` method, just like any other react app. The schema and presentation are entirely separate. This React friendly approach makes it easy to build forms which dynamically change values or structure based on the current state of the form. 12 | 13 | This library contains: 14 | 15 | * Low level forms control wrappers that communicate errors and missing values to parent components and style themselves appropriately for errors and missing value state. You can write your own in the same way. Supplied standard form controls: 16 | * Textedit 17 | * TextArea 18 | * Checkboxes 19 | * RadioButtons 20 | * Chooser (internally we use react-select) 21 | * TagsEdit (again using react-select) 22 | * DateEdit (react-datepicker) 23 | * A `` component that lets you define the rules for each field. Each field is specified in a `` component 24 | * A `` component that acts as a top level controlled input for all of the form state, to assemble controls together and track state change, errors and missing values and enabling dynamic forms with via a declarative schema 25 | * Higher Order Components: 26 | * for grouping of controls with their labels, required state and editing control 27 | * building lists of forms 28 | * Inline editing 29 | * List editing 30 | 31 | The library is built on several other open source libraries, especially: 32 | 33 | * react 34 | * immutable.js 35 | * revalidator 36 | * react-bootstrap 37 | * react-select 38 | * react-virtualized 39 | * react-datepicker 40 | 41 | Please browse the examples for a feel for the library, or read on to get started. 42 | -------------------------------------------------------------------------------- /packages/website/src/Header.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | import React, { Component } from "react"; 12 | import logo from "./img/forms.png"; 13 | import githubLogo from "./img/github.png"; 14 | 15 | /* eslint-disable jsx-a11y/href-no-hash */ 16 | 17 | export default class Header extends Component { 18 | render() { 19 | const githubLogoStyle = { 20 | width: 24, 21 | paddingRight: 5, 22 | marginTop: -4 23 | }; 24 | return ( 25 | 66 | ); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /packages/react-dynamic-forms/src/components/RadioButtons.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 - present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | import React from "react"; 12 | import _ from "underscore"; 13 | 14 | import formGroup from "../js/formGroup"; 15 | 16 | class RadioButtons extends React.Component { 17 | handleChange(v) { 18 | // Callbacks 19 | if (this.props.onChange) { 20 | this.props.onChange(this.props.name, v); 21 | } 22 | if (this.props.onBlur) { 23 | this.props.onBlur(this.props.name); 24 | } 25 | } 26 | 27 | getCurrentChoiceLabel() { 28 | const choiceItem = this.props.optionList.find(item => { 29 | return item.get("id") === this.props.value; 30 | }); 31 | return choiceItem ? choiceItem.get("label") : ""; 32 | } 33 | 34 | inlineStyle(hasError, isMissing) { 35 | let color = "inherited"; 36 | let background = "inherited"; 37 | if (hasError) { 38 | color = "#b94a48"; 39 | background = "#fff0f3"; 40 | } else if (isMissing) { 41 | background = "floralwhite"; 42 | } 43 | return { 44 | color, 45 | background, 46 | width: "100%", 47 | paddingLeft: 3 48 | }; 49 | } 50 | 51 | render() { 52 | if (this.props.edit) { 53 | const items = this.props.optionList.map((item, i) => { 54 | const id = item.get("id"); 55 | const label = item.get("label"); 56 | return ( 57 |
58 | 69 |
70 | ); 71 | }); 72 | return ( 73 |
74 | {items} 75 |
76 | ); 77 | } else { 78 | let text = this.getCurrentChoiceLabel(); 79 | return ( 80 |
81 | {text} 82 |
83 | ); 84 | } 85 | } 86 | } 87 | 88 | RadioButtons.defaultProps = { 89 | width: 300 90 | }; 91 | 92 | export default formGroup(RadioButtons); 93 | -------------------------------------------------------------------------------- /packages/react-dynamic-forms/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-dynamic-forms", 3 | "version": "1.0.3", 4 | "description": "Dynamic forms library for React", 5 | "keywords": [ 6 | "forms", 7 | "dynamic", 8 | "react" 9 | ], 10 | "main": "lib/index.js", 11 | "author": "ESnet SEG ", 12 | "bugs": { 13 | "url": "https://github.com/esnet/esnet-react-forms/issues" 14 | }, 15 | "scripts": { 16 | "docs": "echo \"*** Building API docs\n\" && react-docgen src/components -x js -o ../website/src/api/docs.json --pretty", 17 | "lint": "eslint src/components/*.js", 18 | "test": "npm run lint", 19 | "build": "echo \"*** Building lib\n\" && rm -rf lib/* && babel src/components --optional runtime --stage 0 --out-dir lib/components && mkdir lib/css && cp ./src/css/*.css ./lib/css/ && babel src/js --optional runtime --stage 0 --out-dir lib/js && babel src/index.js --optional runtime --stage 0 --out-file lib/index.js", 20 | "start-website": "react-scripts start", 21 | "build-website": "echo \"*** Building website\n\" && rm -rf docs && react-scripts build && mv build docs", 22 | "precommit": "lint-staged", 23 | "prettier": "prettier --print-width 100 --tab-width 4 --write \"src/**/*.js\"" 24 | }, 25 | "lint-staged": { 26 | "*.js": [ 27 | "prettier --print-width 100 --tab-width 4 --write", 28 | "git add" 29 | ] 30 | }, 31 | "pre-commit": [ 32 | "lint", 33 | "build" 34 | ], 35 | "license": "BSD-3-Clause-LBNL", 36 | "peerDependencies": { 37 | "react": "^16.2.0", 38 | "react-dom": "^16.2.0" 39 | }, 40 | "dependencies": { 41 | "classnames": "^2.1.3", 42 | "deepcopy": "^0.6.3", 43 | "flexbox-react": "^4.2.1", 44 | "immutable": "^3.8.1", 45 | "invariant": "^2.2.3", 46 | "keymirror": "^0.1.1", 47 | "moment": "^2.21.0", 48 | "react-datepicker": "^1.2.2", 49 | "react-transition-group": "^1.0.0", 50 | "react-virtualized": "^9.18.5", 51 | "react-virtualized-select": "^3.1.3", 52 | "revalidator": "^0.3.1", 53 | "underscore": "^1.8.3" 54 | }, 55 | "devDependencies": { 56 | "babel-cli": "^6.5.1", 57 | "babel-core": "^6.5.2", 58 | "babel-loader": "^7.1.4", 59 | "babel-plugin-transform-class-properties": "^6.22.0", 60 | "babel-preset-es2015": "^6.5.0", 61 | "babel-preset-react": "^6.5.0", 62 | "babel-preset-stage-0": "^6.5.0", 63 | "chance": "^1.0.6", 64 | "enzyme": "3.3.0", 65 | "enzyme-to-json": "3.3.1", 66 | "eslint-config-prettier": "^2.9.0", 67 | "eslint-config-react-app": "^2.1.0", 68 | "lint-staged": "^7.0.0", 69 | "prettier": "^1.11.1", 70 | "prop-types": "^15.6.1", 71 | "react": "^16.2.0", 72 | "react-docgen": "^2.20.1", 73 | "react-dom": "^16.2.0", 74 | "react-scripts": "^1.1.1", 75 | "react-select": "^1.2.1", 76 | "react-test-renderer": "^16.2.0" 77 | }, 78 | "eslintConfig": { 79 | "extends": "react-app" 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /packages/react-dynamic-forms/lib/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.FormGroupLayout = exports.FormEditStates = exports.View = exports.CheckBoxes = exports.RadioButtons = exports.TagsEdit = exports.DateEdit = exports.Chooser = exports.TextArea = exports.TextEdit = exports.List = exports.formList = exports.formGroup = exports.Field = exports.Schema = exports.Form = undefined; 7 | 8 | var _Form = require("./components/Form"); 9 | 10 | var _Form2 = _interopRequireDefault(_Form); 11 | 12 | var _Schema = require("./components/Schema"); 13 | 14 | var _Schema2 = _interopRequireDefault(_Schema); 15 | 16 | var _Field = require("./components/Field"); 17 | 18 | var _Field2 = _interopRequireDefault(_Field); 19 | 20 | var _formGroup = require("./js/formGroup"); 21 | 22 | var _formGroup2 = _interopRequireDefault(_formGroup); 23 | 24 | var _formList = require("./js/formList"); 25 | 26 | var _formList2 = _interopRequireDefault(_formList); 27 | 28 | var _List = require("./components/List"); 29 | 30 | var _List2 = _interopRequireDefault(_List); 31 | 32 | var _TextEdit = require("./components/TextEdit"); 33 | 34 | var _TextEdit2 = _interopRequireDefault(_TextEdit); 35 | 36 | var _TextArea = require("./components/TextArea"); 37 | 38 | var _TextArea2 = _interopRequireDefault(_TextArea); 39 | 40 | var _Chooser = require("./components/Chooser.js"); 41 | 42 | var _Chooser2 = _interopRequireDefault(_Chooser); 43 | 44 | var _DateEdit = require("./components/DateEdit"); 45 | 46 | var _DateEdit2 = _interopRequireDefault(_DateEdit); 47 | 48 | var _TagsEdit = require("./components/TagsEdit"); 49 | 50 | var _TagsEdit2 = _interopRequireDefault(_TagsEdit); 51 | 52 | var _RadioButtons = require("./components/RadioButtons"); 53 | 54 | var _RadioButtons2 = _interopRequireDefault(_RadioButtons); 55 | 56 | var _CheckBoxes = require("./components/CheckBoxes"); 57 | 58 | var _CheckBoxes2 = _interopRequireDefault(_CheckBoxes); 59 | 60 | var _View = require("./components/View"); 61 | 62 | var _View2 = _interopRequireDefault(_View); 63 | 64 | var _constants = require("./js/constants"); 65 | 66 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 67 | 68 | exports.Form = _Form2.default; /** 69 | * Copyright (c) 2015 - present, The Regents of the University of California, 70 | * through Lawrence Berkeley National Laboratory (subject to receipt 71 | * of any required approvals from the U.S. Dept. of Energy). 72 | * All rights reserved. 73 | * 74 | * This source code is licensed under the BSD-style license found in the 75 | * LICENSE file in the root directory of this source tree. 76 | */ 77 | 78 | exports.Schema = _Schema2.default; 79 | exports.Field = _Field2.default; 80 | exports.formGroup = _formGroup2.default; 81 | exports.formList = _formList2.default; 82 | exports.List = _List2.default; 83 | exports.TextEdit = _TextEdit2.default; 84 | exports.TextArea = _TextArea2.default; 85 | exports.Chooser = _Chooser2.default; 86 | exports.DateEdit = _DateEdit2.default; 87 | exports.TagsEdit = _TagsEdit2.default; 88 | exports.RadioButtons = _RadioButtons2.default; 89 | exports.CheckBoxes = _CheckBoxes2.default; 90 | exports.View = _View2.default; 91 | exports.FormEditStates = _constants.FormEditStates; 92 | exports.FormGroupLayout = _constants.FormGroupLayout; 93 | -------------------------------------------------------------------------------- /packages/website/src/components/Example.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2016-present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | import React, {Component} from "react"; 12 | import Markdown from "react-markdown"; 13 | 14 | import Examples from "../examples/examples.js"; 15 | // import Meta from "../examples/examples.json"; 16 | 17 | import Prism from "prismjs"; 18 | import { codeRenderer, codeBlockRenderer } from "../renderers"; 19 | 20 | export default class extends Component { 21 | constructor(props) { 22 | super(props); 23 | this.state = { 24 | markdown: null 25 | }; 26 | } 27 | 28 | fetchMarkdownForProps(props) { 29 | window.scrollTo(0, 0); 30 | const exampleName = props.match.params.example; 31 | const markdownFile = Examples[`${exampleName}_docs`]; 32 | fetch(markdownFile) 33 | .then(response => { 34 | return response.text(); 35 | }) 36 | .then(markdown => { 37 | this.setState({ markdown }); 38 | }); 39 | } 40 | 41 | componentDidMount() { 42 | Prism.highlightAll(); 43 | this.fetchMarkdownForProps(this.props); 44 | } 45 | 46 | componentWillReceiveProps(nextProps) { 47 | this.fetchMarkdownForProps(nextProps); 48 | } 49 | 50 | componentDidUpdate() { 51 | Prism.highlightAll(); 52 | } 53 | 54 | renderMarkdown() { 55 | if (this.state.markdown) { 56 | return ( 57 |
58 |
59 | 63 |
64 |
65 | ); 66 | } else { 67 | return ( 68 |
69 |
70 | Loading... 71 |
72 |
73 | ); 74 | } 75 | } 76 | 77 | render() { 78 | /* const tagStyle = { 79 | background: "#EEE", 80 | padding: 5, 81 | borderRadius: 2, 82 | margin: 2, 83 | fontSize: "smaller" 84 | }; */ 85 | 86 | const exampleName = this.props.match.params.example; 87 | // const ExampleMetaData = Meta[exampleName]; 88 | const Component = Examples[exampleName]; 89 | // const Link = Meta[exampleName].link; 90 | // const sourceCode = `https://github.com/esnet/react-dynamic-forms/tree/inline-editing-layouts2/src/website/examples/${Link}.js`; 91 | 92 | return ( 93 |
94 |
95 |
96 | 97 |
98 | {this.renderMarkdown()} 99 |
100 |
101 |
102 | ); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /packages/react-dynamic-forms/src/components/CheckBoxes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 - present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | import React from "react"; 12 | import _ from "underscore"; 13 | import Immutable from "immutable"; 14 | 15 | import formGroup from "../js/formGroup"; 16 | 17 | /** 18 | * Form control to select multiple items from a list, 19 | * uses checkboxes next to each item. 20 | */ 21 | class CheckBoxes extends React.Component { 22 | componentWillReceiveProps(nextProps) { 23 | if (this.props.value !== nextProps.value) { 24 | const missingCount = this.isMissing(nextProps.value) ? 1 : 0; 25 | if (this.props.onMissingCountChange) { 26 | this.props.onMissingCountChange(this.props.name, missingCount); 27 | } 28 | } 29 | } 30 | 31 | handleChange(i) { 32 | let value; 33 | const option = this.props.optionList.get(i); 34 | if (this.props.value.includes(option)) { 35 | value = this.props.value.filterNot(item => item === option); 36 | } else { 37 | value = this.props.value.push(option); 38 | } 39 | if (this.props.onChange) { 40 | this.props.onChange(this.props.name, value); 41 | } 42 | } 43 | 44 | isEmpty(value) { 45 | if (Immutable.List.isList(value)) { 46 | return value.size === 0; 47 | } 48 | return _.isNull(value) || _.isUndefined(value); 49 | } 50 | 51 | isMissing(value = this.props.value) { 52 | return this.props.required && !this.props.disabled && this.isEmpty(value); 53 | } 54 | 55 | inlineStyle(hasError, isMissing) { 56 | let color = "inherited"; 57 | let background = "inherited"; 58 | if (hasError) { 59 | color = "#b94a48"; 60 | background = "#fff0f3"; 61 | } else if (isMissing) { 62 | background = "floralwhite"; 63 | } 64 | return { 65 | color, 66 | background, 67 | width: "100%", 68 | paddingLeft: 3 69 | }; 70 | } 71 | 72 | render() { 73 | if (this.props.edit) { 74 | const items = []; 75 | this.props.optionList.forEach((option, i) => { 76 | items.push( 77 |
78 | 86 |
87 | ); 88 | }); 89 | 90 | return ( 91 |
92 | {items} 93 |
94 | ); 95 | } else { 96 | return ( 97 |
98 | {this.props.value.join(", ")} 99 |
100 | ); 101 | } 102 | } 103 | } 104 | 105 | export default formGroup(CheckBoxes); 106 | -------------------------------------------------------------------------------- /packages/website/src/App.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | body { 12 | padding: 0; 13 | margin: 0; 14 | overflow: hidden; 15 | } 16 | 17 | h2 { 18 | font-size: 27px; 19 | font-weight: 400; 20 | color: #333; 21 | } 22 | 23 | h4 { 24 | padding-top: 20px; 25 | } 26 | 27 | /* react-select dropdown conflicts with Bootstrap controls */ 28 | 29 | .list-group-item.active, 30 | .list-group-item.active:focus, 31 | .list-group-item.active:hover { 32 | z-index: 0; 33 | } 34 | 35 | /* Hamburger sidebar expander */ 36 | 37 | .sidebar-icon { 38 | font-size: 25px; 39 | margin-right: 45px; 40 | color: #a4a4a4; 41 | } 42 | 43 | .sidebar-icon:hover, 44 | .sidebar-icon.active { 45 | color: #4ec1e0; 46 | } 47 | 48 | .sidebar-link { 49 | display: block; 50 | font-weight: 500; 51 | font-family: "Open Sans Condensed", sans-serif; 52 | font-size: 14px; 53 | padding: 5px 0px; 54 | color: #757575; 55 | text-decoration: none; 56 | cursor: pointer; 57 | } 58 | 59 | .sidebar-link:hover { 60 | color: #4ec1e0; 61 | text-decoration: none; 62 | cursor: hand; 63 | } 64 | 65 | .sidebar-link.active { 66 | color: #4ec1e0; 67 | font-weight: 700; 68 | text-decoration: none; 69 | } 70 | 71 | /* Header customization */ 72 | 73 | .navbar { 74 | height: 80px; 75 | background: -webkit-gradient( 76 | linear, 77 | left top, 78 | left bottom, 79 | color-stop(0, #fafafa), 80 | color-stop(1, #f5f5f5) 81 | ); 82 | background: linear-gradient(to bottom, #fafafa, #f5f5f5); 83 | border-bottom: 1px solid #eee; 84 | border-top: 1px solid #eee; 85 | } 86 | 87 | .navbar-brand { 88 | font-family: "Open Sans", sans-serif; 89 | font-weight: 700; 90 | font-size: 32px; 91 | color: #6d6e71; 92 | } 93 | 94 | /* ESnet fasterdata and ESnet main site links */ 95 | 96 | .tools-links > li:first-child a { 97 | border-left: 0; 98 | } 99 | 100 | .tools-links > li > a { 101 | text-align: left; 102 | font-size: 14px; 103 | margin-top: 20px; 104 | padding: 8px 10px; 105 | background-color: #6d6e71; 106 | border-left: 1px solid #fff; 107 | color: #fff; 108 | width: 119px; 109 | height: 34px; 110 | display: block; 111 | } 112 | 113 | .tools-links { 114 | margin-right: 10px !important; 115 | list-style-type: none; 116 | padding: 0; 117 | margin: 0; 118 | font-family: "Open Sans", sans-serif; 119 | font-weight: 700; 120 | text-align: right; 121 | font-size: 0; 122 | } 123 | 124 | .tools-links > li a.selected, 125 | .tools-links > li a:hover { 126 | background-color: #4ec1e0 !important; 127 | } 128 | 129 | /* Navigation pills altered to look like the links above */ 130 | 131 | .nav-pills > li.active > a, 132 | .nav-pills > li.active > a:focus, 133 | .nav-pills > li.active > a:hover { 134 | background-color: #8c8d93 !important; 135 | } 136 | 137 | .nav-pills > li > a { 138 | border-radius: 0px !important; 139 | } 140 | 141 | .nav > li > a { 142 | padding: 7px 15px; 143 | } 144 | 145 | /* Hide the footer on small screens */ 146 | @media (max-width: 600px) { 147 | .footer { 148 | display: none; 149 | } 150 | } 151 | 152 | .scrollable::-webkit-scrollbar { 153 | display: none; 154 | } 155 | -------------------------------------------------------------------------------- /packages/website/src/components/API.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | /* eslint max-len:0 */ 12 | 13 | import React, {Component} from "react"; 14 | import { Link } from "react-router-dom"; 15 | import _ from "underscore"; 16 | import Flexbox from "flexbox-react"; 17 | 18 | import Prism from "prismjs"; 19 | import APIDoc from "./APIDoc"; 20 | 21 | import Meta from "../examples/examples.json"; 22 | import Examples from "../examples/examples.js"; 23 | import docsFile from "../api/docs.json"; 24 | 25 | import { headingStyle } from "../styles"; 26 | 27 | class Example extends Component { 28 | render() { 29 | const style = { 30 | display: "inline-block", 31 | margin: 5, 32 | padding: 20, 33 | borderStyle: "solid", 34 | borderWidth: 1, 35 | borderColor: "#DDD", 36 | width: 160, 37 | height: 160 38 | }; 39 | const { example } = this.props; 40 | const name = example.key; 41 | const imgName = `${name}_thumbnail`; 42 | const img = Examples[imgName]; 43 | const link = {example.value.title}; 44 | return ( 45 | 46 |
47 | {`${name}`} 48 |
49 |
50 | {link} 51 |
52 |
53 | ); 54 | } 55 | }; 56 | 57 | class TaggedExamples extends Component { 58 | render() { 59 | const exampleList = []; 60 | _.forEach(Meta, (value, key) => { 61 | const tags = value.tags; 62 | if (_.contains(tags, this.props.tag)) { 63 | exampleList.push({ key, value }); 64 | } 65 | }); 66 | const examples = exampleList.map((example, i) => { 67 | return ; 68 | }); 69 | 70 | if (examples.length > 0) { 71 | return ( 72 |
73 |

Examples

74 | 75 | {examples} 76 | 77 |
78 | ); 79 | } else { 80 | return
; 81 | } 82 | } 83 | }; 84 | 85 | export default class extends Component { 86 | componentDidMount() { 87 | Prism.highlightAll(); 88 | } 89 | 90 | componentDidUpdate() { 91 | Prism.highlightAll(); 92 | } 93 | 94 | render() { 95 | const component = this.props.match.params.component; 96 | const path = `src/components/${component}.js`; 97 | 98 | if (!_.has(docsFile, path)) { 99 | return
API could not be found
; 100 | } 101 | const title = component; 102 | return ( 103 |
104 |
105 |
106 |

{`${title}`}

107 | 108 | 109 |
110 |
111 |
112 | ); 113 | } 114 | } 115 | 116 | -------------------------------------------------------------------------------- /packages/website/src/styles.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | export const sidebarStyle = { 12 | position: "fixed", 13 | right: 0, 14 | top: 80, 15 | width: 250, 16 | bottom: 0, 17 | overflowY: "auto", 18 | background: "#FEFEFE", 19 | color: "#4183C4", 20 | textDecoration: "none", 21 | borderWidth: 1, 22 | borderLeftStyle: "solid", 23 | borderLeftColor: "#ddd", 24 | marginLeft: 40 25 | }; 26 | 27 | export const sidebarTitleStyle = { 28 | textTransform: "uppercase", 29 | letterSpacing: ".08em", 30 | color: "#5c666f", 31 | fontSize: 13, 32 | fontWeight: 500, 33 | marginBottom: 15, 34 | marginTop: 30, 35 | padding: "0 20px" 36 | }; 37 | 38 | export const sidebarItemStyle = { 39 | fontFamily: "fakt-web,Helvetica Neue,Hevetica,sans-serif", 40 | fontSize: 14, 41 | fontWeight: 400, 42 | letterSpacing: 0, 43 | padding: "10px 20px", 44 | color: "#5c666f" 45 | }; 46 | 47 | export const activeStyle = { 48 | color: "black", 49 | textDecoration: "none" 50 | }; 51 | 52 | export const activeLinkStyle = { 53 | color: "#626466", 54 | fontWeight: "bold" 55 | }; 56 | 57 | export const bodyStyle = { 58 | marginTop: 100, 59 | marginRight: 300, 60 | display: "flex", 61 | minHeight: "100vh", 62 | flexDirection: "column", 63 | overflowY: "hidden" 64 | }; 65 | 66 | export const mainStyle = { 67 | display: "flex", 68 | flex: 1, 69 | marginLeft: 20, 70 | marginRight: 40 71 | }; 72 | 73 | export const footerStyle = { 74 | flex: "none", 75 | height: 10, 76 | background: "#DDD" 77 | }; 78 | 79 | export const contentStyle = { 80 | flex: 1 81 | }; 82 | 83 | export const githubLogoStyle = { 84 | width: 24, 85 | paddingRight: 5, 86 | marginTop: -4 87 | }; 88 | 89 | export const linkStyle = { 90 | color: "#4183C4", 91 | textDecoration: "none" 92 | }; 93 | 94 | export const discussionStyle = { 95 | color: "#555", 96 | fontSize: 18, 97 | letterSpacing: ".25ch", 98 | lineHeight: "16px", 99 | margin: "1rem 0 .125rem", 100 | textTransform: "uppercase" 101 | }; 102 | 103 | export const groupStyle = { 104 | color: "#9A9C9E", 105 | // fontSize: 12, 106 | fontSize: "1.5em", 107 | fontWeight: 300, 108 | margin: "2rem 0 2rem" 109 | }; 110 | 111 | export const headingStyle = { 112 | fontFamily: 'fakt-web, "Helvetica Neue", Hevetica, sans-serif', 113 | fontSize: 32, 114 | fontWeight: 500, 115 | lineHeight: "72px", 116 | color: "#000" 117 | }; 118 | 119 | export const methodHeadingStyle = { 120 | fontFamily: 'fakt-web, "Helvetica Neue", Hevetica, sans-serif', 121 | fontSize: 24, 122 | fontWeight: 500, 123 | lineHeight: "26px", 124 | color: "#000" 125 | }; 126 | 127 | export const textStyle = { 128 | color: "#626466", 129 | fontFamily: 'fakt-web, "Helvetica Neue", Hevetica, sans-serif', 130 | fontSize: 14, 131 | lineHeight: "28px", 132 | padding: "3px 0px 0px 0px" 133 | }; 134 | 135 | export const codeStyle = { 136 | backgroundColor: "rgb(245, 247, 249)", 137 | borderBottomLeftRadius: 3, 138 | borderBottomRightRadius: 3, 139 | borderTopLeftRadius: 3, 140 | borderTopRightRadius: 3, 141 | borderCollapse: "collapse", 142 | color: "rgba(0, 0, 0, 0.86)", 143 | fontFamily: "'Roboto Mono', Menlo, Monaco, Consolas, 'Courier New', monospace", 144 | fontSize: 12.6, 145 | lineHeight: "25.2px", 146 | paddingBottom: 2, 147 | paddingLeft: 6, 148 | paddingRight: 6, 149 | paddingTop: 0 150 | }; 151 | -------------------------------------------------------------------------------- /docs/static/media/list_docs.12101c16.md: -------------------------------------------------------------------------------- 1 | ### List example 2 | 3 | The first step is to render a form for entering an email address. In the case of this example we do have a little form that asks for the email address and email type. In that case we specify a schema and a form component to render that form: 4 | 5 | const schema = ( 6 | 7 | 14 | 15 | 16 | ); 17 | 18 | /** 19 | * Renders a form for entering an email address 20 | */ 21 | class EmailForm extends React.Component { 22 | 23 | renderForm() { 24 | const id = this.value("email_type"); 25 | return ( 26 |
34 | 40 | 41 | 42 | ); 43 | } 44 | }; 45 | 46 | const EmailList = formList(EmailForm); 47 | const Emails = formGroup(EmailList); 48 | 49 | Having defined that, we can now create a form to edit a contact: 50 | 51 | class ContactForm extends React.Component { 52 | 53 | schema() { 54 | return ( 55 | 56 | 63 | 70 | 71 | 72 | ); 73 | } 74 | 75 | render() { 76 | const disableSubmit = false; 77 | const style = { background: "#FAFAFA", padding: 10, borderRadius: 5 }; 78 | const { value } = this.props; 79 | const emails = value.get("emails"); 80 | 81 | return ( 82 |
this.handleChange(fieldName, value)} 90 | onMissingCountChange={(form, missing) => 91 | this.handleMissingCountChange(form, missing)} 92 | onErrorCountChange={(form, errors) => this.handleErrorCountChange(form, errors)} 93 | > 94 | 95 | 96 | 97 |
98 | 99 | ); 100 | } 101 | 102 | }); 103 | --- -------------------------------------------------------------------------------- /packages/website/src/examples/list/list_docs.md: -------------------------------------------------------------------------------- 1 | ### List example 2 | 3 | The first step is to render a form for entering an email address. In the case of this example we do have a little form that asks for the email address and email type. In that case we specify a schema and a form component to render that form: 4 | 5 | const schema = ( 6 | 7 | 14 | 15 | 16 | ); 17 | 18 | /** 19 | * Renders a form for entering an email address 20 | */ 21 | class EmailForm extends React.Component { 22 | 23 | renderForm() { 24 | const id = this.value("email_type"); 25 | return ( 26 |
34 | 40 | 41 | 42 | ); 43 | } 44 | }; 45 | 46 | const EmailList = formList(EmailForm); 47 | const Emails = formGroup(EmailList); 48 | 49 | Having defined that, we can now create a form to edit a contact: 50 | 51 | class ContactForm extends React.Component { 52 | 53 | schema() { 54 | return ( 55 | 56 | 63 | 70 | 71 | 72 | ); 73 | } 74 | 75 | render() { 76 | const disableSubmit = false; 77 | const style = { background: "#FAFAFA", padding: 10, borderRadius: 5 }; 78 | const { value } = this.props; 79 | const emails = value.get("emails"); 80 | 81 | return ( 82 |
this.handleChange(fieldName, value)} 90 | onMissingCountChange={(form, missing) => 91 | this.handleMissingCountChange(form, missing)} 92 | onErrorCountChange={(form, errors) => this.handleErrorCountChange(form, errors)} 93 | > 94 | 95 | 96 | 97 |
98 | 99 | ); 100 | } 101 | 102 | }); 103 | --- -------------------------------------------------------------------------------- /docs/service-worker.js: -------------------------------------------------------------------------------- 1 | "use strict";var precacheConfig=[["/react-dynamic-forms/index.html","55629829bed102766b685e46075e2579"],["/react-dynamic-forms/static/css/main.1d316427.css","cb8f3e7561ccd1df6b5ad8d24ecdb60a"],["/react-dynamic-forms/static/js/main.f2da4b7a.js","dedd342e0fd9383c169d1dd71831e8d5"],["/react-dynamic-forms/static/media/dynamic_docs.c45dd5e7.md","c45dd5e78fa2eee95bda79c8db5af2a5"],["/react-dynamic-forms/static/media/form_docs.c680d6e1.md","c680d6e1735aa3e59e9b5c1405bfa6de"],["/react-dynamic-forms/static/media/forms.aec5c7b8.png","aec5c7b8a344873d9d4f6cbd5cbdd81c"],["/react-dynamic-forms/static/media/getting_started.2be5c59d.md","2be5c59d289c1d198b7f5a75ec92ec2c"],["/react-dynamic-forms/static/media/glyphicons-halflings-regular.448c34a5.woff2","448c34a56d699c29117adc64c43affeb"],["/react-dynamic-forms/static/media/glyphicons-halflings-regular.89889688.svg","89889688147bd7575d6327160d64e760"],["/react-dynamic-forms/static/media/glyphicons-halflings-regular.e18bbf61.ttf","e18bbf611f2a2e43afc071aa2f4e1512"],["/react-dynamic-forms/static/media/glyphicons-halflings-regular.f4769f9b.eot","f4769f9bdb7466be65088239c12046d1"],["/react-dynamic-forms/static/media/glyphicons-halflings-regular.fa277232.woff","fa2772327f55d8198301fdb8bcfc8158"],["/react-dynamic-forms/static/media/intro.fda87512.md","fda875123c517186590247e34c3ec8bf"],["/react-dynamic-forms/static/media/list_docs.12101c16.md","12101c16b67ac38ae6f98be1647a558e"],["/react-dynamic-forms/static/media/schema_docs.01abfc75.md","01abfc750a0c942167651c40d088531d"]],cacheName="sw-precache-v3-sw-precache-webpack-plugin-"+(self.registration?self.registration.scope:""),ignoreUrlParametersMatching=[/^utm_/],addDirectoryIndex=function(e,t){var a=new URL(e);return"/"===a.pathname.slice(-1)&&(a.pathname+=t),a.toString()},cleanResponse=function(t){return t.redirected?("body"in t?Promise.resolve(t.body):t.blob()).then(function(e){return new Response(e,{headers:t.headers,status:t.status,statusText:t.statusText})}):Promise.resolve(t)},createCacheKey=function(e,t,a,r){var n=new URL(e);return r&&n.pathname.match(r)||(n.search+=(n.search?"&":"")+encodeURIComponent(t)+"="+encodeURIComponent(a)),n.toString()},isPathWhitelisted=function(e,t){if(0===e.length)return!0;var a=new URL(t).pathname;return e.some(function(e){return a.match(e)})},stripIgnoredUrlParameters=function(e,a){var t=new URL(e);return t.hash="",t.search=t.search.slice(1).split("&").map(function(e){return e.split("=")}).filter(function(t){return a.every(function(e){return!e.test(t[0])})}).map(function(e){return e.join("=")}).join("&"),t.toString()},hashParamName="_sw-precache",urlsToCacheKeys=new Map(precacheConfig.map(function(e){var t=e[0],a=e[1],r=new URL(t,self.location),n=createCacheKey(r,hashParamName,a,/\.\w{8}\./);return[r.toString(),n]}));function setOfCachedUrls(e){return e.keys().then(function(e){return e.map(function(e){return e.url})}).then(function(e){return new Set(e)})}self.addEventListener("install",function(e){e.waitUntil(caches.open(cacheName).then(function(r){return setOfCachedUrls(r).then(function(a){return Promise.all(Array.from(urlsToCacheKeys.values()).map(function(t){if(!a.has(t)){var e=new Request(t,{credentials:"same-origin"});return fetch(e).then(function(e){if(!e.ok)throw new Error("Request for "+t+" returned a response with status "+e.status);return cleanResponse(e).then(function(e){return r.put(t,e)})})}}))})}).then(function(){return self.skipWaiting()}))}),self.addEventListener("activate",function(e){var a=new Set(urlsToCacheKeys.values());e.waitUntil(caches.open(cacheName).then(function(t){return t.keys().then(function(e){return Promise.all(e.map(function(e){if(!a.has(e.url))return t.delete(e)}))})}).then(function(){return self.clients.claim()}))}),self.addEventListener("fetch",function(t){if("GET"===t.request.method){var e,a=stripIgnoredUrlParameters(t.request.url,ignoreUrlParametersMatching),r="index.html";(e=urlsToCacheKeys.has(a))||(a=addDirectoryIndex(a,r),e=urlsToCacheKeys.has(a));var n="/react-dynamic-forms/index.html";!e&&"navigate"===t.request.mode&&isPathWhitelisted(["^(?!\\/__).*"],t.request.url)&&(a=new URL(n,self.location).toString(),e=urlsToCacheKeys.has(a)),e&&t.respondWith(caches.open(cacheName).then(function(e){return e.match(urlsToCacheKeys.get(a)).then(function(e){if(e)return e;throw Error("The cached response that was expected is missing.")})}).catch(function(e){return console.warn('Couldn\'t serve response for "%s" from cache: %O',t.request.url,e),fetch(t.request)}))}}); -------------------------------------------------------------------------------- /packages/react-dynamic-forms/src/components/TagsEdit.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 - present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | import React from "react"; 12 | import _ from "underscore"; 13 | import { Creatable } from "react-select"; 14 | import Immutable from "immutable"; 15 | 16 | import formGroup from "../js/formGroup"; 17 | 18 | import "react-select/dist/react-select.css"; 19 | import "../css/tagsedit.css"; 20 | 21 | /** 22 | * Form control to select tags from a pull down list. 23 | * You can also add a new tag with the Add tag button. 24 | */ 25 | class TagsEdit extends React.Component { 26 | constructor(props) { 27 | super(props); 28 | this.state = { 29 | touched: false 30 | }; 31 | } 32 | 33 | componentWillReceiveProps(nextProps) { 34 | if (this.props.value !== nextProps.value) { 35 | const missingCount = this.isMissing(nextProps.value) ? 1 : 0; 36 | if (this.props.onMissingCountChange) { 37 | this.props.onMissingCountChange(this.props.name, missingCount); 38 | } 39 | } 40 | } 41 | 42 | handleChange(tags) { 43 | const value = _.map(tags, tag => tag.label); 44 | 45 | let updatedTagList; 46 | _.each(tags, tag => { 47 | if (tag.className === "Select-create-option-placeholder") { 48 | updatedTagList = this.props.tagList.push(tag.label); 49 | } 50 | }); 51 | 52 | if (updatedTagList && this.props.onTagListChange) { 53 | this.props.onTagListChange(this.props.name, updatedTagList); 54 | } 55 | 56 | if (this.props.onChange) { 57 | this.props.onChange(this.props.name, Immutable.fromJS(value)); 58 | } 59 | } 60 | 61 | isEmpty(value) { 62 | if (Immutable.List.isList(value)) { 63 | return value.size === 0; 64 | } 65 | return _.isNull(value) || _.isUndefined(value); 66 | } 67 | 68 | isMissing(value = this.props.value) { 69 | return this.props.required && !this.props.disabled && this.isEmpty(value); 70 | } 71 | 72 | render() { 73 | const isMissing = this.isMissing(this.props.value); 74 | if (this.props.edit) { 75 | const options = []; 76 | const value = []; 77 | 78 | this.props.tagList.forEach((tag, i) => { 79 | if (this.props.value.contains(tag)) { 80 | value.push({ value: i, label: tag }); 81 | } else { 82 | options.push({ value: i, label: tag }); 83 | } 84 | }); 85 | 86 | let className; 87 | if (isMissing) { 88 | className = "missing"; 89 | } 90 | 91 | return ( 92 |
93 | this.handleChange(value)} 103 | /> 104 |
105 |
106 | ); 107 | } else { 108 | const tagStyle = { 109 | cursor: "default", 110 | paddingTop: 2, 111 | paddingBottom: 2, 112 | paddingLeft: 5, 113 | paddingRight: 5, 114 | background: "#ececec", 115 | borderRadius: 2, 116 | marginLeft: 2, 117 | marginRight: 2 118 | }; 119 | return ( 120 |
121 | {this.props.value.map((tag, i) => {tag})} 122 |
123 | ); 124 | } 125 | } 126 | } 127 | 128 | export default formGroup(TagsEdit); 129 | -------------------------------------------------------------------------------- /packages/website/src/components/APIDoc.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from "react"; 2 | import _ from "underscore"; 3 | import Markdown from "react-markdown"; 4 | import docsFile from "../api/docs.json"; 5 | import Prism from "prismjs"; 6 | import { codeRenderer, codeBlockRenderer } from "../renderers"; 7 | import { textStyle } from "../styles"; 8 | 9 | /** 10 | * Displays API data from the docs.json file 11 | */ 12 | export default class extends Component { 13 | componentDidMount() { 14 | Prism.highlightAll(); 15 | } 16 | 17 | componentDidUpdate() { 18 | Prism.highlightAll(); 19 | } 20 | 21 | renderArrayOf(value) { 22 | if (value.name === "shape") { 23 | return "shape {" + 24 | _.map(value.value, (value, key) => { 25 | return key; 26 | }).join(", ") + 27 | "}"; 28 | } else { 29 | return `array of ${value.name}s`; 30 | } 31 | } 32 | 33 | renderPropType(type) { 34 | if (!type) { 35 | return "unknown type"; 36 | } 37 | if (type.name === "enum") { 38 | return "enum (" + 39 | _.map(type.value, value => { 40 | return value.value; 41 | }).join(", ") + 42 | ")"; 43 | } 44 | if (type.name === "union") { 45 | return "one of (" + 46 | _.map(type.value, value => { 47 | return this.renderPropType(value); 48 | }).join(", ") + 49 | ")"; 50 | } 51 | if (type.name === "instanceOf") { 52 | return `instance of a ${type.value}`; 53 | } 54 | if (type.name === "arrayOf") { 55 | return `array of ${this.renderArrayOf(type.value)}`; 56 | } 57 | if (type.name === "shapes") { 58 | return `shape of {` + 59 | _.map(type.value, (value, key) => { 60 | return key; 61 | }).join(", ") + 62 | "}"; 63 | } else { 64 | return `${type.name}`; 65 | } 66 | } 67 | 68 | renderProps(props) { 69 | const propNameStyle = { 70 | padding: 3, 71 | marginRight: 5, 72 | borderRadius: 2, 73 | fontFamily: "'Fira Mono',Menlo,monospace", 74 | color: "#c7254e", 75 | background: "#f9f2f4", 76 | letterSpacing: -0.015 77 | }; 78 | 79 | const infoStyle = { 80 | color: "#626466", 81 | fontFamily: "Fira Sans,Helvetica Neue,Helvetica,Arial,sans-serif", 82 | fontSize: 16, 83 | lineHeight: 1.625 84 | }; 85 | 86 | const typeStyle = { 87 | color: "#626466", 88 | background: "#F5F4F4", 89 | fontFamily: "Fira Sans,Helvetica Neue,Helvetica,Arial,sans-serif", 90 | fontSize: 16, 91 | lineHeight: 1.625 92 | }; 93 | 94 | return _.map(props, (prop, propName) => ( 95 |
96 | 97 | {propName} 98 | 99 | 100 | {prop.defaultValue ? ` = ${prop.defaultValue.value}` : ""} 101 | 102 | 103 | {prop.required ? "Required" : ""} 104 | 105 |
106 | 110 |
111 | 112 | Type: {this.renderPropType(prop.type)} 113 | 114 |
115 |
116 | )); 117 | } 118 | 119 | /** 120 | * If we add back in auto props, add this to the JSX below: 121 | * {docs.props ? this.renderProps(docs.props) : ""} 122 | */ 123 | render() { 124 | const file = this.props.file; 125 | const docs = docsFile[file]; 126 | return ( 127 |
128 |

API

129 | 133 |
134 |

Props

135 |
136 | {docs.props ? this.renderProps(docs.props) : "none"} 137 |
138 | ); 139 | } 140 | }; 141 | -------------------------------------------------------------------------------- /packages/react-dynamic-forms/src/components/DateEdit.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 - present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | import React from "react"; 12 | import _ from "underscore"; 13 | import moment from "moment"; 14 | import PropTypes from "prop-types"; 15 | import DatePicker from "react-datepicker"; 16 | 17 | import formGroup from "../js/formGroup"; 18 | 19 | import "react-datepicker/dist/react-datepicker.css"; 20 | import "../css/dateedit.css"; 21 | 22 | /** 23 | * Form control to edit a date text field. 24 | * 25 | * Set the initial value with `initialValue` and set a callback for 26 | * value changed with `onChange`. 27 | */ 28 | class DateEdit extends React.Component { 29 | isEmpty(value) { 30 | return _.isNull(value) || _.isUndefined(value) || value === ""; 31 | } 32 | 33 | isMissing(v) { 34 | return this.props.required && !this.props.disabled && this.isEmpty(v); 35 | } 36 | 37 | componentWillReceiveProps(nextProps) { 38 | if (this.props.value && nextProps.value) { 39 | if (this.props.value.getTime() !== nextProps.value.getTime()) { 40 | const missing = this.isMissing(nextProps.value); 41 | if (this.props.onMissingCountChange) { 42 | this.props.onMissingCountChange(this.props.name, missing ? 1 : 0); 43 | } 44 | } 45 | } 46 | } 47 | 48 | componentDidMount() { 49 | const missing = this.isMissing(this.props.value); 50 | if (this.props.onMissingCountChange) { 51 | this.props.onMissingCountChange(this.props.name, missing ? 1 : 0); 52 | } 53 | } 54 | 55 | handleDateChange(v) { 56 | const value = v ? v.toDate() : null; 57 | const missing = this.isMissing(value); 58 | 59 | // Callbacks 60 | if (this.props.onChange) { 61 | this.props.onChange(this.props.name, value); 62 | } 63 | if (this.props.onMissingCountChange) { 64 | this.props.onMissingCountChange(this.props.name, missing ? 1 : 0); 65 | } 66 | if (this.props.onBlur) { 67 | this.props.onBlur(this.props.name); 68 | } 69 | } 70 | 71 | inlineStyle(hasError, isMissing) { 72 | let color = "inherited"; 73 | let background = "inherited"; 74 | if (hasError) { 75 | color = "#b94a48"; 76 | background = "#fff0f3"; 77 | } else if (isMissing) { 78 | background = "floralwhite"; 79 | } 80 | return { 81 | color, 82 | background, 83 | height: 23, 84 | width: "100%", 85 | paddingLeft: 3 86 | }; 87 | } 88 | 89 | render() { 90 | // Control state 91 | const isMissing = this.isMissing(this.props.value); 92 | 93 | // Selected date 94 | const selected = this.props.value ? moment(this.props.value) : null; 95 | 96 | let className = "datepicker__input rdf"; 97 | 98 | if (isMissing) { 99 | className += " is-missing"; 100 | } 101 | 102 | if (this.props.edit) { 103 | return ( 104 |
105 |
106 | { this.textInput = input; }} 109 | className={className} 110 | disabled={this.props.disabled} 111 | placeholderText={this.props.placeholder} 112 | selected={selected} 113 | onChange={v => this.handleDateChange(v)} 114 | /> 115 |
116 |
117 | ); 118 | } else { 119 | const hasError = false; 120 | let text = selected ? selected.format("MM/DD/YYYY") : ""; 121 | if (isMissing) { 122 | text = " "; 123 | } 124 | const style = this.inlineStyle(hasError, isMissing); 125 | return
{text}
; 126 | } 127 | } 128 | } 129 | 130 | DateEdit.propTypes = { 131 | /** 132 | * width - Customize the horizontal size of the Chooser 133 | */ 134 | width: PropTypes.number, 135 | 136 | /** 137 | * field - The identifier of the field being edited 138 | */ 139 | field: PropTypes.string 140 | }; 141 | 142 | DateEdit.defaultProps = { 143 | width: 100 144 | }; 145 | 146 | export default formGroup(DateEdit); 147 | -------------------------------------------------------------------------------- /packages/website/src/Sidebar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | import React, { Component } from "react"; 12 | import { Link } from "react-router-dom"; 13 | import { sidebarStyle, sidebarItemStyle, sidebarTitleStyle } from "./styles"; 14 | import { AutoAffix } from "react-overlays"; 15 | 16 | export default class extends Component { 17 | render() { 18 | return ( 19 |
20 |
21 | GUIDE 22 |
23 |
    24 |
  • 25 | Introduction 26 |
  • 27 |
  • 28 | Getting Started 29 |
  • 30 |
31 | 32 |
33 | Examples 34 |
35 |
    36 |
  • 37 | Basic form 38 |
  • 39 |
  • 40 | Dynamic form 41 |
  • 42 |
  • 43 | List example 44 |
  • 45 |
  • 46 | Schema example 47 |
  • 48 |
49 | 50 |
51 | API 52 |
53 |
    54 |
  • 55 | CheckBoxes 56 |
  • 57 |
  • 58 | Chooser 59 |
  • 60 |
  • 61 | DateEdit 62 |
  • 63 |
  • 64 | Field 65 |
  • 66 |
  • 67 | Form 68 |
  • 69 |
  • 70 | List 71 |
  • 72 |
  • 73 | RadioButtons 74 |
  • 75 |
  • 76 | Schema 77 |
  • 78 |
  • 79 | TagsEdit 80 |
  • 81 |
  • 82 | TextArea 83 |
  • 84 |
  • 85 | TextEdit 86 |
  • 87 |
  • 88 | View 89 |
  • 90 |
91 | 92 |
93 | Links 94 |
95 | 106 | 107 |
108 | Related Projects 109 |
110 | 120 |
121 | ); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /docs/static/media/form_docs.c680d6e1.md: -------------------------------------------------------------------------------- 1 | ### Forms example 2 | 3 | The forms library is designed to help you build a complete form. In this example 4 | we create a simple contacts form. There are other examples too of forms which change 5 | their structure as the user interacts with tham, as well as demostrating the use 6 | of lists within the forms. But here we keep it relatively simple. 7 | 8 | **What do we want from our form?** 9 | 10 | Essentially we want to provide perhaps some initial data, our form `"value"`, 11 | defaults in the case of a new form, or maybe our current 12 | database state in the case of editing an existing entity. 13 | 14 | As the user edits the data, we'll want to track that. We may choose to save 15 | it on submit (if it's a new form, that's likely), or save it as the user edits it 16 | (perhaps if they are using inline editing we might 17 | want to save the data when any fields are changed). Either way, the forms library 18 | allows you to provide a callback function, which will be called whenever the values 19 | in the form change. How you want to respond to that is up to you, but this example 20 | demostrates one possible approach. 21 | 22 | In addition to knowing that the form values have changed, we also need to know if 23 | the form has any errors or missing fields. We do this via callbacks as well, where 24 | each callback will tell you the number of missing or empty fields that exist within 25 | the form. You can use that to control if the user can submit the form or not, as 26 | we do in this example. 27 | 28 | Okay, so we have initial values and we have some callbacks. 29 | 30 | **How do we get a form up and running to use those?** 31 | 32 | Forms have two concerns. Each form has a schema which we use to provide the meta 33 | data for fields within the form. This includes UI elements like the label for each 34 | fields, the placeholder text, etc, but also rules around the field itself. For 35 | example a field (called an Field in this library), 36 | 37 | The form elements are defined by a **schema**. Schemas can be defined with JSX or manually. Here's the schema used in this page: 38 | 39 | const schema = ( 40 | 41 | 43 | 45 | 47 | 48 | 49 | 50 | ); 51 | 52 | As you can see the schema is used to associate the Field name (`"first_name"` for example) with some properties which define how it looks and what is a valid value for that Field. Here we define a label (`"First name"`), a placeholder text, and some validation properties. Required can be set true to have the form track that this Field field needs to be filled out before the form is submitted. More on errors and missing value counts below. In addition to being required or not, the Field can have a validation prop set which will be passed to Revalidator for field validation while the user interacts with the form. It is most common to use it to specify the type (`"string", "integer", or "number"`), but you can also specify a format, such as in the example above where the email Field is checked to make sure it is a valid email address. Maximum string lengths, or ranges of numeric values can also be specified. For full details see the [Revalidator website](https://github.com/flatiron/revalidator). 53 | 54 | Rendering is not automatic. Instead the form itself is a React component that you define. We define the form itself like this: 55 | 56 | class ContactForm extends React.Component { 57 | 58 | } 59 | 60 | And then implement the form layout like this: 61 | 62 | renderForm() { 63 | const disableSubmit = this.hasErrors(); 64 | return ( 65 |
66 | 67 | 68 | 69 | 70 |
71 | 72 | 73 | ); 74 | } 75 | 76 | As you can see, we return a `
` element which contains further JSX, which is a convenience. In fact, you can define this with a `` too. You can use any JSX in here to render the form however you like. This makes the layout of the form as flexible as any other React code. 77 | 78 | The special elements here are the `TextEdit`s. They specify an `field` prop which references the schema (we'll see how to get the schema hooked up in a minute). Each TextEditGroup will generate a label and a form control (in this case a `TextEdit`). We use Bootstrap for the layout. In addition to TextEditGroups there's also: `TextAreaGroup`, `ChooserGroup`, `OptionsGroup` and `TagsGroup`. You can also wrap your own controls in the generic `Group`. 79 | 80 | Now that we have out form it's time to use it. Typically the form will be contained (rendered by) another React component which will hold the business logic of sourcing the schema and initial values, as well as handling the submit of the form in some way. 81 | 82 | To render the form we created above we need to pass in the initial values and schema. Here is the key part of render function for this page's example: 83 | 84 | render: function() { 85 | ... 86 | 91 | ... 92 | } 93 | 94 | Note that the schema is required, so you cannot render the form until one is available. If this is being loaded from the server you would display a Spinner until it is available. 95 | 96 | --- -------------------------------------------------------------------------------- /packages/website/src/examples/form/form_docs.md: -------------------------------------------------------------------------------- 1 | ### Forms example 2 | 3 | The forms library is designed to help you build a complete form. In this example 4 | we create a simple contacts form. There are other examples too of forms which change 5 | their structure as the user interacts with tham, as well as demostrating the use 6 | of lists within the forms. But here we keep it relatively simple. 7 | 8 | **What do we want from our form?** 9 | 10 | Essentially we want to provide perhaps some initial data, our form `"value"`, 11 | defaults in the case of a new form, or maybe our current 12 | database state in the case of editing an existing entity. 13 | 14 | As the user edits the data, we'll want to track that. We may choose to save 15 | it on submit (if it's a new form, that's likely), or save it as the user edits it 16 | (perhaps if they are using inline editing we might 17 | want to save the data when any fields are changed). Either way, the forms library 18 | allows you to provide a callback function, which will be called whenever the values 19 | in the form change. How you want to respond to that is up to you, but this example 20 | demostrates one possible approach. 21 | 22 | In addition to knowing that the form values have changed, we also need to know if 23 | the form has any errors or missing fields. We do this via callbacks as well, where 24 | each callback will tell you the number of missing or empty fields that exist within 25 | the form. You can use that to control if the user can submit the form or not, as 26 | we do in this example. 27 | 28 | Okay, so we have initial values and we have some callbacks. 29 | 30 | **How do we get a form up and running to use those?** 31 | 32 | Forms have two concerns. Each form has a schema which we use to provide the meta 33 | data for fields within the form. This includes UI elements like the label for each 34 | fields, the placeholder text, etc, but also rules around the field itself. For 35 | example a field (called an Field in this library), 36 | 37 | The form elements are defined by a **schema**. Schemas can be defined with JSX or manually. Here's the schema used in this page: 38 | 39 | const schema = ( 40 | 41 | 43 | 45 | 47 | 48 | 49 | 50 | ); 51 | 52 | As you can see the schema is used to associate the Field name (`"first_name"` for example) with some properties which define how it looks and what is a valid value for that Field. Here we define a label (`"First name"`), a placeholder text, and some validation properties. Required can be set true to have the form track that this Field field needs to be filled out before the form is submitted. More on errors and missing value counts below. In addition to being required or not, the Field can have a validation prop set which will be passed to Revalidator for field validation while the user interacts with the form. It is most common to use it to specify the type (`"string", "integer", or "number"`), but you can also specify a format, such as in the example above where the email Field is checked to make sure it is a valid email address. Maximum string lengths, or ranges of numeric values can also be specified. For full details see the [Revalidator website](https://github.com/flatiron/revalidator). 53 | 54 | Rendering is not automatic. Instead the form itself is a React component that you define. We define the form itself like this: 55 | 56 | class ContactForm extends React.Component { 57 | 58 | } 59 | 60 | And then implement the form layout like this: 61 | 62 | renderForm() { 63 | const disableSubmit = this.hasErrors(); 64 | return ( 65 | 66 | 67 | 68 | 69 | 70 |
71 | 72 | 73 | ); 74 | } 75 | 76 | As you can see, we return a `
` element which contains further JSX, which is a convenience. In fact, you can define this with a `` too. You can use any JSX in here to render the form however you like. This makes the layout of the form as flexible as any other React code. 77 | 78 | The special elements here are the `TextEdit`s. They specify an `field` prop which references the schema (we'll see how to get the schema hooked up in a minute). Each TextEditGroup will generate a label and a form control (in this case a `TextEdit`). We use Bootstrap for the layout. In addition to TextEditGroups there's also: `TextAreaGroup`, `ChooserGroup`, `OptionsGroup` and `TagsGroup`. You can also wrap your own controls in the generic `Group`. 79 | 80 | Now that we have out form it's time to use it. Typically the form will be contained (rendered by) another React component which will hold the business logic of sourcing the schema and initial values, as well as handling the submit of the form in some way. 81 | 82 | To render the form we created above we need to pass in the initial values and schema. Here is the key part of render function for this page's example: 83 | 84 | render: function() { 85 | ... 86 | 91 | ... 92 | } 93 | 94 | Note that the schema is required, so you cannot render the form until one is available. If this is being loaded from the server you would display a Spinner until it is available. 95 | 96 | --- -------------------------------------------------------------------------------- /packages/react-dynamic-forms/tests/__snapshots__/textedit.test.js.snap: -------------------------------------------------------------------------------- 1 | exports[`test Required field (with showRequired turned ON and initial value 1`] = ` 2 |
4 | 18 |
20 | 21 |
22 |
23 | `; 24 | 25 | exports[`test TextEdit email address validate 1`] = ` 26 |
28 | 40 |
42 | Value is not a valid email 43 |
44 |
45 | `; 46 | 47 | exports[`test TextEdit email address validate 2`] = ` 48 |
50 | 62 |
64 |
65 | `; 66 | 67 | exports[`test TextEdit isRequired snapshot test 1`] = ` 68 |
70 | 82 |
84 |
85 | `; 86 | 87 | exports[`test TextEdit isRequired snapshot test 2`] = ` 88 |
90 | 102 |
104 |
105 | `; 106 | 107 | exports[`test TextEdit that is disabled 1`] = ` 108 |
110 | 124 |
126 | 127 |
128 |
129 | `; 130 | 131 | exports[`test TextEdit with a placeholder 1`] = ` 132 |
134 | 148 |
150 | 151 |
152 |
153 | `; 154 | 155 | exports[`test TextEdit with an initial value and width 1`] = ` 156 |
158 | 172 |
174 | 175 |
176 |
177 | `; 178 | 179 | exports[`test TextEdit with required field (with showRequired turned OFF) 1`] = ` 180 |
182 | 196 |
198 | 199 |
200 |
201 | `; 202 | 203 | exports[`test TextEdit with required field (with showRequired turned ON) 1`] = ` 204 |
206 | 220 |
222 | 223 |
224 |
225 | `; 226 | 227 | exports[`test Validated field (email address) 1`] = ` 228 |
230 | 244 |
246 | Value is not a valid email 247 |
248 |
249 | `; 250 | 251 | exports[`test Validated field (integer) 1`] = ` 252 |
254 | 268 |
270 | 271 |
272 |
273 | `; 274 | -------------------------------------------------------------------------------- /packages/react-dynamic-forms/tests/components_test/ChooserExamples.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 - present, The Regents of the University of California, 3 | * through Lawrence Berkeley National Laboratory (subject to receipt 4 | * of any required approvals from the U.S. Dept. of Energy). 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */ 10 | 11 | import Chooser from "../../src/components/Chooser"; 12 | import React from "react"; 13 | import _ from "underscore"; 14 | import Chance from "chance"; 15 | 16 | const chance = Chance.Chance(); 17 | 18 | const animals = { 19 | 1: "dog", 20 | 2: "duck", 21 | 3: "cat", 22 | 4: "donkey", 23 | 5: "fish", 24 | 6: "hedgehog", 25 | 7: "banana slug" 26 | }; 27 | const animalList = _.map(animals, (value, key) => ({ id: key, label: value })); 28 | const sortedAnimalList = _.sortBy(animalList, item => item.label); 29 | 30 | let locationList = [ 31 | { id: 12, label: "Spain" }, 32 | { id: 14, label: "Portugal" }, 33 | { id: 16, label: "Italy" }, 34 | { id: 78, label: "France" }, 35 | { id: 99, label: "Germany" }, 36 | { id: 104, label: "Norway" }, 37 | { id: 112, label: "Denmark" }, 38 | { id: 154, label: "Greece" }, 39 | { id: 206, label: "Holland" } 40 | ]; 41 | 42 | let largeList = []; 43 | for (let i = 1; i < 5000; i++) { 44 | largeList.push({ id: `${i}`, label: chance.word() }); 45 | } 46 | 47 | export class ChooserBasic extends React.Component { 48 | constructor(props) { 49 | super(props); 50 | this.state = { 51 | animalList 52 | }; 53 | } 54 | 55 | render() { 56 | return ( 57 | 62 | ); 63 | } 64 | }; 65 | 66 | export class ChooserWider extends React.Component { 67 | constructor(props) { 68 | super(props); 69 | this.state = { 70 | animalList 71 | }; 72 | } 73 | 74 | render() { 75 | return ; 76 | } 77 | }; 78 | 79 | export class ChooserSortedList extends React.Component { 80 | constructor(props) { 81 | super(props); 82 | this.state = { 83 | sortedAnimalList 84 | }; 85 | } 86 | 87 | render() { 88 | return ; 89 | } 90 | }; 91 | 92 | export class ChooserInitialValue extends React.Component { 93 | constructor(props) { 94 | super(props); 95 | this.state = { 96 | animalList 97 | }; 98 | } 99 | 100 | render() { 101 | return ; 102 | } 103 | }; 104 | 105 | export class ChooserInitialNull extends React.Component { 106 | constructor(props) { 107 | super(props); 108 | this.state = { 109 | animalList 110 | }; 111 | } 112 | 113 | render() { 114 | return ( 115 | 116 | ); 117 | } 118 | }; 119 | 120 | export class ChooserSortedInitial extends React.Component { 121 | constructor(props) { 122 | super(props); 123 | this.state = { 124 | sortedAnimalList 125 | }; 126 | } 127 | 128 | render() { 129 | return ( 130 | 135 | ); 136 | } 137 | }; 138 | 139 | export class ChooserDisabled extends React.Component { 140 | constructor(props) { 141 | super(props); 142 | this.state = { 143 | animalList 144 | }; 145 | } 146 | 147 | render() { 148 | return ( 149 | 155 | ); 156 | } 157 | }; 158 | 159 | export class ChooserItemDisabled extends React.Component { 160 | constructor(props) { 161 | super(props); 162 | this.state = { 163 | animalList 164 | }; 165 | } 166 | 167 | render() { 168 | return ( 169 | 176 | ); 177 | } 178 | }; 179 | 180 | export class ChooserSearchDisabled extends React.Component { 181 | constructor(props) { 182 | super(props); 183 | this.state = { 184 | animalList 185 | }; 186 | } 187 | 188 | render() { 189 | return ( 190 | 196 | ); 197 | } 198 | }; 199 | 200 | export class ChooserSingleDeselect extends React.Component { 201 | constructor(props) { 202 | super(props); 203 | this.state = { 204 | animalList 205 | }; 206 | } 207 | 208 | render() { 209 | return ( 210 | 217 | ); 218 | } 219 | }; 220 | 221 | export class ChooserLongList extends React.Component { 222 | constructor(props) { 223 | super(props); 224 | this.state = { 225 | locationList 226 | }; 227 | } 228 | 229 | render() { 230 | return ; 231 | } 232 | }; -------------------------------------------------------------------------------- /docs/static/media/dynamic_docs.c45dd5e7.md: -------------------------------------------------------------------------------- 1 | ### Description 2 | 3 | The forms library allows you to create forms that dynamically change depending on other filled out fields. An example of this is a form which has a type field and that field controls several other fields that only apply to that type. In this case we want to: 4 | 5 | * Hide and show fields in reaction to a change in the type 6 | * Have hidden fields not be required, i.e. support conditional requires 7 | 8 | #### Render 9 | 10 | The above example begins with a pretty simple `renderForm()` implementation. In fact there's not much to see here. Regardless of the visibility that we'll control in a minute, we can just render all the fields and the forms code will take care of selectively hiding fields for us. Here is the rendered ``, part of the `renderForm()` function, excluding a little code to get out bookmarks map for the Bookmark chooser choice list. 11 | 12 | ```jsx 13 | this.handleChange(formName, value)} 22 | onMissingCountChange={(formName, missing) => this.setState({ hasMissing: missing > 0 })} 23 | onErrorCountChange={(formName, errors) => this.setState({ hasErrors: errors > 0 })} 24 | > 25 |
Bookmarked endpoints
26 | 27 |
28 |
General information
29 | 30 |