Skip to content

Commit e3e7aba

Browse files
authored
Section, TextDisplay
1 parent 49080e7 commit e3e7aba

File tree

1 file changed

+109
-11
lines changed

1 file changed

+109
-11
lines changed

discord/components.py

Lines changed: 109 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828
from typing import TYPE_CHECKING, Any, ClassVar, TypeVar
2929

30-
from .enums import ButtonStyle, ChannelType, ComponentType, InputTextStyle, try_enum
30+
from .enums import ButtonStyle, ChannelType, ComponentType, InputTextStyle, SeparatorSpacingSize, try_enum
3131
from .partial_emoji import PartialEmoji, _EmojiTag
3232
from .utils import MISSING, get_slots
3333

@@ -36,9 +36,19 @@
3636
from .types.components import ActionRow as ActionRowPayload
3737
from .types.components import ButtonComponent as ButtonComponentPayload
3838
from .types.components import Component as ComponentPayload
39+
from .types.components import BaseComponent as BaseComponentPayload
3940
from .types.components import InputText as InputTextComponentPayload
4041
from .types.components import SelectMenu as SelectMenuPayload
4142
from .types.components import SelectOption as SelectOptionPayload
43+
from .types.components import TextDisplayComponent as TextDisplayComponentPayload
44+
from .types.components import SectionComponent as SectionComponentPayload
45+
from .types.components import UnfurledMediaItem as UnfurledMediaItemPayload
46+
from .types.components import ThumbnailComponent as ThumbnailComponentPayload
47+
from .types.components import MediaGalleryItem as MediaGalleryItemPayload
48+
from .types.components import MediaGalleryComponent as MediaGalleryComponentPayload
49+
from .types.components import FileComponent as FileComponentPayload
50+
from .types.components import SeparatorComponent as SeparatorComponentPayload
51+
from .types.components import ContainerComponent as ContainerComponentPayload
4252

4353
__all__ = (
4454
"Component",
@@ -47,11 +57,12 @@
4757
"SelectMenu",
4858
"SelectOption",
4959
"InputText",
60+
"Section",
61+
"TextDisplay",
5062
)
5163

5264
C = TypeVar("C", bound="Component")
5365

54-
5566
class Component:
5667
"""Represents a Discord Bot UI Kit Component.
5768
@@ -69,12 +80,15 @@ class Component:
6980
----------
7081
type: :class:`ComponentType`
7182
The type of component.
83+
id: :class:`str`
84+
The component's ID.
7285
"""
7386

74-
__slots__: tuple[str, ...] = ("type",)
87+
__slots__: tuple[str, ...] = ("type", "id")
7588

7689
__repr_info__: ClassVar[tuple[str, ...]]
7790
type: ComponentType
91+
id: str
7892

7993
def __repr__(self) -> str:
8094
attrs = " ".join(f"{key}={getattr(self, key)!r}" for key in self.__repr_info__)
@@ -494,16 +508,100 @@ def to_dict(self) -> SelectOptionPayload:
494508
return payload
495509

496510

511+
class Section(Component):
512+
"""Represents a Section from Components V2.
513+
514+
This is a component that contains other components such as :class:`TextDisplay` and :class:`Thumbnail`.
515+
516+
This inherits from :class:`Component`.
517+
518+
.. versionadded:: 2.7
519+
520+
Attributes
521+
----------
522+
components: List[:class:`Component`]
523+
The components contained in this section.
524+
accessory: Optional[:class:`Component`]
525+
The accessory attached to this Section.
526+
"""
527+
528+
__slots__: tuple[str, ...] = ("components", "accessory")
529+
530+
__repr_info__: ClassVar[tuple[str, ...]] = __slots__
531+
532+
def __init__(self, data: SectionComponentPayload):
533+
self.type: ComponentType = try_enum(ComponentType, data["type"])
534+
self.id: str = data.get("id")
535+
self.components: list[Component] = [_component_factory(d) for d in data.get("components", [])]
536+
self.accessory: Component | None = None
537+
if _accessory := data.get("accessory"):
538+
self.accessory = _component_factory(_accessory)
539+
540+
def to_dict(self) -> SectionComponentPayload:
541+
payload = {
542+
"type": int(self.type),
543+
"id": self.id,
544+
"components": [c.to_dict() for c in self.components]
545+
}
546+
if self.accessory:
547+
payload["accessory"] = self.accessory.to_dict()
548+
return payload
549+
550+
551+
class TextDisplay(Component):
552+
"""Represents a Text Display from Components V2.
553+
554+
This is a component that displays text.
555+
556+
This inherits from :class:`Component`.
557+
558+
.. versionadded:: 2.7
559+
560+
Attributes
561+
----------
562+
content: :class:`str`
563+
The component's text content.
564+
"""
565+
566+
__slots__: tuple[str, ...] = ("content",)
567+
568+
__repr_info__: ClassVar[tuple[str, ...]] = __slots__
569+
570+
def __init__(self, data: TextDisplayComponentPayload):
571+
self.type: ComponentType = try_enum(ComponentType, data["type"])
572+
self.id: str = data.get("id")
573+
self.content: str = data.get("content")
574+
575+
def to_dict(self) -> TextDisplayComponentPayload:
576+
return {
577+
"type": int(self.type),
578+
"id": self.id,
579+
"content": self.content
580+
}
581+
582+
583+
COMPONENT_MAPPINGS = {
584+
1: ActionRow,
585+
2: Button,
586+
3: SelectMenu,
587+
4: InputText,
588+
5: SelectMenu,
589+
6: SelectMenu,
590+
7: SelectMenu,
591+
8: SelectMenu,
592+
9: Section,
593+
10: TextDisplay,
594+
11: None,
595+
12: None,
596+
13: None,
597+
14: None,
598+
17: None,
599+
}
600+
497601
def _component_factory(data: ComponentPayload) -> Component:
498602
component_type = data["type"]
499-
if component_type == 1:
500-
return ActionRow(data)
501-
elif component_type == 2:
502-
return Button(data) # type: ignore
503-
elif component_type == 4:
504-
return InputText(data) # type: ignore
505-
elif component_type in (3, 5, 6, 7, 8):
506-
return SelectMenu(data) # type: ignore
603+
if cls := COMPONENT_MAPPINGS.get(component_type):
604+
return cls(data)
507605
else:
508606
as_enum = try_enum(ComponentType, component_type)
509607
return Component._raw_construct(type=as_enum)

0 commit comments

Comments
 (0)