mirror of
https://github.com/discordjs/discord.js.git
synced 2026-05-31 08:00:07 +00:00
175 lines
5.2 KiB
TypeScript
175 lines
5.2 KiB
TypeScript
import type { APICheckboxGroupComponent, APICheckboxGroupOption } from 'discord-api-types/v10';
|
|
import { ComponentType } from 'discord-api-types/v10';
|
|
import type { RestOrArray } from '../../util/normalizeArray';
|
|
import { normalizeArray } from '../../util/normalizeArray';
|
|
import { ComponentBuilder } from '../Component';
|
|
import { checkboxGroupOptionPredicate, checkboxGroupPredicate } from './Assertions';
|
|
import { CheckboxGroupOptionBuilder } from './CheckboxGroupOption';
|
|
|
|
/**
|
|
* A builder that creates API-compatible JSON data for checkbox groups.
|
|
*/
|
|
export class CheckboxGroupBuilder extends ComponentBuilder<APICheckboxGroupComponent> {
|
|
/**
|
|
* The options within this checkbox group.
|
|
*/
|
|
public readonly options: CheckboxGroupOptionBuilder[];
|
|
|
|
/**
|
|
* Creates a new checkbox group from API data.
|
|
*
|
|
* @param data - The API data to create this checkbox group with
|
|
* @example
|
|
* Creating a checkbox group from an API data object:
|
|
* ```ts
|
|
* const checkboxGroup = new CheckboxGroupBuilder({
|
|
* custom_id: 'select_options',
|
|
* options: [
|
|
* { label: 'Option 1', value: 'option_1' },
|
|
* { label: 'Option 2', value: 'option_2' },
|
|
* ],
|
|
* });
|
|
* ```
|
|
* @example
|
|
* Creating a checkbox group using setters and API data:
|
|
* ```ts
|
|
* const checkboxGroup = new CheckboxGroupBuilder()
|
|
* .setCustomId('choose_items')
|
|
* .setOptions([
|
|
* { label: 'Item A', value: 'item_a' },
|
|
* { label: 'Item B', value: 'item_b' },
|
|
* ])
|
|
* .setMinValues(1)
|
|
* .setMaxValues(2);
|
|
* ```
|
|
*/
|
|
public constructor(data?: Partial<APICheckboxGroupComponent>) {
|
|
const { options, ...initData } = data ?? {};
|
|
super({ ...initData, type: ComponentType.CheckboxGroup });
|
|
this.options = options?.map((option: APICheckboxGroupOption) => new CheckboxGroupOptionBuilder(option)) ?? [];
|
|
}
|
|
|
|
/**
|
|
* Sets the custom id of this checkbox group.
|
|
*
|
|
* @param customId - The custom id to use
|
|
*/
|
|
public setCustomId(customId: string) {
|
|
this.data.custom_id = customId;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Adds options to this checkbox group.
|
|
*
|
|
* @param options - The options to add
|
|
*/
|
|
public addOptions(...options: RestOrArray<APICheckboxGroupOption | CheckboxGroupOptionBuilder>) {
|
|
const normalizedOptions = normalizeArray(options);
|
|
|
|
this.options.push(
|
|
...normalizedOptions.map((normalizedOption) => {
|
|
// I do this because TS' duck typing causes issues,
|
|
// if I put in a RadioGroupOption, TS lets it pass but
|
|
// it fails to convert to a checkbox group option at runtime
|
|
const json = 'toJSON' in normalizedOption ? normalizedOption.toJSON() : normalizedOption;
|
|
const option = new CheckboxGroupOptionBuilder(json);
|
|
checkboxGroupOptionPredicate.parse(option.toJSON());
|
|
return option;
|
|
}),
|
|
);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets the options for this checkbox group.
|
|
*
|
|
* @param options - The options to use
|
|
*/
|
|
public setOptions(...options: RestOrArray<APICheckboxGroupOption | CheckboxGroupOptionBuilder>) {
|
|
return this.spliceOptions(0, this.options.length, ...options);
|
|
}
|
|
|
|
/**
|
|
* Removes, replaces, or inserts options for this checkbox group.
|
|
*
|
|
* @remarks
|
|
* This method behaves similarly
|
|
* to {@link https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/splice | Array.prototype.splice()}.
|
|
* It's useful for modifying and adjusting the order of existing options.
|
|
* @param index - The index to start at
|
|
* @param deleteCount - The number of options to remove
|
|
* @param options - The replacing option objects or builders
|
|
*/
|
|
public spliceOptions(
|
|
index: number,
|
|
deleteCount: number,
|
|
...options: RestOrArray<APICheckboxGroupOption | CheckboxGroupOptionBuilder>
|
|
) {
|
|
const normalizedOptions = normalizeArray(options);
|
|
|
|
const clone = [...this.options];
|
|
|
|
clone.splice(
|
|
index,
|
|
deleteCount,
|
|
...normalizedOptions.map((normalizedOption) => {
|
|
// I do this because TS' duck typing causes issues,
|
|
// if I put in a RadioGroupOption, TS lets it pass but
|
|
// it fails to convert to a checkbox group option at runtime
|
|
const json = 'toJSON' in normalizedOption ? normalizedOption.toJSON() : normalizedOption;
|
|
const option = new CheckboxGroupOptionBuilder(json);
|
|
checkboxGroupOptionPredicate.parse(option.toJSON());
|
|
return option;
|
|
}),
|
|
);
|
|
|
|
this.options.splice(0, this.options.length, ...clone);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets the minimum number of options that must be selected.
|
|
*
|
|
* @param minValues - The minimum number of options that must be selected
|
|
*/
|
|
public setMinValues(minValues: number) {
|
|
this.data.min_values = minValues;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets the maximum number of options that can be selected.
|
|
*
|
|
* @param maxValues - The maximum number of options that can be selected
|
|
*/
|
|
public setMaxValues(maxValues: number) {
|
|
this.data.max_values = maxValues;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets whether selecting options is required.
|
|
*
|
|
* @param required - Whether selecting options is required
|
|
*/
|
|
public setRequired(required: boolean) {
|
|
this.data.required = required;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc ComponentBuilder.toJSON}
|
|
*/
|
|
public override toJSON(): APICheckboxGroupComponent {
|
|
const data = {
|
|
...this.data,
|
|
options: this.options.map((option) => option.toJSON()),
|
|
};
|
|
|
|
checkboxGroupPredicate.parse(data);
|
|
|
|
return data as APICheckboxGroupComponent;
|
|
}
|
|
}
|