Skip to content

Commit

Permalink
Item sheets V2 Description tab (foundryvtt#3936)
Browse files Browse the repository at this point in the history
  • Loading branch information
Fyorl authored Aug 6, 2024
1 parent 9c01943 commit ecc053a
Show file tree
Hide file tree
Showing 12 changed files with 346 additions and 0 deletions.
1 change: 1 addition & 0 deletions lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1077,6 +1077,7 @@
"DND5E.DefaultAbilityCheck": "Default Ability Check",
"DND5E.Description": "Description",
"DND5E.DescriptionChat": "Chat Description",
"DND5E.DescriptionEdit": "Edit {description}",
"DND5E.DescriptionSummary": "Summary Description",
"DND5E.DescriptionUnidentified": "Unidentified Description",
"DND5E.Details": "Details",
Expand Down
1 change: 1 addition & 0 deletions less/dnd5e.less
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
@import "v2/dark/apps.less";
@import "v2/dark/forms.less";
@import "v2/dark/actors.less";
@import "v2/dark/items.less";
@import "v2/dark/character.less";
@import "v2/dark/npc.less";
@import "v2/dark/inventory.less";
Expand Down
9 changes: 9 additions & 0 deletions less/v2/dark/items.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.theme-dark .dnd5e2.sheet.item,
.dnd5e2.sheet.item.dnd5e-theme-dark {
.sheet-body .tab.advancement {
.item-name .summary .content-link {
color: var(--color-text-dark-5);
> i { color: var(--color-text-dark-5); }
}
}
}
169 changes: 169 additions & 0 deletions less/v2/items.less
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,175 @@

form > hr.ampersand { margin-bottom: -4px; }

/* ---------------------------------- */
/* Sheet Body */
/* ---------------------------------- */

.sheet-body {
.tab {
max-height: calc(70vh - var(--dnd5e-sheet-header-height));
overflow: auto;
display: flex;
flex-direction: column;
gap: 8px;
margin: -6px -11px -6px -6px;
padding: 6px 2px 6px 6px;
scrollbar-width: thin;
scrollbar-color: var(--dnd5e-color-scrollbar) transparent;
scrollbar-gutter: stable;

&:not(.active) { display: none; }
&.effects { padding: 12px 2px 58px 6px; }

> .pills .pill {
font-size: var(--font-size-10);
padding: 3px 6px;
line-height: 1;
}

&.single-description {
padding-right: 5px;
scrollbar-gutter: auto;

> .editor {
padding-right: 6px;
scrollbar-width: thin;
scrollbar-color: var(--dnd5e-color-scrollbar) transparent;
}
}
}

.spell-block {
width: 250px;
margin: 4px auto 4px;
}

.info-block {
display: flex;
justify-content: space-evenly;
align-items: center;
gap: 16px;

> div {
display: flex;
flex-direction: column;
align-items: center;

.label {
font-family: var(--dnd5e-font-roboto-condensed);
font-size: var(--font-size-11);
color: var(--color-text-dark-5);
text-transform: uppercase;
}

.value {
font-family: var(--dnd5e-font-roboto-slab);
font-weight: bold;
font-size: var(--font-size-24);
}

.sign {
color: var(--color-text-light-6);
font-size: var(--font-size-18);
}

&.damage > {
flex: none;

.value {
--icon-fill: var(--color-text-dark-5);
color: var(--color-text-dark-5);
display: grid;
grid-template-columns: auto auto;
gap: 4px;
font-size: var(--font-size-14);
font-family: var(--dnd5e-font-roboto);
font-weight: normal;
}
}
}
}

/* Descriptions */
.item-descriptions {
display: flex;
flex-direction: column;
gap: 8px;

.description {
padding: 8px;
font-family: var(--dnd5e-font-roboto-condensed);
box-shadow: 0 0 6px var(--dnd5e-shadow-15);

> .header {
background: none;
border: none;
color: var(--color-text-dark-primary);
display: flex;
justify-content: space-between;
align-items: center;

> span {
flex: 1;
font-family: var(--dnd5e-font-roboto-slab);
font-weight: bold;
text-align: center;
font-size: var(--font-size-14);
}

> button {
flex: none;
width: unset;

&:hover, &:focus-visible {
box-shadow: none;
text-shadow: 0 0 8px var(--color-shadow-primary);
}
}
}

&:not(.collapsible) > .header { padding-left: 14px; }

&.collapsible {
> .header {
cursor: pointer;

&::before {
content: "\f078";
font-family: var(--font-awesome);
font-weight: bold;
color: var(--color-text-dark-5);
transition: all 250ms ease;
}
}

&.empty > .header {
cursor: unset;
&::before { visibility: hidden; }
}

&.collapsed > .header::before { transform: rotate(-90deg); }

.editor { overflow: hidden; }
}

.editor { padding: 0 6px; }
}
}

.editor.prosemirror {
.editor-content {
position: unset;
min-height: 300px;
}

> textarea {
flex: none;
min-height: 300px;
}
}
}

/* ---------------------------------- */
/* Editable */
/* ---------------------------------- */
Expand Down
1 change: 1 addition & 0 deletions module/applications/item/item-sheet.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,7 @@ export default class ItemSheet5e extends ItemSheet {
});
html.find(".description-edit").click(event => {
if ( event.currentTarget.ariaDisabled ) return;
event.stopPropagation();
this.editingDescriptionTarget = event.currentTarget.dataset.target;
this.render();
});
Expand Down
46 changes: 46 additions & 0 deletions module/applications/item/sheet-v2-mixin.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ export default function ItemSheetV2Mixin(Base) {
{ tab: "advancement", label: "DND5E.AdvancementTitle", condition: this.itemHasAdvancements.bind(this) }
];

