mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-12 03:31:07 +01:00
Feature/178 searchbar logic to items in character sheet (#209)
* REFACTOR: remove DhpApplicationMixin REFACTOR: remove getEmbeddedDocument method from Item class REFACTOR: remove prepareData method from Actor class REFACTOR: remove _preUpdate method from Actor class * REFACTOR: rename dhpItem to DHItem REFACTOR: improvement Item#isInventoryItem getter REFACTOR: simplify Item's createDialog static method. REFACTOR: remove documentCreate template * FEAT: add SearchFilter for character-sheet Inventory and DomainCards FEAT: simplify the preparetion of inventory context --------- Co-authored-by: Joaquin Pereyra <joaquinpereyra98@users.noreply.github.com>
This commit is contained in:
parent
7114a9e749
commit
7135716da9
17 changed files with 245 additions and 254 deletions
|
|
@ -62,7 +62,7 @@ Hooks.once('init', () => {
|
||||||
CONFIG.Dice.rolls = [...CONFIG.Dice.rolls, ...[DHRoll, DualityRoll, D20Roll, DamageRoll]];
|
CONFIG.Dice.rolls = [...CONFIG.Dice.rolls, ...[DHRoll, DualityRoll, D20Roll, DamageRoll]];
|
||||||
CONFIG.MeasuredTemplate.objectClass = DhMeasuredTemplate;
|
CONFIG.MeasuredTemplate.objectClass = DhMeasuredTemplate;
|
||||||
|
|
||||||
CONFIG.Item.documentClass = documents.DhpItem;
|
CONFIG.Item.documentClass = documents.DHItem;
|
||||||
|
|
||||||
//Registering the Item DataModel
|
//Registering the Item DataModel
|
||||||
CONFIG.Item.dataModels = models.items.config;
|
CONFIG.Item.dataModels = models.items.config;
|
||||||
|
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
export default function DhpApplicationMixin(Base) {
|
|
||||||
return class DhpSheet extends Base {
|
|
||||||
static applicationType = 'sheets';
|
|
||||||
static documentType = '';
|
|
||||||
|
|
||||||
static get defaultOptions() {
|
|
||||||
return Object.assign(super.defaultOptions, {
|
|
||||||
classes: ['daggerheart', 'sheet', this.documentType],
|
|
||||||
template: `systems/${SYSTEM.id}/templates/${this.applicationType}/${this.documentType}.hbs`,
|
|
||||||
height: 'auto',
|
|
||||||
submitOnChange: true,
|
|
||||||
submitOnClose: false,
|
|
||||||
width: 450
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @override */
|
|
||||||
get title() {
|
|
||||||
const { documentName, type, name } = this.object;
|
|
||||||
// const typeLabel = game.i18n.localize(CONFIG[documentName].typeLabels[type]);
|
|
||||||
const typeLabel = documentName;
|
|
||||||
return `[${typeLabel}] ${name}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// async _renderOuter() {
|
|
||||||
// const html = await super._renderOuter();
|
|
||||||
// // const overlaySrc = "systems/amia/assets/ThePrimordial.png";
|
|
||||||
// const overlay = `<div class="outer-render"></div>`
|
|
||||||
// $(html).find('.window-header').prepend(overlay);
|
|
||||||
// return html;
|
|
||||||
// }
|
|
||||||
|
|
||||||
activateListeners(html) {
|
|
||||||
super.activateListeners(html);
|
|
||||||
html.on('click', '[data-action]', this.#onClickAction.bind(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
async #onClickAction(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
const button = event.currentTarget;
|
|
||||||
const action = button.dataset.action;
|
|
||||||
|
|
||||||
return this._handleAction(action, event, button);
|
|
||||||
}
|
|
||||||
|
|
||||||
async _handleAction(action, event, button) {}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -56,7 +56,6 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
resizable: true
|
resizable: true
|
||||||
},
|
},
|
||||||
form: {
|
form: {
|
||||||
handler: this.updateForm,
|
|
||||||
submitOnChange: true,
|
submitOnChange: true,
|
||||||
closeOnSubmit: false
|
closeOnSubmit: false
|
||||||
},
|
},
|
||||||
|
|
@ -218,6 +217,15 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
this._createContextMenues();
|
this._createContextMenues();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @inheritDoc */
|
||||||
|
async _onRender(context, options) {
|
||||||
|
await super._onRender(context, options);
|
||||||
|
|
||||||
|
this._createSearchFilter();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
_createContextMenues() {
|
_createContextMenues() {
|
||||||
const allOptions = {
|
const allOptions = {
|
||||||
useItem: {
|
useItem: {
|
||||||
|
|
@ -431,11 +439,105 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
static async updateForm(event, _, formData) {
|
/* -------------------------------------------- */
|
||||||
await this.document.update(formData.object);
|
/* Search Filter */
|
||||||
this.render();
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The currently active search filter.
|
||||||
|
* @type {foundry.applications.ux.SearchFilter}
|
||||||
|
*/
|
||||||
|
#search = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Track which item IDs are currently displayed due to a search filter.
|
||||||
|
* @type {{ inventory: Set<string>, loadout: Set<string> }}
|
||||||
|
*/
|
||||||
|
#filteredItems = {
|
||||||
|
inventory: new Set(),
|
||||||
|
loadout: new Set()
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create and initialize search filter instances for the inventory and loadout sections.
|
||||||
|
*
|
||||||
|
* Sets up two {@link foundry.applications.ux.SearchFilter} instances:
|
||||||
|
* - One for the inventory, which filters items in the inventory grid.
|
||||||
|
* - One for the loadout, which filters items in the loadout/card grid.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_createSearchFilter() {
|
||||||
|
//Filters could be a application option if needed
|
||||||
|
const filters = [
|
||||||
|
{
|
||||||
|
key: 'inventory',
|
||||||
|
input: 'input[type="search"].search-inventory',
|
||||||
|
content: '[data-application-part="inventory"] .items-section',
|
||||||
|
callback: this._onSearchFilterInventory.bind(this)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'loadout',
|
||||||
|
input: 'input[type="search"].search-loadout',
|
||||||
|
content: '[data-application-part="loadout"] .items-section',
|
||||||
|
callback: this._onSearchFilterCard.bind(this)
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const { key, input, content, callback } of filters) {
|
||||||
|
const filter = new foundry.applications.ux.SearchFilter({
|
||||||
|
inputSelector: input,
|
||||||
|
contentSelector: content,
|
||||||
|
callback
|
||||||
|
});
|
||||||
|
filter.bind(this.element);
|
||||||
|
this.#search[key] = filter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle invetory items search and filtering.
|
||||||
|
* @param {KeyboardEvent} event The keyboard input event.
|
||||||
|
* @param {string} query The input search string.
|
||||||
|
* @param {RegExp} rgx The regular expression query that should be matched against.
|
||||||
|
* @param {HTMLElement} html The container to filter items from.
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
_onSearchFilterInventory(event, query, rgx, html) {
|
||||||
|
this.#filteredItems.inventory.clear();
|
||||||
|
|
||||||
|
for (const ul of html.querySelectorAll('.items-list')) {
|
||||||
|
for (const li of ul.querySelectorAll('.inventory-item')) {
|
||||||
|
const item = this.document.items.get(li.dataset.itemId);
|
||||||
|
const match = !query || foundry.applications.ux.SearchFilter.testQuery(rgx, item.name);
|
||||||
|
if (match) this.#filteredItems.inventory.add(item.id);
|
||||||
|
li.hidden = !match;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle card items search and filtering.
|
||||||
|
* @param {KeyboardEvent} event The keyboard input event.
|
||||||
|
* @param {string} query The input search string.
|
||||||
|
* @param {RegExp} rgx The regular expression query that should be matched against.
|
||||||
|
* @param {HTMLElement} html The container to filter items from.
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
_onSearchFilterCard(event, query, rgx, html) {
|
||||||
|
this.#filteredItems.loadout.clear();
|
||||||
|
|
||||||
|
const elements = html.querySelectorAll('.items-list .inventory-item, .card-list .card-item');
|
||||||
|
|
||||||
|
for (const li of elements) {
|
||||||
|
const item = this.document.items.get(li.dataset.itemId);
|
||||||
|
const match = !query || foundry.applications.ux.SearchFilter.testQuery(rgx, item.name);
|
||||||
|
if (match) this.#filteredItems.loadout.add(item.id);
|
||||||
|
li.hidden = !match;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
async mapFeatureType(data, configType) {
|
async mapFeatureType(data, configType) {
|
||||||
return await Promise.all(
|
return await Promise.all(
|
||||||
data.map(async x => {
|
data.map(async x => {
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,8 @@ export default class DHArmor extends BaseDataItem {
|
||||||
label: 'TYPES.Item.armor',
|
label: 'TYPES.Item.armor',
|
||||||
type: 'armor',
|
type: 'armor',
|
||||||
hasDescription: true,
|
hasDescription: true,
|
||||||
isQuantifiable: true
|
isQuantifiable: true,
|
||||||
|
isInventoryItem: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import { actionsTypes } from '../action/_module.mjs';
|
||||||
* @property {string} type - The system type that this data model represents.
|
* @property {string} type - The system type that this data model represents.
|
||||||
* @property {boolean} hasDescription - Indicates whether items of this type have description field
|
* @property {boolean} hasDescription - Indicates whether items of this type have description field
|
||||||
* @property {boolean} isQuantifiable - Indicates whether items of this type have quantity field
|
* @property {boolean} isQuantifiable - Indicates whether items of this type have quantity field
|
||||||
|
* @property {boolean} isInventoryItem- Indicates whether items of this type is a Inventory Item
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const fields = foundry.data.fields;
|
const fields = foundry.data.fields;
|
||||||
|
|
@ -18,7 +19,8 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
|
||||||
label: 'Base Item',
|
label: 'Base Item',
|
||||||
type: 'base',
|
type: 'base',
|
||||||
hasDescription: false,
|
hasDescription: false,
|
||||||
isQuantifiable: false
|
isQuantifiable: false,
|
||||||
|
isInventoryItem: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,8 @@ export default class DHConsumable extends BaseDataItem {
|
||||||
label: 'TYPES.Item.consumable',
|
label: 'TYPES.Item.consumable',
|
||||||
type: 'consumable',
|
type: 'consumable',
|
||||||
hasDescription: true,
|
hasDescription: true,
|
||||||
isQuantifiable: true
|
isQuantifiable: true,
|
||||||
|
isInventoryItem: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,8 @@ export default class DHMiscellaneous extends BaseDataItem {
|
||||||
label: 'TYPES.Item.miscellaneous',
|
label: 'TYPES.Item.miscellaneous',
|
||||||
type: 'miscellaneous',
|
type: 'miscellaneous',
|
||||||
hasDescription: true,
|
hasDescription: true,
|
||||||
isQuantifiable: true
|
isQuantifiable: true,
|
||||||
|
isInventoryItem: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,8 @@ export default class DHWeapon extends BaseDataItem {
|
||||||
type: 'weapon',
|
type: 'weapon',
|
||||||
hasDescription: true,
|
hasDescription: true,
|
||||||
isQuantifiable: true,
|
isQuantifiable: true,
|
||||||
embedded: {
|
isInventoryItem: true,
|
||||||
feature: 'featureTest'
|
hasInitialAction: true,
|
||||||
},
|
|
||||||
hasInitialAction: true
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
export { default as DhpActor } from './actor.mjs';
|
export { default as DhpActor } from './actor.mjs';
|
||||||
export { default as DhpItem } from './item.mjs';
|
export { default as DHItem } from './item.mjs';
|
||||||
export { default as DhpCombat } from './combat.mjs';
|
export { default as DhpCombat } from './combat.mjs';
|
||||||
export { default as DhActiveEffect } from './activeEffect.mjs';
|
export { default as DhActiveEffect } from './activeEffect.mjs';
|
||||||
|
|
|
||||||
|
|
@ -17,14 +17,6 @@ export default class DhpActor extends Actor {
|
||||||
this.updateSource({ prototypeToken });
|
this.updateSource({ prototypeToken });
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareData() {
|
|
||||||
super.prepareData();
|
|
||||||
}
|
|
||||||
|
|
||||||
async _preUpdate(changed, options, user) {
|
|
||||||
super._preUpdate(changed, options, user);
|
|
||||||
}
|
|
||||||
|
|
||||||
async updateLevel(newLevel) {
|
async updateLevel(newLevel) {
|
||||||
if (this.type !== 'character' || newLevel === this.system.levelData.level.changed) return;
|
if (this.type !== 'character' || newLevel === this.system.levelData.level.changed) return;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,8 @@
|
||||||
export default class DhpItem extends Item {
|
/**
|
||||||
/** @inheritdoc */
|
* Override and extend the basic Item implementation.
|
||||||
getEmbeddedDocument(embeddedName, id, { invalid = false, strict = false } = {}) {
|
* @extends {foundry.documents.Item}
|
||||||
const systemEmbeds = this.system.constructor.metadata.embedded ?? {};
|
*/
|
||||||
if (embeddedName in systemEmbeds) {
|
export default class DHItem extends foundry.documents.Item {
|
||||||
const path = `system.${systemEmbeds[embeddedName]}`;
|
|
||||||
return foundry.utils.getProperty(this, path).get(id) ?? null;
|
|
||||||
}
|
|
||||||
return super.getEmbeddedDocument(embeddedName, id, { invalid, strict });
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @inheritDoc */
|
/** @inheritDoc */
|
||||||
prepareEmbeddedDocuments() {
|
prepareEmbeddedDocuments() {
|
||||||
super.prepareEmbeddedDocuments();
|
super.prepareEmbeddedDocuments();
|
||||||
|
|
@ -35,75 +29,59 @@ export default class DhpItem extends Item {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
isInventoryItem() {
|
/**
|
||||||
return ['weapon', 'armor', 'miscellaneous', 'consumable'].includes(this.type);
|
* Determine if this item is classified as an inventory item based on its metadata.
|
||||||
|
* @returns {boolean} Returns `true` if the item is an inventory item.
|
||||||
|
*/
|
||||||
|
get isInventoryItem() {
|
||||||
|
return this.system.constructor.metadata.isInventoryItem ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static async createDialog(data = {}, { parent = null, pack = null, ...options } = {}) {
|
/** @inheritdoc */
|
||||||
const documentName = this.metadata.name;
|
static async createDialog(data = {}, createOptions = {}, options = {}) {
|
||||||
const types = game.documentTypes[documentName].filter(t => t !== CONST.BASE_DOCUMENT_TYPE);
|
const { folders, types, template, context = {}, ...dialogOptions } = options;
|
||||||
let collection;
|
|
||||||
if (!parent) {
|
|
||||||
if (pack) collection = game.packs.get(pack);
|
|
||||||
else collection = game.collections.get(documentName);
|
|
||||||
}
|
|
||||||
const folders = collection?._formatFolderSelectOptions() ?? [];
|
|
||||||
const label = game.i18n.localize(this.metadata.label);
|
|
||||||
const title = game.i18n.format('DOCUMENT.Create', { type: label });
|
|
||||||
const typeObjects = types.reduce((obj, t) => {
|
|
||||||
const label = CONFIG[documentName]?.typeLabels?.[t] ?? t;
|
|
||||||
obj[t] = { value: t, label: game.i18n.has(label) ? game.i18n.localize(label) : t };
|
|
||||||
return obj;
|
|
||||||
}, {});
|
|
||||||
|
|
||||||
// Render the document creation form
|
if (types?.length === 0) {
|
||||||
const html = await foundry.applications.handlebars.renderTemplate(
|
throw new Error('The array of sub-types to restrict to must not be empty.');
|
||||||
'systems/daggerheart/templates/sidebar/documentCreate.hbs',
|
}
|
||||||
{
|
|
||||||
folders,
|
const documentTypes = this.TYPES.filter(type => type !== 'base' && (!types || types.includes(type))).map(
|
||||||
name: data.name || game.i18n.format('DOCUMENT.New', { type: label }),
|
type => {
|
||||||
folder: data.folder,
|
const labelKey = CONFIG.Item?.typeLabels?.[type];
|
||||||
hasFolders: folders.length >= 1,
|
const label = labelKey && game.i18n.has(labelKey) ? game.i18n.localize(labelKey) : type;
|
||||||
type: data.type || CONFIG[documentName]?.defaultType || typeObjects.armor,
|
|
||||||
types: {
|
const isInventoryItem = CONFIG.Item.dataModels[type]?.metadata?.isInventoryItem;
|
||||||
Items: [typeObjects.armor, typeObjects.weapon, typeObjects.consumable, typeObjects.miscellaneous],
|
const group =
|
||||||
Character: [
|
isInventoryItem === true
|
||||||
typeObjects.class,
|
? 'Inventory Items'
|
||||||
typeObjects.subclass,
|
: isInventoryItem === false
|
||||||
typeObjects.ancestry,
|
? 'Character Items'
|
||||||
typeObjects.community,
|
: 'Other';
|
||||||
typeObjects.feature,
|
|
||||||
typeObjects.domainCard
|
return { value: type, label, group };
|
||||||
]
|
|
||||||
},
|
|
||||||
hasTypes: types.length > 1
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// Render the confirmation dialog window
|
if (!documentTypes.length) {
|
||||||
return Dialog.prompt({
|
throw new Error('No document types were permitted to be created.');
|
||||||
title: title,
|
}
|
||||||
content: html,
|
|
||||||
label: title,
|
const sortedTypes = documentTypes.sort((a, b) => a.label.localeCompare(b.label, game.i18n.lang));
|
||||||
callback: html => {
|
|
||||||
const form = html[0].querySelector('form');
|
return await super.createDialog(data, createOptions, {
|
||||||
const fd = new FormDataExtended(form);
|
folders,
|
||||||
foundry.utils.mergeObject(data, fd.object, { inplace: true });
|
types,
|
||||||
if (!data.folder) delete data.folder;
|
template,
|
||||||
if (types.length === 1) data.type = types[0];
|
context: { types: sortedTypes, ...context },
|
||||||
if (!data.name?.trim()) data.name = this.defaultName();
|
...dialogOptions
|
||||||
return this.create(data, { parent, pack, renderSheet: true });
|
|
||||||
},
|
|
||||||
rejectClose: false,
|
|
||||||
options
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async selectActionDialog() {
|
async selectActionDialog() {
|
||||||
const content = await foundry.applications.handlebars.renderTemplate(
|
const content = await foundry.applications.handlebars.renderTemplate(
|
||||||
'systems/daggerheart/templates/views/actionSelect.hbs',
|
'systems/daggerheart/templates/views/actionSelect.hbs',
|
||||||
{ actions: this.system.actions }
|
{ actions: this.system.actions }
|
||||||
),
|
),
|
||||||
title = 'Select Action',
|
title = 'Select Action',
|
||||||
type = 'div',
|
type = 'div',
|
||||||
data = {};
|
data = {};
|
||||||
|
|
@ -142,8 +120,8 @@ export default class DhpItem extends Item {
|
||||||
this.type === 'ancestry'
|
this.type === 'ancestry'
|
||||||
? game.i18n.localize('DAGGERHEART.Chat.FoundationCard.AncestryTitle')
|
? game.i18n.localize('DAGGERHEART.Chat.FoundationCard.AncestryTitle')
|
||||||
: this.type === 'community'
|
: this.type === 'community'
|
||||||
? game.i18n.localize('DAGGERHEART.Chat.FoundationCard.CommunityTitle')
|
? game.i18n.localize('DAGGERHEART.Chat.FoundationCard.CommunityTitle')
|
||||||
: game.i18n.localize('DAGGERHEART.Chat.FoundationCard.SubclassFeatureTitle'),
|
: game.i18n.localize('DAGGERHEART.Chat.FoundationCard.SubclassFeatureTitle'),
|
||||||
origin: origin,
|
origin: origin,
|
||||||
img: this.img,
|
img: this.img,
|
||||||
name: this.name,
|
name: this.name,
|
||||||
|
|
|
||||||
|
|
@ -4080,6 +4080,10 @@ div.daggerheart.views.multiclass {
|
||||||
.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section .search-bar input:placeholder {
|
.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section .search-bar input:placeholder {
|
||||||
color: light-dark(#18162e50, #efe6d850);
|
color: light-dark(#18162e50, #efe6d850);
|
||||||
}
|
}
|
||||||
|
.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section .search-bar input::-webkit-search-cancel-button {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section .search-bar .icon {
|
.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section .search-bar .icon {
|
||||||
align-content: center;
|
align-content: center;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
|
|
|
||||||
|
|
@ -1,65 +1,70 @@
|
||||||
@import '../../utils/colors.less';
|
@import '../../utils/colors.less';
|
||||||
@import '../../utils/fonts.less';
|
@import '../../utils/fonts.less';
|
||||||
|
|
||||||
.application.sheet.daggerheart.actor.dh-style.character {
|
.application.sheet.daggerheart.actor.dh-style.character {
|
||||||
.tab.inventory {
|
.tab.inventory {
|
||||||
.search-section {
|
.search-section {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
.search-bar {
|
.search-bar {
|
||||||
position: relative;
|
position: relative;
|
||||||
color: light-dark(@dark-blue-50, @beige-50);
|
color: light-dark(@dark-blue-50, @beige-50);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding-top: 5px;
|
padding-top: 5px;
|
||||||
|
|
||||||
input {
|
input {
|
||||||
border-radius: 50px;
|
border-radius: 50px;
|
||||||
font-family: @font-body;
|
font-family: @font-body;
|
||||||
background: light-dark(@dark-blue-10, @golden-10);
|
background: light-dark(@dark-blue-10, @golden-10);
|
||||||
border: none;
|
border: none;
|
||||||
outline: 2px solid transparent;
|
outline: 2px solid transparent;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
padding: 0 20px;
|
padding: 0 20px;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
outline: 2px solid light-dark(@dark, @golden);
|
outline: 2px solid light-dark(@dark, @golden);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:placeholder {
|
&:placeholder {
|
||||||
color: light-dark(@dark-blue-50, @beige-50);
|
color: light-dark(@dark-blue-50, @beige-50);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
&::-webkit-search-cancel-button {
|
||||||
.icon {
|
-webkit-appearance: none;
|
||||||
align-content: center;
|
display: none;
|
||||||
height: 32px;
|
}
|
||||||
position: absolute;
|
}
|
||||||
right: 20px;
|
|
||||||
font-size: 16px;
|
.icon {
|
||||||
z-index: 1;
|
align-content: center;
|
||||||
color: light-dark(@dark-blue-50, @beige-50);
|
height: 32px;
|
||||||
}
|
position: absolute;
|
||||||
}
|
right: 20px;
|
||||||
}
|
font-size: 16px;
|
||||||
|
z-index: 1;
|
||||||
.items-section {
|
color: light-dark(@dark-blue-50, @beige-50);
|
||||||
display: flex;
|
}
|
||||||
flex-direction: column;
|
}
|
||||||
gap: 10px;
|
}
|
||||||
overflow-y: auto;
|
|
||||||
mask-image: linear-gradient(0deg, transparent 0%, black 5%, black 95%, transparent 100%);
|
.items-section {
|
||||||
padding: 20px 0;
|
display: flex;
|
||||||
height: 80%;
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
scrollbar-width: thin;
|
overflow-y: auto;
|
||||||
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
|
mask-image: linear-gradient(0deg, transparent 0%, black 5%, black 95%, transparent 100%);
|
||||||
}
|
padding: 20px 0;
|
||||||
|
height: 80%;
|
||||||
.currency-section {
|
|
||||||
display: flex;
|
scrollbar-width: thin;
|
||||||
gap: 10px;
|
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
.currency-section {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<i class="fa-solid fa-magnifying-glass"></i>
|
<i class="fa-solid fa-magnifying-glass"></i>
|
||||||
</div>
|
</div>
|
||||||
<input type="text" name="" id="" placeholder="Search...">
|
<input type="search" name="search" class="search-inventory" placeholder="Search...">
|
||||||
</div>
|
</div>
|
||||||
<a><i class="fa-solid fa-filter"></i></a>
|
<a><i class="fa-solid fa-filter"></i></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<i class="fa-solid fa-magnifying-glass"></i>
|
<i class="fa-solid fa-magnifying-glass"></i>
|
||||||
</div>
|
</div>
|
||||||
<input type="text" name="" id="" placeholder="Search...">
|
<input type="search" name="search" class="search-loadout" placeholder="Search...">
|
||||||
</div>
|
</div>
|
||||||
<a><i class="fa-solid fa-filter"></i></a>
|
<a><i class="fa-solid fa-filter"></i></a>
|
||||||
<button class="btn-toggle-view" data-action="toggleLoadoutView" data-value="{{this.abilities.loadout.listView}}">
|
<button class="btn-toggle-view" data-action="toggleLoadoutView" data-value="{{this.abilities.loadout.listView}}">
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
<li class="card-item" data-item-id="{{item.id}}">
|
<li class="card-item" data-item-id="{{item.id}}" data-item-id="{{item.id}}">
|
||||||
<img src="{{item.img}}" data-action="useItem" class="card-img" />
|
<img src="{{item.img}}" data-action="useItem" class="card-img" />
|
||||||
<div class="card-label">
|
<div class="card-label">
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
|
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
<form id="document-create" autocomplete="off">
|
|
||||||
<div class="form-group">
|
|
||||||
<label>{{localize "Name"}}</label>
|
|
||||||
<div class="form-fields">
|
|
||||||
<input type="text" name="name" placeholder="{{name}}" autofocus>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{#if hasTypes}}
|
|
||||||
<div class="form-group">
|
|
||||||
<label>{{localize "Type"}}</label>
|
|
||||||
<div class="form-fields">
|
|
||||||
<select name="type">
|
|
||||||
{{#select type}}
|
|
||||||
{{#each types as |values key|}}
|
|
||||||
<optgroup label="{{key}}">
|
|
||||||
{{#each values}}
|
|
||||||
<option value="{{this.value}}">{{this.label}}</option>
|
|
||||||
{{/each}}
|
|
||||||
</optgroup>
|
|
||||||
{{/each}}
|
|
||||||
{{/select}}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{#if hasFolders}}
|
|
||||||
<div class="form-group">
|
|
||||||
<label>{{ localize "DOCUMENT.Folder" }}</label>
|
|
||||||
<div class="form-fields">
|
|
||||||
<select name="folder">
|
|
||||||
{{#select folder}}
|
|
||||||
<option value=""></option>
|
|
||||||
{{#each folders}}
|
|
||||||
<option value="{{ this.id }}">{{ this.name }}</option>
|
|
||||||
{{/each}}
|
|
||||||
{{/select}}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{{content}}}
|
|
||||||
</form>
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue