Skip to content

Conversation

AstreaTSS
Copy link
Member

@AstreaTSS AstreaTSS commented Sep 18, 2025

Pull Request Type

  • Feature addition
  • Bugfix
  • Documentation update
  • Code refactor
  • Tests improvement
  • CI/CD pipeline enhancement
  • Other: [Replace with a description]

Description

This PR adds support for using select menus in modals, as Discord recently added this.

To use select menus, users must use the new LabelComponent, which also allows adding more flexible labels to questions. Select menus there function how one would expect with the addition of a new required value to control if they are required or not.

To get the values the user selects from these menus, responses in ModalContext has been changed to be dict[str, Any] as opposed to dict[str, str]. This is a breaking change, but it shouldn't be considered a feature that cannot be merged until v6 because:

  • This shouldn't break things for most users. InputText still returns a string, as expected. This only potentially breaks things if one were iterating through responses.
  • This is Discord changing things up, not us.

Changes

  • Added LabelComponent.
  • Adjusted Modal to be able to handle LabelComponent.
  • 💥 Made responses for ModalContext dict[str, Any].
    • See the description for a better explanation.
    • Currently, all of the new methods return lists, so theoretically this could be dict[str, str | list] - Discord plans on adding more components that break this assumption, though.
  • Made ModalContext able to handle LabelComponent and select menus.

Related Issues

Test Scenarios

import interactions as ipy

@ipy.slash_command()
async def test(ctx: ipy.SlashContext) -> None:
    modal = ipy.Modal(
        ipy.LabelComponent(
            label="Question 1",
            component=ipy.UserSelectMenu(
                custom_id="user",
                placeholder="Select a user",
                min_values=1,
                max_values=1,
                required=True,
            )
        ),
        ipy.LabelComponent(
            label="Question 2",
            component=ipy.ChannelSelectMenu(
                custom_id="channel",
                placeholder="Select a channel",
                min_values=1,
                max_values=1,
                required=True,
            )
        ),
        ipy.LabelComponent(
            label="Question 3",
            component=ipy.RoleSelectMenu(
                custom_id="role",
                placeholder="Select a role",
                min_values=1,
                max_values=1,
                required=True,
            )
        ),
        ipy.LabelComponent(
            label="Question 4",
            component=ipy.MentionableSelectMenu(
                custom_id="mentionable",
                placeholder="Select a mentionable",
                min_values=1,
                max_values=1,
                required=True,
            )
        ),
        ipy.LabelComponent(
            label="Question 5",
            component=ipy.StringSelectMenu(
                ipy.StringSelectOption(label="Option 1", value="option_1"),
                ipy.StringSelectOption(label="Option 2", value="option_2"),
                ipy.StringSelectOption(label="Option 3", value="option_3"),
                custom_id="string",
                placeholder="Select an option",
                min_values=1,
                max_values=1,
                required=True,
            )
        ),
        title="Test Modal",
        custom_id="test_modal"
    )
    await ctx.send_modal(modal)


@ipy.modal_callback("test_modal")
async def test_modal_response(ctx: ipy.ModalContext) -> None:
    await ctx.send(
        f"You selected:\n"
        f"User: {ctx.responses["user"][0].mention}\n"
        f"Channel: {ctx.responses["channel"][0].mention}\n"
        f"Role: {ctx.responses["role"][0].mention}\n"
        f"Mentionable: {ctx.responses["mentionable"][0].mention}\n"
        f"String: {ctx.responses["string"][0]}"
    )

Python Compatibility

  • I've ensured my code works on Python 3.10.x
  • I've ensured my code works on Python 3.11.x

Checklist

  • I've run the pre-commit code linter over all edited files
  • I've tested my changes on supported Python versions
  • I've added tests for my code, if applicable
  • I've updated / added documentation, where applicable

Many attempts have been made to make this non-breaking - this means the UX is a little bit off.
Also, as title says, untested.
This requires breaking the assumption that responses always has string keys. That being said, since this is Discord breaking things, not us, this should be fine for a non-breaking release.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant