From d516ce2c964fd16bb3956cef8c4659a2a1b0cff3 Mon Sep 17 00:00:00 2001
From: Nick Grosenbacher <nickgrosenbacher@gmail.com>
Date: Fri, 11 Aug 2023 12:16:14 -0400
Subject: [PATCH] fix #3815

- Fix #3815 by removing TitleFieldTemplate, antd Checkbox.Group handles title rendering itself.
- Add title field in related snapshot test
---
 CHANGELOG.md                                  |  4 ++
 .../src/widgets/CheckboxesWidget/index.tsx    | 32 +----------
 .../test/__snapshots__/Form.test.tsx.snap     | 12 +++++
 .../test/__snapshots__/Form.test.tsx.snap     |  2 +-
 .../test/__snapshots__/Form.test.tsx.snap     | 54 +++++++++++--------
 .../test/__snapshots__/FormSnap.test.jsx.snap |  6 +++
 packages/core/testSnap/formTests.tsx          |  1 +
 .../test/__snapshots__/Form.test.tsx.snap     |  4 +-
 .../test/__snapshots__/Form.test.tsx.snap     |  4 +-
 .../mui/test/__snapshots__/Form.test.tsx.snap |  4 +-
 .../test/__snapshots__/Form.test.tsx.snap     |  6 +++
 11 files changed, 73 insertions(+), 56 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7812e78bd6..89ee1e5b6b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,10 @@ should change the heading of the (upcoming) version to include a major version b
 -->
 # 5.12.1
 
+## @rjsf/antd
+
+- Updated CheckboxesWidget to not show duplicate title, fixing [#3815](https://github.com/rjsf-team/react-jsonschema-form/issues/3815)
+
 ## @rjsf/utils
 
 - Updated `retrieveSchemaInternal` allOf logic for precompiled schemas to resolve top level properties fixing [#3817](https://github.com/rjsf-team/react-jsonschema-form/issues/3817)
diff --git a/packages/antd/src/widgets/CheckboxesWidget/index.tsx b/packages/antd/src/widgets/CheckboxesWidget/index.tsx
index 8dd296ae90..a6d8fd5a8b 100644
--- a/packages/antd/src/widgets/CheckboxesWidget/index.tsx
+++ b/packages/antd/src/widgets/CheckboxesWidget/index.tsx
@@ -4,9 +4,7 @@ import {
   ariaDescribedByIds,
   enumOptionsIndexForValue,
   enumOptionsValueForIndex,
-  getTemplate,
   optionId,
-  titleId,
   FormContextType,
   WidgetProps,
   RJSFSchema,
@@ -23,25 +21,8 @@ export default function CheckboxesWidget<
   T = any,
   S extends StrictRJSFSchema = RJSFSchema,
   F extends FormContextType = any
->({
-  autofocus,
-  disabled,
-  formContext,
-  id,
-  label,
-  hideLabel,
-  onBlur,
-  onChange,
-  onFocus,
-  options,
-  readonly,
-  registry,
-  schema,
-  uiSchema,
-  value,
-}: WidgetProps<T, S, F>) {
+>({ autofocus, disabled, formContext, id, onBlur, onChange, onFocus, options, readonly, value }: WidgetProps<T, S, F>) {
   const { readonlyAsDisabled = true } = formContext as GenericObjectType;
-  const TitleFieldTemplate = getTemplate<'TitleFieldTemplate', T, S, F>('TitleFieldTemplate', registry, options);
 
   const { enumOptions, enumDisabled, inline, emptyValue } = options;
 
@@ -65,17 +46,6 @@ export default function CheckboxesWidget<
 
   return Array.isArray(enumOptions) && enumOptions.length > 0 ? (
     <>
-      {!hideLabel && !!label && (
-        <div>
-          <TitleFieldTemplate
-            id={titleId<T>(id)}
-            title={label}
-            schema={schema}
-            uiSchema={uiSchema}
-            registry={registry}
-          />
-        </div>
-      )}
       <Checkbox.Group
         disabled={disabled || (readonlyAsDisabled && readonly)}
         name={id}
diff --git a/packages/antd/test/__snapshots__/Form.test.tsx.snap b/packages/antd/test/__snapshots__/Form.test.tsx.snap
index 9eb38d3285..ad89ced4af 100644
--- a/packages/antd/test/__snapshots__/Form.test.tsx.snap
+++ b/packages/antd/test/__snapshots__/Form.test.tsx.snap
@@ -321,6 +321,18 @@ exports[`single fields checkboxes field 1`] = `
         className="ant-row ant-form-item-row"
         style={{}}
       >
+        <div
+          className="ant-col ant-col-24 ant-form-item-label"
+          style={{}}
+        >
+          <label
+            className=""
+            htmlFor="root"
+            title="An enum list rendered as checkboxes"
+          >
+            An enum list rendered as checkboxes
+          </label>
+        </div>
         <div
           className="ant-col ant-col-24 ant-form-item-control"
           style={{}}
diff --git a/packages/bootstrap-4/test/__snapshots__/Form.test.tsx.snap b/packages/bootstrap-4/test/__snapshots__/Form.test.tsx.snap
index 76868dc453..8a0473750d 100644
--- a/packages/bootstrap-4/test/__snapshots__/Form.test.tsx.snap
+++ b/packages/bootstrap-4/test/__snapshots__/Form.test.tsx.snap
@@ -119,7 +119,7 @@ exports[`single fields checkboxes field 1`] = `
         className="form-label"
         htmlFor="root"
       >
-        
+        An enum list rendered as checkboxes
       </label>
       <div
         className="form-group"
diff --git a/packages/chakra-ui/test/__snapshots__/Form.test.tsx.snap b/packages/chakra-ui/test/__snapshots__/Form.test.tsx.snap
index 9e1ed6496f..ead16904e9 100644
--- a/packages/chakra-ui/test/__snapshots__/Form.test.tsx.snap
+++ b/packages/chakra-ui/test/__snapshots__/Form.test.tsx.snap
@@ -326,6 +326,11 @@ exports[`single fields checkboxes field 1`] = `
 }
 
 .emotion-2 {
+  display: block;
+  text-align: start;
+}
+
+.emotion-3 {
   display: -webkit-box;
   display: -webkit-flex;
   display: -ms-flexbox;
@@ -335,7 +340,7 @@ exports[`single fields checkboxes field 1`] = `
   flex-direction: column;
 }
 
-.emotion-2>*:not(style)~*:not(style) {
+.emotion-3>*:not(style)~*:not(style) {
   margin-top: 0.5rem;
   -webkit-margin-end: 0px;
   margin-inline-end: 0px;
@@ -344,7 +349,7 @@ exports[`single fields checkboxes field 1`] = `
   margin-inline-start: 0px;
 }
 
-.emotion-3 {
+.emotion-4 {
   cursor: pointer;
   display: -webkit-inline-box;
   display: -webkit-inline-flex;
@@ -358,7 +363,7 @@ exports[`single fields checkboxes field 1`] = `
   position: relative;
 }
 
-.emotion-4 {
+.emotion-5 {
   display: -webkit-inline-box;
   display: -webkit-inline-flex;
   display: -ms-inline-flexbox;
@@ -381,16 +386,16 @@ exports[`single fields checkboxes field 1`] = `
   flex-shrink: 0;
 }
 
-.emotion-5 {
+.emotion-6 {
   -webkit-margin-start: 0.5rem;
   margin-inline-start: 0.5rem;
 }
 
-.emotion-19 {
+.emotion-20 {
   margin-top: 3px;
 }
 
-.emotion-20 {
+.emotion-21 {
   display: -webkit-inline-box;
   display: -webkit-inline-flex;
   display: -ms-inline-flexbox;
@@ -435,11 +440,18 @@ exports[`single fields checkboxes field 1`] = `
         className="chakra-form-control emotion-1"
         role="group"
       >
+        <label
+          className="chakra-form__label emotion-2"
+          htmlFor="root"
+          id="root-label"
+        >
+          An enum list rendered as checkboxes
+        </label>
         <div
-          className="chakra-stack emotion-2"
+          className="chakra-stack emotion-3"
         >
           <label
-            className="chakra-checkbox emotion-3"
+            className="chakra-checkbox emotion-4"
             onClick={[Function]}
           >
             <input
@@ -475,14 +487,14 @@ exports[`single fields checkboxes field 1`] = `
             />
             <span
               aria-hidden={true}
-              className="chakra-checkbox__control emotion-4"
+              className="chakra-checkbox__control emotion-5"
               onMouseDown={[Function]}
               onMouseEnter={[Function]}
               onMouseLeave={[Function]}
               onMouseUp={[Function]}
             />
             <span
-              className="chakra-checkbox__label emotion-5"
+              className="chakra-checkbox__label emotion-6"
               onMouseDown={[Function]}
               onTouchStart={[Function]}
             >
@@ -494,7 +506,7 @@ exports[`single fields checkboxes field 1`] = `
             </span>
           </label>
           <label
-            className="chakra-checkbox emotion-3"
+            className="chakra-checkbox emotion-4"
             onClick={[Function]}
           >
             <input
@@ -530,14 +542,14 @@ exports[`single fields checkboxes field 1`] = `
             />
             <span
               aria-hidden={true}
-              className="chakra-checkbox__control emotion-4"
+              className="chakra-checkbox__control emotion-5"
               onMouseDown={[Function]}
               onMouseEnter={[Function]}
               onMouseLeave={[Function]}
               onMouseUp={[Function]}
             />
             <span
-              className="chakra-checkbox__label emotion-5"
+              className="chakra-checkbox__label emotion-6"
               onMouseDown={[Function]}
               onTouchStart={[Function]}
             >
@@ -549,7 +561,7 @@ exports[`single fields checkboxes field 1`] = `
             </span>
           </label>
           <label
-            className="chakra-checkbox emotion-3"
+            className="chakra-checkbox emotion-4"
             onClick={[Function]}
           >
             <input
@@ -585,14 +597,14 @@ exports[`single fields checkboxes field 1`] = `
             />
             <span
               aria-hidden={true}
-              className="chakra-checkbox__control emotion-4"
+              className="chakra-checkbox__control emotion-5"
               onMouseDown={[Function]}
               onMouseEnter={[Function]}
               onMouseLeave={[Function]}
               onMouseUp={[Function]}
             />
             <span
-              className="chakra-checkbox__label emotion-5"
+              className="chakra-checkbox__label emotion-6"
               onMouseDown={[Function]}
               onTouchStart={[Function]}
             >
@@ -604,7 +616,7 @@ exports[`single fields checkboxes field 1`] = `
             </span>
           </label>
           <label
-            className="chakra-checkbox emotion-3"
+            className="chakra-checkbox emotion-4"
             onClick={[Function]}
           >
             <input
@@ -640,14 +652,14 @@ exports[`single fields checkboxes field 1`] = `
             />
             <span
               aria-hidden={true}
-              className="chakra-checkbox__control emotion-4"
+              className="chakra-checkbox__control emotion-5"
               onMouseDown={[Function]}
               onMouseEnter={[Function]}
               onMouseLeave={[Function]}
               onMouseUp={[Function]}
             />
             <span
-              className="chakra-checkbox__label emotion-5"
+              className="chakra-checkbox__label emotion-6"
               onMouseDown={[Function]}
               onTouchStart={[Function]}
             >
@@ -663,10 +675,10 @@ exports[`single fields checkboxes field 1`] = `
     </div>
   </div>
   <div
-    className="emotion-19"
+    className="emotion-20"
   >
     <button
-      className="chakra-button emotion-20"
+      className="chakra-button emotion-21"
       disabled={false}
       type="submit"
     >
diff --git a/packages/core/test/__snapshots__/FormSnap.test.jsx.snap b/packages/core/test/__snapshots__/FormSnap.test.jsx.snap
index fa20aae360..2341334618 100644
--- a/packages/core/test/__snapshots__/FormSnap.test.jsx.snap
+++ b/packages/core/test/__snapshots__/FormSnap.test.jsx.snap
@@ -97,6 +97,12 @@ exports[`single fields checkboxes field 1`] = `
   <div
     className="form-group field field-array"
   >
+    <label
+      className="control-label"
+      htmlFor="root"
+    >
+      An enum list rendered as checkboxes
+    </label>
     <div
       className="checkboxes"
       id="root"
diff --git a/packages/core/testSnap/formTests.tsx b/packages/core/testSnap/formTests.tsx
index be221565c0..92d6a24eb7 100644
--- a/packages/core/testSnap/formTests.tsx
+++ b/packages/core/testSnap/formTests.tsx
@@ -268,6 +268,7 @@ export default function formTests(Form: ComponentType<FormProps>, customOptions:
     test('checkboxes field', () => {
       const schema: RJSFSchema = {
         type: 'array',
+        title: 'An enum list rendered as checkboxes',
         items: {
           type: 'string',
           enum: ['foo', 'bar', 'fuzz', 'qux'],
diff --git a/packages/fluent-ui/test/__snapshots__/Form.test.tsx.snap b/packages/fluent-ui/test/__snapshots__/Form.test.tsx.snap
index 96d9cd92d9..76135bcc86 100644
--- a/packages/fluent-ui/test/__snapshots__/Form.test.tsx.snap
+++ b/packages/fluent-ui/test/__snapshots__/Form.test.tsx.snap
@@ -195,7 +195,9 @@ exports[`single fields checkboxes field 1`] = `
   >
     <label
       className="ms-Label root-130"
-    />
+    >
+      An enum list rendered as checkboxes
+    </label>
     <div
       className="ms-Checkbox is-enabled root-201"
     >
diff --git a/packages/material-ui/test/__snapshots__/Form.test.tsx.snap b/packages/material-ui/test/__snapshots__/Form.test.tsx.snap
index 9e88a8e0bb..21adbdb4fd 100644
--- a/packages/material-ui/test/__snapshots__/Form.test.tsx.snap
+++ b/packages/material-ui/test/__snapshots__/Form.test.tsx.snap
@@ -215,7 +215,9 @@ exports[`single fields checkboxes field 1`] = `
       <label
         className="MuiFormLabel-root"
         htmlFor="root"
-      />
+      >
+        An enum list rendered as checkboxes
+      </label>
       <div
         className="MuiFormGroup-root"
         id="root"
diff --git a/packages/mui/test/__snapshots__/Form.test.tsx.snap b/packages/mui/test/__snapshots__/Form.test.tsx.snap
index d74d4de936..bd3deb0c87 100644
--- a/packages/mui/test/__snapshots__/Form.test.tsx.snap
+++ b/packages/mui/test/__snapshots__/Form.test.tsx.snap
@@ -1011,7 +1011,9 @@ exports[`single fields checkboxes field 1`] = `
       <label
         className="MuiFormLabel-root MuiFormLabel-colorPrimary emotion-1"
         htmlFor="root"
-      />
+      >
+        An enum list rendered as checkboxes
+      </label>
       <div
         className="MuiFormGroup-root emotion-2"
         id="root"
diff --git a/packages/semantic-ui/test/__snapshots__/Form.test.tsx.snap b/packages/semantic-ui/test/__snapshots__/Form.test.tsx.snap
index 24183dd466..ee6fa2ebf0 100644
--- a/packages/semantic-ui/test/__snapshots__/Form.test.tsx.snap
+++ b/packages/semantic-ui/test/__snapshots__/Form.test.tsx.snap
@@ -276,6 +276,12 @@ exports[`single fields checkboxes field 1`] = `
     <div
       className="grouped equal width fields"
     >
+      <h5
+        className="ui dividing header"
+        id="root__title"
+      >
+        An enum list rendered as checkboxes
+      </h5>
       <div
         className="grouped fields"
         id="root"