Repository: mui/material-ui (TypeScript)
Date: 2021-08-28 14:52:50+00:00
Task type: Feature

Issue:
ToggleButtonGroup API - disabled prop
It would be nice to have a `disabled` prop on the `ToggleButtonGroup` that would disable all the buttons, like the `ButtonGroup` do.



Issue discussion:
@RemyMachado Feel free to work on it. Should be straightforward enough.
@mbrookes  I would like to try this issue. Can I ?
@RemyMachado are you working on this already?
@chetas411 @mbrookes  

I was about to give it a try, but I never contributed before so I'm afraid I would be slow.  Go ahead, please yourself.
> @chetas411 @mbrookes
> 
> I was about to give it a try, but I never contributed before so I'm afraid I would be slow. Go ahead, please yourself.

This codebase is completely new for me as well but I will explore and see what I can do .
The contributing guide is a good place to start

Solution patch:
diff --git a/docs/pages/api-docs/toggle-button-group.json b/docs/pages/api-docs/toggle-button-group.json
--- a/docs/pages/api-docs/toggle-button-group.json
+++ b/docs/pages/api-docs/toggle-button-group.json
@@ -9,6 +9,7 @@
       },
       "default": "'standard'"
     },
+    "disabled": { "type": { "name": "bool" } },
     "exclusive": { "type": { "name": "bool" } },
     "fullWidth": { "type": { "name": "bool" } },
     "onChange": { "type": { "name": "func" } },
@@ -28,8 +29,8 @@
   },
   "name": "ToggleButtonGroup",
   "styles": {
-    "classes": ["root", "vertical", "grouped", "groupedHorizontal", "groupedVertical"],
-    "globalClasses": {},
+    "classes": ["root", "vertical", "disabled", "grouped", "groupedHorizontal", "groupedVertical"],
+    "globalClasses": { "disabled": "Mui-disabled" },
     "name": "MuiToggleButtonGroup"
   },
   "spread": true,
diff --git a/docs/translations/api-docs/toggle-button-group/toggle-button-group.json b/docs/translations/api-docs/toggle-button-group/toggle-button-group.json
--- a/docs/translations/api-docs/toggle-button-group/toggle-button-group.json
+++ b/docs/translations/api-docs/toggle-button-group/toggle-button-group.json
@@ -4,6 +4,7 @@
     "children": "The content of the component.",
     "classes": "Override or extend the styles applied to the component. See <a href=\"#css\">CSS API</a> below for more details.",
     "color": "The color of a button when it is selected.",
+    "disabled": "If <code>true</code>, the component is disabled. This implies that all ToggleButton children will be disabled.",
     "exclusive": "If <code>true</code>, only allow one of the child ToggleButton values to be selected.",
     "fullWidth": "If <code>true</code>, the button group will take up the full width of its container.",
     "onChange": "Callback fired when the value changes.<br><br><strong>Signature:</strong><br><code>function(event: React.MouseEvent&lt;HTMLElement&gt;, value: any) =&gt; void</code><br><em>event:</em> The event source of the callback.<br><em>value:</em> of the selected buttons. When <code>exclusive</code> is true this is a single value; when false an array of selected values. If no value is selected and <code>exclusive</code> is true the value is null; when false an empty array.",
@@ -19,6 +20,11 @@
       "nodeName": "the root element",
       "conditions": "<code>orientation=\"vertical\"</code>"
     },