/**
* Store the collapsed state of the description boxes.
* @type {Record<string, boolean>}
* @protected
*/
_collapsed = {};

/* -------------------------------------------- */
/* Rendering */
/* -------------------------------------------- */
Expand Down Expand Up @@ -45,6 +52,13 @@ export default function ItemSheetV2Mixin(Base) {
const { identified, schema, unidentified } = this.item.system;
context.fields = schema.fields;

// Set some default collapsed states on first open.
if ( foundry.utils.isEmpty(this._collapsed) ) Object.assign(this._collapsed, {
"system.description.chat": true,
"system.unidentified.description": game.user.isGM
});
context.collapsed = this._collapsed;

// Tabs
const activeTab = this._tabs?.[0]?.active ?? this.options.tabs[0].initial;
context.cssClass += ` tab-${activeTab}`;
Expand All @@ -71,9 +85,25 @@ export default function ItemSheetV2Mixin(Base) {
};
}

// Properties
context.properties = {
active: [],
object: Object.fromEntries((context.source.properties ?? []).map(p => [p, true])),
options: Object.entries(context.properties ?? {}).map(([k, v]) => ({ value: k, ...v }))
};
if ( game.user.isGM || (identified !== false) ) {
context.properties.active.push(
...this.item.system.cardProperties ?? [],
...this.item.system.activatedEffectCardProperties ?? [],
...this.item.system.equippableItemCardProperties ?? []
);
}

// Sub-type context
await this.item.system.getSheetData?.(context);

context.properties.active = context.properties.active.filter(_ => _);

return context;
}

Expand All @@ -94,6 +124,7 @@ export default function ItemSheetV2Mixin(Base) {
/** @inheritDoc */
activateListeners(html) {
super.activateListeners(html);
html.find(".description.collapsible > .header").on("click", this._onToggleOwnDescription.bind(this));

// Play mode only.
if ( this._mode === this.constructor.MODES.PLAY ) {
Expand All @@ -103,6 +134,21 @@ export default function ItemSheetV2Mixin(Base) {

/* -------------------------------------------- */

/**
* Handle toggling one of the item's description categories.
* @param {PointerEvent} event The triggering event.
* @protected
*/
_onToggleOwnDescription(event) {
const description = event.currentTarget.closest("[data-target]");
if ( !description ) return;
const { target } = description.dataset;
description.classList.toggle("collapsed");
this._collapsed[target] = description.classList.contains("collapsed");
}

/* -------------------------------------------- */

/**
* Handle showing the Item's art.
* @protected
Expand Down
7 changes: 7 additions & 0 deletions module/data/item/equipment.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,13 @@ export default class EquipmentData extends ItemDataModel.mixin(
{ label: this.type.label },
...this.physicalItemSheetFields
];
if ( this.armor.value ) {
context.properties.active.shift();
context.info = [{
label: "DND5E.ArmorClass",
value: this.type.value === "shield" ? dnd5e.utils.formatModifier(this.armor.value) : this.armor.value
}];
}
}

/* -------------------------------------------- */
Expand Down
1 change: 1 addition & 0 deletions module/data/item/spell.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ export default class SpellData extends ItemDataModel.mixin(
{ label: context.labels.school },
{ label: context.itemStatus }
];
context.properties.active = this.parent.labels?.components?.tags;
}

/* -------------------------------------------- */
Expand Down
13 changes: 13 additions & 0 deletions module/data/item/weapon.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,19 @@ export default class WeaponData extends ItemDataModel.mixin(
{ label: this.type.label },
...this.physicalItemSheetFields
];
context.info = [{ label: "DND5E.ToHit", value: dnd5e.utils.formatModifier(parseInt(this.parent.labels.modifier)) }];
if ( this.parent.labels.derivedDamage?.length ) {
const config = { ...CONFIG.DND5E.damageTypes, ...CONFIG.DND5E.healingTypes };
context.info.push({ value: this.parent.labels.derivedDamage.reduce((str, { formula, damageType }) => {
const { label, icon } = config[damageType];
return `${str}
<span class="formula">${formula}</span>
<span class="damage-type" data-tooltip="${label}" aria-label="${label}">
<dnd5e-icon src="${icon}"></dnd5e-icon>
</span>
`;
}, ""), classes: "damage" });
}
}

/* -------------------------------------------- */
Expand Down
1 change: 1 addition & 0 deletions module/utils.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@ export async function preloadHandlebarsTemplates() {
"systems/dnd5e/templates/items/parts/item-activation.hbs",
"systems/dnd5e/templates/items/parts/item-advancement.hbs",
"systems/dnd5e/templates/items/parts/item-description.hbs",
"systems/dnd5e/templates/items/parts/item-description2.hbs",
"systems/dnd5e/templates/items/parts/item-mountable.hbs",
"systems/dnd5e/templates/items/parts/item-spellcasting.hbs",
"systems/dnd5e/templates/items/parts/item-source.hbs",
Expand Down
2 changes: 2 additions & 0 deletions templates/items/item-sheet-2.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@
{{!-- Body --}}
<section class="sheet-body">

{{!-- Description Tab --}}
{{> "dnd5e.item-description2" }}


</section>
Expand Down
Loading

0 comments on commit ecc053a

Please sign in to comment.