Repository: speee/jsx-slack (ts)

Issue:
Radio buttons for <Modal>
Today Slack shipped radio buttons for Modal surface.
https://api.slack.com/reference/block-kit/block-elements#radio

Currently jsx-slack allows using `<RadioButtonGroup>` and `<RadioButton>` only in `<Home>` for home tab. We have to remove this restriction.

> In addition, we may consider the interface of `<input type="radio" />` for HTML-form style templating. (Probably it's better for the other issue)

### ToDo

- [x] Allow using `<RadioButtonGroup>` and `<RadioButton>` in...
  - [x] `<Modal>` container component
  - [x] `<Input>` block
    - [x] `<RadioButtonGroup>` as input component

Pull request:
Radio buttons for modal
Now `<RadioButtonGroup>` / `<RadioButton>` can use in `<Modal>` container! jsx-slack will no longer throw an error even if using `<RadioButtonGroup>` in modal.

```jsx
<Modal title="Radio buttons for modal">
  <Actions>
    <RadioButtonGroup>
      <RadioButton value="a" description="Option A">A</RadioButton>
      <RadioButton value="b" description="Option B">B</RadioButton>
      <RadioButton value="c" description="Option C">C</RadioButton>
    </RadioButtonGroup>
  </Actions>

  <Section>
    Radio button group as <i>an accessory of &lt;Section&gt;</i>
    <RadioButtonGroup>
      <RadioButton value="a" description="Option A">A</RadioButton>
      <RadioButton value="b" description="Option B">B</RadioButton>
      <RadioButton value="c" description="Option C">C</RadioButton>
    </RadioButtonGroup>
  </Section>

  <Input label="Radio buttons in &lt;Input&gt;" name="input-block">
    <RadioButtonGroup>
      <RadioButton value="a" description="Option A">A</RadioButton>
      <RadioButton value="b" description="Option B">B</RadioButton>
      <RadioButton value="c" description="Option C">C</RadioButton>
    </RadioButtonGroup>
  </Input>

  <RadioButtonGroup label="Radio button group as input component" name="input-component">
    <RadioButton value="a" description="Option A">A</RadioButton>
    <RadioButton value="b" description="Option B">B</RadioButton>
    <RadioButton value="c" description="Option C">C</RadioButton>
  </RadioButtonGroup>
</Modal>
```

[<img src="https://raw.githubusercontent.com/speee/jsx-slack/master/docs/preview-btn.svg?sanitize=true" width="240" />](https://api.slack.com/tools/block-kit-builder?mode=modal&view=%7B%22type%22%3A%22modal%22%2C%22title%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Radio%20buttons%20for%20modal%22%2C%22emoji%22%3Atrue%7D%2C%22submit%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Submit%22%2C%22emoji%22%3Atrue%7D%2C%22blocks%22%3A%5B%7B%22type%22%3A%22actions%22%2C%22elements%22%3A%5B%7B%22type%22%3A%22radio_buttons%22%2C%22options%22%3A%5B%7B%22text%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22A%22%2C%22emoji%22%3Atrue%7D%2C%22value%22%3A%22a%22%2C%22description%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Option%20A%22%2C%22emoji%22%3Atrue%7D%7D%2C%7B%22text%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22B%22%2C%22emoji%22%3Atrue%7D%2C%22value%22%3A%22b%22%2C%22description%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Option%20B%22%2C%22emoji%22%3Atrue%7D%7D%2C%7B%22text%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22C%22%2C%22emoji%22%3Atrue%7D%2C%22value%22%3A%22c%22%2C%22description%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Option%20C%22%2C%22emoji%22%3Atrue%7D%7D%5D%7D%5D%7D%2C%7B%22type%22%3A%22section%22%2C%22text%22%3A%7B%22text%22%3A%22Radio%20button%20group%20as%20_an%20accessory%20of%20%26lt%3BSection%26gt%3B_%22%2C%22type%22%3A%22mrkdwn%22%2C%22verbatim%22%3Atrue%7D%2C%22accessory%22%3A%7B%22type%22%3A%22radio_buttons%22%2C%22options%22%3A%5B%7B%22text%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22A%22%2C%22emoji%22%3Atrue%7D%2C%22value%22%3A%22a%22%2C%22description%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Option%20A%22%2C%22emoji%22%3Atrue%7D%7D%2C%7B%22text%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22B%22%2C%22emoji%22%3Atrue%7D%2C%22value%22%3A%22b%22%2C%22description%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Option%20B%22%2C%22emoji%22%3Atrue%7D%7D%2C%7B%22text%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22C%22%2C%22emoji%22%3Atrue%7D%2C%22value%22%3A%22c%22%2C%22description%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Option%20C%22%2C%22emoji%22%3Atrue%7D%7D%5D%7D%7D%2C%7B%22type%22%3A%22input%22%2C%22label%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Radio%20buttons%20in%20%3CInput%3E%22%2C%22emoji%22%3Atrue%7D%2C%22optional%22%3Atrue%2C%22element%22%3A%7B%22type%22%3A%22radio_buttons%22%2C%22options%22%3A%5B%7B%22text%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22A%22%2C%22emoji%22%3Atrue%7D%2C%22value%22%3A%22a%22%2C%22description%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Option%20A%22%2C%22emoji%22%3Atrue%7D%7D%2C%7B%22text%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22B%22%2C%22emoji%22%3Atrue%7D%2C%22value%22%3A%22b%22%2C%22description%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Option%20B%22%2C%22emoji%22%3Atrue%7D%7D%2C%7B%22text%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22C%22%2C%22emoji%22%3Atrue%7D%2C%22value%22%3A%22c%22%2C%22description%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Option%20C%22%2C%22emoji%22%3Atrue%7D%7D%5D%7D%7D%2C%7B%22type%22%3A%22input%22%2C%22label%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Radio%20button%20group%20as%20input%20component%22%2C%22emoji%22%3Atrue%7D%2C%22optional%22%3Atrue%2C%22element%22%3A%7B%22type%22%3A%22radio_buttons%22%2C%22action_id%22%3A%22input-component%22%2C%22options%22%3A%5B%7B%22text%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22A%22%2C%22emoji%22%3Atrue%7D%2C%22value%22%3A%22a%22%2C%22description%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Option%20A%22%2C%22emoji%22%3Atrue%7D%7D%2C%7B%22text%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22B%22%2C%22emoji%22%3Atrue%7D%2C%22value%22%3A%22b%22%2C%22description%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Option%20B%22%2C%22emoji%22%3Atrue%7D%7D%2C%7B%22text%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22C%22%2C%22emoji%22%3Atrue%7D%2C%22value%22%3A%22c%22%2C%22description%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Option%20C%22%2C%22emoji%22%3Atrue%7D%7D%5D%7D%7D%5D%7D)

We've added a interface for input component too. User can migrate easily from `<Select>` / `<Option>` with just replacing component.

Resolves #88.

### ToDo

- [x] Allow using `<RadioButtonGroup>` in modal
- [x] Add interface as an input component
- [x] Fix existing tests
- [x] Update documentation

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 42a2c72..75780c7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,11 @@
 
 ## [Unreleased]
 
+### Added
+
+- Radio buttons for modal ([#88](https://github.com/speee/jsx-slack/issues/88), [#91](https://github.com/speee/jsx-slack/pull/91))
+  - `<RadioButtonGroup>` now can use in `<Modal>` container and acts as input component for modal
+
 ### Changed
 
 - Upgrade dependent packages to the latest version ([#90](https://github.com/speee/jsx-slack/pull/90))
diff --git a/demo/schema.js b/demo/schema.js
index 3cb9a81..10a7877 100644
--- a/demo/schema.js
+++ b/demo/schema.js
@@ -101,6 +101,7 @@ const schema = {
       'ConversationsSelect',
       'ChannelsSelect',
       'DatePicker',
+      'RadioButtonGroup',
     ],
   },
 
@@ -173,6 +174,7 @@ const schema = {
       'ConversationsSelect',
       'ChannelsSelect',
       'DatePicker',
+      'RadioButtonGroup',
     ],
   },
   input: {
@@ -192,6 +194,7 @@ const schema = {
       'ConversationsSelect',
       'ChannelsSelect',
       'DatePicker',
+      'RadioButtonGroup',
     ],
   },
 
@@ -300,7 +303,11 @@ const schema = {
     children: [],
   },
   RadioButtonGroup: {
-    attrs: { value: null, ...blockInteractiveCommonAttrs },
+    attrs: {
+      value: null,
+      ...blockInteractiveCommonAttrs,
+      ...inputComponentAttrs,
+    },
     children: ['RadioButton'],
   },
   RadioButton: { attrs: { value: null, description: null }, children: [] },
diff --git a/docs/block-elements.md b/docs/block-elements.md
index 64401b9..e5d76fc 100644
--- a/docs/block-elements.md
+++ b/docs/block-elements.md
@@ -379,11 +379,11 @@ An easy way to let the user selecting any date is using `<DatePicker>` component
 - `title`/ `hint` (optional): Specify a helpful text appears under the element.
 - `required` (optional): A boolean prop to specify whether any value must be filled when user confirms modal.
 
-### <a name="radio-button-group" id="radio-button-group"></a> [`<RadioButtonGroup>`: Radio button group](https://api.slack.com/reference/block-kit/block-elements#radio) (Only for home tab)
+### <a name="radio-button-group" id="radio-button-group"></a> [`<RadioButtonGroup>`: Radio button group](https://api.slack.com/reference/block-kit/block-elements#radio) (Only for modal and home tab)
 
 A container for grouping radio buttons. It provides easy control of the selected option through similar interface to [`<Select>`](#select).
 
-_This component is only for [`<Home>` container](block-containers.md#home)._
+_This component is only for [`<Modal>`](block-containers.md#modal) and [`<Home>`](block-containers.md#home) container. It cannot use in [`<Blocks>`](block-containers.md#blocks) container for messaging._
 
 ```jsx
 <Home>
@@ -393,7 +393,7 @@ _This component is only for [`<Home>` container](block-containers.md#home)._
       <RadioButton value="free" description="$0!">
         Free
       </RadioButton>
-      <RadioButton value="standard" description="$5/month + 30 days trial!">
+      <RadioButton value="standard" description="$5/month and 30 days trial!">
         Standard
       </RadioButton>
       <RadioButton value="premium" description="$30/month">
@@ -407,7 +407,7 @@ _This component is only for [`<Home>` container](block-containers.md#home)._
 </Home>
 ```
 
-[<img src="https://raw.githubusercontent.com/speee/jsx-slack/master/docs/preview-btn.svg?sanitize=true" width="240" />](https://api.slack.com/tools/block-kit-builder?mode=appHome&view=%7B%22type%22%3A%22home%22%2C%22blocks%22%3A%5B%7B%22type%22%3A%22section%22%2C%22text%22%3A%7B%22text%22%3A%22Select%20the%20tier%20of%20our%20service%3A%22%2C%22type%22%3A%22mrkdwn%22%2C%22verbatim%22%3Atrue%7D%2C%22accessory%22%3A%7B%22type%22%3A%22radio_buttons%22%2C%22action_id%22%3A%22tier%22%2C%22options%22%3A%5B%7B%22text%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Free%22%2C%22emoji%22%3Atrue%7D%2C%22value%22%3A%22free%22%2C%22description%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22%240!%22%2C%22emoji%22%3Atrue%7D%7D%2C%7B%22text%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Standard%22%2C%22emoji%22%3Atrue%7D%2C%22value%22%3A%22standard%22%2C%22description%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22%245%2Fmonth%20%2B%2030%20days%20trial!%22%2C%22emoji%22%3Atrue%7D%7D%2C%7B%22text%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Premium%22%2C%22emoji%22%3Atrue%7D%2C%22value%22%3A%22premium%22%2C%22description%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22%2430%2Fmonth%22%2C%22emoji%22%3Atrue%7D%7D%2C%7B%22text%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Business%22%2C%22emoji%22%3Atrue%7D%2C%22value%22%3A%22business%22%2C%22description%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Please%20contact%20to%20support.%22%2C%22emoji%22%3Atrue%7D%7D%5D%2C%22initial_option%22%3A%7B%22text%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Free%22%2C%22emoji%22%3Atrue%7D%2C%22value%22%3A%22free%22%2C%22description%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22%240!%22%2C%22emoji%22%3Atrue%7D%7D%7D%7D%5D%7D)
+[<img src="https://raw.githubusercontent.com/speee/jsx-slack/master/docs/preview-btn.svg?sanitize=true" width="240" />](https://api.slack.com/tools/block-kit-builder?mode=appHome&view=%7B%22type%22%3A%22home%22%2C%22blocks%22%3A%5B%7B%22type%22%3A%22section%22%2C%22text%22%3A%7B%22text%22%3A%22Select%20the%20tier%20of%20our%20service%3A%22%2C%22type%22%3A%22mrkdwn%22%2C%22verbatim%22%3Atrue%7D%2C%22accessory%22%3A%7B%22type%22%3A%22radio_buttons%22%2C%22action_id%22%3A%22tier%22%2C%22options%22%3A%5B%7B%22text%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Free%22%2C%22emoji%22%3Atrue%7D%2C%22value%22%3A%22free%22%2C%22description%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22%240!%22%2C%22emoji%22%3Atrue%7D%7D%2C%7B%22text%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Standard%22%2C%22emoji%22%3Atrue%7D%2C%22value%22%3A%22standard%22%2C%22description%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22%245%2Fmonth%20and%2030%20days%20trial!%22%2C%22emoji%22%3Atrue%7D%7D%2C%7B%22text%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Premium%22%2C%22emoji%22%3Atrue%7D%2C%22value%22%3A%22premium%22%2C%22description%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22%2430%2Fmonth%22%2C%22emoji%22%3Atrue%7D%7D%2C%7B%22text%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Business%22%2C%22emoji%22%3Atrue%7D%2C%22value%22%3A%22business%22%2C%22description%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Please%20contact%20to%20support.%22%2C%22emoji%22%3Atrue%7D%7D%5D%2C%22initial_option%22%3A%7B%22text%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Free%22%2C%22emoji%22%3Atrue%7D%2C%22value%22%3A%22free%22%2C%22description%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22%240!%22%2C%22emoji%22%3Atrue%7D%7D%7D%7D%5D%7D)
 
 #### Props
 
@@ -415,6 +415,47 @@ _This component is only for [`<Home>` container](block-containers.md#home)._
 - `value` (optional): A value for initial selected option. It must choose value from defined `<RadioButton>` elements in children.
 - `confirm` (optional): [`<Confirm>` element](#confirm) to show confirmation dialog.
 
+#### As [an input component for modal](#input-components-for-modal)
+
+In `<Modal>` container, `<RadioButtonGroup>` can place as `<Modal>`'s direct child by passing `label` prop as same as the input component for modal.
+
+```jsx
+<Modal title="Preferences" close="Cancel">
+  <RadioButtonGroup
+    label="Notifications"
+    id="notifications"
+    name="notifications"
+    title="Setting a frequency of notifications by app."
+    value="all"
+    required
+  >
+    <RadioButton
+      value="all"
+      description="Notify all received events every time."
+    >
+      All events
+    </RadioButton>
+    <RadioButton
+      value="summary"
+      description="Send a daily summary at AM 9:30 every day."
+    >
+      Daily summary
+    </RadioButton>
+    <RadioButton value="off">Off</RadioButton>
+  </RadioButtonGroup>
+  <Input type="submit" value="OK" />
+</Modal>
+```
+
+[<img src="https://raw.githubusercontent.com/speee/jsx-slack/master/docs/preview-btn.svg?sanitize=true" width="240" />](https://api.slack.com/tools/block-kit-builder?mode=modal&view=%7B%22type%22%3A%22modal%22%2C%22title%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Preferences%22%2C%22emoji%22%3Atrue%7D%2C%22submit%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22OK%22%2C%22emoji%22%3Atrue%7D%2C%22close%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Cancel%22%2C%22emoji%22%3Atrue%7D%2C%22blocks%22%3A%5B%7B%22type%22%3A%22input%22%2C%22block_id%22%3A%22notifications%22%2C%22hint%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Setting%20a%20frequency%20of%20notifications%20by%20app.%22%2C%22emoji%22%3Atrue%7D%2C%22label%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Notifications%22%2C%22emoji%22%3Atrue%7D%2C%22optional%22%3Afalse%2C%22element%22%3A%7B%22type%22%3A%22radio_buttons%22%2C%22action_id%22%3A%22notifications%22%2C%22options%22%3A%5B%7B%22text%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22All%20events%22%2C%22emoji%22%3Atrue%7D%2C%22value%22%3A%22all%22%2C%22description%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Notify%20all%20received%20events%20every%20time.%22%2C%22emoji%22%3Atrue%7D%7D%2C%7B%22text%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Daily%20summary%22%2C%22emoji%22%3Atrue%7D%2C%22value%22%3A%22summary%22%2C%22description%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Send%20a%20daily%20summary%20at%20AM%209%3A30%20every%20day.%22%2C%22emoji%22%3Atrue%7D%7D%2C%7B%22text%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Off%22%2C%22emoji%22%3Atrue%7D%2C%22value%22%3A%22off%22%7D%5D%2C%22initial_option%22%3A%7B%22text%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22All%20events%22%2C%22emoji%22%3Atrue%7D%2C%22value%22%3A%22all%22%2C%22description%22%3A%7B%22type%22%3A%22plain_text%22%2C%22text%22%3A%22Notify%20all%20received%20events%20every%20time.%22%2C%22emoji%22%3Atrue%7D%7D%7D%7D%5D%7D)
+
+##### Props for modal's input
+
+- `label` (**required**): The label string for the group.
+- `id` / `blockId` (optional): A string of unique identifier of [`<Input>` layout block](layout-blocks.md#input).
+- `title`/ `hint` (optional): Specify a helpful text appears under the group.
+- `required` (optional): A boolean prop to specify whether any value must be filled when user confirms modal.
+
 ### <a name="radio-button" id="radio-button"></a> `<RadioButton>`: Radio button
 
 #### Props
@@ -476,6 +517,7 @@ The list of input components is following:
 - [`<ConversationsSelect>`](#conversations-select)
 - [`<ChannelsSelect>`](#channels-select)
 - [`<DatePicker>`](#date-picker)
+- [`<RadioButtonGroup>`](#radio-button-group)
 
 ### <a name="input" id="input"></a> [`<Input>`: Plain-text input element](https://api.slack.com/reference/block-kit/block-elements#input)
 
diff --git a/docs/jsx-components-for-block-kit.md b/docs/jsx-components-for-block-kit.md
index 4d9a55f..2fe3633 100644
--- a/docs/jsx-components-for-block-kit.md
+++ b/docs/jsx-components-for-block-kit.md
@@ -35,7 +35,7 @@
 - [**`<Overflow>`**: Overflow menu](block-elements.md#overflow)
   - [**`<OverflowItem>`**: Menu item in overflow menu](block-elements.md#overflow-item)
 - [**`<DatePicker>`**: Select date from calendar](block-elements.md#date-picker)
-- [**`<RadioButtonGroup>`**: Radio button group](block-elements.md#radio-button-group) (Only for home tab)
+- [**`<RadioButtonGroup>`**: Radio button group](block-elements.md#radio-button-group) (Only for modal and home tab)
   - [**`<RadioButton>`**: Radio button](block-elements.md#radio-button)
 
 ### **[Composition objects](block-elements.md#composition-objects)**
diff --git a/docs/layout-blocks.md b/docs/layout-blocks.md
index 6b53b0f..67286b1 100644
--- a/docs/layout-blocks.md
+++ b/docs/layout-blocks.md
@@ -52,7 +52,7 @@ A one of accessory component may include as the children of `<Section>`. The def
 - [`<ChannelsSelect>`](block-elements.md#channels-select)
 - [`<Overflow>`](block-elements.md#overflow)
 - [`<DatePicker>`](block-elements.md#date-picker)
-- [`<RadioButtonGroup>`](block-elements.md#radio-button-group) (Only for [`<Home>` container](block-containers.md#home))
+- [`<RadioButtonGroup>`](block-elements.md#radio-button-group) (Only for [`<Modal>`](block-containers.md#modal) and [`<Home>`](block-containers.md#home) container)
 
 ### <a name="field" id="field"></a> `<Field>`: Fields for section block
 
@@ -218,6 +218,7 @@ If you want to use `<Input>` as layout block, you have to place one of [availabl
 - [`<ConversationsSelect>`](block-elements.md#conversations-select)
 - [`<ChannelsSelect>`](block-elements.md#channels-select)
 - [`<DatePicker>`](block-elements.md#date-picker)
+- [`<RadioButtonGroup>`](block-elements.md#radio-button-group)
 
 ### Note
 
diff --git a/src/block-kit/Blocks.tsx b/src/block-kit/Blocks.tsx
index 35015a1..81787b0 100644
--- a/src/block-kit/Blocks.tsx
+++ b/src/block-kit/Blocks.tsx
@@ -48,14 +48,8 @@ knownBlocks.set(InternalBlockType.Modal, [
   internalHiddenType,
   internalSubmitType,
 ])
-knownActions.set(
-  InternalBlockType.Modal,
-  actionTypes.filter(t => t !== 'radio_buttons')
-)
-knownSectionAccessories.set(
-  InternalBlockType.Modal,
-  sectionAccessoryTypes.filter(t => t !== 'radio_buttons')
-)
+knownActions.set(InternalBlockType.Modal, [...actionTypes])
+knownSectionAccessories.set(InternalBlockType.Modal, [...sectionAccessoryTypes])
 
 // Home
 knownBlocks.set(InternalBlockType.Home, basicBlocks)
diff --git a/src/block-kit/Input.tsx b/src/block-kit/Input.tsx
index 0579317..1664061 100644
--- a/src/block-kit/Input.tsx
+++ b/src/block-kit/Input.tsx
@@ -79,6 +79,7 @@ const knownInputs = [
   'multi_static_select',
   'multi_users_select',
   'plain_text_input',
+  'radio_buttons',
   'static_select',
   'users_select',
 ]
diff --git a/src/block-kit/elements/RadioButton.tsx b/src/block-kit/elements/RadioButton.tsx
index 7a34ad0..fb1b434 100644
--- a/src/block-kit/elements/RadioButton.tsx
+++ b/src/block-kit/elements/RadioButton.tsx
@@ -4,10 +4,11 @@ import { ConfirmProps } from '../composition/Confirm'
 import { plainText } from '../composition/utils'
 import { JSXSlack } from '../../jsx'
 import { ObjectOutput, PlainText, isNode } from '../../utils'
+import { WithInputProps, wrapInInput } from '../Input'
 
 const radioButtonInternal = Symbol('radioButtonInternal')
 
-export interface RadioButtonGroupProps {
+interface RadioButtonGroupPropsBase {
   actionId?: string
   children?: JSXSlack.Children<any>
   confirm?: JSXSlack.Node<ConfirmProps>
@@ -15,6 +16,8 @@ export interface RadioButtonGroupProps {
   value?: string
 }
 
+export type RadioButtonGroupProps = WithInputProps<RadioButtonGroupPropsBase>
+
 export interface RadioButtonProps {
   children: JSXSlack.Children<{}>
   description?: string
@@ -59,7 +62,7 @@ export const RadioButtonGroup: JSXSlack.FC<RadioButtonGroupProps> = props => {
     ? options.find(o => o.value === props.value)
     : undefined
 
-  return (
+  const element = (
     <ObjectOutput
       type="radio_buttons"
       action_id={props.actionId || props.name}
@@ -68,6 +71,8 @@ export const RadioButtonGroup: JSXSlack.FC<RadioButtonGroupProps> = props => {
       confirm={props.confirm ? JSXSlack(props.confirm) : undefined}
     />
   )
+
+  return props.label ? wrapInInput(element, props) : element
 }
 
 export const RadioButton: JSXSlack.FC<RadioButtonProps> = props => (


Test patch:
diff --git a/test/block-kit/block-elements/input-components-for-modal.tsx b/test/block-kit/block-elements/input-components-for-modal.tsx
index 48e978f..f13a861 100644
--- a/test/block-kit/block-elements/input-components-for-modal.tsx
+++ b/test/block-kit/block-elements/input-components-for-modal.tsx
@@ -8,6 +8,8 @@ import JSXSlack, {
   Input,
   Modal,
   Option,
+  RadioButton,
+  RadioButtonGroup,
   Select,
   Textarea,
   UsersSelect,
@@ -28,6 +30,11 @@ describe('Input components for modal', () => {
       ConversationsSelect,
       UsersSelect,
       DatePicker,
+      props => (
+        <RadioButtonGroup {...props}>
+          <RadioButton value="test">test</RadioButton>
+        </RadioButtonGroup>
+      ),
     ]) {
       expect(
         JSXSlack(
diff --git a/test/block-kit/block-elements/interactive-components.tsx b/test/block-kit/block-elements/interactive-components.tsx
index 8e80946..3132571 100644
--- a/test/block-kit/block-elements/interactive-components.tsx
+++ b/test/block-kit/block-elements/interactive-components.tsx
@@ -703,10 +703,10 @@ describe('Interactive components', () => {
         ).blocks
       ).toStrictEqual([action(radioButtonAction)])
 
-      // "confirm" prop and HTML-compatible props
+      // "confirm" prop and HTML-compatible props in <Modal>
       expect(
         JSXSlack(
-          <Home>
+          <Modal title="test">
             <Actions id="actions">
               <RadioButtonGroup
                 name="radio-buttons"
@@ -726,7 +726,7 @@ describe('Interactive components', () => {
                 <RadioButton value="third">3rd</RadioButton>
               </RadioButtonGroup>
             </Actions>
-          </Home>
+          </Modal>
         ).blocks
       ).toStrictEqual([
         action({
@@ -781,32 +781,18 @@ describe('Interactive components', () => {
       ).toThrow(/must include/i)
     })
 
-    it('throws error when using <RadioButtonGroup> within invalid container', () => {
-      const invalidContainers: JSXSlack.FC<{ children: any }>[] = [
-        Blocks,
-        ({ children }) => <Modal title="test">{children}</Modal>,
-      ]
-
-      const invalidBlocks: JSXSlack.FC<{ children: any }>[] = [
-        Actions,
-        ({ children }) => <Section>test{children}</Section>,
-      ]
-
-      for (const Container of invalidContainers) {
-        for (const Block of invalidBlocks) {
-          expect(() =>
-            JSXSlack(
-              <Container>
-                <Block>
-                  <RadioButtonGroup>
-                    <RadioButton value="a">A</RadioButton>
-                  </RadioButtonGroup>
-                </Block>
-              </Container>
-            )
-          ).toThrow(/incompatible/i)
-        }
-      }
-    })
+    it('throws error when using <RadioButtonGroup> within <Blocks> container', () =>
+      expect(() =>
+        JSXSlack(
+          <Blocks>
+            <Section>
+              test
+              <RadioButtonGroup>
+                <RadioButton value="a">A</RadioButton>
+              </RadioButtonGroup>
+            </Section>
+          </Blocks>
+        )
+      ).toThrow(/incompatible/i))
   })
 })