Skip to content

feat: Radio Groups & Checkboxes#3073

Open
NeloBlivion wants to merge 42 commits intoPycord-Development:masterfrom
NeloBlivion:checkbox
Open

feat: Radio Groups & Checkboxes#3073
NeloBlivion wants to merge 42 commits intoPycord-Development:masterfrom
NeloBlivion:checkbox

Conversation

@NeloBlivion
Copy link
Member

@NeloBlivion NeloBlivion commented Jan 21, 2026

Summary

Implements radio groups, checkbox groups, and checkboxes in modals
image
Alpha server only right now

Information

  • This PR fixes an issue.
  • This PR adds something new (e.g. new method or parameters).
  • This PR is a breaking change (e.g. methods or parameters removed/renamed).
  • This PR is not a code change (e.g. documentation, README, typehinting,
    examples, ...).

Checklist

  • I have searched the open pull requests for duplicates.
  • If code changes were made then they have been tested.
    • I have updated the documentation to reflect the changes.
  • If type: ignore comments were used, a comment is also left explaining why.
  • I have updated the changelog to include these changes.

@pycord-app
Copy link

pycord-app bot commented Jan 21, 2026

Thanks for opening this pull request!
Please make sure you have read the Contributing Guidelines and Code of Conduct.

This pull request can be checked-out with:

git fetch origin pull/3073/head:pr-3073
git checkout pr-3073

This pull request can be installed with:

pip install git+https://github.com/Pycord-Development/pycord@refs/pull/3073/head

Copy link
Member

@Lulalaby Lulalaby left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SMH blindly copying

Signed-off-by: Lala Sabathil <[email protected]>
@NeloBlivion NeloBlivion marked this pull request as ready for review January 21, 2026 05:50
@Paillat-dev Paillat-dev added this to the v2.8 milestone Jan 25, 2026
NeloBlivion and others added 4 commits February 8, 2026 00:09
Co-authored-by: Paillat <[email protected]>
Signed-off-by: Nelo <[email protected]>
Co-authored-by: JustaSqu1d <[email protected]>
Signed-off-by: Nelo <[email protected]>
Co-authored-by: JustaSqu1d <[email protected]>
Signed-off-by: Nelo <[email protected]>
Co-authored-by: JustaSqu1d <[email protected]>
Signed-off-by: Nelo <[email protected]>
@Paillat-dev Paillat-dev self-requested a review February 8, 2026 00:11
@NeloBlivion
Copy link
Member Author

todo:

  • update with generate_underlying

@Soheab Soheab added priority: medium Medium Priority status: in progress Work in Progess upcoming discord feature Involves a feature not yet fully released by Discord python Pull requests that update Python code components Related to discord components (Views + Modals) labels Feb 8, 2026
@Paillat-dev
Copy link
Member

Test Code
import logging
import os
from typing import override

from dotenv import load_dotenv

import discord

load_dotenv()
logging.basicConfig(level=logging.INFO)

bot = discord.Bot(intents=discord.Intents.all())


class WowModal(discord.ui.DesignerModal):
    def __init__(self):
        super().__init__(timeout=None, title="PYCORD IS AMAZING")
        self.add_item(
            discord.ui.Label(
                label="Enable",
                description="Enable or disable the bot",
                item=discord.ui.Checkbox(default=False),
            )
        )

    @override
    async def callback(self, interaction: discord.Interaction):
        await interaction.respond("Button clicked!")


@bot.slash_command(name="test_modalsv5")
async def test_modal(ctx: discord.ApplicationContext):
    await ctx.send_modal(WowModal())


bot.run(os.getenv("TOKEN_2"))

Fyi I encounter this:

Traceback (most recent call last):
  File "/home/paillat/Documents/pycord/pycord/discord/commands/core.py", line 138, in wrapped
    ret = await coro(arg)
          ^^^^^^^^^^^^^^^
  File "/home/paillat/Documents/pycord/pycord/discord/commands/core.py", line 1108, in _invoke
    await self.callback(ctx, **kwargs)
  File "/home/paillat/Documents/pycord/pycord/test_modals_v5.py", line 29, in test_modal
    await ctx.send_modal(WowModal())
                         ~~~~~~~~^^
  File "/home/paillat/Documents/pycord/pycord/test_modals_v5.py", line 18, in __init__
    self.add_item(discord.ui.Label(label="Enable", description="Enable or disable the bot", item=discord.ui.Checkbox(default=False)))
                  ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/paillat/Documents/pycord/pycord/discord/ui/label.py", line 124, in __init__
    self.set_item(item)
    ~~~~~~~~~~~~~^^^^^^
  File "/home/paillat/Documents/pycord/pycord/discord/ui/label.py", line 177, in set_item
    self._set_component_from_item(item)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/home/paillat/Documents/pycord/pycord/discord/ui/label.py", line 133, in _set_component_from_item
    self.underlying.component = item._generate_underlying()
                                ~~~~~~~~~~~~~~~~~~~~~~~~~^^
TypeError: Item._generate_underlying() missing 1 required positional argument: 'cls'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/paillat/Documents/pycord/pycord/discord/bot.py", line 1154, in invoke_application_command
    await ctx.command.invoke(ctx)
  File "/home/paillat/Documents/pycord/pycord/discord/commands/core.py", line 435, in invoke
    await injected(ctx)
  File "/home/paillat/Documents/pycord/pycord/discord/commands/core.py", line 146, in wrapped
    raise ApplicationCommandInvokeError(exc) from exc
discord.errors.ApplicationCommandInvokeError: Application Command raised an exception: TypeError: Item._generate_underlying() missing 1 required positional argument: 'cls'

@NeloBlivion
Copy link
Member Author

probably done?

Comment on lines +1781 to +1782
if self.default is not None:
payload["default"] = self.default
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't be None, should be in the initial payload.

Comment on lines +85 to +89
def __repr__(self) -> str:
attrs = " ".join(
f"{key}={getattr(self, key)!r}" for key in self.__item_repr_attributes__
)
return f"<{self.__class__.__name__} {attrs}>"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does it redefine this? It's handled by Item.

custom_id: Optional[:class:`str`]
The custom ID of the radio group that gets received during an interaction.
options: List[:class:`RadioGroupOption`]
A list of options that can be selected in this group.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could mention that this can only contain min 2 and max 10 items.

Comment on lines +112 to +116
def __repr__(self) -> str:
attrs = " ".join(
f"{key}={getattr(self, key)!r}" for key in self.__item_repr_attributes__
)
return f"<{self.__class__.__name__} {attrs}>"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as checkbox

Comment on lines +94 to +98
def __repr__(self) -> str:
attrs = " ".join(
f"{key}={getattr(self, key)!r}" for key in self.__item_repr_attributes__
)
return f"<{self.__class__.__name__} {attrs}>"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as checkbox

Comment on lines +156 to +157
if len(value) > 10:
raise ValueError("you may only provide up to 10 options.")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe also check the minimum (2)?

@Soheab
Copy link
Contributor

Soheab commented Feb 11, 2026

All version strings need changing to 2.8 too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

components Related to discord components (Views + Modals) priority: medium Medium Priority python Pull requests that update Python code status: in progress Work in Progess upcoming discord feature Involves a feature not yet fully released by Discord

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants