Skip to content

Commit

Permalink
Implement new selects (#1702)
Browse files Browse the repository at this point in the history
* feat: initial implementation of selects v2

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix: bugs

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* feat: add new classes and methods to docs

* fix: add new classes to __all__

* fix: title underlines

* fix: ComponentType refs

* refactor: make value parsing somewhat consistent

* Update discord/ui/select.py

Co-authored-by: Dorukyum <53639936+Dorukyum@users.noreply.github.com>

* Update select.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* feat: update docs

* feat: redo impl for one select class

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Delete api.rst

* Update ui_kit.rst

* Update models.rst

* Update discord/ui/select.py

Co-authored-by: Dorukyum <53639936+Dorukyum@users.noreply.github.com>

* Update discord/ui/select.py

Co-authored-by: NeloBlivion <41271523+NeloBlivion@users.noreply.github.com>

* Update components.py

* Update components.py

* Update components.py

* Update select.py

* Update enums.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* alias

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* add string_select to __all__

* update docs

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Dorukyum <53639936+Dorukyum@users.noreply.github.com>
Co-authored-by: BobDotCom <71356958+BobDotCom@users.noreply.github.com>
Co-authored-by: Lala Sabathil <lala@pycord.dev>
Co-authored-by: Lala Sabathil <aiko@aitsys.dev>
Co-authored-by: NeloBlivion <41271523+NeloBlivion@users.noreply.github.com>
  • Loading branch information
7 people committed Nov 4, 2022
1 parent 20bed13 commit 8c408fc
Show file tree
Hide file tree
Showing 7 changed files with 383 additions and 32 deletions.
35 changes: 28 additions & 7 deletions discord/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

from typing import TYPE_CHECKING, Any, ClassVar, TypeVar

from .enums import ButtonStyle, ComponentType, InputTextStyle, try_enum
from .enums import ButtonStyle, ChannelType, ComponentType, InputTextStyle, try_enum
from .partial_emoji import PartialEmoji, _EmojiTag
from .utils import MISSING, get_slots

Expand All @@ -40,7 +40,6 @@
from .types.components import SelectMenu as SelectMenuPayload
from .types.components import SelectOption as SelectOptionPayload


__all__ = (
"Component",
"ActionRow",
Expand Down Expand Up @@ -293,8 +292,15 @@ class SelectMenu(Component):
.. versionadded:: 2.0
.. versionchanged:: 2.3
Added support for :attr:`ComponentType.user_select`, :attr:`ComponentType.role_select`,
:attr:`ComponentType.mentionable_select`, and :attr:`ComponentType.channel_select`.
Attributes
----------
type: :class:`ComponentType`
The select menu's type.
custom_id: Optional[:class:`str`]
The ID of the select menu that gets received during an interaction.
placeholder: Optional[:class:`str`]
Expand All @@ -307,6 +313,12 @@ class SelectMenu(Component):
Defaults to 1 and must be between 1 and 25.
options: List[:class:`SelectOption`]
A list of options that can be selected in this menu.
Will be an empty list for all component types
except for :attr:`ComponentType.string_select`.
channel_types: List[:class:`ChannelType`]
A list of channel types that can be selected.
Will be an empty list for all component types
except for :attr:`ComponentType.channel_select`.
disabled: :class:`bool`
Whether the select is disabled or not.
"""
Expand All @@ -317,40 +329,47 @@ class SelectMenu(Component):
"min_values",
"max_values",
"options",
"channel_types",
"disabled",
)

__repr_info__: ClassVar[tuple[str, ...]] = __slots__

def __init__(self, data: SelectMenuPayload):
self.type = ComponentType.select
self.type = try_enum(ComponentType, data["type"])
self.custom_id: str = data["custom_id"]
self.placeholder: str | None = data.get("placeholder")
self.min_values: int = data.get("min_values", 1)
self.max_values: int = data.get("max_values", 1)
self.disabled: bool = data.get("disabled", False)
self.options: list[SelectOption] = [
SelectOption.from_dict(option) for option in data.get("options", [])
]
self.disabled: bool = data.get("disabled", False)
self.channel_types: list[ChannelType] = [
try_enum(ChannelType, ct) for ct in data.get("channel_types", [])
]

def to_dict(self) -> SelectMenuPayload:
payload: SelectMenuPayload = {
"type": self.type.value,
"custom_id": self.custom_id,
"min_values": self.min_values,
"max_values": self.max_values,
"options": [op.to_dict() for op in self.options],
"disabled": self.disabled,
}

if self.type is ComponentType.string_select:
payload["options"] = [op.to_dict() for op in self.options]
if self.type is ComponentType.channel_select and self.channel_types:
payload["channel_types"] = [ct.value for ct in self.channel_types]
if self.placeholder:
payload["placeholder"] = self.placeholder

return payload


class SelectOption:
"""Represents a select menu's option.
"""Represents a :class:`discord.SelectMenu`'s option.
These can be created by users.
Expand Down Expand Up @@ -474,7 +493,9 @@ def _component_factory(data: ComponentPayload) -> Component:
return ActionRow(data)
elif component_type == 2:
return Button(data) # type: ignore
elif component_type == 3:
elif component_type == 4:
return InputText(data) # type: ignore
elif component_type in (3, 5, 6, 7, 8):
return SelectMenu(data) # type: ignore
else:
as_enum = try_enum(ComponentType, component_type)
Expand Down
7 changes: 6 additions & 1 deletion discord/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -654,8 +654,13 @@ class ComponentType(Enum):

action_row = 1
button = 2
select = 3
string_select = 3
select = string_select # (deprecated) alias for string_select
input_text = 4
user_select = 5
role_select = 6
mentionable_select = 7
channel_select = 8

def __int__(self):
return self.value
Expand Down
6 changes: 4 additions & 2 deletions discord/types/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from typing import Literal, Union

from .._typed_dict import NotRequired, TypedDict
from .channel import ChannelType
from .emoji import PartialEmoji

ComponentType = Literal[1, 2, 3, 4]
Expand Down Expand Up @@ -75,9 +76,10 @@ class SelectMenu(TypedDict):
min_values: NotRequired[int]
max_values: NotRequired[int]
disabled: NotRequired[bool]
type: Literal[3]
channel_types: NotRequired[list[ChannelType]]
options: NotRequired[list[SelectOption]]
type: Literal[3, 5, 6, 7, 8]
custom_id: str
options: list[SelectOption]


Component = Union[ActionRow, ButtonComponent, SelectMenu, InputText]

0 comments on commit 8c408fc

Please sign in to comment.