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

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions