Repository: mozilla-services/react-jsonschema-form
Pull request #549 (2017-04-18 22:14:02)

add prop-types package and add respective imports b/c it was deprecated
### Reasons for making this change

Utilizing in a React 15.5 project and getting the console warning:

> Warning: Accessing PropTypes via the main React package is deprecated. Use the prop-types package from npm instead.

So, just adding the prop-types package and importing as Proptypes from the prop-types package where Proptypes were previously imported from React.

If this is related to existing tickets, include links to them as well.

### Checklist

* [ ] **I'm updating documentation**
  - [ ] I've checked the rendering of the Markdown text I've added
  - [ ] If I'm adding a new section, I've updated the Table of Content
* [x] **I'm adding or updating code**
  - [ ] I've added and/or updated tests
  - [ ] I've updated docs if needed
  - [ ] I've run `npm run cs-format` on my branch to conform my code to [prettier](https://github.com/prettier/prettier) coding style
* [ ] **I'm adding a new feature**
  - [ ] I've updated the playground with an example use of the feature


elxris: I think its `PropTypes` instead of `Proptypes`, that's why the CI failed.
NathanQ: Doh! I'll resubmit. Thanks @elxris 
elxris: Prettier has changed a bit, and because CI install always the newest version you should run `npm run cs-format` to fix it

Patch:
diff --git a/README.md b/README.md
index 7f6ce4f80..aa4953efe 100644
--- a/README.md
+++ b/README.md
@@ -48,6 +48,7 @@ A [live playground](https://mozilla-services.github.io/react-jsonschema-form/) i
      - [Auto focus](#auto-focus)
      - [Textarea rows option](#textarea-rows-option)
      - [Placeholders](#placeholders)
+     - [Field labels](#field-labels)
      - [Form attributes](#form-attributes)
   - [Advanced customization](#advanced-customization)
      - [Field template](#field-template)
@@ -686,6 +687,19 @@ const uiSchema = {
 };
 ```
 
+### Field labels
+
+Field labels are rendered by default. Labels may be omitted by setting the `label` option to `false` from `ui:options` uiSchema directive.
+
+```jsx
+const schema = {type: "string"};
+const uiSchema = {
+  "ui:options": {
+    label: false
+  }
+};
+```
+
 ### Form attributes
 
 Form component supports the following html attributes:
diff --git a/package.json b/package.json
index 1a689501e..c8f662cb1 100644
--- a/package.json
+++ b/package.json
@@ -74,7 +74,8 @@
     "mocha": "^2.5.3",
     "prettier": "^1.0.0",
     "prettier-check": "^1.0.0",
-    "react": "^15.0.0",
+    "prop-types": "^15.5.8",
+    "react": "^15.5.0",
     "react-addons-test-utils": "^15.3.2",
     "react-codemirror": "^0.2.3",
     "react-dom": "^15.3.2",
diff --git a/playground/app.js b/playground/app.js
index 7c96dc6ee..364d3d442 100644
--- a/playground/app.js
+++ b/playground/app.js
@@ -292,7 +292,7 @@ class CopyLink extends Component {
       <div className="input-group">
         <input
           type="text"
-          ref={input => this.input = input}
+          ref={input => (this.input = input)}
           className="form-control"
           defaultValue={shareURL}
         />
diff --git a/src/components/fields/BooleanField.js b/src/components/fields/BooleanField.js
index e986e7590..80cb2f21a 100644
--- a/src/components/fields/BooleanField.js
+++ b/src/components/fields/BooleanField.js
@@ -1,4 +1,5 @@
-import React, { PropTypes } from "react";
+import React from "react";
+import PropTypes from "prop-types";
 
 import {
   getWidget,
diff --git a/src/components/fields/DescriptionField.js b/src/components/fields/DescriptionField.js
index 8085127f1..d848ed7ff 100644
--- a/src/components/fields/DescriptionField.js
+++ b/src/components/fields/DescriptionField.js
@@ -1,4 +1,5 @@
-import React, { PropTypes } from "react";
+import React from "react";
+import PropTypes from "prop-types";
 
 function DescriptionField(props) {
   const { id, description } = props;
diff --git a/src/components/fields/NumberField.js b/src/components/fields/NumberField.js
index 63c00deaf..30c297b19 100644
--- a/src/components/fields/NumberField.js
+++ b/src/components/fields/NumberField.js
@@ -1,4 +1,5 @@
-import React, { PropTypes } from "react";
+import React from "react";
+import PropTypes from "prop-types";
 
 import { asNumber } from "../../utils";
 
diff --git a/src/components/fields/SchemaField.js b/src/components/fields/SchemaField.js
index be11f4bd9..7e3e0d4d6 100644
--- a/src/components/fields/SchemaField.js
+++ b/src/components/fields/SchemaField.js
@@ -1,9 +1,11 @@
-import React, { PropTypes } from "react";
+import React from "react";
+import PropTypes from "prop-types";
 
 import {
   isMultiSelect,
   retrieveSchema,
   getDefaultRegistry,
+  getUiOptions,
   isFilesArray,
   deepEquals,
 } from "../../utils";
@@ -149,7 +151,8 @@ function SchemaFieldRender(props) {
     return <div />;
   }
 
-  let displayLabel = true;
+  const uiOptions = getUiOptions(uiSchema);
+  let { label: displayLabel = true } = uiOptions;
   if (schema.type === "array") {
     displayLabel = isMultiSelect(schema) || isFilesArray(schema, uiSchema);
   }
diff --git a/src/components/fields/StringField.js b/src/components/fields/StringField.js
index 307597c66..b8dd22fd0 100644
--- a/src/components/fields/StringField.js
+++ b/src/components/fields/StringField.js
@@ -1,4 +1,5 @@
-import React, { PropTypes } from "react";
+import React from "react";
+import PropTypes from "prop-types";
 
 import {
   getWidget,
diff --git a/src/components/fields/TitleField.js b/src/components/fields/TitleField.js
index aeb1c57eb..30ed634df 100644
--- a/src/components/fields/TitleField.js
+++ b/src/components/fields/TitleField.js
@@ -1,4 +1,5 @@
-import React, { PropTypes } from "react";
+import React from "react";
+import PropTypes from "prop-types";
 
 const REQUIRED_FIELD_SYMBOL = "*";
 
diff --git a/src/components/widgets/AltDateTimeWidget.js b/src/components/widgets/AltDateTimeWidget.js
index 94b7b7625..fd97c0e22 100644
--- a/src/components/widgets/AltDateTimeWidget.js
+++ b/src/components/widgets/AltDateTimeWidget.js
@@ -1,4 +1,5 @@
-import React, { PropTypes } from "react";
+import React from "react";
+import PropTypes from "prop-types";
 
 function AltDateTimeWidget(props) {
   const { AltDateWidget } = props.registry.widgets;
diff --git a/src/components/widgets/BaseInput.js b/src/components/widgets/BaseInput.js
index 2d5d0693b..dffe3fe08 100644
--- a/src/components/widgets/BaseInput.js
+++ b/src/components/widgets/BaseInput.js
@@ -1,4 +1,5 @@
-import React, { PropTypes } from "react";
+import React from "react";
+import PropTypes from "prop-types";
 
 function BaseInput(props) {
   // Note: since React 15.2.0 we can't forward unknown element attributes, so we
@@ -20,12 +21,12 @@ function BaseInput(props) {
   };
   return (
     <input
-      {...inputProps}
       className="form-control"
       readOnly={readonly}
       disabled={disabled}
       autoFocus={autofocus}
       value={value == null ? "" : value}
+      {...inputProps}
       onChange={_onChange}
       onBlur={onBlur && (event => onBlur(inputProps.id, event.target.value))}
     />
diff --git a/src/components/widgets/CheckboxWidget.js b/src/components/widgets/CheckboxWidget.js
index 093bebed7..2851840f8 100644
--- a/src/components/widgets/CheckboxWidget.js
+++ b/src/components/widgets/CheckboxWidget.js
@@ -1,4 +1,5 @@
-import React, { PropTypes } from "react";
+import React from "react";
+import PropTypes from "prop-types";
 import DescriptionField from "../fields/DescriptionField.js";
 
 function CheckboxWidget(props) {
diff --git a/src/components/widgets/CheckboxesWidget.js b/src/components/widgets/CheckboxesWidget.js
index 42f4930b6..6228f29a5 100644
--- a/src/components/widgets/CheckboxesWidget.js
+++ b/src/components/widgets/CheckboxesWidget.js
@@ -1,4 +1,5 @@
-import React, { PropTypes } from "react";
+import React from "react";
+import PropTypes from "prop-types";
 
 function selectValue(value, selected, all) {
   const at = all.indexOf(value);
diff --git a/src/components/widgets/ColorWidget.js b/src/components/widgets/ColorWidget.js
index 1c1ac3865..c892283ec 100644
--- a/src/components/widgets/ColorWidget.js
+++ b/src/components/widgets/ColorWidget.js
@@ -1,4 +1,5 @@
-import React, { PropTypes } from "react";
+import React from "react";
+import PropTypes from "prop-types";
 
 import BaseInput from "./BaseInput";
 
diff --git a/src/components/widgets/DateTimeWidget.js b/src/components/widgets/DateTimeWidget.js
index 0a72b44f0..a3cc3232e 100644
--- a/src/components/widgets/DateTimeWidget.js
+++ b/src/components/widgets/DateTimeWidget.js
@@ -1,4 +1,5 @@
-import React, { PropTypes } from "react";
+import React from "react";
+import PropTypes from "prop-types";
 
 import BaseInput from "./BaseInput";
 
diff --git a/src/components/widgets/DateWidget.js b/src/components/widgets/DateWidget.js
index f593bf3f5..d5e583c9d 100644
--- a/src/components/widgets/DateWidget.js
+++ b/src/components/widgets/DateWidget.js
@@ -1,4 +1,5 @@
-import React, { PropTypes } from "react";
+import React from "react";
+import PropTypes from "prop-types";
 
 import BaseInput from "./BaseInput";
 
diff --git a/src/components/widgets/EmailWidget.js b/src/components/widgets/EmailWidget.js
index c89f645d7..cb72a81f7 100644
--- a/src/components/widgets/EmailWidget.js
+++ b/src/components/widgets/EmailWidget.js
@@ -1,4 +1,5 @@
-import React, { PropTypes } from "react";
+import React from "react";
+import PropTypes from "prop-types";
 
 import BaseInput from "./BaseInput";
 
diff --git a/src/components/widgets/FileWidget.js b/src/components/widgets/FileWidget.js
index b14d356fd..b6bef6e23 100644
--- a/src/components/widgets/FileWidget.js
+++ b/src/components/widgets/FileWidget.js
@@ -98,7 +98,7 @@ class FileWidget extends Component {
       <div>
         <p>
           <input
-            ref={ref => this.inputRef = ref}
+            ref={ref => (this.inputRef = ref)}
             id={id}
             type="file"
             disabled={readonly || disabled}
diff --git a/src/components/widgets/HiddenWidget.js b/src/components/widgets/HiddenWidget.js
index 07cb615f4..b50878c93 100644
--- a/src/components/widgets/HiddenWidget.js
+++ b/src/components/widgets/HiddenWidget.js
@@ -1,4 +1,5 @@
-import React, { PropTypes } from "react";
+import React from "react";
+import PropTypes from "prop-types";
 
 function HiddenWidget({ id, value }) {
   return (
diff --git a/src/components/widgets/PasswordWidget.js b/src/components/widgets/PasswordWidget.js
index 84df8fa9f..d41b60d37 100644
--- a/src/components/widgets/PasswordWidget.js
+++ b/src/components/widgets/PasswordWidget.js
@@ -1,4 +1,5 @@
-import React, { PropTypes } from "react";
+import React from "react";
+import PropTypes from "prop-types";
 
 import BaseInput from "./BaseInput";
 
diff --git a/src/components/widgets/RadioWidget.js b/src/components/widgets/RadioWidget.js
index d4c9f395b..cf8e58507 100644
--- a/src/components/widgets/RadioWidget.js
+++ b/src/components/widgets/RadioWidget.js
@@ -1,4 +1,5 @@
-import React, { PropTypes } from "react";
+import React from "react";
+import PropTypes from "prop-types";
 
 function RadioWidget(props) {
   const {
diff --git a/src/components/widgets/RangeWidget.js b/src/components/widgets/RangeWidget.js
index ee541e224..d91c3721e 100644
--- a/src/components/widgets/RangeWidget.js
+++ b/src/components/widgets/RangeWidget.js
@@ -1,4 +1,5 @@
-import React, { PropTypes } from "react";
+import React from "react";
+import PropTypes from "prop-types";
 
 import { rangeSpec } from "../../utils";
 import BaseInput from "./BaseInput";
diff --git a/src/components/widgets/SelectWidget.js b/src/components/widgets/SelectWidget.js
index cdd3ba9f6..2a91455d5 100644
--- a/src/components/widgets/SelectWidget.js
+++ b/src/components/widgets/SelectWidget.js
@@ -1,4 +1,5 @@
-import React, { PropTypes } from "react";
+import React from "react";
+import PropTypes from "prop-types";
 
 import { asNumber } from "../../utils";
 
@@ -10,7 +11,9 @@ function processValue({ type, items }, value) {
   if (value === "") {
     return undefined;
   } else if (
-    type === "array" && items && ["number", "integer"].includes(items.type)
+    type === "array" &&
+    items &&
+    ["number", "integer"].includes(items.type)
   ) {
     return value.map(asNumber);
   } else if (type === "boolean") {
diff --git a/src/components/widgets/TextWidget.js b/src/components/widgets/TextWidget.js
index ebdedbb5a..9443d4bb2 100644
--- a/src/components/widgets/TextWidget.js
+++ b/src/components/widgets/TextWidget.js
@@ -1,4 +1,5 @@
-import React, { PropTypes } from "react";
+import React from "react";
+import PropTypes from "prop-types";
 
 import BaseInput from "./BaseInput";
 
diff --git a/src/components/widgets/TextareaWidget.js b/src/components/widgets/TextareaWidget.js
index bbee35fdc..c2250d20d 100644
--- a/src/components/widgets/TextareaWidget.js
+++ b/src/components/widgets/TextareaWidget.js
@@ -1,4 +1,5 @@
-import React, { PropTypes } from "react";
+import React from "react";
+import PropTypes from "prop-types";
 
 function TextareaWidget(props) {
   const {
diff --git a/src/components/widgets/URLWidget.js b/src/components/widgets/URLWidget.js
index 077050bf7..0627e18ed 100644
--- a/src/components/widgets/URLWidget.js
+++ b/src/components/widgets/URLWidget.js
@@ -1,4 +1,5 @@
-import React, { PropTypes } from "react";
+import React from "react";
+import PropTypes from "prop-types";
 
 import BaseInput from "./BaseInput";
 
diff --git a/src/components/widgets/UpDownWidget.js b/src/components/widgets/UpDownWidget.js
index 3ece1e703..4a74a6e77 100644
--- a/src/components/widgets/UpDownWidget.js
+++ b/src/components/widgets/UpDownWidget.js
@@ -1,4 +1,5 @@
-import React, { PropTypes } from "react";
+import React from "react";
+import PropTypes from "prop-types";
 
 import { rangeSpec } from "../../utils";
 import BaseInput from "./BaseInput";


Test patch:
diff --git a/test/SchemaField_test.js b/test/SchemaField_test.js
index 4147bcae7..153d748d6 100644
--- a/test/SchemaField_test.js
+++ b/test/SchemaField_test.js
@@ -162,6 +162,38 @@ describe("SchemaField", () => {
     });
   });
 
+  describe("label support", () => {
+    const schema = {
+      type: "object",
+      properties: {
+        foo: { type: "string" },
+      },
+    };
+
+    it("should render label by default", () => {
+      const { node } = createFormComponent({ schema });
+      expect(node.querySelectorAll("label")).to.have.length.of(1);
+    });
+
+    it("should render label if ui:options label is set to true", () => {
+      const uiSchema = {
+        foo: { "ui:options": { label: true } },
+      };
+
+      const { node } = createFormComponent({ schema, uiSchema });
+      expect(node.querySelectorAll("label")).to.have.length.of(1);
+    });
+
+    it("should not render label if ui:options label is set to false", () => {
+      const uiSchema = {
+        foo: { "ui:options": { label: false } },
+      };
+
+      const { node } = createFormComponent({ schema, uiSchema });
+      expect(node.querySelectorAll("label")).to.have.length.of(0);
+    });
+  });
+
   describe("description support", () => {
     const schema = {
       type: "object",