@crockery/fellowship-components 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -136,11 +136,13 @@ pnpm --filter @crockery/fellowship-components build
136
136
  pnpm --filter @crockery/fellowship-components pack:check
137
137
  ```
138
138
 
139
- Current Chromium, Firefox, and Safari/WebKit are supported. Add a Changeset with
140
- `pnpm changeset` from the monorepo root for every user-facing change. Merging
141
- the generated version pull request publishes through trusted OIDC publishing.
142
- The private repository means npm provenance attestations are unavailable.
143
- Maintainers should follow [`RELEASING.md`](RELEASING.md).
139
+ Browser tests currently use headless Chromium as the package's deterministic
140
+ browser harness. Cross-browser compatibility is not yet a supported contract.
141
+ Add a Changeset with `pnpm changeset` from the monorepo root for every
142
+ user-facing change. Merging the generated version pull request publishes
143
+ through trusted OIDC publishing. The private repository means npm provenance
144
+ attestations are unavailable. Maintainers should follow
145
+ [`RELEASING.md`](RELEASING.md).
144
146
 
145
147
  ## License
146
148
 
@@ -4,12 +4,12 @@ import { LitElement as i, css as a, html as o, nothing as s } from "lit";
4
4
  import { customElement as c, property as l, query as u, state as d } from "lit/decorators.js";
5
5
  import { repeat as f } from "lit/directives/repeat.js";
6
6
  import { findImage as p } from "@crockery/fellowship-data";
7
- import { calculateGearPlannerBuild as m, getValidGearConfiguration as h, getValidGearItems as g, normalizeGearPlannerBuild as _, validateGearPlannerBuild as v } from "@crockery/fellowship-data/gear-planner";
7
+ import { calculateGearPlannerBuild as m, getValidGearConfiguration as h, getValidGearItems as g, normalizeGearPlannerBuild as _, resolveGearPlannerItemName as v, validateGearPlannerBuild as y } from "@crockery/fellowship-data/gear-planner";
8
8
  //#region src/gear-planner/gear-position.ts
9
9
  r();
10
- var y = class extends i {
10
+ var b = class extends i {
11
11
  constructor(...e) {
12
- super(...e), this.position = null, this.item = null, this.itemBuild = null, this.selected = !1, this.imageUrl = null, this.tooltipDetails = [], this.#e = (e) => {
12
+ super(...e), this.position = null, this.item = null, this.itemBuild = null, this.itemName = null, this.selected = !1, this.imageUrl = null, this.tooltipDetails = [], this.#e = (e) => {
13
13
  this.dispatchEvent(new CustomEvent("fellowship-gear-position-select", {
14
14
  bubbles: !0,
15
15
  composed: !0,
@@ -144,7 +144,7 @@ var y = class extends i {
144
144
  }
145
145
  render() {
146
146
  if (!this.position) return o``;
147
- let e = this.item?.item.name ?? this.item?.item.id ?? "Choose item", t = this.itemBuild ? `${e}. Level ${this.itemBuild.itemLevel}, ${this.itemBuild.rarity}.` : `${this.position.label}. Empty.`, n = o`
147
+ let e = this.itemName ?? this.item?.item.name ?? this.item?.item.id ?? "Choose item", t = this.itemBuild ? `${e}. Level ${this.itemBuild.itemLevel}, ${this.itemBuild.rarity}.` : `${this.position.label}. Empty.`, n = o`
148
148
  <button
149
149
  type="button"
150
150
  aria-pressed=${String(this.selected)}
@@ -180,13 +180,13 @@ var y = class extends i {
180
180
  #e;
181
181
  #t;
182
182
  };
183
- e([l({ attribute: !1 })], y.prototype, "position", void 0), e([l({ attribute: !1 })], y.prototype, "item", void 0), e([l({ attribute: !1 })], y.prototype, "itemBuild", void 0), e([l({
183
+ e([l({ attribute: !1 })], b.prototype, "position", void 0), e([l({ attribute: !1 })], b.prototype, "item", void 0), e([l({ attribute: !1 })], b.prototype, "itemBuild", void 0), e([l({ type: String })], b.prototype, "itemName", void 0), e([l({
184
184
  type: Boolean,
185
185
  reflect: !0
186
- })], y.prototype, "selected", void 0), e([l({ type: String })], y.prototype, "imageUrl", void 0), e([l({ attribute: !1 })], y.prototype, "tooltipDetails", void 0), y = e([c("fellowship-gear-position")], y);
187
- var b = () => {
188
- customElements.get("fellowship-gear-position") || customElements.define("fellowship-gear-position", y);
189
- }, x = a`
186
+ })], b.prototype, "selected", void 0), e([l({ type: String })], b.prototype, "imageUrl", void 0), e([l({ attribute: !1 })], b.prototype, "tooltipDetails", void 0), b = e([c("fellowship-gear-position")], b);
187
+ var x = () => {
188
+ customElements.get("fellowship-gear-position") || customElements.define("fellowship-gear-position", b);
189
+ }, S = a`
190
190
  :host {
191
191
  display: block;
192
192
  min-width: 0;
@@ -431,23 +431,23 @@ var b = () => {
431
431
  grid-row: auto;
432
432
  }
433
433
  }
434
- `, S = class extends i {
434
+ `, C = class extends i {
435
435
  constructor(...e) {
436
436
  super(...e), this.data = null, this.build = null, this.positionId = null, this.resolveAssetUrl = null, this._query = "", this.#g = (e) => {
437
437
  this._query = e.currentTarget.value;
438
438
  };
439
439
  }
440
440
  static {
441
- this.styles = [n, x];
441
+ this.styles = [n, S];
442
442
  }
443
443
  render() {
444
444
  if (!this.data || !this.build || !this.positionId) return o`<div class="empty">Select a gear position to begin.</div>`;
445
445
  let e = this.data.positions.find(({ id: e }) => e === this.positionId), t = this.build.positions.find(({ positionId: e }) => e === this.positionId);
446
446
  if (!e) return o`<div class="empty">This gear position is unavailable.</div>`;
447
- let n = t?.item ?? null, r = n ? this.data.itemById.get(n.itemId) : null, i = n && r ? h(this.data, this.build, this.positionId, n.itemId) : null, a = g(this.data, this.build, this.positionId).filter((e) => {
448
- let t = this._query.trim().toLocaleLowerCase();
449
- return !t || (e.item.name ?? e.item.id).toLocaleLowerCase().includes(t);
450
- });
447
+ let n = t?.item ?? null, r = n ? this.data.itemById.get(n.itemId) : null, i = n && r ? h(this.data, this.build, this.positionId, n.itemId) : null, a = this.data.heroById.get(this.build.heroId), s = this._query.trim().toLocaleLowerCase(), c = a ? g(this.data, this.build, this.positionId).map((e) => ({
448
+ item: e,
449
+ name: v(e, a)
450
+ })).filter(({ name: e }) => !s || e.toLocaleLowerCase().includes(s)) : [];
451
451
  return o`
452
452
  <header class="workbench-header">
453
453
  <div>
@@ -467,20 +467,22 @@ var b = () => {
467
467
  />
468
468
  </label>
469
469
  <div class="item-list" aria-label=${`Valid items for ${e.label}`}>
470
- ${a.length === 0 ? o`<p class="empty-search">No valid items match this search.</p>` : f(a, (e) => e.item.id, (e) => o`
470
+ ${c.length === 0 ? o`<p class="empty-search">No valid items match this search.</p>` : f(c, (e) => e.item.item.id, (e) => o`
471
471
  <button
472
472
  type="button"
473
473
  class="item-choice"
474
- aria-pressed=${String(e.item.id === n?.itemId)}
475
- ?disabled=${e.validItemLevels.length === 0 || e.validRarities.length === 0}
476
- @click=${() => this.#l(e.item.id)}
474
+ aria-pressed=${String(e.item.item.id === n?.itemId)}
475
+ ?disabled=${e.item.validItemLevels.length === 0 || e.item.validRarities.length === 0}
476
+ @click=${() => this.#l(e.item.item.id)}
477
477
  >
478
478
  <span class="choice-mark" aria-hidden="true"></span>
479
479
  <span class="choice-image">
480
- ${this.#o(e.item.images, e.item.name ?? e.item.id)}
480
+ ${this.#o(e.item.item.images, e.name)}
481
481
  </span>
482
- <span>${e.item.name ?? e.item.id}</span>
483
- <small>${e.maxEquipped === 1 ? "Unique" : e.itemType}</small>
482
+ <span>${e.name}</span>
483
+ <small>
484
+ ${e.item.maxEquipped === 1 ? "Unique" : e.item.itemType}
485
+ </small>
484
486
  </button>
485
487
  `)}
486
488
  </div>
@@ -768,10 +770,10 @@ var b = () => {
768
770
  }
769
771
  #g;
770
772
  };
771
- e([l({ attribute: !1 })], S.prototype, "data", void 0), e([l({ attribute: !1 })], S.prototype, "build", void 0), e([l({ type: String })], S.prototype, "positionId", void 0), e([l({ attribute: !1 })], S.prototype, "resolveAssetUrl", void 0), e([d()], S.prototype, "_query", void 0), S = e([c("fellowship-item-workbench")], S);
772
- var C = () => {
773
- customElements.get("fellowship-item-workbench") || customElements.define("fellowship-item-workbench", S);
774
- }, w = a`
773
+ e([l({ attribute: !1 })], C.prototype, "data", void 0), e([l({ attribute: !1 })], C.prototype, "build", void 0), e([l({ type: String })], C.prototype, "positionId", void 0), e([l({ attribute: !1 })], C.prototype, "resolveAssetUrl", void 0), e([d()], C.prototype, "_query", void 0), C = e([c("fellowship-item-workbench")], C);
774
+ var w = () => {
775
+ customElements.get("fellowship-item-workbench") || customElements.define("fellowship-item-workbench", C);
776
+ }, T = a`
775
777
  :host {
776
778
  display: block;
777
779
  min-width: 0;
@@ -1231,7 +1233,7 @@ var C = () => {
1231
1233
  animation-iteration-count: 1 !important;
1232
1234
  }
1233
1235
  }
1234
- `, T = [
1236
+ `, E = [
1235
1237
  "head",
1236
1238
  "shoulders",
1237
1239
  "chest",
@@ -1239,7 +1241,7 @@ var C = () => {
1239
1241
  "waist",
1240
1242
  "ring-1",
1241
1243
  "trinket-1"
1242
- ], E = [
1244
+ ], D = [
1243
1245
  "necklace",
1244
1246
  "back",
1245
1247
  "wrists",
@@ -1247,17 +1249,17 @@ var C = () => {
1247
1249
  "ring-2",
1248
1250
  "trinket-2",
1249
1251
  "weapon"
1250
- ], D = "button:not([disabled]), input:not([disabled]), select:not([disabled]), [href], [tabindex]:not([tabindex=\"-1\"])", O = (e) => {
1252
+ ], O = "button:not([disabled]), input:not([disabled]), select:not([disabled]), [href], [tabindex]:not([tabindex=\"-1\"])", k = (e) => {
1251
1253
  let t = [];
1252
- for (let n of e.children) n instanceof HTMLElement && n.matches(D) && t.push(n), n.shadowRoot && t.push(...O(n.shadowRoot)), t.push(...O(n));
1254
+ for (let n of e.children) n instanceof HTMLElement && n.matches(O) && t.push(n), n.shadowRoot && t.push(...k(n.shadowRoot)), t.push(...k(n));
1253
1255
  return t;
1254
- }, k = (e) => {
1256
+ }, A = (e) => {
1255
1257
  let t = e.activeElement;
1256
1258
  for (; t?.shadowRoot?.activeElement;) t = t.shadowRoot.activeElement;
1257
1259
  return t;
1258
1260
  };
1259
- b(), C();
1260
- var A = class extends i {
1261
+ x(), w();
1262
+ var j = class extends i {
1261
1263
  constructor(...e) {
1262
1264
  super(...e), this.data = null, this.build = null, this.loading = !1, this.error = null, this.resolveAssetUrl = null, this._selectedPositionId = null, this._tab = "gear", this._sheetOpen = !1, this._compact = !1, this._announcement = "", this._calculation = null, this.#e = null, this.#t = null, this.#n = null, this.#r = null, this.#i = null, this.#a = !1, this.#o = /* @__PURE__ */ new Set(), this.#p = (e) => {
1263
1265
  e.stopPropagation(), this._selectedPositionId = e.detail.positionId, this.#i = e.detail.trigger, this._compact && (this._sheetOpen = !0, this.#r !== null && window.clearTimeout(this.#r), this.#r = window.setTimeout(() => {
@@ -1271,7 +1273,7 @@ var A = class extends i {
1271
1273
  ...t,
1272
1274
  item: e.detail.item
1273
1275
  } : t)
1274
- }, n = _(this.data, t), r = v(this.data, n.build);
1276
+ }, n = _(this.data, t), r = y(this.data, n.build);
1275
1277
  if (!r.valid || !r.build) {
1276
1278
  let e = r.issues.find(({ severity: e }) => e === "error");
1277
1279
  this.#_({
@@ -1298,7 +1300,7 @@ var A = class extends i {
1298
1300
  return;
1299
1301
  }
1300
1302
  if (e.key !== "Tab" || !this._workbenchPanel) return;
1301
- let t = O(this._workbenchPanel), n = t[0], r = t.at(-1), i = k(this.shadowRoot);
1303
+ let t = k(this._workbenchPanel), n = t[0], r = t.at(-1), i = A(this.shadowRoot);
1302
1304
  if (!n || !r) {
1303
1305
  e.preventDefault();
1304
1306
  return;
@@ -1320,7 +1322,7 @@ var A = class extends i {
1320
1322
  };
1321
1323
  }
1322
1324
  static {
1323
- this.styles = [n, w];
1325
+ this.styles = [n, T];
1324
1326
  }
1325
1327
  #e;
1326
1328
  #t;
@@ -1419,11 +1421,11 @@ var A = class extends i {
1419
1421
  >
1420
1422
  <div class="slot-grid">
1421
1423
  <div class="slot-rail left-rail">
1422
- ${this.#c(this._compact ? this.data.positions.map(({ id: e }) => e) : T)}
1424
+ ${this.#c(this._compact ? this.data.positions.map(({ id: e }) => e) : E)}
1423
1425
  </div>
1424
1426
  ${this._compact ? s : o`
1425
1427
  <div class="slot-rail right-rail">
1426
- ${this.#c(E)}
1428
+ ${this.#c(D)}
1427
1429
  </div>
1428
1430
  `}
1429
1431
  </div>
@@ -1468,20 +1470,23 @@ var A = class extends i {
1468
1470
  `;
1469
1471
  }
1470
1472
  #c(e) {
1471
- return !this.data || !this.build ? o`` : o`
1473
+ if (!this.data || !this.build) return o``;
1474
+ let t = this.data.heroById.get(this.build.heroId) ?? null;
1475
+ return o`
1472
1476
  ${f(e, (e) => e, (e) => {
1473
- let t = this.data?.positions.find(({ id: t }) => t === e) ?? null, n = this.build?.positions.find((t) => t.positionId === e) ?? null, r = n?.item ? this.data?.itemById.get(n.item.itemId) ?? null : null, i = r ? p(r.item.images, {
1477
+ let n = this.data?.positions.find(({ id: t }) => t === e) ?? null, r = this.build?.positions.find((t) => t.positionId === e) ?? null, i = r?.item ? this.data?.itemById.get(r.item.itemId) ?? null : null, a = i ? p(i.item.images, {
1474
1478
  size: "200",
1475
1479
  type: "hero-item"
1476
1480
  }) : null;
1477
1481
  return o`
1478
1482
  <fellowship-gear-position
1479
- .position=${t}
1480
- .item=${r}
1481
- .itemBuild=${n?.item ?? null}
1483
+ .position=${n}
1484
+ .item=${i}
1485
+ .itemBuild=${r?.item ?? null}
1486
+ .itemName=${i && t ? v(i, t) : null}
1482
1487
  .selected=${e === this._selectedPositionId}
1483
- .imageUrl=${i ? this.#S(i) : null}
1484
- .tooltipDetails=${this.#u(e, n?.item ?? null)}
1488
+ .imageUrl=${a ? this.#S(a) : null}
1489
+ .tooltipDetails=${this.#u(e, r?.item ?? null)}
1485
1490
  @fellowship-gear-position-select=${this.#p}
1486
1491
  ></fellowship-gear-position>
1487
1492
  `;
@@ -1685,12 +1690,12 @@ var A = class extends i {
1685
1690
  }
1686
1691
  #C;
1687
1692
  };
1688
- e([l({ attribute: !1 })], A.prototype, "data", void 0), e([l({ attribute: !1 })], A.prototype, "build", void 0), e([l({
1693
+ e([l({ attribute: !1 })], j.prototype, "data", void 0), e([l({ attribute: !1 })], j.prototype, "build", void 0), e([l({
1689
1694
  type: Boolean,
1690
1695
  reflect: !0
1691
- })], A.prototype, "loading", void 0), e([l({ attribute: !1 })], A.prototype, "error", void 0), e([l({ attribute: !1 })], A.prototype, "resolveAssetUrl", void 0), e([d()], A.prototype, "_selectedPositionId", void 0), e([d()], A.prototype, "_tab", void 0), e([d()], A.prototype, "_sheetOpen", void 0), e([d()], A.prototype, "_compact", void 0), e([d()], A.prototype, "_announcement", void 0), e([d()], A.prototype, "_calculation", void 0), e([u(".workbench-panel")], A.prototype, "_workbenchPanel", void 0), A = e([c("fellowship-gear-planner")], A);
1692
- var j = () => {
1693
- customElements.get("fellowship-gear-planner") || customElements.define("fellowship-gear-planner", A);
1696
+ })], j.prototype, "loading", void 0), e([l({ attribute: !1 })], j.prototype, "error", void 0), e([l({ attribute: !1 })], j.prototype, "resolveAssetUrl", void 0), e([d()], j.prototype, "_selectedPositionId", void 0), e([d()], j.prototype, "_tab", void 0), e([d()], j.prototype, "_sheetOpen", void 0), e([d()], j.prototype, "_compact", void 0), e([d()], j.prototype, "_announcement", void 0), e([d()], j.prototype, "_calculation", void 0), e([u(".workbench-panel")], j.prototype, "_workbenchPanel", void 0), j = e([c("fellowship-gear-planner")], j);
1697
+ var M = () => {
1698
+ customElements.get("fellowship-gear-planner") || customElements.define("fellowship-gear-planner", j);
1694
1699
  };
1695
1700
  //#endregion
1696
- export { j as n, A as t };
1701
+ export { M as n, j as t };
@@ -6,6 +6,7 @@ export declare class FellowshipGearPositionElement extends LitElement {
6
6
  position: GearPlannerPosition | null;
7
7
  item: GearPlannerItem | null;
8
8
  itemBuild: GearPlannerItemBuild | null;
9
+ itemName: string | null;
9
10
  selected: boolean;
10
11
  imageUrl: string | null;
11
12
  tooltipDetails: readonly string[];
@@ -1,4 +1,4 @@
1
- import { n as e, t } from "./chunks/gear-planner-Bgt77Ovf.js";
1
+ import { n as e, t } from "./chunks/gear-planner-uQOpm4QI.js";
2
2
  //#region src/gear-planner/index.ts
3
3
  e();
4
4
  //#endregion
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import "./dungeon-cast-browser.js";
7
7
  import { n as C, o as w, r as T, s as E, t as D } from "./chunks/tooltip-C3SSJw-t.js";
8
8
  import "./talent-calculator.js";
9
9
  import "./tooltip.js";
10
- import { n as O, t as k } from "./chunks/gear-planner-Bgt77Ovf.js";
10
+ import { n as O, t as k } from "./chunks/gear-planner-uQOpm4QI.js";
11
11
  import "./gear-planner.js";
12
12
  import { createPackageFellowshipDataClient as A } from "@crockery/fellowship-data/client";
13
13
  export { e as FellowshipDataError, d as FellowshipDungeonCastBrowserElement, o as FellowshipDungeonMapElement, k as FellowshipGearPlannerElement, x as FellowshipTalentCalculatorElement, D as FellowshipTooltipElement, h as MAX_TALENT_POINTS, a as ViewportController, T as calculateTooltipPosition, f as canSelectTalent, u as castIdentityKey, c as createDungeonCastBrowserModel, n as createDungeonMapRenderModel, s as createPackageFellowshipCastDataSource, A as createPackageFellowshipDataClient, i as createPackageFellowshipDataSource, m as createPackageFellowshipTalentDataSource, g as createTalentCalculatorRenderModel, v as createTalentCalculatorSelectionState, l as defineFellowshipDungeonCastBrowser, r as defineFellowshipDungeonMap, O as defineFellowshipGearPlanner, _ as defineFellowshipTalentCalculator, C as defineFellowshipTooltip, t as humanizeMapLabel, b as normalizeSelectedTalentIds, p as normalizeTalentPoints, w as resolveFellowshipRichText, E as stripFellowshipRichText, S as talentRowLabel, y as talentSlotName };
@@ -1,4 +1,4 @@
1
- import { n as e, t } from "../chunks/gear-planner-Bgt77Ovf.js";
1
+ import { n as e, t } from "../chunks/gear-planner-uQOpm4QI.js";
2
2
  import { createComponent as n } from "@lit/react";
3
3
  import r, { forwardRef as i } from "react";
4
4
  import { jsx as a } from "react/jsx-runtime";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crockery/fellowship-components",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Lit web components for rendering Fellowship game data.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -112,7 +112,7 @@
112
112
  "dependencies": {
113
113
  "@lit/react": "^1.0.8",
114
114
  "lit": "^3.3.3",
115
- "@crockery/fellowship-data": "^3.0.0"
115
+ "@crockery/fellowship-data": "^3.1.0"
116
116
  },
117
117
  "peerDependencies": {
118
118
  "react": ">=18 <20",
@@ -155,8 +155,6 @@
155
155
  "test": "pnpm test:unit && pnpm test:browser",
156
156
  "test:unit": "vitest run --project unit",
157
157
  "test:browser": "vitest run --project browser",
158
- "test:browser:smoke": "FELLOWSHIP_TEST_BROWSERS=smoke vitest run --project browser -t '\\[smoke\\]'",
159
- "test:browser:all": "FELLOWSHIP_TEST_BROWSERS=all vitest run --project browser",
160
158
  "ladle": "ladle serve",
161
159
  "ladle:build": "ladle build",
162
160
  "package:lint": "publint --strict --pack npm && attw --pack . --profile esm-only",