From aac4b014b094e64e6e5b33ea044f689df5fbbc5e Mon Sep 17 00:00:00 2001 From: Johannes Loher Date: Thu, 25 Feb 2021 19:07:25 +0100 Subject: [PATCH] Use BEM for item-list styling and add support for drag & drop of items (between sheets and for sorting) --- src/ds4.scss | 2 +- src/module/actor/sheets/actor-sheet.ts | 15 ++-- .../{_items_list.scss => _item_list.scss} | 84 ++++++++++--------- .../actor/partials/items-overview.hbs | 84 +++++++++---------- .../actor/partials/overview-add-button.hbs | 2 +- .../actor/partials/spells-overview.hbs | 36 ++++---- 6 files changed, 116 insertions(+), 107 deletions(-) rename src/scss/components/{_items_list.scss => _item_list.scss} (70%) diff --git a/src/ds4.scss b/src/ds4.scss index 7843d56..0f8aec2 100644 --- a/src/ds4.scss +++ b/src/ds4.scss @@ -17,7 +17,7 @@ @include meta.load-css("scss/components/combat_values"); @include meta.load-css("scss/components/description"); @include meta.load-css("scss/components/forms"); - @include meta.load-css("scss/components/items_list"); + @include meta.load-css("scss/components/item_list"); @include meta.load-css("scss/components/tabs"); @include meta.load-css("scss/components/talents"); } diff --git a/src/module/actor/sheets/actor-sheet.ts b/src/module/actor/sheets/actor-sheet.ts index de9a0e3..aee139f 100644 --- a/src/module/actor/sheets/actor-sheet.ts +++ b/src/module/actor/sheets/actor-sheet.ts @@ -58,12 +58,17 @@ export class DS4ActorSheet extends ActorSheet> { * @returns The data fed to the template of the actor sheet */ async getData(): Promise> { + const itemsByType = Object.fromEntries( + Object.entries(this.actor.itemTypes).map(([itemType, items]) => { + return [itemType, items.map((item) => item.data).sort((a, b) => (a.sort || 0) - (b.sort || 0))]; + }), + ); const data = { ...this._addTooltipsToData(await super.getData()), // Add the localization config to the data: config: DS4, // Add the items explicitly sorted by type to the data: - itemsByType: this.actor.itemTypes, + itemsByType, }; return data; } @@ -98,7 +103,7 @@ export class DS4ActorSheet extends ActorSheet> { // Update Inventory Item html.find(".item-edit").on("click", (ev) => { - const li = $(ev.currentTarget).parents(".item-row"); + const li = $(ev.currentTarget).parents(".item"); const id = li.data("itemId"); const item = this.actor.getOwnedItem(id); if (!item) { @@ -112,7 +117,7 @@ export class DS4ActorSheet extends ActorSheet> { // Delete Inventory Item html.find(".item-delete").on("click", (ev) => { - const li = $(ev.currentTarget).parents(".item-row"); + const li = $(ev.currentTarget).parents(".item"); this.actor.deleteOwnedItem(li.data("itemId")); li.slideUp(200, () => this.render(false)); }); @@ -155,7 +160,7 @@ export class DS4ActorSheet extends ActorSheet> { protected _onItemChange(ev: JQuery.ChangeEvent): void { ev.preventDefault(); const el: HTMLFormElement = $(ev.currentTarget).get(0); - const id = $(ev.currentTarget).parents(".item-row").data("itemId"); + const id = $(ev.currentTarget).parents(".item").data("itemId"); const item = duplicate(this.actor.getOwnedItem(id)); const property: string | undefined = $(ev.currentTarget).data("property"); @@ -224,7 +229,7 @@ export class DS4ActorSheet extends ActorSheet> { // unsupported: else { - throw TypeError("Binding of item property to this type of HTML element not supported; given: " + el); + throw new TypeError("Binding of item property to this type of HTML element not supported; given: " + el); } } diff --git a/src/scss/components/_items_list.scss b/src/scss/components/_item_list.scss similarity index 70% rename from src/scss/components/_items_list.scss rename to src/scss/components/_item_list.scss index 6706a32..75fcbe3 100644 --- a/src/scss/components/_items_list.scss +++ b/src/scss/components/_item_list.scss @@ -1,41 +1,48 @@ @use "../utils/mixins"; @use "../utils/variables"; -.items-list { +.ds4-item-list { $row-height: 1.75em; + display: grid; grid-column-gap: 0.5em; grid-row-gap: 0.2em; align-items: center; - &.weapon { - grid-template-columns: $row-height $row-height 3ch 3fr $row-height 1fr 3ch 5fr 4ch; - } - &.armor { - grid-template-columns: $row-height $row-height 3ch 3fr 1fr 1fr 3ch 5fr 4ch; - } - &.shield { - grid-template-columns: $row-height $row-height 3ch 3fr 3ch 5fr 4ch; - } - &.equipment { - grid-template-columns: $row-height $row-height 3ch 3fr 10ch 5fr 4ch; - } - &.loot { - grid-template-columns: $row-height 3ch 3fr 10ch 5fr 4ch; - } - &.spell { - grid-template-columns: $row-height $row-height 2fr $row-height 1fr 1fr 1fr 1fr 4ch; - } margin: 7px 0; padding: 0; overflow-y: auto; - .item-row { - display: contents; + transition: all 0.5s; - &.item-header { + @include mixins.mark-invalid-or-disabled-input; + + &--weapon { + grid-template-columns: $row-height $row-height 3ch 3fr $row-height 1fr 3ch 5fr 4ch; + } + &--armor { + grid-template-columns: $row-height $row-height 3ch 3fr 1fr 1fr 3ch 5fr 4ch; + } + &--shield { + grid-template-columns: $row-height $row-height 3ch 3fr 3ch 5fr 4ch; + } + &--equipment { + grid-template-columns: $row-height $row-height 3ch 3fr 10ch 5fr 4ch; + } + &--loot { + grid-template-columns: $row-height 3ch 3fr 10ch 5fr 4ch; + } + &--spell { + grid-template-columns: $row-height $row-height 2fr $row-height 1fr 1fr 1fr 1fr 4ch; + } + + &__row { + grid-column: 1/-1; + display: grid; + grid-template-columns: subgrid; + + &--header { font-weight: bold; - display: contents; } > * { @@ -43,29 +50,26 @@ line-height: $row-height; white-space: nowrap; } + } - .item-image { - background-repeat: no-repeat; - background-size: 100%; - background-position: center; - } - - input { - border: 0; - padding: 0; - background-color: transparent; - } - - input[type="checkbox"] { + &__editable { + border: 0; + padding: 0; + background-color: transparent; + &--checkbox { width: 100%; height: 100%; margin: 0px; } - - @include mixins.mark-invalid-or-disabled-input; } - .item-description { + &__image { + background-repeat: no-repeat; + background-size: 100%; + background-position: center; + } + + &__description { overflow: hidden; text-overflow: ellipsis; :not(:first-child) { @@ -80,7 +84,7 @@ } } -.items-list-title { +.ds4-item-list-title { margin-top: 1em; margin-bottom: 0; padding-left: 1em; diff --git a/src/templates/actor/partials/items-overview.hbs b/src/templates/actor/partials/items-overview.hbs index 704cb49..b5e48e9 100644 --- a/src/templates/actor/partials/items-overview.hbs +++ b/src/templates/actor/partials/items-overview.hbs @@ -31,17 +31,17 @@ !-- @param partial-block: hand over custom children in the partial block. --}} {{#*inline "itemListHeader" }} -
  • +
  • {{!-- equipped --}} {{#if (ne dataType 'loot')}}
    {{localize 'DS4.ItemEquippedAbbr'}}
    {{/if}} {{!-- image --}} -
    +
    {{!-- amount --}} -
    #
    +
    #
    {{!-- name --}} -
    {{localize 'DS4.ItemName'}}
    +
    {{localize 'DS4.ItemName'}}
    {{!-- item type specifics --}} {{> @partial-block }} {{!-- description --}} @@ -62,25 +62,25 @@ !-- @param partial-block: hand over custom children in the partial block. --}} {{#*inline "itemListEntry"}} -
  • +
  • {{!-- equipped --}} - {{#if (ne item.data.type 'loot')}} - + {{#if (ne item.type 'loot')}} + {{/if}} {{!-- image --}} -
    +
    {{!-- amount --}} - {{!-- name --}} - + {{!-- item type specifics --}} {{> @partial-block}} {{!-- description --}} -
    - {{{item.data.data.description}}}
    +
    + {{{item.data.description}}}
    {{!-- control buttons --}} {{> systems/ds4/templates/actor/partials/overview-control-buttons.hbs }}
  • @@ -90,51 +90,51 @@ {{!-- ======================================================================== --}} {{!-- WEAPONS --}} -

    {{localize 'DS4.ItemTypeWeaponPlural'}}

    +

    {{localize 'DS4.ItemTypeWeaponPlural'}}

    {{#> ifHasItemOfType itemsArray=itemsByType.weapon dataType='weapon' }} -
      +
        {{#> itemListHeader dataType='weapon'}} -
        {{localize 'DS4.AttackTypeAbbr'}}
        -
        +
        {{localize 'DS4.AttackTypeAbbr'}}
        +
        {{localize 'DS4.WeaponBonusAbbr'}}
        -
        +
        {{localize 'DS4.OpponentDefenseAbbr'}}
        {{/itemListHeader}} {{#each itemsByType.weapon as |item id|}} {{#> itemListEntry item=item}} -
        +
        -
        {{ item.data.data.weaponBonus}}
        -
        {{ item.data.data.opponentDefense}}
        +
        {{ item.data.weaponBonus}}
        +
        {{ item.data.opponentDefense}}
        {{/itemListEntry}} {{/each}}
      {{/ifHasItemOfType}} {{!-- ARMOR --}} -

      {{localize 'DS4.ItemTypeArmorPlural'}}

      +

      {{localize 'DS4.ItemTypeArmorPlural'}}

      {{#> ifHasItemOfType itemsArray=itemsByType.armor dataType='armor' }} -
        +
          {{#> itemListHeader dataType='armor'}}
          {{localize 'DS4.ArmorMaterialTypeAbbr'}}
          {{localize 'DS4.ArmorTypeAbbr'}}
          -
          +
          {{localize 'DS4.ArmorValueAbbr'}}
          {{/itemListHeader}} {{#each itemsByType.armor as |item id|}} {{#> itemListEntry item=item }} -
          - {{lookup ../../config.i18n.armorMaterialTypesAbbr item.data.data.armorMaterialType}} +
          + {{lookup ../../config.i18n.armorMaterialTypesAbbr item.data.armorMaterialType}}
          -
          - {{lookup ../../config.i18n.armorTypesAbbr item.data.data.armorType}} +
          + {{lookup ../../config.i18n.armorTypesAbbr item.data.armorType}}
          -
          {{ item.data.data.armorValue}}
          +
          {{ item.data.armorValue}}
          {{/itemListEntry}} {{/each}}
        @@ -142,17 +142,17 @@ {{!-- SHIELD --}} -

        {{localize 'DS4.ItemTypeShieldPlural'}}

        +

        {{localize 'DS4.ItemTypeShieldPlural'}}

        {{#> ifHasItemOfType itemsArray=itemsByType.shield dataType='shield' }} -
          +
            {{#> itemListHeader dataType='shield' }} -
            +
            {{localize 'DS4.ArmorValueAbbr'}}
            {{/itemListHeader}} {{#each itemsByType.shield as |item id|}} {{#> itemListEntry item=item }} -
            {{item.data.data.armorValue}}
            +
            {{item.data.armorValue}}
            {{/itemListEntry}} {{/each}}
          @@ -160,15 +160,15 @@ {{!-- EQUIPMENT --}} -

          {{localize 'DS4.ItemTypeEquipmentPlural'}}

          +

          {{localize 'DS4.ItemTypeEquipmentPlural'}}

          {{#> ifHasItemOfType itemsArray=itemsByType.equipment dataType='equipment' }} -
            +
              {{#> itemListHeader dataType='equipment'}}
              {{localize 'DS4.StorageLocation'}}
              {{/itemListHeader}} {{#each itemsByType.equipment as |item id|}} {{#> itemListEntry item=item }} - {{/itemListEntry}} {{/each}} @@ -176,15 +176,15 @@ {{/ifHasItemOfType}} {{!-- LOOT --}} -

              {{localize 'DS4.ItemTypeLootPlural'}}

              +

              {{localize 'DS4.ItemTypeLootPlural'}}

              {{#> ifHasItemOfType itemsArray=itemsByType.loot dataType='loot' }} -
                +
                  {{#> itemListHeader dataType='loot'}}
                  {{localize 'DS4.StorageLocation'}}
                  {{/itemListHeader}} {{#each itemsByType.loot as |item id|}} {{#> itemListEntry item=item }} - {{/itemListEntry}} {{/each}} diff --git a/src/templates/actor/partials/overview-add-button.hbs b/src/templates/actor/partials/overview-add-button.hbs index 86e5d77..c0e7d18 100644 --- a/src/templates/actor/partials/overview-add-button.hbs +++ b/src/templates/actor/partials/overview-add-button.hbs @@ -8,4 +8,4 @@ {{localize "DS4.UserInteractionAddItem"}} - \ No newline at end of file + diff --git a/src/templates/actor/partials/spells-overview.hbs b/src/templates/actor/partials/spells-overview.hbs index e10b34d..bb97076 100644 --- a/src/templates/actor/partials/spells-overview.hbs +++ b/src/templates/actor/partials/spells-overview.hbs @@ -10,7 +10,7 @@ !-- @param unitAbbrs: mapping of allowed unitDatum.unit values to unit abbreviation --}} {{#*inline "unit"}} -
                  +
                  {{#if unitDatum.value }} {{unitDatum.value}} {{lookup unitAbbrs unitDatum.unit}} {{else}}-{{/if}} @@ -36,44 +36,44 @@ localizationString=localizationString}}
                  -
                    -
                  1. +
                      +
                    1. {{!-- equipped --}}
                      {{localize 'DS4.ItemEquippedAbbr'}}
                      {{!-- image --}} -
                      +
                      {{!-- name --}} -
                      {{localize 'DS4.ItemName'}}
                      +
                      {{localize 'DS4.ItemName'}}
                      {{!-- spell type --}} -
                      {{localize 'DS4.SpellTypeAbbr'}}
                      +
                      {{localize 'DS4.SpellTypeAbbr'}}
                      {{!-- spell bonus --}} -
                      {{localize 'DS4.SpellBonusAbbr'}}
                      +
                      {{localize 'DS4.SpellBonusAbbr'}}
                      {{!-- max. distance --}} -
                      +
                      {{!-- duration --}} -
                      +
                      {{!-- cooldown duration --}} -
                      +
                      {{!-- control buttons placeholder --}}
                    2. {{#each itemsByType.spell as |item id|}} -
                    3. - +
                    4. + {{!-- image --}} -
                      +
                      {{!-- name --}} - {{!-- spell type --}} -
                      {{!-- spell bonus --}} - {{!-- max. distance --}} {{> distanceUnit localizationString='DS4.SpellMaxDistance' unitDatum=item.data.data.maxDistance