The Tidy 5e Sheets API. The API becomes available after the hook tidy5e-sheet.ready is called. When the hook fires, it provides an instance of the API.

Hooks.once('tidy5e-sheet.ready', (api) => {
// Do something awesome!
});
game.modules.get('tidy5e-sheet').api

It is recommended to retrieve the API from the tidy5e-sheet.ready hook, since the hook guarantees that the API has been initialized.

Properties

config: ConfigApi = ...

Provides extensibility APIs for customizing various aspects of Tidy 5e Sheets.

constants: {
    SHEET_PART_ATTRIBUTE: "data-tidy-sheet-part";
    SHEET_PARTS: {
        ABILITY_CONFIGURATION_CONTROL: "ability-configuration-control";
        ABILITY_ROLLER: "ability-roller";
        ABILITY_SAVE_PROFICIENCY_TOGGLE: "ability-save-proficiency-toggle";
        ABILITY_SAVE_ROLLER: "ability-save-roller";
        ABILITY_SCORE: "ability-score";
        ABILITY_SCORE_CONTAINER: "ability-score-container";
        ABILITY_TEST_ROLLER: "ability-test-roller";
        ACTOR_PORTRAIT_CONTAINER: "actor-portrait-container";
        ACTOR_PORTRAIT_HEALTH_OVERLAY: "actor-portrait-health-overlay";
        ACTOR_PORTRAIT_IMAGE: "actor-portrait-image";
        ACTOR_TRAIT: "actor-trait";
        ACTOR_TRAIT_DETAILS: "actor-trait-details";
        CONDITION_TOGGLE: "condition-toggle";
        DAMAGE_PART_CONTAINER: "damage-part-container";
        DAMAGE_PART_DELETE_COMMAND: "damage-part-delete-command";
        DAMAGE_PART_FORMULA: "damage-part-formula";
        DAMAGE_PART_TYPE: "damage-part-type";
        DEATH_SAVE_FAILURES: "death-save-failures";
        DEATH_SAVE_ROLLER: "death-save-roller";
        DEATH_SAVE_SUCCESSES: "death-save-successes";
        EXPANSION_TOGGLE: "table-expansion-toggle";
        GROUP_MEMBER_PORTRAIT: "group-member-portrait";
        INLINE_CONTAINER_TOGGLE: "inline-container-toggle";
        ITEM_CREATE_COMMAND: "item-create-command";
        ITEM_IMAGE: "item-image";
        ITEM_IMAGE_CONTAINER: "item-image-container";
        ITEM_NAME: "item-name";
        ITEM_PROPERTY_LIST: "item-property-list";
        ITEM_SHEET_PROPERTIES: "item-sheet-properties";
        ITEM_SUMMARY: "item-summary";
        ITEM_TABLE: "item-table";
        ITEM_TABLE_HEADER_ROW: "item-table-header-row";
        ITEM_TABLE_ROW: "item-table-row";
        ITEM_USE_COMMAND: "item-use-command";
        ITEMS_CONTAINER: "items-container";
        MELEE_SPELL_ATTACK_MOD: "melee-spell-attack-mod";
        NAME_CONTAINER: "name-container";
        NAME_HEADER_ROW: "name-header-row";
        NPC_ABILITIES_CONTAINER: "npc-abilities-list";
        RANGED_SPELL_ATTACK_MOD: "ranged-spell-attack-mod";
        RESOURCE: "resource";
        RESOURCES_CONTAINER: "resources-container";
        SEARCH_CLEAR: "search-clear";
        SEARCH_CONTAINER: "search-container";
        SEARCH_INPUT: "search-input";
        SHEET_LOCK_TOGGLE: "sheet-lock-toggle";
        SKILL_CONFIGURATION_CONTROL: "skill-configuration-control";
        SKILL_CONTAINER: "skill-container";
        SKILL_PROFICIENCY_TOGGLE: "skill-proficiency-toggle";
        SKILL_ROLLER: "skill-roller";
        SKILLS_LIST: "skills-list";
        SKILLS_SHOW_PROFICIENT_TOGGLE: "skills-show-proficiency-toggle";
        SPELL_ATTACK_MOD: "spell-attack-mod";
        SPELL_DC: "spell-dc";
        TABLE_CELL: "table-cell";
        TABLE_HEADER_CELL: "table-header-cell";
        TABLE_HEADER_ROW: "table-header-row";
        TABLE_ROW: "table-row";
        TOOL_CONFIGURATION_CONTROL: "tool-configuration-control";
        TOOL_CONTAINER: "tool-container";
        TOOL_PROFICIENCY_TOGGLE: "tool-proficiency-toggle";
        TOOL_ROLLER: "tool-roller";
        TOOLS_LIST: "tools-list";
        UTILITY_TOOLBAR: "utility-toolbar";
        UTILITY_TOOLBAR_COMMAND: "utility-toolbar-command";
    };
    TAB_ID_ACTOR_ACTIONS: "actions";
    TAB_ID_CHARACTER_ATTRIBUTES: "attributes";
    TAB_ID_CHARACTER_BIOGRAPHY: "biography";
    TAB_ID_CHARACTER_EFFECTS: "effects";
    TAB_ID_CHARACTER_FEATURES: "features";
    TAB_ID_CHARACTER_INVENTORY: "inventory";
    TAB_ID_CHARACTER_JOURNAL: "journal";
    TAB_ID_CHARACTER_SPELLBOOK: "spellbook";
    TAB_ID_GROUP_DESCRIPTION: "description";
    TAB_ID_GROUP_INVENTORY: "inventory";
    TAB_ID_GROUP_MEMBERS: "members";
    TAB_ID_NPC_ABILITIES: "attributes";
    TAB_ID_NPC_BIOGRAPHY: "biography";
    TAB_ID_NPC_EFFECTS: "effects";
    TAB_ID_NPC_JOURNAL: "journal";
    TAB_ID_NPC_SPELLBOOK: "spellbook";
    TAB_ID_VEHICLE_ATTRIBUTES: "attributes";
    TAB_ID_VEHICLE_CARGO_AND_CREW: "cargo";
    TAB_ID_VEHICLE_DESCRIPTION: "biography";
    TAB_ID_VEHICLE_EFFECTS: "effects";
} = ApiConstants

Constants for a variety of uses.

Type declaration

  • SHEET_PART_ATTRIBUTE: "data-tidy-sheet-part"

    The attribute which indicates a particular part of a sheet.

  • SHEET_PARTS: {
        ABILITY_CONFIGURATION_CONTROL: "ability-configuration-control";
        ABILITY_ROLLER: "ability-roller";
        ABILITY_SAVE_PROFICIENCY_TOGGLE: "ability-save-proficiency-toggle";
        ABILITY_SAVE_ROLLER: "ability-save-roller";
        ABILITY_SCORE: "ability-score";
        ABILITY_SCORE_CONTAINER: "ability-score-container";
        ABILITY_TEST_ROLLER: "ability-test-roller";
        ACTOR_PORTRAIT_CONTAINER: "actor-portrait-container";
        ACTOR_PORTRAIT_HEALTH_OVERLAY: "actor-portrait-health-overlay";
        ACTOR_PORTRAIT_IMAGE: "actor-portrait-image";
        ACTOR_TRAIT: "actor-trait";
        ACTOR_TRAIT_DETAILS: "actor-trait-details";
        CONDITION_TOGGLE: "condition-toggle";
        DAMAGE_PART_CONTAINER: "damage-part-container";
        DAMAGE_PART_DELETE_COMMAND: "damage-part-delete-command";
        DAMAGE_PART_FORMULA: "damage-part-formula";
        DAMAGE_PART_TYPE: "damage-part-type";
        DEATH_SAVE_FAILURES: "death-save-failures";
        DEATH_SAVE_ROLLER: "death-save-roller";
        DEATH_SAVE_SUCCESSES: "death-save-successes";
        EXPANSION_TOGGLE: "table-expansion-toggle";
        GROUP_MEMBER_PORTRAIT: "group-member-portrait";
        INLINE_CONTAINER_TOGGLE: "inline-container-toggle";
        ITEM_CREATE_COMMAND: "item-create-command";
        ITEM_IMAGE: "item-image";
        ITEM_IMAGE_CONTAINER: "item-image-container";
        ITEM_NAME: "item-name";
        ITEM_PROPERTY_LIST: "item-property-list";
        ITEM_SHEET_PROPERTIES: "item-sheet-properties";
        ITEM_SUMMARY: "item-summary";
        ITEM_TABLE: "item-table";
        ITEM_TABLE_HEADER_ROW: "item-table-header-row";
        ITEM_TABLE_ROW: "item-table-row";
        ITEM_USE_COMMAND: "item-use-command";
        ITEMS_CONTAINER: "items-container";
        MELEE_SPELL_ATTACK_MOD: "melee-spell-attack-mod";
        NAME_CONTAINER: "name-container";
        NAME_HEADER_ROW: "name-header-row";
        NPC_ABILITIES_CONTAINER: "npc-abilities-list";
        RANGED_SPELL_ATTACK_MOD: "ranged-spell-attack-mod";
        RESOURCE: "resource";
        RESOURCES_CONTAINER: "resources-container";
        SEARCH_CLEAR: "search-clear";
        SEARCH_CONTAINER: "search-container";
        SEARCH_INPUT: "search-input";
        SHEET_LOCK_TOGGLE: "sheet-lock-toggle";
        SKILL_CONFIGURATION_CONTROL: "skill-configuration-control";
        SKILL_CONTAINER: "skill-container";
        SKILL_PROFICIENCY_TOGGLE: "skill-proficiency-toggle";
        SKILL_ROLLER: "skill-roller";
        SKILLS_LIST: "skills-list";
        SKILLS_SHOW_PROFICIENT_TOGGLE: "skills-show-proficiency-toggle";
        SPELL_ATTACK_MOD: "spell-attack-mod";
        SPELL_DC: "spell-dc";
        TABLE_CELL: "table-cell";
        TABLE_HEADER_CELL: "table-header-cell";
        TABLE_HEADER_ROW: "table-header-row";
        TABLE_ROW: "table-row";
        TOOL_CONFIGURATION_CONTROL: "tool-configuration-control";
        TOOL_CONTAINER: "tool-container";
        TOOL_PROFICIENCY_TOGGLE: "tool-proficiency-toggle";
        TOOL_ROLLER: "tool-roller";
        TOOLS_LIST: "tools-list";
        UTILITY_TOOLBAR: "utility-toolbar";
        UTILITY_TOOLBAR_COMMAND: "utility-toolbar-command";
    }

    Values used in conjunction with the attribute api.constants.SHEET_PART_ATTRIBUTE to identify a part of a Tidy 5e sheet.

    <div class="resources" data-tidy-sheet-part="resources-container">...</div>
    
    // Every time Tidy renders, whether a full render or a partial
    Hooks.on("tidy5e-sheet.renderActorSheet", (sheet, element, data) => {
    const api = game.modules.get('tidy5e-sheet').api;
    const selector = api.getSheetPartSelector(
    api.constants.SHEET_PARTS.RESOURCES_CONTAINER
    );
    // get the resources container of the target actor sheet
    element
    .querySelector(selector)
    // inject some HTML
    ?.insertAdjacentHTML(
    // put it as the first element inside the resources container; see https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML#afterbegin
    "afterbegin",
    // here's my content
    // pro tip: `data-tidy-render-scheme="handlebars"` causes this content to re-render on every Tidy render, full or partial
    `<div style="display: contents;" data-tidy-render-scheme="handlebars">
    <h2 type="button" style="width: 100%;">Resources for ${data.actor.name}</h2>
    </div>`
    );
    });

    Tidy 5e Sheets are tagged with data-tidy-sheet-part attributes so that most parts of the sheet can be generally identified. This module uses specific attributes rather than classes because of HTML classes' multiple purposes, including use for CSS styling. Using sheet part attributes allows for identifying the same general thing even when considering a potentially alternate Tidy sheet layout.

    • ReadonlyABILITY_CONFIGURATION_CONTROL: "ability-configuration-control"

      An interactable control that can open configuration settings for a target ability.

    • ReadonlyABILITY_ROLLER: "ability-roller"

      A rollable/interactable element which rolls an ability save or test.

    • ReadonlyABILITY_SAVE_PROFICIENCY_TOGGLE: "ability-save-proficiency-toggle"

      An interactable toggle for ability saving throw proficiency.

    • ReadonlyABILITY_SAVE_ROLLER: "ability-save-roller"

      A rollable/interactable element which rolls an ability save.

    • ReadonlyABILITY_SCORE: "ability-score"

      An ability score (e.g., "str", "dex", "wis", etc.), whether readonly or editable.

    • ReadonlyABILITY_SCORE_CONTAINER: "ability-score-container"

      A container for a given ability score (e.g., "str", "dex", "wis", etc.).

    • ReadonlyABILITY_TEST_ROLLER: "ability-test-roller"

      A rollable/interactable element which rolls an ability test.

    • ReadonlyACTOR_PORTRAIT_CONTAINER: "actor-portrait-container"

      A container which houses an actor portrait and other parts related to actor portrait features.

    • ReadonlyACTOR_PORTRAIT_HEALTH_OVERLAY: "actor-portrait-health-overlay"

      An overlay element for an actor portrait which provides a visual representation of remaining health.

    • ReadonlyACTOR_PORTRAIT_IMAGE: "actor-portrait-image"

      An actor portrait image element.

    • ReadonlyACTOR_TRAIT: "actor-trait"

      An actor trait container, such as Senses, Languages, or Tools.

    • ReadonlyACTOR_TRAIT_DETAILS: "actor-trait-details"

      The specific details of an actor trait container, such as Senses, Languages, or Tools.

    • ReadonlyCONDITION_TOGGLE: "condition-toggle"

      A control for toggling a condition

    • ReadonlyDAMAGE_PART_CONTAINER: "damage-part-container"

      A container for all form fields related to a given damage part.

    • ReadonlyDAMAGE_PART_DELETE_COMMAND: "damage-part-delete-command"

      An interactable control which the user can execute to delete a damage part to an item.

    • ReadonlyDAMAGE_PART_FORMULA: "damage-part-formula"

      An input element which contains a damage part formula, usually for an item.

    • ReadonlyDAMAGE_PART_TYPE: "damage-part-type"

      An input element which represents the damage type of a damage part, usually for an item.

    • ReadonlyDEATH_SAVE_FAILURES: "death-save-failures"

      An input for the number of failed death saves an actor has.

    • ReadonlyDEATH_SAVE_ROLLER: "death-save-roller"

      A rollable/interactable element which rolls a death saving throw.

    • ReadonlyDEATH_SAVE_SUCCESSES: "death-save-successes"

      An input for the number of successful death saves an actor has.

    • ReadonlyEXPANSION_TOGGLE: "table-expansion-toggle"

      An interactable element which toggles a view

    • ReadonlyGROUP_MEMBER_PORTRAIT: "group-member-portrait"

      An image representing a member of a group sheet.

    • ReadonlyINLINE_CONTAINER_TOGGLE: "inline-container-toggle"

      An interactable element which toggles an inline container's contents view

    • ReadonlyITEM_CREATE_COMMAND: "item-create-command"

      An interactable control which the user can execute to create an item (e.g., consumable, feature, loot, spell, weapon, etc.).

    • ReadonlyITEM_IMAGE: "item-image"

      An image element for an item.

    • ReadonlyITEM_IMAGE_CONTAINER: "item-image-container"

      The container element for an item image.

    • ReadonlyITEM_NAME: "item-name"

      An element which contains the name of an item.

    • ReadonlyITEM_PROPERTY_LIST: "item-property-list"

      A series of properties related to an item, to be found on item summaries, item cards, and other locations where read-only item information is given.

    • ReadonlyITEM_SHEET_PROPERTIES: "item-sheet-properties"

      A series of properties related to an item, viewed from that item's sheet. These include read-only properties, currency value, and other situational input.

    • ReadonlyITEM_SUMMARY: "item-summary"

      A summary of an item, usually taken from the item's chat data.

    • ReadonlyITEM_TABLE: "item-table"

      A list-based tabular representation of items (e.g., equipment, loot, spells, etc.).

    • ReadonlyITEM_TABLE_HEADER_ROW: "item-table-header-row"

      The header row of an item table.

    • ReadonlyITEM_TABLE_ROW: "item-table-row"

      A row in an item table.

    • ReadonlyITEM_USE_COMMAND: "item-use-command"

      An interactable control which the user can execute to use an item (e.g., consumable, feature, loot, spell, weapon, etc.).

    • ReadonlyITEMS_CONTAINER: "items-container"

      A containing element for a series of item lists or grids.

    • ReadonlyMELEE_SPELL_ATTACK_MOD: "melee-spell-attack-mod"

      The element which contains the modifier text for melee spell attacks.

    • ReadonlyNAME_CONTAINER: "name-container"

      A container for a sheet name. The sheet name is usually in input, and its container has some additional styles associated with it. The container typically sits in a sheet header row with other header-related elements.

    • ReadonlyNAME_HEADER_ROW: "name-header-row"

      The sheet header row where the sheet name appears.

    • ReadonlyNPC_ABILITIES_CONTAINER: "npc-abilities-list"

      A containing element for a series of item lists related to the NPC Abilities tab.

    • ReadonlyRANGED_SPELL_ATTACK_MOD: "ranged-spell-attack-mod"

      The element which contains the modifier text for ranged spell attacks.

    • ReadonlyRESOURCE: "resource"

      A container for a single resource (first, second, third, etc.).

    • ReadonlyRESOURCES_CONTAINER: "resources-container"

      The container where all known resources (first, second, third, etc.) are kept.

    • ReadonlySEARCH_CLEAR: "search-clear"

      An interactable element that can clear the search input it is associated with.

    • ReadonlySEARCH_CONTAINER: "search-container"

      A container for a search input and its search clearing interactable element.

    • ReadonlySEARCH_INPUT: "search-input"

      A user input for performing searches.

    • ReadonlySHEET_LOCK_TOGGLE: "sheet-lock-toggle"

      A button for toggling whether the sheet is locked or unlocked.

    • ReadonlySKILL_CONFIGURATION_CONTROL: "skill-configuration-control"

      An interactable control that can open configuration settings for a target skill.

    • ReadonlySKILL_CONTAINER: "skill-container"

      A container for a single skill, including its roller, proficiency toggle, and any other elements related to the skill.

    • ReadonlySKILL_PROFICIENCY_TOGGLE: "skill-proficiency-toggle"

      An interactable toggle for skill proficiency.

    • ReadonlySKILL_ROLLER: "skill-roller"

      A rollable/interactable element which rolls a skill check.

    • ReadonlySKILLS_LIST: "skills-list"

      A list of skills for the target actor.

    • ReadonlySKILLS_SHOW_PROFICIENT_TOGGLE: "skills-show-proficiency-toggle"

      An interactable toggle for showing/hiding unproficienct skills.

    • ReadonlySPELL_ATTACK_MOD: "spell-attack-mod"

      The element which contains the modifier text for spell attacks in general. This field is shown when melee and ranged spell attack mods are the same.

    • ReadonlySPELL_DC: "spell-dc"

      The element which contains spell DC.

    • ReadonlyTABLE_CELL: "table-cell"

      A cell in a table row.

    • ReadonlyTABLE_HEADER_CELL: "table-header-cell"

      A cell in a table's header row.

    • ReadonlyTABLE_HEADER_ROW: "table-header-row"

      The header row in a table.

    • ReadonlyTABLE_ROW: "table-row"

      A row in a table.

    • ReadonlyTOOL_CONFIGURATION_CONTROL: "tool-configuration-control"

      An interactable control that can open configuration settings for a target tool.

    • ReadonlyTOOL_CONTAINER: "tool-container"

      A container for a single tool, including its roller, proficiency toggle, and any other elements related to the tool.

    • ReadonlyTOOL_PROFICIENCY_TOGGLE: "tool-proficiency-toggle"

      An interactable toggle for tool proficiency.

    • ReadonlyTOOL_ROLLER: "tool-roller"

      A rollable/interactable element which rolls a tool check.

    • ReadonlyTOOLS_LIST: "tools-list"

      A list of tools for the target actor.

    • ReadonlyUTILITY_TOOLBAR: "utility-toolbar"

      A toolbar that usually sits at the top of a section of content, providing features like search, filtering, etc.

    • ReadonlyUTILITY_TOOLBAR_COMMAND: "utility-toolbar-command"

      A toolbar command, usually a button

  • TAB_ID_ACTOR_ACTIONS: "actions"
  • TAB_ID_CHARACTER_ATTRIBUTES: "attributes"
  • TAB_ID_CHARACTER_BIOGRAPHY: "biography"
  • TAB_ID_CHARACTER_EFFECTS: "effects"
  • TAB_ID_CHARACTER_FEATURES: "features"
  • TAB_ID_CHARACTER_INVENTORY: "inventory"
  • TAB_ID_CHARACTER_JOURNAL: "journal"
  • TAB_ID_CHARACTER_SPELLBOOK: "spellbook"
  • TAB_ID_GROUP_DESCRIPTION: "description"
  • TAB_ID_GROUP_INVENTORY: "inventory"
  • TAB_ID_GROUP_MEMBERS: "members"
  • TAB_ID_NPC_ABILITIES: "attributes"
  • TAB_ID_NPC_BIOGRAPHY: "biography"
  • TAB_ID_NPC_EFFECTS: "effects"
  • TAB_ID_NPC_JOURNAL: "journal"
  • TAB_ID_NPC_SPELLBOOK: "spellbook"
  • TAB_ID_VEHICLE_ATTRIBUTES: "attributes"
  • TAB_ID_VEHICLE_CARGO_AND_CREW: "cargo"
  • TAB_ID_VEHICLE_DESCRIPTION: "biography"
  • TAB_ID_VEHICLE_EFFECTS: "effects"

