Skip to content

Conversation

@Cenngo
Copy link
Collaborator

@Cenngo Cenngo commented Sep 17, 2025

This PR adds support for FileUpload, UserSelect, RoleSelect, ChannelSelect, MentionableSelect and SelectMenu to Interaction Framework.

To make modal generation/response flow more modular and make granular control possible, a new TypeConverter type called ModalComponentTypeConverter has been introduced. The new TypeConverter exposes a WriteAsync<>() method to allow the alteration of input component parameters when a RespondWithModal<>() extension method is called. 4 default TypeConverters are included in this PR for the following types: Array, Enum, IConvertible, Nullable.
With the default setup, User/Channel/Role/Mentionable select values can be automatically mapped to IUser[]/IRole[]/IChannel[] arrays. For SelectMenu components, just like with message component SelectMenus, the converter falls back to a TypeReader for converting the returned string values to the underlying CLR type. Enums can be used to auto-populate SelectMenu options and returned values can be mapped to regular enums if a single-select is used, to flags enums if a multi-select is used. [HideAttribute] used for SlashCommand parameters, can be used to hide select enum values,
and a new [SelectMenuOptionAttribute] can be used to define description, emote, and IsDefault values for individul enum values. A new [ModalSelectMenuOptionAttribute] can be used on properties marked with [ModalSelectMenuInputAttribute] to add select menu options decleratively. Nullable types can be used which use the ModalComponentTypeConverter assigned to the underlying type for convertion. TextInput and single-select menu values can be converted to IConvertible types. Instance values of the component properties are used to supply the default values of components. The default behaviour of all of the converters is that they use the property value of the modal instance to populate their respective components' default values. As always, every default behaviour defined in the default typeconverters can be overridden by defining custom typecoverters for the respective clr type. Text display component cannot have any assigned typeconverters and must be a type of string, its content is populated using the property value of the instance and falls back to the content provided in the attribute. [HideAttribute] now features an overrideable Predicate() method to selectively hide enum options on runtime.

Changes:

  • Added description field to [InputLabelAttribute]
  • Added [ModalFileUploadInputAttribute], [ModalMentionableSelectInputAttribute], [ModalRoleSelectInputAttribute], [ModalSelectMenuInputAttribute], [ModalTextDisplayAttribute], [ModalUserSelectInputAttribute]
  • Created IModalComponent entities to pave the road for more non-input components

Breaking Changes:

  • ModalBuilder.AddTextComponent() has been renamed to .AddTextInputComponent()
  • ModalBuilder.Components property now inherits from a stripped down version of IInputComponentBuilder which is called IModalComponentBuilder
  • InputComponentInfo now uses the new ModalComponentTypeConverter instead of ComponentTypeConverter with Write capabilities
  • ModalInfo.Components property now inherits from a stripped down version of InputComponentInfo which is called ModalComponentInfo (new InputComponents property can be used as a drop-in replacement)

Cenngo and others added 30 commits September 17, 2025 19:15
@Cenngo Cenngo requested a review from Misha-133 November 13, 2025 10:26
@Cenngo Cenngo marked this pull request as ready for review November 13, 2025 10:26
@Cenngo Cenngo requested a review from Misha-133 November 15, 2025 20:46
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.

2 participants