Skip to content

Bug: Incorrect passing of the "required" prop while using JSX components in modals #602

@Pawe-320

Description

@Pawe-320

Hi it's me again, and back at it with JSX Modals, this time it's the "required" prop, omitting it or especially setting it required={false} still makes the modal component required to interact with, same example as my previous issue:

import { ChatInputCommand, CommandData, Label, Modal, StringSelectMenu, StringSelectMenuOption, TextInput, UserSelectMenu } from "commandkit";
import { ApplicationCommandOptionType, TextInputStyle } from "discord.js";

export const command: CommandData = {
  name: "movement",
  description: "Issue a Staff Movement on a member",
  options: [
    {
      name: "target",
      description: "Who is the target of this command?",
      type: ApplicationCommandOptionType.User,
      required: true
    }
  ]
}

export const chatInput: ChatInputCommand = async ({ interaction }) => {
  const target = interaction.options.getUser("target", true)

  const correctModal = (
  <Modal title="Staff Movement Selection" customId="staffmovemententrymodal">
      <Label label="Member" description="The target of the command">
        <UserSelectMenu customId="member" minValues={1} maxValues={1} defaultValues={[target.id]} required/>
      </Label>
      <Label label="Movement Type">
        <StringSelectMenu customId="type" minValues={1} maxValues={1}> // Prop not present, yet field is required
          <StringSelectMenuOption label="Warning" value="warning" />
          <StringSelectMenuOption label="Strike" value="strike"/>
          <StringSelectMenuOption label="Suspension" description="Use it to initiate investigations" value="suspension"/>
          <StringSelectMenuOption label="Termination" value="termination"/>
          <StringSelectMenuOption label="Termination & Staff Blacklist" description="Use this for staff members that need to be blacklisted and terminated" value="termandbl"/>
          <StringSelectMenuOption label="Staff Blacklist" description="Use this for non-staff members that need to be blacklisted" value="blacklist"/>
          <StringSelectMenuOption label="Rank Movement" description="Promotions & Demotions, auto selected" value="rankmovement"/>
          <StringSelectMenuOption label="Reinstatement" value="reinstatement"/>
          <StringSelectMenuOption label="Retirement" value="retirement"/>
        </StringSelectMenu>
      </Label>
      <Label label="Reason">
        <TextInput customId="reason" style={TextInputStyle.Paragraph} required={false}/> // <- Here, set to false
      </Label>
      <Label label="Text Proof">
        <TextInput customId="textproof" style={TextInputStyle.Paragraph}/> // <- Prop omitted
      </Label>
    </Modal>)
  await interaction.showModal(correctModal)
  return;
}

Note

Setting "required" to any false-ish value (0, null) still provokes the field to become required, here's the modal in discord

Image

Weirdly enough, in packages/commandkit/src/components/interactive/modal/Modal.ts
The textinput props seem to pass in the required field just like all the others, I have no idea what can cause this behavior

export interface TextInputProps {
  customId: string;
  /**
   * @deprecated use the `<Label />` component instead.
   */
  label?: string;
  placeholder?: string;
  maxLength?: number;
  minLength?: number;
  value?: string;
  required?: boolean;
}

/**
 * The text input component.
 * @param props The text input properties.
 * @returns The commandkit element.
 * @example <TextInput customId="input" style={TextInputStyle.Short} />
 */
export function TextInput(
  props: TextInputProps & { style: TextInputStyle },
): CommandKitElement<'text-input'> {
  const input = new TextInputBuilder().setStyle(props.style);

  if (props.customId) {
    input.setCustomId(props.customId);
  }

  if (props.label) {
    warnDeprecated({
      what: 'Property `label`',
      where: '<TextInput />',
      message: 'Use the <Label /> component instead.',
    });

    input.setLabel(props.label);
  }

  if (props.placeholder) {
    input.setPlaceholder(props.placeholder);
  }

  if (props.maxLength) {
    input.setMaxLength(props.maxLength);
  }

  if (props.minLength) {
    input.setMinLength(props.minLength);
  }

  if (props.value) {
    input.setValue(props.value);
  }

  if (props.required) {
    input.setRequired(props.required);
  }

  return input;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions