5858 from .types .components import SeparatorComponent as SeparatorComponentPayload
5959 from .types .components import TextDisplayComponent as TextDisplayComponentPayload
6060 from .types .components import ThumbnailComponent as ThumbnailComponentPayload
61+ from .types .components import LabelComponent as LabelComponentPayload
6162 from .types .components import UnfurledMediaItem as UnfurledMediaItemPayload
6263
6364__all__ = (
7677 "FileComponent" ,
7778 "Separator" ,
7879 "Container" ,
80+ "Label" ,
7981)
8082
8183C = TypeVar ("C" , bound = "Component" )
@@ -375,6 +377,10 @@ class SelectMenu(Component):
375377 Added support for :attr:`ComponentType.user_select`, :attr:`ComponentType.role_select`,
376378 :attr:`ComponentType.mentionable_select`, and :attr:`ComponentType.channel_select`.
377379
380+ .. versionchanged:: 2.7
381+
382+ Added the :attr:`required` attribute for use in modals.
383+
378384 Attributes
379385 ----------
380386 type: :class:`ComponentType`
@@ -399,6 +405,8 @@ class SelectMenu(Component):
399405 except for :attr:`ComponentType.channel_select`.
400406 disabled: :class:`bool`
401407 Whether the select is disabled or not.
408+ required: Optional[:class:`bool`]
409+ Whether the select is required or not. Only useable in modals. Defaults to ``False``.
402410 """
403411
404412 __slots__ : tuple [str , ...] = (
@@ -409,6 +417,7 @@ class SelectMenu(Component):
409417 "options" ,
410418 "channel_types" ,
411419 "disabled" ,
420+ "required" ,
412421 )
413422
414423 __repr_info__ : ClassVar [tuple [str , ...]] = __slots__
@@ -428,6 +437,7 @@ def __init__(self, data: SelectMenuPayload):
428437 self .channel_types : list [ChannelType ] = [
429438 try_enum (ChannelType , ct ) for ct in data .get ("channel_types" , [])
430439 ]
440+ self .required : bool | None = data .get ("required" ) # Currently defaults to False, pending change
431441
432442 def to_dict (self ) -> SelectMenuPayload :
433443 payload : SelectMenuPayload = {
@@ -445,6 +455,8 @@ def to_dict(self) -> SelectMenuPayload:
445455 payload ["channel_types" ] = [ct .value for ct in self .channel_types ]
446456 if self .placeholder :
447457 payload ["placeholder" ] = self .placeholder
458+ if self .required is not None :
459+ payload ["required" ] = self .required
448460
449461 return payload
450462
@@ -1037,6 +1049,55 @@ def walk_components(self) -> Iterator[Component]:
10371049 yield c
10381050
10391051
1052+ class Label (Component ):
1053+ """Represents a Label used in modals as the top-level component.
1054+
1055+ This is a component that holda another component alongside additional text in modals.
1056+ ``component`` may only be:
1057+
1058+ - :class:`InputText`
1059+ - :class:`SelectMenu` (string)
1060+
1061+ This inherits from :class:`Component`.
1062+
1063+ .. versionadded:: 2.7
1064+
1065+ Attributes
1066+ ----------
1067+ component: :class:`Component`
1068+ The component contained in this label. Currently supports :class:`InputText` and :class:`SelectMenu`.
1069+ label: :class:`str`
1070+ The main text associated with this label's ``component``.
1071+ description: Optional[:class:`str`]
1072+ The description associated with this label's ``component``.
1073+ """
1074+
1075+ __slots__ : tuple [str , ...] = ("component" , "label" , "description" )
1076+
1077+ __repr_info__ : ClassVar [tuple [str , ...]] = __slots__
1078+ versions : tuple [int , ...] = ()
1079+
1080+ def __init__ (self , data : LabelComponentPayload ):
1081+ self .type : ComponentType = try_enum (ComponentType , data ["type" ])
1082+ self .id : int = data .get ("id" )
1083+ self .component : Component = _component_factory (data .get ("component" , {}))
1084+ self .label : str = data .get ("label" )
1085+ self .description : str | None = data .get ("description" )
1086+
1087+ def to_dict (self ) -> LabelComponentPayload :
1088+ payload = {
1089+ "type" : int (self .type ),
1090+ "id" : self .id ,
1091+ "component" : self .components .to_dict (),
1092+ "label" : self .label ,
1093+ "description" : self .description
1094+ }
1095+ return payload
1096+
1097+ def walk_components (self ) -> Iterator [Component ]:
1098+ yield from [self .component ]
1099+
1100+
10401101COMPONENT_MAPPINGS = {
10411102 1 : ActionRow ,
10421103 2 : Button ,
@@ -1053,6 +1114,7 @@ def walk_components(self) -> Iterator[Component]:
10531114 13 : FileComponent ,
10541115 14 : Separator ,
10551116 17 : Container ,
1117+ 18 : Label ,
10561118}
10571119
10581120STATE_COMPONENTS = (Section , Container , Thumbnail , MediaGallery , FileComponent )
0 commit comments