Attribute Item Subtype #76

Merged
Oliver merged 50 commits from feature/attribute-items into main 2026-04-27 02:12:56 +00:00
8 changed files with 242 additions and 0 deletions
Showing only changes of commit e8c73de6bd - Show all commits

View file

@ -0,0 +1,75 @@
import { __ID__, filePath } from "../consts.mjs";
import { TAFDocumentSheetMixin } from "./mixins/TAFDocumentSheetMixin.mjs";
const { HandlebarsApplicationMixin } = foundry.applications.api;
const { ItemSheetV2 } = foundry.applications.sheets;
const { setProperty } = foundry.utils;
export class AttributeItemSheet extends
TAFDocumentSheetMixin(
HandlebarsApplicationMixin(
ItemSheetV2,
)) {
// #region Options
static DEFAULT_OPTIONS = {
classes: [
__ID__,
`AttributeItemSheet`,
],
position: {
width: 350,
height: `auto`,
},
window: {
resizable: true,
},
form: {
submitOnChange: true,
closeOnSubmit: false,
},
actions: {},
};
static PARTS = {
header: { template: filePath(`templates/AttributeItemSheet/header.hbs`) },
value: { template: filePath(`templates/AttributeItemSheet/value.hbs`) },
settings: { template: filePath(`templates/AttributeItemSheet/settings.hbs`) },
};
/**
* This tells the Application's TAFDocumentSheetMixin how to rerender
* this app when specific properties get changed on the actor, so that
* it doesn't need to full-app rendering if we can do a partial
* rerender instead.
*/
static PROPERTY_TO_PARTIAL = {
"name": [`header`],
"system.value": [`value`],
"system.min": [`value`],
"system.max": [`value`],
"system.aboveTheFold": [`settings`],
"system.group": [`settings`],
"system.key": [`settings`],
};
// #endregion Options
// #region Instance Data
// #endregion Instance Data
// #region Lifecycle
async _prepareContext() {
return {
meta: {
idp: this.id,
editable: this.isEditable,
limited: this.isLimited,
},
item: this.item,
system: this.item.system,
};
};
// #endregion Lifecycle
// #region Actions
// #endregion Actions
};

View file

@ -1,4 +1,5 @@
// Apps
import { AttributeItemSheet } from "../apps/AttributeItemSheet.mjs";
import { AttributeOnlyPlayerSheet } from "../apps/AttributeOnlyPlayerSheet.mjs";
import { GenericItemSheet } from "../apps/GenericItemSheet.mjs";
import { PlayerSheet } from "../apps/PlayerSheet.mjs";
@ -68,6 +69,15 @@ Hooks.on(`init`, () => {
label: `taf.sheet-names.GenericItemSheet`,
},
);
foundry.documents.collections.Items.registerSheet(
__ID__,
AttributeItemSheet,
{
types: [`attribute`],
makeDefault: true,
label: `taf.sheet-names.AttributeItemSheet`,
},
);
// #endregion Sheets
registerWorldSettings();

View file

@ -0,0 +1,56 @@
.taf.AttributeItemSheet {
min-width: 300px;
> .window-content {
padding: 0;
color: var(--attribute-sheet-colour);
background: var(--attribute-sheet-background);
}
.sheet-header {
padding: 0.5rem;
border-bottom: 1px solid var(--attribute-sheet-divider-colour);
}
.value-controls {
display: grid;
align-items: center;
grid-auto-flow: column;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, auto);
gap: 2px 4px;
padding: 0 8px;
}
.property {
display: grid;
align-items: center;
justify-items: left;
grid-template-columns: 2fr 1fr;
gap: 2px 8px;
margin: 0 8px 8px;
.hint {
grid-column: 1 / -1;
margin: 0;
color: var(--attribute-sheet-hint-colour);
}
}
input {
color: var(--attribute-sheet-input-colour);
background: var(--attribute-sheet-input-background);
&:disabled {
color: var(--attribute-sheet-disabled-input-colour);
cursor: not-allowed;
}
}
taf-toggle {
--toggle-background: var(--attribute-sheet-input-background);
--slider-checked-colour: var(--attribute-sheet-toggle-slider-enabled-colour);
--slider-unchecked-colour: var(--attribute-sheet-toggle-slider-disabled-colour);
justify-self: right;
}
}