+    "disabled": {
+      "description": "State class applied to {{nodeName}} if {{conditions}}.",
+      "nodeName": "the root element",
+      "conditions": "<code>disabled={true}</code>"
+    },
     "grouped": { "description": "Styles applied to {{nodeName}}.", "nodeName": "the children" },
     "groupedHorizontal": {
       "description": "Styles applied to {{nodeName}} if {{conditions}}.",
diff --git a/packages/material-ui/src/ToggleButtonGroup/ToggleButtonGroup.d.ts b/packages/material-ui/src/ToggleButtonGroup/ToggleButtonGroup.d.ts
--- a/packages/material-ui/src/ToggleButtonGroup/ToggleButtonGroup.d.ts
+++ b/packages/material-ui/src/ToggleButtonGroup/ToggleButtonGroup.d.ts
@@ -32,6 +32,11 @@ export interface ToggleButtonGroupProps
    * @default false
    */
   exclusive?: boolean;
+  /**
+   * If `true`, the component is disabled. This implies that all ToggleButton children will be disabled.
+   * @default false
+   */
+  disabled?: boolean;
   /**
    * If `true`, the button group will take up the full width of its container.
    * @default false
diff --git a/packages/material-ui/src/ToggleButtonGroup/ToggleButtonGroup.js b/packages/material-ui/src/ToggleButtonGroup/ToggleButtonGroup.js
--- a/packages/material-ui/src/ToggleButtonGroup/ToggleButtonGroup.js
+++ b/packages/material-ui/src/ToggleButtonGroup/ToggleButtonGroup.js
@@ -12,11 +12,11 @@ import toggleButtonGroupClasses, {
 } from './toggleButtonGroupClasses';
 
 const useUtilityClasses = (ownerState) => {
-  const { classes, orientation, fullWidth } = ownerState;
+  const { classes, orientation, fullWidth, disabled } = ownerState;
 
   const slots = {
     root: ['root', orientation === 'vertical' && 'vertical', fullWidth && 'fullWidth'],
-    grouped: ['grouped', `grouped${capitalize(orientation)}`],
+    grouped: ['grouped', `grouped${capitalize(orientation)}`, disabled && 'disabled'],
   };
 
   return composeClasses(slots, getToggleButtonGroupUtilityClass, classes);
@@ -93,6 +93,7 @@ const ToggleButtonGroup = React.forwardRef(function ToggleButtonGroup(inProps, r
     children,
     className,
     color = 'standard',
+    disabled = false,
     exclusive = false,
     fullWidth = false,
     onChange,
@@ -101,7 +102,7 @@ const ToggleButtonGroup = React.forwardRef(function ToggleButtonGroup(inProps, r
     value,
     ...other
   } = props;
-  const ownerState = { ...props, fullWidth, orientation, size };
+  const ownerState = { ...props, disabled, fullWidth, orientation, size };
   const classes = useUtilityClasses(ownerState);
 
   const handleChange = (event, buttonValue) => {
@@ -164,6 +165,7 @@ const ToggleButtonGroup = React.forwardRef(function ToggleButtonGroup(inProps, r
           size: child.props.size || size,
           fullWidth,
           color: child.props.color || color,
+          disabled: child.props.disabled || disabled,
         });
       })}
     </ToggleButtonGroupRoot>
@@ -195,6 +197,11 @@ ToggleButtonGroup.propTypes /* remove-proptypes */ = {
     PropTypes.oneOf(['standard', 'primary', 'secondary', 'error', 'info', 'success', 'warning']),
     PropTypes.string,
   ]),
+  /**
+   * If `true`, the component is disabled. This implies that all ToggleButton children will be disabled.
+   * @default false
+   */
+  disabled: PropTypes.bool,
   /**
    * If `true`, only allow one of the child ToggleButton values to be selected.
    * @default false
diff --git a/packages/material-ui/src/ToggleButtonGroup/toggleButtonGroupClasses.ts b/packages/material-ui/src/ToggleButtonGroup/toggleButtonGroupClasses.ts
--- a/packages/material-ui/src/ToggleButtonGroup/toggleButtonGroupClasses.ts
+++ b/packages/material-ui/src/ToggleButtonGroup/toggleButtonGroupClasses.ts
@@ -5,6 +5,8 @@ export interface ToggleButtonGroupClasses {
   root: string;
   /** Styles applied to the root element if `orientation="vertical"`. */
   vertical: string;
+  /** State class applied to the root element if `disabled={true}`. */
+  disabled: string;
   /** Styles applied to the children. */
   grouped: string;
   /** Styles applied to the children if `orientation="horizontal"`. */
@@ -21,7 +23,7 @@ export function getToggleButtonGroupUtilityClass(slot: string): string {
 
 const toggleButtonGroupClasses: ToggleButtonGroupClasses = generateUtilityClasses(
   'MuiToggleButtonGroup',
-  ['root', 'selected', 'vertical', 'grouped', 'groupedHorizontal', 'groupedVertical'],
+  ['root', 'selected', 'vertical', 'disabled', 'grouped', 'groupedHorizontal', 'groupedVertical'],
 );
 
 export default toggleButtonGroupClasses;


Test patch:
diff --git a/packages/material-ui/src/ToggleButtonGroup/ToggleButtonGroup.test.js b/packages/material-ui/src/ToggleButtonGroup/ToggleButtonGroup.test.js
--- a/packages/material-ui/src/ToggleButtonGroup/ToggleButtonGroup.test.js
+++ b/packages/material-ui/src/ToggleButtonGroup/ToggleButtonGroup.test.js
@@ -1,7 +1,7 @@
 import * as React from 'react';
 import { expect } from 'chai';
 import { spy } from 'sinon';
-import { describeConformance, createClientRender } from 'test/utils';
+import { describeConformance, createClientRender, screen } from 'test/utils';
 import ToggleButtonGroup, {
   toggleButtonGroupClasses as classes,
 } from '@material-ui/core/ToggleButtonGroup';
@@ -37,6 +37,18 @@ describe('<ToggleButtonGroup />', () => {
     expect(getByRole('button')).to.have.class('MuiToggleButtonGroup-groupedVertical');
   });
 
+  it('should disable all ToggleButton if disabled prop is passed', () => {
+    render(
+      <ToggleButtonGroup disabled>
+        <ToggleButton value="one">1</ToggleButton>
+        <ToggleButton value="two">2</ToggleButton>
+      </ToggleButtonGroup>,
+    );
+    const [firstButton, secondButton] = screen.getAllByRole('button');
+    expect(firstButton).to.have.property('disabled', true);
+    expect(secondButton).to.have.property('disabled', true);
+  });
+
   describe('exclusive', () => {
     it('should render a selected ToggleButton if value is selected', () => {
       const { getByRole } = render(