When APIs call for specific IDs or selectors related to Tidy 5e Sheets, using the related constant when available will insulate against breakage when Tidy has internal changes.

models: {
    HandlebarsContent: typeof HandlebarsContent;
    HandlebarsTab: typeof HandlebarsTab;
    HtmlContent: typeof HtmlContent;
    HtmlTab: typeof HtmlTab;
    SvelteTab: typeof SvelteTab;
} = ...

Various models can be used for API calls.

Accessors

Methods

  • Creates a selector which allows for locating a part of a given sheet.

    Parameters

    • sheetPart: string

      a part of the sheet as found in api.constants.SHEET_PARTS

    Returns string

    an HTML selector valid for use with JavaScript query selectors

  • Determines whether the provided sheet is a Tidy 5e Character sheet.

    Parameters

    • app: any

      an actor sheet

    Returns boolean

    boolean indicating if the sheet is a Tidy 5e Character sheet

  • Determines whether the provided sheet is a Tidy 5e Container sheet.

    Parameters

    • app: any

      a container sheet

    Returns boolean

    boolean indicating if the sheet is a Tidy 5e Container sheet

  • Determines whether the provided sheet is a Tidy 5e Group sheet.

    Parameters

    • app: any

      a group sheet

    Returns boolean

    boolean indicating if the sheet is a Tidy 5e Group sheet

  • Determines whether the provided sheet is a Tidy 5e Item sheet.

    Parameters

    • app: any

      an item sheet

    Returns boolean

    boolean indicating if the sheet is a Tidy 5e Item sheet

  • Determines whether the provided sheet is a Tidy 5e NPC sheet.

    Parameters

    • app: any

      an actor sheet

    Returns boolean

    boolean indicating if the sheet is a Tidy 5e NPC sheet

  • Determines whether the provided sheet is any Tidy 5e sheet.

    Parameters

    • app: any

      an actor sheet

    Returns boolean

    boolean indicating if the sheet is any Tidy 5e sheet

  • Determines whether the provided sheet is a Tidy 5e Vehicle sheet.

    Parameters

    • app: any

      an actor sheet

    Returns boolean

    boolean indicating if the sheet is a Tidy 5e Vehicle sheet

  • Adds custom content to all actor sheets at position relative to selector.

    Parameters

    Returns void

    void

    Hooks.once("tidy5e-sheet.ready", (api) => {
    api.registerActorContent(
    new api.models.HtmlContent({
    html: `<a title="Example Button" class="my-custom-icon"><i class="fas fa-user"></i></a>`,
    injectParams: {
    selector: `[data-tidy-sheet-part="${api.constants.SHEET_PARTS.NAME_CONTAINER}"]`
    position: "beforebegin",
    },
    onContentReady: (params) => {
    console.log("content ready to render", params);
    console.log("my content", params.content);
    },
    onRender: (params) => {
    params.element
    .querySelector(".my-custom-icon")
    .addEventListener("click", () => alert("Clicked custom actor icon"));
    },
    })
    );
    });
  • Registers header controls for all Tidy Application V2 Actor sheets.

    Parameters

    Returns void

    Hooks.once('tidy5e-sheet.ready', (api) => {
    api.registerActorHeaderControls({
    controls: [
    {
    icon: 'fas fa-hand-sparkles',
    label: 'Say Hello',
    async onClickAction() {
    ui.notifications.info(`Hello, Foundry!`);
    },
    },
    ],
    });
    });
    Hooks.once('tidy5e-sheet.ready', (api) => {
    api.registerActorHeaderControls({
    controls: [
    {
    icon: 'fas fa-broom',
    label: 'Debug Button',
    visible() {
    return !this.document.compendium?.locked;
    },
    async onClickAction(event) {
    ui.notifications.info(
    `Logged document data for ${this.document.name} to console for review.`
    );
    console.log(this.document);
    console.log(await this.document.sheet._prepareContext());
    },
    ownership: CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER,
    },
    ],
    });
    });
  • Adds custom content to player character sheets at position relative to selector.

    Parameters

    Returns void

    void

    Hooks.once("tidy5e-sheet.ready", (api) => {
    api.registerCharacterContent(
    new api.models.HtmlContent({
    html: `<a title="Example Button" class="my-custom-icon"><i class="fas fa-user"></i></a>`,
    injectParams: {
    selector: `[data-tidy-sheet-part="${api.constants.SHEET_PARTS.NAME_CONTAINER}"]`
    position: "beforebegin",
    },
    onContentReady: (params) => {
    console.log("content ready to render", params);
    console.log("my content", params.content);
    },
    onRender: (params) => {
    params.element
    .querySelector(".my-custom-icon")
    .addEventListener("click", () => alert("Clicked custom PC icon"));
    },
    })
    );
    });
  • Registers header controls for all Tidy Application V2 Character sheets.

    Parameters

    Returns void

    Hooks.once('tidy5e-sheet.ready', (api) => {
    api.registerCharacterHeaderControls({
    controls: [
    {
    icon: 'fas fa-broom',
    label: 'Debug Button',
    visible() {
    return !this.document.compendium?.locked;
    },
    async onClickAction(event) {
    ui.notifications.info(
    `Logged document data for ${this.document.name} to console for review.`
    );
    console.log(this.document);
    console.log(await this.document.sheet._prepareContext());
    },
    ownership: CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER,
    },
    ],
    });
    });
  • Adds a tab to the available Character sheet tabs.

    Parameters

    Returns void

    void

    Hooks.once('tidy5e-sheet.ready', (api) => {
    api.registerCharacterTab(
    new api.models.HandlebarsTab({
    title: 'My Tab',
    path: '/modules/my-module-id/templates/my-handlebars-template.hbs',
    tabId: 'my-module-id-registered-character-tab',
    getData: async (data) => {
    data['my-message'] = 'Hello, world! 🌊🏄‍♂️';
    return Promise.resolve(data);
    },
    onRender(params) {
    const myTab = $(params.tabContentsElement);
    myTab.find('.my-control').click(_myHandler.bind(params.app));
    },
    })
    );
    });
    Hooks.once('tidy5e-sheet.ready', (api) => {
    api.registerCharacterTab(
    new api.models.HandlebarsTab({
    title: 'The New Inventory Tab',
    path: '/modules/my-module-id/templates/my-handlebars-template.hbs',
    tabId: api.constants.TAB_ID_CHARACTER_INVENTORY,
    getData: async (data) => {
    data['my-message'] = 'Hello, world! 🌊🏄‍♂️';
    return Promise.resolve(data);
    },
    onRender(params) {
    const myTab = $(params.tabContentsElement);
    myTab.find('.my-control').click(_myHandler.bind(params.app));
    },
    }),
    {
    overrideExisting: true,
    }
    );
    });

    A tab ID is always required (see TabId).

  • Adds custom content to group sheets at position relative to selector.

    Parameters

    Returns void

    void

    Hooks.once("tidy5e-sheet.ready", (api) => {
    api.registerGroupContent(
    new api.models.HtmlContent({
    html: `<a title="Example Button" class="my-custom-icon"><i class="fas fa-user"></i></a>`,
    injectParams: {
    selector: `[data-tidy-sheet-part="${api.constants.SHEET_PARTS.NAME_CONTAINER}"]`
    position: "beforebegin",
    },
    onContentReady: (params) => {
    console.log("content ready to render", params);
    console.log("my content", params.content);
    },
    onRender: (params) => {
    params.element
    .querySelector(".my-custom-icon")
    .addEventListener("click", () => alert("Clicked custom PC icon"));
    },
    })
    );
    });
  • Registers header controls for all Tidy Application V2 Group sheets.

    Parameters

    Returns void

    Hooks.once('tidy5e-sheet.ready', (api) => {
    api.registerGroupHeaderControls({
    controls: [
    {
    icon: 'fas fa-broom',
    label: 'Debug Button',
    visible() {
    return !this.document.compendium?.locked;
    },
    async onClickAction(event) {
    ui.notifications.info(
    `Logged document data for ${this.document.name} to console for review.`
    );
    console.log(this.document);
    console.log(await this.document.sheet._prepareContext());
    },
    ownership: CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER,
    },
    ],
    });
    });
  • Adds a tab to the available Group sheet tabs.

    Parameters

    Returns void

    void

    Hooks.once('tidy5e-sheet.ready', (api) => {
    api.registerGroupTab(
    new api.models.HandlebarsTab({
    title: 'My Tab',
    path: '/modules/my-module-id/templates/my-handlebars-template.hbs',
    tabId: 'my-module-id-registered-group-tab',
    getData: async (data) => {
    data['my-message'] = 'Hello, world! 🌊🏄‍♂️';
    return Promise.resolve(data);
    },
    onRender(params) {
    const myTab = $(params.tabContentsElement);
    myTab.find('.my-control').click(_myHandler.bind(params.app));
    },
    })
    );
    });
    Hooks.once('tidy5e-sheet.ready', (api) => {
    api.registerGroupTab(
    new api.models.HandlebarsTab({
    title: 'The New Inventory Tab',
    path: '/modules/my-module-id/templates/my-handlebars-template.hbs',
    tabId: api.constants.TAB_ID_GROUP_INVENTORY,
    getData: async (data) => {
    data['my-message'] = 'Hello, world! 🌊🏄‍♂️';
    return Promise.resolve(data);
    },
    onRender(params) {
    const myTab = $(params.tabContentsElement);
    myTab.find('.my-control').click(_myHandler.bind(params.app));
    },
    }),
    {
    overrideExisting: true,
    }
    );
    });

    A tab ID is always required (see TabId).

  • Adds custom content to item sheets at position relative to selector.

    Parameters

    Returns void

    void

    Hooks.once("tidy5e-sheet.ready", (api) => {
    api.registerItemContent(
    new api.models.HtmlContent({
    html: `<a title="Example Button" class="my-custom-icon"><i class="fas fa-flask"></i></a>`,
    injectParams: {
    selector: `[data-tidy-sheet-part="${api.constants.SHEET_PARTS.NAME_CONTAINER}"]`
    position: "beforebegin",
    },
    onContentReady: (params) => {
    console.log("content ready to render", params);
    console.log("my content", params.content);
    },
    onRender: (params) => {
    params.element
    .querySelector(".my-custom-icon")
    .addEventListener("click", () => alert("Clicked custom item icon"));
    },
    })
    );
    });
  • Registers header controls for all Tidy Application V2 Item sheets.

    Parameters

    Returns void

    Hooks.once('tidy5e-sheet.ready', (api) => {
    api.registerItemHeaderControls({
    controls: [
    {
    icon: 'fas fa-coins',
    label: 'Take all the coin!',
    visible() {
    return (
    this.document.type === 'container' &&
    this.document.actor &&
    this.document.isOwner
    );
    },
    async onClickAction(event) {
    ui.notifications.info(`Taking all the money out of the bag!`);
    const actorCurrency = this.actor.toObject().system.currency;
    const containerCurrency = this.document.toObject().system.currency;
    for (let [key, value] of Object.entries(containerCurrency)) {
    actorCurrency[key] += containerCurrency[key];
    containerCurrency[key] = 0;
    }
    this.actor.update({
    system: {
    currency: actorCurrency,
    },
    });
    this.document.update({
    system: {
    currency: containerCurrency,
    },
    });
    },
    ownership: CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER,
    },
    ],
    });
    });
  • Adds a tab to all relevant item sheets.

    Parameters

    Returns void

    CustomTabBase for options related to all tabs.

    Hooks.once('tidy5e-sheet.ready', (api) => {
    api.registerItemTab(
    new api.models.HandlebarsTab({
    title: 'My Item Tab',
    tabId: 'my-module-id-my-item-tab',
    path: '/modules/my-module-id/my-item-tab.hbs',
    enabled: (data) => data.item.type === 'spell',
    getData: (data) => {
    data['my-extra-data'] = 'Hello, world! 👋';
    return data;
    },
    onRender(params) {
    const myTab = $(params.tabContentsElement);
    myTab.find('.my-control').click(_myHandler.bind(params.app));
    },
    }));
    });
    Hooks.once("tidy5e-sheet.ready", (api) => {
    api.registerItemTab(
    new api.models.HtmlTab({
    title: "My Item Tab",
    tabId: "my-module-id-my-item-tab",
    html: "<h1>LOREM! IPSUM! FIREBALLLLLL!!</h1><h1>LOREM! IPSUM! FIREBALLLLLL!!</h1><h1>LOREM! IPSUM! FIREBALLLLLL!!</h1><h1>LOREM! IPSUM! FIREBALLLLLL!!</h1><h1>LOREM! IPSUM! FIREBALLLLLL!!</h1><h1>LOREM! IPSUM! FIREBALLLLLL!!</h1><h1>LOREM! IPSUM! FIREBALLLLLL!!</h1><h1>LOREM! IPSUM! FIREBALLLLLL!!</h1><h1>LOREM! IPSUM! FIREBALLLLLL!!</h1><h1>LOREM! IPSUM! FIREBALLLLLL!!</h1><h1>LOREM! IPSUM! FIREBALLLLLL!!</h1><h1>LOREM! IPSUM! FIREBALLLLLL!!</h1><h1>LOREM! IPSUM! FIREBALLLLLL!!</h1><h1>LOREM! IPSUM! FIREBALLLLLL!!</h1><h1>LOREM! IPSUM! FIREBALLLLLL!!</h1><h1>LOREM! IPSUM! FIREBALLLLLL!!</h1><h1>LOREM! IPSUM! FIREBALLLLLL!!</h1><h2>🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥</h2>",
    }),
    { autoHeight: true } // 👈 With Auto Height set to `true`, the item window will stretch as tall as it can to match the content height when this tab is viewed.
    );
    });

    A tab ID is always required (see TabId).

  • Adds custom content to NPC sheets at position relative to selector.

    Parameters

    Returns void

    void

    Hooks.once("tidy5e-sheet.ready", (api) => {
    api.registerNpcContent(
    new api.models.HtmlContent({
    html: `<a title="Example Button" class="my-custom-icon"><i class="fas fa-user"></i></a>`,
    injectParams: {
    selector: `[data-tidy-sheet-part="${api.constants.SHEET_PARTS.NAME_CONTAINER}"]`
    position: "beforebegin",
    },
    onContentReady: (params) => {
    console.log("content ready to render", params);
    console.log("my content", params.content);
    },
    onRender: (params) => {
    params.element
    .querySelector(".my-custom-icon")
    .addEventListener("click", () => alert("Clicked custom NPC icon"));
    },
    })
    );
    });
  • Registers header controls for all Tidy Application V2 NPC sheets.

    Parameters

    Returns void

    Hooks.once('tidy5e-sheet.ready', (api) => {
    api.registerNpcHeaderControls({
    controls: [
    {
    icon: 'fas fa-broom',
    label: 'Debug Button',
    visible() {
    return !this.document.compendium?.locked;
    },
    async onClickAction(event) {
    ui.notifications.info(
    `Logged document data for ${this.document.name} to console for review.`
    );
    console.log(this.document);
    console.log(await this.document.sheet._prepareContext());
    },
    ownership: CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER,
    },
    ],
    });
    });
  • Adds a tab to the available NPC sheet tabs.

    Parameters

    Returns void

    void

    Hooks.once('tidy5e-sheet.ready', (api) => {
    api.registerNpcTab(
    new api.models.HandlebarsTab({
    title: 'My Tab',
    path: '/modules/my-module-id/templates/my-handlebars-template.hbs',
    tabId: 'my-module-id-registered-npc-tab',
    getData: async (data) => {
    data['my-message'] = 'Hello, world! 🌊🏄‍♂️';
    return Promise.resolve(data);
    },
    onRender(params) {
    const myTab = $(params.tabContentsElement);
    myTab.find('.my-control').click(_myHandler.bind(params.app));
    },
    })
    );
    });

    A tab ID is always required (see TabId).

  • Adds custom content to vehicle sheets at position relative to selector.

    Parameters

    Returns void

    void

    Hooks.once("tidy5e-sheet.ready", (api) => {
    api.registerVehicleContent(
    new api.models.HtmlContent({
    html: `<a title="Example Button" class="my-custom-icon"><i class="fas fa-user"></i></a>`,
    injectParams: {
    selector: `[data-tidy-sheet-part="${api.constants.SHEET_PARTS.NAME_CONTAINER}"]`
    position: "beforebegin",
    },
    onContentReady: (params) => {
    console.log("content ready to render", params);
    console.log("my content", params.content);
    },
    onRender: (params) => {
    params.element
    .querySelector(".my-custom-icon")
    .addEventListener("click", () => alert("Clicked Vehicle custom icon"));
    },
    })
    );
    });
  • Registers header controls for all Tidy Application V2 Vehicle sheets.

    Parameters

    Returns void

    Hooks.once('tidy5e-sheet.ready', (api) => {
    api.registerVehicleHeaderControls({
    controls: [
    {
    icon: 'fas fa-broom',
    label: 'Debug Button',
    visible() {
    return !this.document.compendium?.locked;
    },
    async onClickAction(event) {
    ui.notifications.info(
    `Logged document data for ${this.document.name} to console for review.`
    );
    console.log(this.document);
    console.log(await this.document.sheet._prepareContext());
    },
    ownership: CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER,
    },
    ],
    });
    });
  • Adds a tab to the available Vehicle sheet tabs.

    Parameters

    Returns void

    void

    Hooks.once('tidy5e-sheet.ready', (api) => {
    api.registerVehicleTab(
    new api.models.HandlebarsTab({
    title: 'My Tab',
    path: '/modules/my-module-id/templates/my-handlebars-template.hbs',
    tabId: 'my-module-id-registered-vehicle-tab',
    getData: async (data) => {
    data['my-message'] = 'Hello, world! 🌊🏄‍♂️';
    return Promise.resolve(data);
    },
    onRender(params) {
    const myTab = $(params.tabContentsElement);
    myTab.find('.my-control').click(_myHandler.bind(params.app));
    },
    })
    );
    });

    A tab ID is always required (see TabId).

  • Wraps the provided HTML so that Tidy will remove the content when handling document changes.

    Parameters

    • html: string

      any HTML string that needs to be re-rendered in the style of Foundry Handlebars (usually, this is any time the target document or its embedded documents change).

    Returns string

    the original HTML with a transparent element wrapped around which indicates to Tidy that this should be removed and re-rendered.

    The intended use of this function is to accompany the use of the tidy5e-sheet.renderActorSheet or tidy5e-sheet.renderItemSheet hook. Any content injected through those hooks needs to be wrapped in this way so that the old version of the HTML can be removed before adding it back in. Handlebars refreshes content in this way, but for Tidy purposes, the module needs to know when an arbitrary segment of HTML is meant to be removed. This function provides that information to Tidy for your HTML.

    Hooks.on('tidy5e-sheet.renderActorSheet', (app, element, data) => {
    const api = game.modules.get('tidy5e-sheet').api;
    const actorEmoji = data.actor.system.currency.pp > 0 ? '💹' : '📉';
    let iconHtml = api.useHandlebarsRendering(`<h1>${actorEmoji}</h1>`);
    // 👆 This HTML looks like `<div style="display: contents;" data-tidy-render-scheme="handlebars"><h1>📉</h1></div>`
    // if the actor doesn't have at least 1 platinum.
    // Tidy will remove this each time the sheet would normally re-render, and it will add it back.
    // When the actor have more than 0 platinum, stonks will rise.

    let actorNameElement = element.querySelector(`[data-tidy-field="name"]`);
    actorNameElement?.insertAdjacentHTML('afterend', iconHtml);
    });