Initial commit
This commit is contained in:
commit
03761d2e2f
17 changed files with 5662 additions and 0 deletions
16
.eslintrc.json
Normal file
16
.eslintrc.json
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"es2021": true
|
||||||
|
},
|
||||||
|
"extends": [
|
||||||
|
"standard"
|
||||||
|
],
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": "latest",
|
||||||
|
"sourceType": "module"
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"indent": ["error", 4]
|
||||||
|
}
|
||||||
|
}
|
||||||
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
node_modules/*
|
||||||
|
.vscode/
|
||||||
|
mkzip.sh
|
||||||
|
*.zip
|
||||||
20
languages/en.json
Normal file
20
languages/en.json
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"tokenActionHud": {
|
||||||
|
"template": {
|
||||||
|
"armor": "Armor",
|
||||||
|
"containers": "Containers",
|
||||||
|
"consumables": "Consumables",
|
||||||
|
"equipment": "Equipment",
|
||||||
|
"inventory": "Inventory",
|
||||||
|
"item": "Item",
|
||||||
|
"weapons": "Weapons",
|
||||||
|
"treasure": "Treasure",
|
||||||
|
"settings": {
|
||||||
|
"displayUnequipped": {
|
||||||
|
"hint": "Choose whether to display unequipped items on the HUD",
|
||||||
|
"name": "Display Unequipped"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
72
module.json
Normal file
72
module.json
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
{
|
||||||
|
"id": "token-action-hud-gurps",
|
||||||
|
"title": "Token Action HUD for GURPS",
|
||||||
|
"description": "Token Action HUD is a repositionable HUD of actions for a selected token",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Neill Cox",
|
||||||
|
"url": "https://github.com/neillc"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"url": "This is auto replaced",
|
||||||
|
"flags": {},
|
||||||
|
"version": "0.0.37",
|
||||||
|
"compatibility": {
|
||||||
|
"minimum": "11",
|
||||||
|
"verified": "11.351"
|
||||||
|
},
|
||||||
|
"esmodules": [
|
||||||
|
"./scripts/init.js"
|
||||||
|
],
|
||||||
|
"scripts": [
|
||||||
|
],
|
||||||
|
"styles": [
|
||||||
|
"./styles/tah-template-style.css"
|
||||||
|
],
|
||||||
|
"languages": [
|
||||||
|
{
|
||||||
|
"lang": "en",
|
||||||
|
"name": "English",
|
||||||
|
"path": "languages/en.json"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"packs": [],
|
||||||
|
"relationships": {
|
||||||
|
"systems": [
|
||||||
|
{
|
||||||
|
"id": "gurps",
|
||||||
|
"type": "system",
|
||||||
|
"compatibility": [
|
||||||
|
{
|
||||||
|
"minimum": "0.16.10",
|
||||||
|
"verified": "01.16.10"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"requires": [
|
||||||
|
{
|
||||||
|
"id": "token-action-hud-core",
|
||||||
|
"type": "module",
|
||||||
|
"compatibility": [
|
||||||
|
{
|
||||||
|
"minimum": "1.5.0",
|
||||||
|
"maximum": "1.5",
|
||||||
|
"verified": "1.5.0"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"optional": [],
|
||||||
|
"flags": {
|
||||||
|
"optional": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"socket": false,
|
||||||
|
"readme": "http://172.23.0.17:8000/module.json",
|
||||||
|
"manifest": "http://172.23.0.17:8000/module.json",
|
||||||
|
"download": "http://172.23.0.17:8000/fvtt-token-action-hud-gurps.zip",
|
||||||
|
"protected": false,
|
||||||
|
"coreTranslation": false,
|
||||||
|
"library": false
|
||||||
|
}
|
||||||
4462
package-lock.json
generated
Normal file
4462
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
16
package.json
Normal file
16
package.json
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"build": "rollup -c",
|
||||||
|
"dev": "rollup -wcm"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@rollup/plugin-multi-entry": "^6.0.0",
|
||||||
|
"eslint": "^8.25.0",
|
||||||
|
"eslint-config-standard": "^17.0.0",
|
||||||
|
"eslint-plugin-import": "^2.26.0",
|
||||||
|
"eslint-plugin-n": "^15.3.0",
|
||||||
|
"eslint-plugin-promise": "^6.1.0",
|
||||||
|
"rollup": "^2.56.3",
|
||||||
|
"rollup-plugin-terser": "^7.0.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
51
readme.md
Normal file
51
readme.md
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
 [](https://forge-vtt.com/bazaar#package=token-action-hud-template)
|
||||||
|
|
||||||
|
# Token Action HUD Template
|
||||||
|
|
||||||
|
Token Action HUD is a repositionable HUD of actions for a selected token.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
# Features
|
||||||
|
- Make rolls directly from the HUD instead of opening your character sheet.
|
||||||
|
- Use items from the HUD or right-click an item to open its sheet.
|
||||||
|
- Move the HUD and choose to expand the menus up or down.
|
||||||
|
- Unlock the HUD to customise layout and groups per user, and actions per actor.
|
||||||
|
- Add your own macros, journal entries and roll table compendiums.
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
|
||||||
|
## Method 1
|
||||||
|
1. On Foundry VTT's **Configuration and Setup** screen, go to **Add-on Modules**
|
||||||
|
2. Click **Install Module**
|
||||||
|
3. Search for **Token Action HUD Pathfinder 2**
|
||||||
|
4. Click **Install** next to the module listing
|
||||||
|
|
||||||
|
## Method 2
|
||||||
|
1. On Foundry VTT's **Configuration and Setup** screen, go to **Add-on Modules**
|
||||||
|
2. Click **Install Module**
|
||||||
|
3. In the Manifest URL field, paste: `https://github.com/Larkinabout/fvtt-token-action-hud-template/releases/latest/download/module.json`
|
||||||
|
4. Click **Install** next to the pasted Manifest URL
|
||||||
|
|
||||||
|
## Required Modules
|
||||||
|
|
||||||
|
**IMPORTANT** - Token Action HUD Template requires the [Token Action HUD Core](https://foundryvtt.com/packages/token-action-hud-core) module to be installed.
|
||||||
|
|
||||||
|
## Recommended Modules
|
||||||
|
Token Action HUD uses the [Color Picker](https://foundryvtt.com/packages/color-picker) library module for its color picker settings.
|
||||||
|
|
||||||
|
# Support
|
||||||
|
|
||||||
|
For a guide on using Token Action HUD, go to: [How to Use Token Action HUD](https://github.com/Larkinabout/fvtt-token-action-hud-core/wiki/How-to-Use-Token-Action-HUD)
|
||||||
|
|
||||||
|
For questions, feature requests or bug reports, please open an issue [here](https://github.com/Larkinabout/fvtt-token-action-hud-core/issues).
|
||||||
|
|
||||||
|
Pull requests are welcome. Please include a reason for the request or create an issue before starting one.
|
||||||
|
|
||||||
|
# Acknowledgements
|
||||||
|
|
||||||
|
Thank you to the Community Helpers on Foundry's Discord who provide tireless support for people seeking help with the HUD.
|
||||||
|
|
||||||
|
# License
|
||||||
|
|
||||||
|
This Foundry VTT module is licensed under a [Creative Commons Attribution 4.0 International License](https://creativecommons.org/licenses/by/4.0/) and this work is licensed under [Foundry Virtual Tabletop EULA - Limited License Agreement for module development](https://foundryvtt.com/article/license/).
|
||||||
23
rollup.config.js
Normal file
23
rollup.config.js
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { terser } from 'rollup-plugin-terser'
|
||||||
|
import multi from '@rollup/plugin-multi-entry'
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
input: {
|
||||||
|
include: [
|
||||||
|
'scripts/*.js',
|
||||||
|
'scripts/*/*.js'
|
||||||
|
],
|
||||||
|
exclude: [
|
||||||
|
'scripts/token-action-hud-gurps.min.js']
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
format: 'esm',
|
||||||
|
file: 'scripts/token-action-hud-gurps.min.js'
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
terser({ keep_classnames: true, keep_fnames: true }),
|
||||||
|
multi()
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
131
scripts/action-handler.js
Normal file
131
scripts/action-handler.js
Normal file
|
|
@ -0,0 +1,131 @@
|
||||||
|
// System Module Imports
|
||||||
|
import { ACTION_TYPE, ITEM_TYPE } from './constants.js'
|
||||||
|
import { Utils } from './utils.js'
|
||||||
|
|
||||||
|
export let ActionHandler = null
|
||||||
|
|
||||||
|
Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
||||||
|
/**
|
||||||
|
* Extends Token Action HUD Core's ActionHandler class and builds system-defined actions for the HUD
|
||||||
|
*/
|
||||||
|
ActionHandler = class ActionHandler extends coreModule.api.ActionHandler {
|
||||||
|
/**
|
||||||
|
* Build system actions
|
||||||
|
* Called by Token Action HUD Core
|
||||||
|
* @override
|
||||||
|
* @param {array} groupIds
|
||||||
|
*/a
|
||||||
|
async buildSystemActions (groupIds) {
|
||||||
|
// Set actor and token variables
|
||||||
|
this.actors = (!this.actor) ? this._getActors() : [this.actor]
|
||||||
|
this.actorType = this.actor?.type
|
||||||
|
|
||||||
|
// Settings
|
||||||
|
this.displayUnequipped = Utils.getSetting('displayUnequipped')
|
||||||
|
|
||||||
|
// Set items variable
|
||||||
|
if (this.actor) {
|
||||||
|
let items = this.actor.items
|
||||||
|
items = coreModule.api.Utils.sortItemsByName(items)
|
||||||
|
this.items = items
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.actorType === 'character') {
|
||||||
|
debugger;
|
||||||
|
this.#buildCharacterActions()
|
||||||
|
} else if (!this.actor) {
|
||||||
|
this.#buildMultipleTokenActions()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build character actions
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
#buildCharacterActions () {
|
||||||
|
this._get_attributes({id: "attributes", type:"system"})
|
||||||
|
this.#buildInventory()
|
||||||
|
}
|
||||||
|
|
||||||
|
_get_attributes(parent) {
|
||||||
|
const macroType = "attributes";
|
||||||
|
let actions = [];
|
||||||
|
|
||||||
|
let attributes = Object.entries(this.actor.system.attributes)
|
||||||
|
attributes.forEach((a) => {
|
||||||
|
const key = a[0];
|
||||||
|
const value = a[1].value
|
||||||
|
// img
|
||||||
|
|
||||||
|
actions.push({
|
||||||
|
id: key,
|
||||||
|
name: coreModule.api.Utils.i18n(key),
|
||||||
|
description: coreModule.api.Utils.i18n('GURPS.Attributes'),
|
||||||
|
encodedValue: [macroType, key].join(this.delimiter),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
this.addActions(actions, parent)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build multiple token actions
|
||||||
|
* @private
|
||||||
|
* @returns {object}
|
||||||
|
*/
|
||||||
|
#buildMultipleTokenActions () {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build inventory
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
async #buildInventory () {
|
||||||
|
if (this.items.size === 0) return
|
||||||
|
|
||||||
|
const actionTypeId = 'item'
|
||||||
|
const inventoryMap = new Map()
|
||||||
|
|
||||||
|
for (const [itemId, itemData] of this.items) {
|
||||||
|
const type = itemData.type
|
||||||
|
const equipped = itemData.equipped
|
||||||
|
|
||||||
|
if (equipped || this.displayUnequipped) {
|
||||||
|
const typeMap = inventoryMap.get(type) ?? new Map()
|
||||||
|
typeMap.set(itemId, itemData)
|
||||||
|
inventoryMap.set(type, typeMap)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [type, typeMap] of inventoryMap) {
|
||||||
|
const groupId = ITEM_TYPE[type]?.groupId
|
||||||
|
|
||||||
|
if (!groupId) continue
|
||||||
|
|
||||||
|
const groupData = { id: groupId, type: 'system' }
|
||||||
|
|
||||||
|
// Get actions
|
||||||
|
const actions = [...typeMap].map(([itemId, itemData]) => {
|
||||||
|
const id = itemId
|
||||||
|
const name = itemData.name
|
||||||
|
const actionTypeName = coreModule.api.Utils.i18n(ACTION_TYPE[actionTypeId])
|
||||||
|
const listName = `${actionTypeName ? `${actionTypeName}: ` : ''}${name}`
|
||||||
|
const encodedValue = [actionTypeId, id].join(this.delimiter)
|
||||||
|
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
listName,
|
||||||
|
encodedValue
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// TAH Core method to add actions to the action list
|
||||||
|
this.addActions(actions, groupData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
55
scripts/constants.js
Normal file
55
scripts/constants.js
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
/**
|
||||||
|
* Module-based constants
|
||||||
|
*/
|
||||||
|
export const MODULE = {
|
||||||
|
ID: 'token-action-hud-gurps'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Core module
|
||||||
|
*/
|
||||||
|
export const CORE_MODULE = {
|
||||||
|
ID: 'token-action-hud-core'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Core module version required by the system module
|
||||||
|
*/
|
||||||
|
export const REQUIRED_CORE_MODULE_VERSION = '1.5'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action types
|
||||||
|
*/
|
||||||
|
export const ACTION_TYPE = {
|
||||||
|
item: 'tokenActionHud.template.item',
|
||||||
|
utility: 'tokenActionHud.utility'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Groups
|
||||||
|
*/
|
||||||
|
export const GROUP = {
|
||||||
|
attributes: { id: 'attributes', name: 'tokenActionHud.gurps.attributes', type: 'system' },
|
||||||
|
armor: { id: 'armor', name: 'tokenActionHud.template.armor', type: 'system' },
|
||||||
|
equipment: { id: 'equipment', name: 'tokenActionHud.template.equipment', type: 'system' },
|
||||||
|
consumables: { id: 'consumables', name: 'tokenActionHud.template.consumables', type: 'system' },
|
||||||
|
containers: { id: 'containers', name: 'tokenActionHud.template.containers', type: 'system' },
|
||||||
|
treasure: { id: 'treasure', name: 'tokenActionHud.template.treasure', type: 'system' },
|
||||||
|
weapons: { id: 'weapons', name: 'tokenActionHud.template.weapons', type: 'system' },
|
||||||
|
combat: { id: 'combat', name: 'tokenActionHud.combat', type: 'system' },
|
||||||
|
token: { id: 'token', name: 'tokenActionHud.token', type: 'system' },
|
||||||
|
utility: { id: 'utility', name: 'tokenActionHud.utility', type: 'system' }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item types
|
||||||
|
*/
|
||||||
|
export const ITEM_TYPE = {
|
||||||
|
attributes: { groupId: 'attributes' },
|
||||||
|
armor: { groupId: 'armor' },
|
||||||
|
backpack: { groupId: 'containers' },
|
||||||
|
consumable: { groupId: 'consumables' },
|
||||||
|
equipment: { groupId: 'equipment' },
|
||||||
|
treasure: { groupId: 'treasure' },
|
||||||
|
weapon: { groupId: 'weapons' }
|
||||||
|
}
|
||||||
53
scripts/defaults.js
Normal file
53
scripts/defaults.js
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
import { GROUP } from './constants.js'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default layout and groups
|
||||||
|
*/
|
||||||
|
export let DEFAULTS = null
|
||||||
|
|
||||||
|
Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
||||||
|
const groups = GROUP
|
||||||
|
Object.values(groups).forEach(group => {
|
||||||
|
group.name = coreModule.api.Utils.i18n(group.name)
|
||||||
|
group.listName = `Group: ${coreModule.api.Utils.i18n(group.listName ?? group.name)}`
|
||||||
|
})
|
||||||
|
const groupsArray = Object.values(groups)
|
||||||
|
debugger;
|
||||||
|
DEFAULTS = {
|
||||||
|
layout: [
|
||||||
|
{
|
||||||
|
nestId: 'inventory',
|
||||||
|
id: 'inventory',
|
||||||
|
name: coreModule.api.Utils.i18n('Template.Inventory'),
|
||||||
|
groups: [
|
||||||
|
{ ...groups.weapons, nestId: 'inventory_weapons' },
|
||||||
|
{ ...groups.armor, nestId: 'inventory_armor' },
|
||||||
|
{ ...groups.equipment, nestId: 'inventory_equipment' },
|
||||||
|
{ ...groups.consumables, nestId: 'inventory_consumables' },
|
||||||
|
{ ...groups.containers, nestId: 'inventory_containers' },
|
||||||
|
{ ...groups.treasure, nestId: 'inventory_treasure' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nestId: 'utility',
|
||||||
|
id: 'utility',
|
||||||
|
name: coreModule.api.Utils.i18n('tokenActionHud.utility'),
|
||||||
|
groups: [
|
||||||
|
{ ...groups.combat, nestId: 'utility_combat' },
|
||||||
|
{ ...groups.token, nestId: 'utility_token' },
|
||||||
|
{ ...groups.rests, nestId: 'utility_rests' },
|
||||||
|
{ ...groups.utility, nestId: 'utility_utility' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nestId: 'attributes',
|
||||||
|
id: 'attributes',
|
||||||
|
name: coreModule.api.Utils.i18n('GURPS.attributes'),
|
||||||
|
groups: [
|
||||||
|
{ ...groups.attributes, nestId: 'attributes_attributes' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
groups: groupsArray
|
||||||
|
}
|
||||||
|
})
|
||||||
14
scripts/init.js
Normal file
14
scripts/init.js
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { SystemManager } from './system-manager.js'
|
||||||
|
import { MODULE, REQUIRED_CORE_MODULE_VERSION } from './constants.js'
|
||||||
|
|
||||||
|
Hooks.on('tokenActionHudCoreApiReady', async () => {
|
||||||
|
/**
|
||||||
|
* Return the SystemManager and requiredCoreModuleVersion to Token Action HUD Core
|
||||||
|
*/
|
||||||
|
const module = game.modules.get(MODULE.ID)
|
||||||
|
module.api = {
|
||||||
|
requiredCoreModuleVersion: REQUIRED_CORE_MODULE_VERSION,
|
||||||
|
SystemManager
|
||||||
|
}
|
||||||
|
Hooks.call('tokenActionHudSystemReady', module)
|
||||||
|
})
|
||||||
108
scripts/roll-handler.js
Normal file
108
scripts/roll-handler.js
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
export let RollHandler = null
|
||||||
|
|
||||||
|
Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
||||||
|
/**
|
||||||
|
* Extends Token Action HUD Core's RollHandler class and handles action events triggered when an action is clicked
|
||||||
|
*/
|
||||||
|
RollHandler = class RollHandler extends coreModule.api.RollHandler {
|
||||||
|
/**
|
||||||
|
* Handle action click
|
||||||
|
* Called by Token Action HUD Core when an action is left or right-clicked
|
||||||
|
* @override
|
||||||
|
* @param {object} event The event
|
||||||
|
* @param {string} encodedValue The encoded value
|
||||||
|
*/
|
||||||
|
async handleActionClick (event, encodedValue) {
|
||||||
|
const [actionTypeId, actionId] = encodedValue.split('|')
|
||||||
|
|
||||||
|
const renderable = ['item']
|
||||||
|
|
||||||
|
if (renderable.includes(actionTypeId) && this.isRenderItem()) {
|
||||||
|
return this.doRenderItem(this.actor, actionId)
|
||||||
|
}
|
||||||
|
|
||||||
|
const knownCharacters = ['character']
|
||||||
|
|
||||||
|
// If single actor is selected
|
||||||
|
if (this.actor) {
|
||||||
|
await this.#handleAction(event, this.actor, this.token, actionTypeId, actionId)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const controlledTokens = canvas.tokens.controlled
|
||||||
|
.filter((token) => knownCharacters.includes(token.actor?.type))
|
||||||
|
|
||||||
|
// If multiple actors are selected
|
||||||
|
for (const token of controlledTokens) {
|
||||||
|
const actor = token.actor
|
||||||
|
await this.#handleAction(event, actor, token, actionTypeId, actionId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle action hover
|
||||||
|
* Called by Token Action HUD Core when an action is hovered on or off
|
||||||
|
* @override
|
||||||
|
* @param {object} event The event
|
||||||
|
* @param {string} encodedValue The encoded value
|
||||||
|
*/
|
||||||
|
async handleActionHover (event, encodedValue) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle group click
|
||||||
|
* Called by Token Action HUD Core when a group is right-clicked while the HUD is locked
|
||||||
|
* @override
|
||||||
|
* @param {object} event The event
|
||||||
|
* @param {object} group The group
|
||||||
|
*/
|
||||||
|
async handleGroupClick (event, group) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle action
|
||||||
|
* @private
|
||||||
|
* @param {object} event The event
|
||||||
|
* @param {object} actor The actor
|
||||||
|
* @param {object} token The token
|
||||||
|
* @param {string} actionTypeId The action type id
|
||||||
|
* @param {string} actionId The actionId
|
||||||
|
*/
|
||||||
|
async #handleAction (event, actor, token, actionTypeId, actionId) {
|
||||||
|
switch (actionTypeId) {
|
||||||
|
case 'item':
|
||||||
|
this.#handleItemAction(event, actor, actionId)
|
||||||
|
break
|
||||||
|
case 'utility':
|
||||||
|
this.#handleUtilityAction(token, actionId)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle item action
|
||||||
|
* @private
|
||||||
|
* @param {object} event The event
|
||||||
|
* @param {object} actor The actor
|
||||||
|
* @param {string} actionId The action id
|
||||||
|
*/
|
||||||
|
#handleItemAction (event, actor, actionId) {
|
||||||
|
const item = actor.items.get(actionId)
|
||||||
|
item.toChat(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle utility action
|
||||||
|
* @private
|
||||||
|
* @param {object} token The token
|
||||||
|
* @param {string} actionId The action id
|
||||||
|
*/
|
||||||
|
async #handleUtilityAction (token, actionId) {
|
||||||
|
switch (actionId) {
|
||||||
|
case 'endTurn':
|
||||||
|
if (game.combat?.current?.tokenId === token.id) {
|
||||||
|
await game.combat?.nextTurn()
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
21
scripts/settings.js
Normal file
21
scripts/settings.js
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { MODULE } from './constants.js'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register module settings
|
||||||
|
* Called by Token Action HUD Core to register Token Action HUD system module settings
|
||||||
|
* @param {function} coreUpdate Token Action HUD Core update function
|
||||||
|
*/
|
||||||
|
export function register (coreUpdate) {
|
||||||
|
game.settings.register(MODULE.ID, 'displayUnequipped', {
|
||||||
|
name: game.i18n.localize('tokenActionHud.template.settings.displayUnequipped.name'),
|
||||||
|
hint: game.i18n.localize('tokenActionHud.template.settings.displayUnequipped.hint'
|
||||||
|
),
|
||||||
|
scope: 'client',
|
||||||
|
config: true,
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
onChange: (value) => {
|
||||||
|
coreUpdate(value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
92
scripts/system-manager.js
Normal file
92
scripts/system-manager.js
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
// System Module Imports
|
||||||
|
import { ActionHandler } from './action-handler.js'
|
||||||
|
import { RollHandler as Core } from './roll-handler.js'
|
||||||
|
import { MODULE } from './constants.js'
|
||||||
|
import { DEFAULTS } from './defaults.js'
|
||||||
|
import * as systemSettings from './settings.js'
|
||||||
|
|
||||||
|
export let SystemManager = null
|
||||||
|
|
||||||
|
Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
||||||
|
/**
|
||||||
|
* Extends Token Action HUD Core's SystemManager class
|
||||||
|
*/
|
||||||
|
SystemManager = class SystemManager extends coreModule.api.SystemManager {
|
||||||
|
/**
|
||||||
|
* Returns an instance of the ActionHandler to Token Action HUD Core
|
||||||
|
* Called by Token Action HUD Core
|
||||||
|
* @override
|
||||||
|
* @returns {class} The ActionHandler instance
|
||||||
|
*/
|
||||||
|
getActionHandler () {
|
||||||
|
return new ActionHandler()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of roll handlers to Token Action HUD Core
|
||||||
|
* Used to populate the Roll Handler module setting choices
|
||||||
|
* Called by Token Action HUD Core
|
||||||
|
* @override
|
||||||
|
* @returns {object} The available roll handlers
|
||||||
|
*/
|
||||||
|
getAvailableRollHandlers () {
|
||||||
|
const coreTitle = 'Core Template'
|
||||||
|
const choices = { core: coreTitle }
|
||||||
|
return choices
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an instance of the RollHandler to Token Action HUD Core
|
||||||
|
* Called by Token Action HUD Core
|
||||||
|
* @override
|
||||||
|
* @param {string} rollHandlerId The roll handler ID
|
||||||
|
* @returns {class} The RollHandler instance
|
||||||
|
*/
|
||||||
|
getRollHandler (rollHandlerId) {
|
||||||
|
let rollHandler
|
||||||
|
switch (rollHandlerId) {
|
||||||
|
case 'core':
|
||||||
|
default:
|
||||||
|
rollHandler = new Core()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return rollHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the default layout and groups to Token Action HUD Core
|
||||||
|
* Called by Token Action HUD Core
|
||||||
|
* @returns {object} The default layout and groups
|
||||||
|
*/
|
||||||
|
async registerDefaults () {
|
||||||
|
return DEFAULTS
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register Token Action HUD system module settings
|
||||||
|
* Called by Token Action HUD Core
|
||||||
|
* @override
|
||||||
|
* @param {function} coreUpdate The Token Action HUD Core update function
|
||||||
|
*/
|
||||||
|
registerSettings (coreUpdate) {
|
||||||
|
systemSettings.register(coreUpdate)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns styles to Token Action HUD Core
|
||||||
|
* Called by Token Action HUD Core
|
||||||
|
* @override
|
||||||
|
* @returns {object} The TAH system styles
|
||||||
|
*/
|
||||||
|
registerStyles () {
|
||||||
|
return {
|
||||||
|
template: {
|
||||||
|
class: 'tah-style-template-style', // The class to add to first DIV element
|
||||||
|
file: 'tah-template-style', // The file without the css extension
|
||||||
|
moduleId: MODULE.ID, // The module ID
|
||||||
|
name: 'Template Style' // The name to display in the Token Action HUD Core 'Style' module setting
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
40
scripts/utils.js
Normal file
40
scripts/utils.js
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
import { MODULE } from './constants.js'
|
||||||
|
|
||||||
|
export let Utils = null
|
||||||
|
|
||||||
|
Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
|
||||||
|
/**
|
||||||
|
* Utility functions
|
||||||
|
*/
|
||||||
|
Utils = class Utils {
|
||||||
|
/**
|
||||||
|
* Get setting
|
||||||
|
* @param {string} key The key
|
||||||
|
* @param {string=null} defaultValue The default value
|
||||||
|
* @returns {string} The setting value
|
||||||
|
*/
|
||||||
|
static getSetting (key, defaultValue = null) {
|
||||||
|
let value = defaultValue ?? null
|
||||||
|
try {
|
||||||
|
value = game.settings.get(MODULE.ID, key)
|
||||||
|
} catch {
|
||||||
|
coreModule.api.Logger.debug(`Setting '${key}' not found`)
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set setting
|
||||||
|
* @param {string} key The key
|
||||||
|
* @param {string} value The value
|
||||||
|
*/
|
||||||
|
static async setSetting (key, value) {
|
||||||
|
try {
|
||||||
|
value = await game.settings.set(MODULE.ID, key, value)
|
||||||
|
coreModule.api.Logger.debug(`Setting '${key}' set to '${value}'`)
|
||||||
|
} catch {
|
||||||
|
coreModule.api.Logger.debug(`Setting '${key}' not found`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
484
styles/tah-template-style.css
Normal file
484
styles/tah-template-style.css
Normal file
|
|
@ -0,0 +1,484 @@
|
||||||
|
:root {
|
||||||
|
--tah-background-color: #00000000;
|
||||||
|
--tah-border-radius: 3px;
|
||||||
|
--tah-gap: 5px;
|
||||||
|
|
||||||
|
--tah-button-background-color: #000000b3;
|
||||||
|
--tah-button-border-color: none;
|
||||||
|
--tah-button-box-shadow: 0 2px 0 -1px #0c0c0c, 0 0 0 1px #060606,
|
||||||
|
0 0 5px #000000ff;
|
||||||
|
--tah-button-disabled-text-color: var(--tah-text-secondary-color);
|
||||||
|
--tah-button-text-color: var(--tah-text-primary-color);
|
||||||
|
--tah-button-height: 32px;
|
||||||
|
--tah-button-min-width: 32px;
|
||||||
|
--tah-button-hover-box-shadow: 0 2px 0 -1px var(--tah-text-tertiary-color),
|
||||||
|
0 0 0 1px red, 0 0 10px var(--tah-text-tertiary-color);
|
||||||
|
--tah-button-hover-text-color: #fff;
|
||||||
|
--tah-button-active-background-color: #3c0078bf;
|
||||||
|
--tah-button-active-box-shadow: 0 0 0 1px #9b8dff, inset 0 0 10px #9b8dff;
|
||||||
|
--tah-button-toggle-background-color: #000000b3;
|
||||||
|
--tah-button-toggle-hover-background-color: #3c0078bf;
|
||||||
|
--tah-button-toggle-hover-box-shadow: 0 0 0 1px #9b8dff, 0 0 10px #9b8dff;
|
||||||
|
--tah-text-disabled-color: var(--tah-text-secondary-color);
|
||||||
|
--tah-text-primary-color: #dddddd;
|
||||||
|
--tah-text-secondary-color: #dddddd80;
|
||||||
|
--tah-text-tertiary-color: #ff6400;
|
||||||
|
--tah-text-hover-primary-color: var(--tah-text-primary-color);
|
||||||
|
--tah-text-hover-secondary-color: var(--tah-text-secondary-color);
|
||||||
|
--tah-text-hover-tertiary-color: var(--tah-text-tertiary-color);
|
||||||
|
--tah-text-shadow: 1px 1px 1px rgb(0 0 0), 0px 1px 3px rgb(0 0 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#token-action-hud {
|
||||||
|
align-items: center;
|
||||||
|
border-radius: var(--tah-border-radius);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
height: auto;
|
||||||
|
left: 150px;
|
||||||
|
position: fixed;
|
||||||
|
top: 80px;
|
||||||
|
width: auto;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
#token-action-hud [class*="icon-"] {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tah-character-name {
|
||||||
|
color: var(--tah-text-primary-color);
|
||||||
|
font-size: var(--font-size-16);
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
position: absolute;
|
||||||
|
text-align: left;
|
||||||
|
text-shadow: var(--tah-text-shadow);
|
||||||
|
top: -22px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-hidden {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#token-action-hud:hover #tah-collapse-hud,
|
||||||
|
#token-action-hud:hover > #tah-buttons {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tah-collapse-hud,
|
||||||
|
#tah-buttons {
|
||||||
|
align-items: center;
|
||||||
|
display: none;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
height: var(--tah-button-height);
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tah-collapse-expand {
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
left: -16px;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tah-collapse-hud,
|
||||||
|
#tah-buttons button {
|
||||||
|
background: transparent;
|
||||||
|
border: 0;
|
||||||
|
line-height: unset;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tah-collapse-hud:hover,
|
||||||
|
#tah-collapse-hud:focus,
|
||||||
|
#tah-buttons button:hover,
|
||||||
|
#tah-buttons button:focus {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tah-collapse-expand button > :is(.fa, .fas),
|
||||||
|
#tah-buttons button > :is(.fa, .fas) {
|
||||||
|
color: var(--tah-text-primary-color);
|
||||||
|
font-size: var(--font-size-12);
|
||||||
|
margin: 3px;
|
||||||
|
padding: 3px;
|
||||||
|
pointer-events: none;
|
||||||
|
position: relative;
|
||||||
|
text-align: center;
|
||||||
|
text-shadow: var(--tah-text-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
#tah-collapse-expand button > :is(.fa, .fas) {
|
||||||
|
font-size: medium;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tah-collapse-hud {
|
||||||
|
left: -3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tah-expand-hud {
|
||||||
|
left: -3px;
|
||||||
|
top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tah-expand-hud,
|
||||||
|
#tah-expand-hud:focus,
|
||||||
|
.tah-action-button,
|
||||||
|
.tah-action-button:focus,
|
||||||
|
.tah-group-button,
|
||||||
|
.tah-group-button:focus {
|
||||||
|
align-items: center;
|
||||||
|
background-color: var(--tah-button-background-color);
|
||||||
|
border: var(--tah-button-border-color);
|
||||||
|
border-radius: var(--tah-border-radius);
|
||||||
|
box-shadow: var(--tah-button-box-shadow);
|
||||||
|
color: var(--tah-button-text-color);
|
||||||
|
display: flex;
|
||||||
|
height: var(--tah-button-height);
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
position: relative;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
text-shadow: var(--tah-text-shadow);
|
||||||
|
transition: all 0.1s ease-in-out;
|
||||||
|
white-space: nowrap;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-action-button,
|
||||||
|
.tah-group-button {
|
||||||
|
font-size: var(--font-size-13);
|
||||||
|
min-width: var(--tah-button-min-width);
|
||||||
|
}
|
||||||
|
|
||||||
|
#tah-expand-hud:hover,
|
||||||
|
.tah-action-button:active,
|
||||||
|
.tah-action-button:not(.disabled):hover,
|
||||||
|
.tah-group-button:not(.disabled):hover {
|
||||||
|
box-shadow: var(--tah-button-hover-box-shadow);
|
||||||
|
color: var(--tah-button-hover-text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-action-button.toggle:not(.disabled):hover {
|
||||||
|
background: var(--tah-button-toggle-hover-background-color);
|
||||||
|
box-shadow: var(--tah-button-toggle-hover-box-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-action-button.active {
|
||||||
|
background: var(--tah-button-active-background-color);
|
||||||
|
box-shadow: var(--tah-button-active-box-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-action-button.active.activeText > .tah-action-button-content:after {
|
||||||
|
content: "*";
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-action-button.disabled {
|
||||||
|
color: var(--tah-button-disabled-text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-action-button.disabled:hover {
|
||||||
|
box-shadow: var(--tah-button-box-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-action-button.shrink {
|
||||||
|
min-width: min-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-group-button > :is(.fa, .fas) {
|
||||||
|
font-size: 8px;
|
||||||
|
position: absolute;
|
||||||
|
right: 0px;
|
||||||
|
top: 2px;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-group-button:hover:not(.disable-edit)
|
||||||
|
> :is(.fa, .fas) {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-button-content:empty {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-button-content {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
gap: var(--tah-gap);
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0 10px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-button-text {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-action-button-content {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
gap: var(--tah-gap);
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0 10px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-action-button-text {
|
||||||
|
overflow: hidden;
|
||||||
|
padding-right: 1px;
|
||||||
|
text-align: left;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tah-collapse-expand:hover button > i,
|
||||||
|
#tah-buttons button:hover > i {
|
||||||
|
color: var(--tah-text-hover-primary-color);
|
||||||
|
text-shadow: 0 0 8px var(--color-shadow-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
#tah-edit-hud > :is(.fa, .fas) {
|
||||||
|
font-size: var(--font-size-16);
|
||||||
|
}
|
||||||
|
|
||||||
|
#tah-groups,
|
||||||
|
.tah-tab-groups {
|
||||||
|
display: flex;
|
||||||
|
gap: var(--tah-gap);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-tab-groups {
|
||||||
|
width: max-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-tab-group,
|
||||||
|
.tah-group {
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-groups-container {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-tab-group.hover > .tah-groups-container,
|
||||||
|
.tah-tab-group.hover > .tah-groups-container > .tah-groups {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-tab-group > .tah-groups-container.expand-down > .tah-groups {
|
||||||
|
flex-direction: column;
|
||||||
|
left: -10px;
|
||||||
|
padding: 3px 10px 10px 10px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-tab-group > .tah-groups-container.expand-up > .tah-groups {
|
||||||
|
flex-direction: column;
|
||||||
|
left: -10px;
|
||||||
|
padding: 10px 10px 3px 10px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tah-groups > .tah-tab-group > .tah-groups-container.expand-up > .tah-groups {
|
||||||
|
flex-direction: column-reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-tab-group > .tah-groups-container.expand-down {
|
||||||
|
top: calc(100% - 7px);
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-tab-group > .tah-groups-container.expand-up {
|
||||||
|
bottom: calc(100% + 3px + -10px);
|
||||||
|
flex-direction: column-reverse;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-tab-group
|
||||||
|
> .tah-groups-container.expand-up
|
||||||
|
> .tah-groups
|
||||||
|
> .tah-list-groups {
|
||||||
|
flex-direction: column-reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-list-groups,
|
||||||
|
.tah-tab-groups > .tah-tab-group > .tah-groups > .tah-actions {
|
||||||
|
background: var(--tah-background-color);
|
||||||
|
border-radius: var(--tah-border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-list-groups {
|
||||||
|
flex-direction: column;
|
||||||
|
display: flex;
|
||||||
|
gap: var(--tah-gap);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-list-groups .tah-list-groups {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-list-group {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-groups {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: var(--tah-gap);
|
||||||
|
width: max-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-groups.expand-down {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tah-groups.tah-unlocked
|
||||||
|
.tah-group
|
||||||
|
> .tah-groups
|
||||||
|
> .tah-list-groups
|
||||||
|
> .tah-group {
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-group[data-show-title="false"]
|
||||||
|
> .tah-list-group
|
||||||
|
> .tah-groups
|
||||||
|
> .tah-list-groups
|
||||||
|
> .tah-group:not([data-show-title="false"]) {
|
||||||
|
padding-left: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-group:not([data-show-title="false"])[data-has-image="false"]
|
||||||
|
> .tah-list-group
|
||||||
|
> .tah-groups
|
||||||
|
> .tah-list-groups
|
||||||
|
> .tah-group:not([data-show-title="false"])[data-has-image="false"] {
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-unlocked
|
||||||
|
.tah-group
|
||||||
|
> .tah-list-group
|
||||||
|
> .tah-groups
|
||||||
|
> .tah-list-groups
|
||||||
|
> .tah-group {
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-subtitle {
|
||||||
|
align-items: center;
|
||||||
|
color: var(--tah-text-primary-color);
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
font-size: var(--tah-font-size-10);
|
||||||
|
gap: var(--tah-gap);
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
line-height: 1;
|
||||||
|
text-shadow: var(--tah-text-shadow);
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-subtitle:hover {
|
||||||
|
color: var(--tah-text-hover-primary-color);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-subtitle-text {
|
||||||
|
color: var(--tah-text-primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-group[data-show-title="false"] > div > .tah-subtitle > .tah-subtitle-text {
|
||||||
|
color: var(--tah-text-disabled-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-subtitle > :is(.tah-edit-icon, .tah-collapse-icon, .tah-expand-icon) {
|
||||||
|
bottom: 1px;
|
||||||
|
font-size: 8px;
|
||||||
|
pointer-events: none;
|
||||||
|
position: relative;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-subtitle:hover
|
||||||
|
> :is(
|
||||||
|
.tah-collapse-icon:not(.tah-hidden),
|
||||||
|
.tah-expand-icon:not(.tah-hidden)
|
||||||
|
),
|
||||||
|
.tah-subtitle:hover:not(.disable-edit) > .tah-edit-icon {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-tab-group > .tah-actions {
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-actions {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row wrap;
|
||||||
|
gap: var(--tah-gap);
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-info1,
|
||||||
|
.tah-info2,
|
||||||
|
.tah-info3 {
|
||||||
|
color: var(--tah-text-secondary-color);
|
||||||
|
font-size: xx-small;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-info1.tah-spotlight,
|
||||||
|
.tah-info2.tah-spotlight,
|
||||||
|
.tah-info3.tah-spotlight {
|
||||||
|
color: var(--tah-text-tertiary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-subtitle > :is(.tah-info1, .tah-info2, .tah-info3) {
|
||||||
|
background: var(--tah-button-background-color);
|
||||||
|
border-radius: 5px;
|
||||||
|
margin: 1px;
|
||||||
|
padding: 1px 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-button-image {
|
||||||
|
border-radius: var(--tah-border-radius);
|
||||||
|
height: var(--tah-button-height);
|
||||||
|
min-width: var(--tah-button-min-width);
|
||||||
|
width: var(--tah-button-min-width);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-list-image {
|
||||||
|
border: none;
|
||||||
|
border-radius: var(--tah-border-radius);
|
||||||
|
box-shadow: var(--tah-button-box-shadow);
|
||||||
|
height: var(--tah-button-height);
|
||||||
|
margin-right: 5px;
|
||||||
|
min-width: var(--tah-button-min-width);
|
||||||
|
width: var(--tah-button-min-width);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-icon > :is(.fa, .fas) {
|
||||||
|
font-size: x-small;
|
||||||
|
margin: 0px 2px 0px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-icon-disabled {
|
||||||
|
color: var(--tah-text-disabled-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tah-subtitle > .tah-icon > :is(.fa, .fas) {
|
||||||
|
text-shadow: var(--tah-text-shadow);
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue