Skip to content

Commit

Permalink
Add types for new custom HTMLElements and form field functions (fou…
Browse files Browse the repository at this point in the history
  • Loading branch information
In3luki authored and CarlosFdez committed May 29, 2024
1 parent 50a2fa1 commit eebce53
Show file tree
Hide file tree
Showing 13 changed files with 554 additions and 2 deletions.
13 changes: 13 additions & 0 deletions types/foundry/client-esm/applications/elements/color-picker.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { AbstractFormInputElement } from "./form-element.d.ts";

/**
* A custom HTMLElement used to select a color using a linked pair of input fields.
*/
export class HTMLColorPickerElement extends AbstractFormInputElement<string> {
static override tagName: "color-picker";

protected override _buildElements(): HTMLInputElement[];

/** Create a HTMLColorPickerElement using provided configuration data. */
static create(config: FormInputConfig<string>): HTMLColorPickerElement;
}
50 changes: 50 additions & 0 deletions types/foundry/client-esm/applications/elements/document-tags.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import type { AbstractFormInputElement } from "./form-element.d.ts";

/**
* A custom HTMLElement used to render a set of associated Documents referenced by UUID.
*/
export default class HTMLDocumentTagsElement extends AbstractFormInputElement<
Record<string, string>,
string | string[] | null
> {
static override tagName: "document-tags";

/** Restrict this element to documents of a particular type. */
get type(): string | null;
set type(value: string | null);

/** Restrict to only allow referencing a single Document instead of an array of documents. */
get single(): boolean;
set single(value: boolean);

/** Allow a maximum number of documents to be tagged to the element. */
get max(): number;
set max(value: number | null);

/** Initialize innerText or an initial value attribute of the element as a serialized JSON array. */
protected _initializeTags(): void;

/**
* Create an HTML string fragment for a single document tag.
* @param uuid The document UUID
* @param name The document name
*/
static renderTag(uuid: DocumentUUID, name: string): string;

/** Create a HTMLDocumentTagsElement using provided configuration data. */
static create(config: DocumentTagsInputConfig): HTMLDocumentTagsElement;
}

declare global {
interface DocumentTagsInputConfig extends FormInputConfig {
/** A specific document type in CONST.ALL_DOCUMENT_TYPES */
type?: string;
/**
* Only allow referencing a single document. In this case the submitted form value will be a single UUID string
* rather than an array
*/
single?: boolean;
/** Only allow attaching a maximum number of documents */
max?: number;
}
}
40 changes: 40 additions & 0 deletions types/foundry/client-esm/applications/elements/file-picker.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import type { AbstractFormInputElement } from "./form-element.d.ts";

/**
* A custom HTML element responsible for rendering a file input field and associated FilePicker button.
* @extends {AbstractFormInputElement<string>}
*/
export default class HTMLFilePickerElement extends AbstractFormInputElement<string> {
static override tagName: "file-picker";

/** The file path selected. */
input: HTMLInputElement;

/** A button to open the file picker interface. */
button: HTMLButtonElement;

/** A reference to the FilePicker application instance originated by this element. */
picker: FilePicker;

/**
* A type of file which can be selected in this field.
* @see {@link FilePicker.FILE_TYPES}
*/
get type(): (typeof FilePicker.FILE_TYPES)[number];
set type(value: (typeof FilePicker.FILE_TYPES)[number]);

/** Prevent uploading new files as part of this element's FilePicker dialog. */
get noupload(): boolean;
set noupload(value: boolean);

/** Create a HTMLFilePickerElement using provided configuration data. */
static create(config: FilePickerInputConfig): HTMLFilePickerElement;
}

declare global {
interface FilePickerInputConfig extends FormInputConfig<string> {
type?: FilePickerOptions["type"];
placeholder?: string;
noupload?: boolean;
}
}
79 changes: 79 additions & 0 deletions types/foundry/client-esm/applications/elements/form-element.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/**
* An abstract custom HTMLElement designed for use with form inputs.
*
* @fires {Event} input An "input" event when the value of the input changes
* @fires {Event} change A "change" event when the value of the element changes
*/
export abstract class AbstractFormInputElement<TInternalValue, TInputValue = TInternalValue> extends HTMLElement {
/** The HTML tag name used by this element. */
static tagName: string;

/** Declare that this custom element provides form element functionality. */
static formAssociated: boolean;

/** Attached ElementInternals which provides form handling functionality. */
protected _internals: ElementInternals;

/** The form this element belongs to. */
get form(): HTMLFormElement;

/* -------------------------------------------- */
/* Element Properties */
/* -------------------------------------------- */

/** The input element name. */
get name(): string;
set name(value: string);

/** The value of the input element. */
get value(): TInputValue;
set value(value: TInputValue);

/** The underlying value of the element. */
protected _value: TInternalValue;

/** Return the value of the input element which should be submitted to the form. */
protected _getValue(): TInputValue;

/**
* Translate user-provided input value into the format that should be stored.
* @param value A new value to assign to the element
* @throws An error if the provided value is invalid
*/
protected _setValue(value: TInputValue): void;

/** Is this element disabled? */
get disabled(): boolean;
set disabled(value: boolean);

/**
* Special behaviors that the subclass should implement when toggling the disabled state of the input.
* @param disabled The new disabled state
*/
protected _toggleDisabled(disabled: boolean): void;

/* -------------------------------------------- */
/* Element Lifecycle */
/* -------------------------------------------- */

/** Initialize the custom element, constructing its HTML. */
connectedCallback(): void;

/**
* Create the HTML elements that should be included in this custom element.
* Elements are returned as an array of ordered children.
*/
protected _buildElements(): HTMLElement[];

/** Refresh the active state of the custom element. */
protected _refresh(): void;

/** Activate event listeners which add dynamic behavior to the custom element. */
_activateListeners(): void;

/**
* Special handling when the custom element is clicked. This should be implemented to transfer focus to an
* appropriate internal element.
*/
protected _onClick(event: PointerEvent): void;
}
10 changes: 10 additions & 0 deletions types/foundry/client-esm/applications/elements/hue-slider.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { AbstractFormInputElement } from "./form-element.d.ts";

/**
* A class designed to standardize the behavior for a hue selector UI component.
*/
export default class HTMLHueSelectorSlider extends AbstractFormInputElement<number> {
static override tagName: "hue-slider";

override _buildElements(): HTMLInputElement[];
}
9 changes: 9 additions & 0 deletions types/foundry/client-esm/applications/elements/module.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export * from "./color-picker.ts";
export * from "./document-tags.ts";
export * from "./file-picker.ts";
export * from "./form-element.ts";
export * from "./hue-slider.ts";
export * from "./multi-select.ts";
export * from "./prosemirror-editor.ts";
export * from "./range-picker.ts";
export * from "./string-tags.ts";
88 changes: 88 additions & 0 deletions types/foundry/client-esm/applications/elements/multi-select.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import type { AbstractFormInputElement } from "./form-element.d.ts";

/**
* An abstract base class designed to standardize the behavior for a multi-select UI component.
* Multi-select components return an array of values as part of form submission.
* Different implementations may provide different experiences around how inputs are presented to the user.
*/
export abstract class AbstractMultiSelectElement extends AbstractFormInputElement<Set<string>, string[]> {
/** Predefined <option> and <optgroup> elements which were defined in the original HTML. */
protected _options: (HTMLOptionElement | HTMLOptGroupElement)[];

/** An object which maps option values to displayed labels. */
protected _choices: Record<string, string>;

/** Preserve existing <option> and <optgroup> elements which are defined in the original HTML. */
protected _initialize(): void;

/**
* Mark a choice as selected.
* @param value The value to add to the chosen set
*/
select(value: string): void;

/**
* Mark a choice as un-selected.
* @param value The value to delete from the chosen set
*/
unselect(value: string): void;

/* -------------------------------------------- */
/* Form Handling */
/* -------------------------------------------- */

override _getValue(): string[];

override _setValue(value: string[]): void;
}

/**
* Provide a multi-select workflow using a select element as the input mechanism.
*
* @example Multi-Select HTML Markup
* ```html
* <multi-select name="select-many-things">
* <optgroup label="Basic Options">
* <option value="foo">Foo</option>
* <option value="bar">Bar</option>
* <option value="baz">Baz</option>
* </optgroup>
* <optgroup label="Advanced Options">
* <option value="fizz">Fizz</option>
* <option value="buzz">Buzz</option>
* </optgroup>
* </multi-select>
* ```
*/
export class HTMLMultiSelectElement extends AbstractMultiSelectElement {
static override tagName: "multi-select";

/**
* Create a HTMLMultiSelectElement using provided configuration data.
* @param {FormInputConfig<string[]> & Omit<SelectInputConfig, "blank">} config
* @returns {HTMLMultiSelectElement}
*/
static create(config: MultiSelectInputConfig): HTMLMultiSelectElement;
}

/**
* Provide a multi-select workflow as a grid of input checkbox elements.
*
* @example Multi-Checkbox HTML Markup
* ```html
* <multi-checkbox name="check-many-boxes">
* <optgroup label="Basic Options">
* <option value="foo">Foo</option>
* <option value="bar">Bar</option>
* <option value="baz">Baz</option>
* </optgroup>
* <optgroup label="Advanced Options">
* <option value="fizz">Fizz</option>
* <option value="buzz">Buzz</option>
* </optgroup>
* </multi-checkbox>
* ```
*/
export class HTMLMultiCheckboxElement extends AbstractMultiSelectElement {
static override tagName: "multi-checkbox";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { AbstractFormInputElement } from "./form-element.d.ts";

/**
* A custom HTML element responsible displaying a ProseMirror rich text editor.
*/
export default class HTMLProseMirrorElement extends AbstractFormInputElement<string> {
static override tagName: "prose-mirror";

disconnectedCallback(): void;

/** Configure ProseMirror editor plugins. */
protected _configurePlugins(): Record<string, ProseMirror.Plugin>;

/** Create a HTMLProseMirrorElement using provided configuration data. */
static create(config: ProseMirrorInputConfig): HTMLProseMirrorElement;
}

declare global {
interface ProseMirrorInputConfig extends FormInputConfig<string> {
/** Is this editor toggled (true) or always active (false) */
toggled: boolean;
/** Does this editor instance support collaborative editing? */
collaborate: boolean;
/** A Document UUID. Required for collaborative editing */
documentUUID?: DocumentUUID;
}
}
21 changes: 21 additions & 0 deletions types/foundry/client-esm/applications/elements/range-picker.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { AbstractFormInputElement } from "./form-element.d.ts";

/**
* A custom HTML element responsible selecting a value on a range slider with a linked number input field.
*/
export default class HTMLRangePickerElement extends AbstractFormInputElement<number> {
static override tagName: "range-picker";

protected override _buildElements(): HTMLInputElement[];

/** Create a HTMLRangePickerElement using provided configuration data. */
static create(config: RangePickerInputConfig): HTMLRangePickerElement;
}

declare global {
interface RangePickerInputConfig extends FormInputConfig<string> {
min: number;
max: number;
step?: number;
}
}
47 changes: 47 additions & 0 deletions types/foundry/client-esm/applications/elements/string-tags.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import type { AbstractFormInputElement } from "./form-element.d.ts";

/**
* A custom HTML element which allows for arbitrary assignment of a set of string tags.
* This element may be used directly or subclassed to impose additional validation or functionality.
*/
export default class HTMLStringTagsElement extends AbstractFormInputElement<Set<string>, string[]> {
static override tagName: "string-tags";

static icons: {
add: string;
remove: string;
};

static labels: {
add: string;
remove: string;
placeholder: string;
};

/**
* Initialize innerText or an initial value attribute of the element as a comma-separated list of currently assigned
* string tags.
*/
protected _initializeTags(): void;

/**
* Subclasses may impose more strict validation on what tags are allowed.
* @param tag A candidate tag
* @throws An error if the candidate tag is not allowed
*/
protected _validateTag(tag: string): void;

/**
* Render the HTML fragment used to represent a tag.
* @param tag The raw tag value
* @returns An HTML string for the tag
*/
static renderTag(tag: string): string;

/* -------------------------------------------- */
/* Form Handling */
/* -------------------------------------------- */

/** Create a HTMLStringTagsElement using provided configuration data. */
static create(config: FormInputConfig<string>): HTMLStringTagsElement;
}
Loading

0 comments on commit eebce53

Please sign in to comment.