Skip to content

Commit 81e4ef7

Browse files
Select Support (#243)
Add select support to context, and tweak docs, select helpers
1 parent 080e684 commit 81e4ef7

File tree

3 files changed

+48
-10
lines changed

3 files changed

+48
-10
lines changed

discord_slash/context.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,16 @@ class InteractionContext:
2323
:ivar bot: discord.py client.
2424
:ivar _http: :class:`.http.SlashCommandRequest` of the client.
2525
:ivar _logger: Logger instance.
26+
:ivar data: The raw data of the interaction.
27+
:ivar values: The values sent with the interaction. Currently for selects.
2628
:ivar deferred: Whether the command is current deferred (loading state)
2729
:ivar _deferred_hidden: Internal var to check that state stays the same
2830
:ivar responded: Whether you have responded with a message to the interaction.
2931
:ivar guild_id: Guild ID of the command message. If the command was invoked in DM, then it is ``None``
3032
:ivar author_id: User ID representing author of the command message.
3133
:ivar channel_id: Channel ID representing channel of the command message.
3234
:ivar author: User or Member instance of the command invoke.
35+
3336
"""
3437

3538
def __init__(
@@ -47,6 +50,8 @@ def __init__(
4750
self._logger = logger
4851
self.deferred = False
4952
self.responded = False
53+
self.data = _json["data"]
54+
self.values = _json["data"]["values"] if "values" in _json["data"] else None
5055
self._deferred_hidden = False # To check if the patch to the deferred response matches
5156
self.guild_id = int(_json["guild_id"]) if "guild_id" in _json.keys() else None
5257
self.author_id = int(
@@ -283,7 +288,7 @@ class ComponentContext(InteractionContext):
283288
:ivar component: Component data retrieved from the message. Not available if the origin message was ephemeral.
284289
:ivar origin_message: The origin message of the component. Not available if the origin message was ephemeral.
285290
:ivar origin_message_id: The ID of the origin message.
286-
291+
:ivar selected_options: The options selected (only for selects)
287292
"""
288293

289294
def __init__(
@@ -309,6 +314,8 @@ def __init__(
309314
)
310315
self.component = self.origin_message.get_component(self.custom_id)
311316

317+
self.selected_options = _json["data"]["values"] if self.component_type == 3 else None
318+
312319
async def defer(self, hidden: bool = False, edit_origin: bool = False):
313320
"""
314321
'Defers' the response, showing a loading state to the user

discord_slash/utils/manage_components.py

+15-9
Original file line numberDiff line numberDiff line change
@@ -156,17 +156,21 @@ def create_select_option(
156156
"""
157157
Creates an option for select components.
158158
159-
.. warning::
160-
Currently, select components are not available for public use, nor do they have official documentation. The parameters will not be documented at this time.
161-
162-
:param label: The label of the option.
163-
:param value: The value that the bot will recieve when this option is selected.
159+
:param label: The user-facing name of the option that will be displayed in discord client.
160+
:param value: The value that the bot will receive when this option is selected.
164161
:param emoji: The emoji of the option.
165-
:param description: A description of the option.
162+
:param description: An additional description of the option.
166163
:param default: Whether or not this is the default option.
167164
"""
168165
emoji = emoji_to_dict(emoji)
169166

167+
if not len(label) or len(label) > 25:
168+
raise IncorrectFormat("Label length should be between 1 and 25.")
169+
if not len(value) or len(value) > 100:
170+
raise IncorrectFormat("Value length should be between 1 and 100.")
171+
if description is not None and len(description) > 50:
172+
raise IncorrectFormat("Description length must be 50 or lower.")
173+
170174
return {
171175
"label": label,
172176
"value": value,
@@ -186,9 +190,11 @@ def create_select(
186190
"""
187191
Creates a select (dropdown) component for use with the ``components`` field. Must be inside an ActionRow to be used (see :meth:`create_actionrow`).
188192
189-
190-
.. warning::
191-
Currently, select components are not available for public use, nor do they have official documentation. The parameters will not be documented at this time.
193+
:param options: The choices the user can pick from
194+
:param custom_id: A custom identifier, like buttons
195+
:param placeholder: Custom placeholder text if nothing is selected
196+
:param min_values: The minimum number of items that **must** be chosen
197+
:param max_values: The maximum number of items that **can** be chosen
192198
"""
193199
if not len(options) or len(options) > 25:
194200
raise IncorrectFormat("Options length should be between 1 and 25.")

docs/components.rst

+25
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,28 @@ How do I know which button was pressed?
9999
_______________________________________
100100

101101
Each button gets a ``custom_id`` (which is always a string), this is a unique identifier of which button is being pressed. You can specify what the ID is when you define your button, if you don't; a random one will be generated. When handling the event, simply check the custom_id, and handle accordingly.
102+
103+
What about selects / Dropdowns?
104+
_______________________________
105+
106+
Yep we support those too. You use them much the same as buttons:
107+
108+
.. code-block:: python
109+
110+
from discord_slash.utils.manage_components import create_select, create_select_option
111+
112+
select = create_select(
113+
options=[# the options in your dropdown
114+
create_select_option("Lab Coat", value="coat", emoji="🥼"),
115+
create_select_option("Test Tube", value="tube", emoji="🧪"),
116+
create_select_option("Petri Dish", value="dish", emoji="🧫"),
117+
],
118+
placeholder="Choose your option", # the placeholder text to show when no options have been chosen
119+
min_values=1, # the minimum number of options a user must select
120+
max_values=2, # the maximum number of options a user can select
121+
)
122+
123+
@bot.event
124+
async def on_component(ctx: ComponentContext):
125+
# ctx.selected_options is a list of all the values the user selected
126+
await ctx.send(content=f"You selected {ctx.selected_options}")

0 commit comments

Comments
 (0)