View file

@ -26,6 +26,7 @@
/* Apps */
@import url("./Apps/common.css") layer(apps);
@import url("./Apps/Ask.css") layer(apps);
@import url("./Apps/AttributeItemSheet.css") layer(apps);
@import url("./Apps/AttributeManager.css") layer(apps);
@import url("./Apps/GenericItemSheet.css") layer(apps);
@import url("./Apps/PlayerSheet.css") layer(apps);

View file

@ -50,6 +50,17 @@
--item-sheet-description-menu-background: var(--steel-700);
--item-sheet-description-content-background: var(--steel-650);
/* Attribute Sheet Variables */
--attribute-sheet-colour: var(--item-sheet-colour);
--attribute-sheet-background: var(--item-sheet-background);
--attribute-sheet-divider-colour: var(--item-sheet-divider);
--attribute-sheet-hint-colour: var(--steel-250);
--attribute-sheet-input-colour: var(--item-sheet-input-colour);
--attribute-sheet-input-background: var(--item-sheet-input-background);
--attribute-sheet-disabled-input-colour: var(--steel-350);
--attribute-sheet-toggle-slider-enabled-colour: var(--item-sheet-toggle-slider-enabled-colour);
--attribute-sheet-toggle-slider-disabled-colour: var(--item-sheet-toggle-slider-disabled-colour);
/* Chip Variables */
--chip-colour: #fff7ed;
--chip-background: #2b3642;

View file

@ -0,0 +1,11 @@
<header class="sheet-header bordered">
<input
type="text"
class="large"
name="name"
value="{{item.name}}"
title="{{item.name}}"
{{disabled (not meta.editable)}}
placeholder="{{localize "Name"}}"
>
</header>

View file

@ -0,0 +1,41 @@
<div>
<div class="property">
<label for="{{meta.idp}}-key">
Key
</label>
<input
type="text"
id="{{meta.idp}}-key"
name="system.key"
value="{{system.key}}"
>
<p class="hint">
This is the computer-friendly identifier for the attribute.
When accessing the attribute in rolls, this is the name you will
need to use. Changing this WILL break any existing macros you have.
</p>
</div>
<div class="property">
<label for="{{meta.idp}}-aboveTheFold">
Always Visible?
</label>
<taf-toggle
id="{{meta.idp}}-aboveTheFold"
name="system.aboveTheFold"
{{checked system.aboveTheFold}}
></taf-toggle>
</div>
{{#if (not system.aboveTheFold)}}
<div class="property">
<label for="{{meta.idp}}-group">
Group
</label>
<input
type="text"
id="{{meta.idp}}-group"
name="system.group"
value="{{system.group}}"
>
</div>
{{/if}}
</div>

View file

@ -0,0 +1,37 @@
<div class="value-controls">
<label for="{{meta.idp}}-min">
Minimum
</label>
<input
type="number"
id="{{meta.idp}}-min"
name="system.min"
value="{{system.min}}"
{{#if system.isRange}}placeholder="0"{{/if}}
{{disabled (not meta.editable)}}
>
<label for="{{meta.idp}}-value">
Current Value
</label>
<input
type="number"
id="{{meta.idp}}-value"
name="system.value"
value="{{system.value}}"
min="{{system.min}}"
max="{{system.max}}"
{{disabled (not meta.editable)}}
>
<label for="{{meta.idp}}-max">
Maximum
</label>
<input
type="number"
id="{{meta.idp}}-max"
name="system.max"
value="{{system.max}}"
{{disabled (not meta.editable)}}
>
</div>