Add example showcasing ui.Label in modals

This commit is contained in:
Rapptz 2025-08-17 20:02:21 -04:00
parent 22d6e8d0aa
commit eb84d0dfcb

98
examples/modals/label.py Normal file
View File

@ -0,0 +1,98 @@
import datetime
import discord
from discord import app_commands
import traceback
# The guild in which this slash command will be registered.
# It is recommended to have a test guild to separate from your "production" bot
TEST_GUILD = discord.Object(0)
class MyClient(discord.Client):
# Suppress error on the User attribute being None since it fills up later
user: discord.ClientUser
def __init__(self) -> None:
# Just default intents and a `discord.Client` instance
# We don't need a `commands.Bot` instance because we are not
# creating text-based commands.
intents = discord.Intents.default()
super().__init__(intents=intents)
# We need an `discord.app_commands.CommandTree` instance
# to register application commands (slash commands in this case)
self.tree = app_commands.CommandTree(self)
async def on_ready(self):
print(f'Logged in as {self.user} (ID: {self.user.id})')
print('------')
async def setup_hook(self) -> None:
# Sync the application command with Discord.
await self.tree.sync(guild=TEST_GUILD)
class TimeoutModal(discord.ui.Modal, title='Timeout Member'):
# We can use a Label to attach a rich label and description to our item.
duration = discord.ui.Label(
text='Duration',
description='How long to timeout the member for.',
component=discord.ui.Select(
options=[
discord.SelectOption(label='1 minute', value='60'),
discord.SelectOption(label='5 minutes', value='300'),
discord.SelectOption(label='10 minutes', value='600'),
discord.SelectOption(label='30 minutes', value='1800'),
discord.SelectOption(label='1 hour', value='3600'),
],
),
)
reason = discord.ui.Label(
text='Reason',
description='The reason for the timeout.',
component=discord.ui.TextInput(
style=discord.TextStyle.short,
max_length=256,
),
)
def __init__(self, member: discord.Member) -> None:
self.member = member
super().__init__()
async def on_submit(self, interaction: discord.Interaction):
# Tell the type checker what our components are...
assert isinstance(self.duration.component, discord.ui.Select)
assert isinstance(self.reason.component, discord.ui.TextInput)
until = discord.utils.utcnow() + datetime.timedelta(seconds=int(self.duration.component.values[0]))
await self.member.timeout(until, reason=self.reason.component.value)
await interaction.response.send_message(
f'Timeout {self.member.mention} until {discord.utils.format_dt(until)} with reason: {self.reason.component.value}',
ephemeral=True,
)
async def on_error(self, interaction: discord.Interaction, error: Exception) -> None:
await interaction.response.send_message('Oops! Something went wrong.', ephemeral=True)
# Make sure we know what the error actually is
traceback.print_exception(type(error), error, error.__traceback__)
client = MyClient()
@client.tree.command(guild=TEST_GUILD, description="Timeout a member")
async def timeout(interaction: discord.Interaction, member: discord.Member):
# Send the modal with an instance of our `TimeoutModal` class
# Since modals require an interaction, they cannot be done as a response to a text command.
# They can only be done as a response to either an application command or a button press.
# Do note that this example is illustrative, Discord comes with this timeout feature natively
# and does not need this command or modal.
await interaction.response.send_modal(TimeoutModal(member))
client.run('token')