diff --git a/addons/controls/README.md b/addons/controls/README.md
index 89ce906e0e45..67eae72161af 100644
--- a/addons/controls/README.md
+++ b/addons/controls/README.md
@@ -40,6 +40,7 @@ Controls replaces [Storybook Knobs](https://github.com/storybookjs/storybook/tre
- [How will this replace addon-knobs?](#how-will-this-replace-addon-knobs)
- [How do I migrate from addon-knobs?](#how-do-i-migrate-from-addon-knobs)
- [My controls aren't being auto-generated. What should I do?](#my-controls-arent-being-auto-generated-what-should-i-do)
+ - [How can I disable controls for certain fields on a particular story?](#how-can-i-disable-controls-for-certain-fields-on-a-particular-story)
## Installation
@@ -505,3 +506,26 @@ Basic.args = {
The `argTypes` annotation (which can also be applied to individual stories if needed), gives Storybook the hints it needs to generate controls in these unsupported cases. See [control annotations](#control-annotations) for a full list of control types.
It's also possible that your Storybook is misconfigured. If you think this might be the case, please search through Storybook's [Github issues](https://github.com/storybookjs/storybook/issues), and file a new issue if you don't find one that matches your use case.
+
+### How can I disable controls for certain fields on a particular story?
+
+The `argTypes` annotation annotation can be used to hide controls for a particular row, or even hide rows.
+
+Suppose you have a `Button` component with `borderWidth` and `label` properties (auto-generated or otherwise) and you want to hide the `borderWidth` row completely and disable controls for the `label` row on a specific story. Here's how you'd do that:
+
+```js
+import { Button } from 'button';
+
+export default {
+ title: 'Button',
+ component: Button,
+};
+
+export const CustomControls = (args) => ;
+CustomControls.argTypes = {
+ borderWidth: { table: { disable: true } },
+ label: { control: { disable: true } },
+};
+```
+
+Like [story parameters](https://github.com/storybookjs/storybook/blob/next/docs/src/pages/basics/writing-stories/index.md#parameters), `args` and `argTypes` annotations are hierarchically merged, so story-level annotations overwrite component-level annotations.
diff --git a/examples/official-storybook/stories/addon-controls.stories.tsx b/examples/official-storybook/stories/addon-controls.stories.tsx
index 5815e3a13b38..c4b7597f18e0 100644
--- a/examples/official-storybook/stories/addon-controls.stories.tsx
+++ b/examples/official-storybook/stories/addon-controls.stories.tsx
@@ -18,3 +18,9 @@ Action.args = {
children: 'hmmm',
type: 'action',
};
+
+export const CustomControls = Story.bind({});
+CustomControls.argTypes = {
+ children: { table: { disable: true } },
+ type: { control: { disable: true } },
+};
diff --git a/lib/components/package.json b/lib/components/package.json
index 70fac4ba77b8..8927ff853013 100644
--- a/lib/components/package.json
+++ b/lib/components/package.json
@@ -37,6 +37,7 @@
"core-js": "^3.0.1",
"fast-deep-equal": "^3.1.1",
"global": "^4.3.2",
+ "lodash": "^4.17.15",
"markdown-to-jsx": "^6.11.4",
"memoizerific": "^1.11.3",
"overlayscrollbars": "^1.10.2",
diff --git a/lib/components/src/blocks/ArgsTable/ArgControl.tsx b/lib/components/src/blocks/ArgsTable/ArgControl.tsx
index 6a99a36ce7b6..e152c43764a4 100644
--- a/lib/components/src/blocks/ArgsTable/ArgControl.tsx
+++ b/lib/components/src/blocks/ArgsTable/ArgControl.tsx
@@ -30,8 +30,10 @@ export const ArgControl: FC = ({ row, arg, updateArgs }) => {
[updateArgs, name]
);
+ if (!control || control.disable) return ;
+
const props = { name, argType: row, value: arg, onChange };
- switch (control?.type) {
+ switch (control.type) {
case 'array':
return ;
case 'boolean':
diff --git a/lib/components/src/blocks/ArgsTable/ArgsTable.tsx b/lib/components/src/blocks/ArgsTable/ArgsTable.tsx
index 61ec4f4b7785..c3a56ee60358 100644
--- a/lib/components/src/blocks/ArgsTable/ArgsTable.tsx
+++ b/lib/components/src/blocks/ArgsTable/ArgsTable.tsx
@@ -1,4 +1,5 @@
import React, { FC } from 'react';
+import pickBy from 'lodash/pickBy';
import { styled, ignoreSsrWarning } from '@storybook/theming';
import { opacify, transparentize, darken, lighten } from 'polished';
import { ArgRow } from './ArgRow';
@@ -226,7 +227,7 @@ export const ArgsTable: FC = (props) => {
const { rows, args, updateArgs, compact, inAddonPanel } = props as ArgsTableRowProps;
- const groups = groupRows(rows);
+ const groups = groupRows(pickBy(rows, (row) => !row?.table?.disable));
if (
groups.ungrouped.length === 0 &&