Move ActionRow to its own separate type split from Component
This commit is contained in:
		| @@ -24,29 +24,75 @@ DEALINGS IN THE SOFTWARE. | ||||
|  | ||||
| from __future__ import annotations | ||||
|  | ||||
| from typing import List, Optional, TYPE_CHECKING, Tuple, Type, TypeVar | ||||
| from typing import Any, ClassVar, Dict, List, Optional, TYPE_CHECKING, Tuple, Type, TypeVar | ||||
| from .enums import try_enum, ComponentType, ButtonStyle | ||||
| from .utils import get_slots | ||||
| from .partial_emoji import PartialEmoji | ||||
|  | ||||
| if TYPE_CHECKING: | ||||
|     from .types.components import ( | ||||
|         Component as ComponentPayload, | ||||
|         ButtonComponent as ButtonComponentPayload, | ||||
|         ComponentContainer as ComponentContainerPayload, | ||||
|         ActionRow as ActionRowPayload, | ||||
|     ) | ||||
|  | ||||
|  | ||||
| __all__ = ( | ||||
|     'Component', | ||||
|     'ActionRow', | ||||
|     'Button', | ||||
| ) | ||||
|  | ||||
| C = TypeVar('C', bound='Component') | ||||
|  | ||||
|  | ||||
| class Component: | ||||
|     """Represents a Discord Bot UI Kit Component. | ||||
|  | ||||
|     Currently, the only components supported by Discord are buttons and button groups. | ||||
|     Currently, the only components supported by Discord are: | ||||
|  | ||||
|     - :class:`ActionRow` | ||||
|     - :class:`Button` | ||||
|  | ||||
|     This class is abstract and cannot be instantiated. | ||||
|  | ||||
|     .. versionadded:: 2.0 | ||||
|  | ||||
|     Attributes | ||||
|     ------------ | ||||
|     type: :class:`ComponentType` | ||||
|         The type of component. | ||||
|     """ | ||||
|  | ||||
|     __slots__: Tuple[str, ...] = ('type',) | ||||
|  | ||||
|     __repr_info__: ClassVar[Tuple[str, ...]] | ||||
|     type: ComponentType | ||||
|  | ||||
|     def __repr__(self) -> str: | ||||
|         attrs = ' '.join(f'{key}={getattr(self, key)!r}' for key in self.__repr_info__) | ||||
|         return f'<{self.__class__.__name__} type={self.type!r} {attrs}>' | ||||
|  | ||||
|     @classmethod | ||||
|     def _raw_construct(cls: Type[C], **kwargs) -> C: | ||||
|         self: C = cls.__new__(cls) | ||||
|         for slot in get_slots(cls): | ||||
|             try: | ||||
|                 value = kwargs[slot] | ||||
|             except KeyError: | ||||
|                 pass | ||||
|             else: | ||||
|                 setattr(self, slot, value) | ||||
|         return self | ||||
|  | ||||
|     def to_dict(self) -> Dict[str, Any]: | ||||
|         raise NotImplementedError | ||||
|  | ||||
|  | ||||
| class ActionRow(Component): | ||||
|     """Represents a Discord Bot UI Kit Action Row. | ||||
|  | ||||
|     This is a component that holds up to 5 children components in a row. | ||||
|  | ||||
|     .. versionadded:: 2.0 | ||||
|  | ||||
| @@ -58,36 +104,21 @@ class Component: | ||||
|         The children components that this holds, if any. | ||||
|     """ | ||||
|  | ||||
|     __slots__: Tuple[str, ...] = ( | ||||
|         'type', | ||||
|         'children', | ||||
|     ) | ||||
|     __slots__: Tuple[str, ...] = ('children',) | ||||
|  | ||||
|     __repr_info__: ClassVar[Tuple[str, ...]] = __slots__ | ||||
|  | ||||
|     def __init__(self, data: ComponentPayload): | ||||
|         self.type: ComponentType = try_enum(ComponentType, data['type']) | ||||
|         self.children: List[Component] = [_component_factory(d) for d in data.get('components', [])] | ||||
|  | ||||
|     def __repr__(self) -> str: | ||||
|         attrs = ' '.join(f'{key}={getattr(self, key)!r}' for key in self.__slots__) | ||||
|         return f'<{self.__class__.__name__} type={self.type!r} {attrs}>' | ||||
|  | ||||
|     def to_dict(self) -> ComponentContainerPayload: | ||||
|     def to_dict(self) -> ActionRowPayload: | ||||
|         return { | ||||
|             'type': int(self.type), | ||||
|             'components': [child.to_dict() for child in self.children], | ||||
|         }  # type: ignore | ||||
|  | ||||
|  | ||||
|     @classmethod | ||||
|     def _raw_construct(cls: Type[C], **kwargs) -> C: | ||||
|         self: C = cls.__new__(cls) | ||||
|         slots = cls.__slots__ | ||||
|         for attr, value in kwargs.items(): | ||||
|             if attr in slots: | ||||
|                 setattr(self, attr, value) | ||||
|         return self | ||||
|  | ||||
|  | ||||
| class Button(Component): | ||||
|     """Represents a button from the Discord Bot UI Kit. | ||||
|  | ||||
| @@ -112,7 +143,7 @@ class Button(Component): | ||||
|         The emoji of the button, if available. | ||||
|     """ | ||||
|  | ||||
|     __slots__: Tuple[str, ...] = Component.__slots__ + ( | ||||
|     __slots__: Tuple[str, ...] = ( | ||||
|         'style', | ||||
|         'custom_id', | ||||
|         'url', | ||||
| @@ -121,6 +152,8 @@ class Button(Component): | ||||
|         'emoji', | ||||
|     ) | ||||
|  | ||||
|     __repr_info__: ClassVar[Tuple[str, ...]] = __slots__ | ||||
|  | ||||
|     def __init__(self, data: ButtonComponentPayload): | ||||
|         self.type: ComponentType = try_enum(ComponentType, data['type']) | ||||
|         self.style: ButtonStyle = try_enum(ButtonStyle, data['style']) | ||||
| @@ -152,11 +185,13 @@ class Button(Component): | ||||
|  | ||||
|         return payload  # type: ignore | ||||
|  | ||||
|  | ||||
| def _component_factory(data: ComponentPayload) -> Component: | ||||
|     component_type = data['type'] | ||||
|     if component_type == 1: | ||||
|         return Component(data) | ||||
|         return ActionRow(data) | ||||
|     elif component_type == 2: | ||||
|         return Button(data)  # type: ignore | ||||
|     else: | ||||
|         return Component(data) | ||||
|         as_enum = try_enum(ComponentType, component_type) | ||||
|         return Component._raw_construct(type=as_enum) | ||||
|   | ||||
| @@ -24,16 +24,16 @@ DEALINGS IN THE SOFTWARE. | ||||
|  | ||||
| from __future__ import annotations | ||||
|  | ||||
| from typing import Literal, TypedDict, Union | ||||
| from typing import List, Literal, TypedDict, Union | ||||
| from .emoji import PartialEmoji | ||||
|  | ||||
| ComponentType = Literal[1, 2] | ||||
| ButtonStyle = Literal[1, 2, 3, 4, 5] | ||||
|  | ||||
|  | ||||
| class ComponentContainer(TypedDict): | ||||
| class ActionRow(TypedDict): | ||||
|     type: Literal[1] | ||||
|     components: Component | ||||
|     components: List[Component] | ||||
|  | ||||
|  | ||||
| class _ButtonComponentOptional(TypedDict, total=False): | ||||
| @@ -48,4 +48,4 @@ class ButtonComponent(_ButtonComponentOptional): | ||||
|     style: ButtonStyle | ||||
|  | ||||
|  | ||||
| Component = Union[ComponentContainer, ButtonComponent] | ||||
| Component = Union[ActionRow, ButtonComponent] | ||||
|   | ||||
| @@ -2885,6 +2885,14 @@ Component | ||||
| .. autoclass:: Component() | ||||
|     :members: | ||||
|  | ||||
| ActionRow | ||||
| ~~~~~~~~~~ | ||||
|  | ||||
| .. attributetable:: ActionRow | ||||
|  | ||||
| .. autoclass:: ActionRow() | ||||
|     :members: | ||||
|  | ||||
| Button | ||||
| ~~~~~~~ | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user