@crockery/fellowship-components 0.4.0 → 0.4.1
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 +12 -12
- package/RELEASING.md +15 -14
- package/dist/chunks/data-source-XbksqUrw.js +0 -2
- package/dist/chunks/decorate-B_ZTN9li.js +0 -2
- package/dist/chunks/dungeon-cast-browser-CSnu3gC5.js +0 -2
- package/dist/chunks/dungeon-map-CutIcCVP.js +0 -2
- package/dist/chunks/talent-calculator-Dxuc2dZ8.js +0 -2
- package/dist/chunks/tooltip-DoQVSnOn.js +0 -2
- package/dist/data/cast-data-source.d.ts +0 -1
- package/dist/data/data-source.d.ts +0 -1
- package/dist/data/package-cast-data-source.d.ts +0 -1
- package/dist/data/package-data-source.d.ts +0 -1
- package/dist/data/package-talent-data-source.d.ts +0 -1
- package/dist/data/talent-data-source.d.ts +0 -1
- package/dist/dungeon-cast-browser/dungeon-cast-browser.d.ts +0 -1
- package/dist/dungeon-cast-browser/dungeon-cast-browser.styles.d.ts +0 -1
- package/dist/dungeon-cast-browser/index.d.ts +0 -1
- package/dist/dungeon-cast-browser/render-model.d.ts +0 -1
- package/dist/dungeon-cast-browser/types.d.ts +0 -1
- package/dist/dungeon-cast-browser.js +0 -2
- package/dist/dungeon-map/dungeon-map.d.ts +0 -1
- package/dist/dungeon-map/dungeon-map.styles.d.ts +0 -1
- package/dist/dungeon-map/index.d.ts +0 -1
- package/dist/dungeon-map/layout.d.ts +0 -1
- package/dist/dungeon-map/render-model.d.ts +0 -1
- package/dist/dungeon-map/types.d.ts +0 -1
- package/dist/dungeon-map/viewport-controller.d.ts +0 -1
- package/dist/dungeon-map.js +0 -2
- package/dist/index.d.ts +0 -1
- package/dist/react/dungeon-cast-browser.d.ts +0 -1
- package/dist/react/dungeon-cast-browser.js +0 -2
- package/dist/react/dungeon-map.d.ts +0 -1
- package/dist/react/dungeon-map.js +0 -2
- package/dist/react/index.d.ts +0 -1
- package/dist/react/talent-calculator.d.ts +0 -1
- package/dist/react/talent-calculator.js +0 -2
- package/dist/react/tooltip.d.ts +0 -1
- package/dist/react/tooltip.js +0 -2
- package/dist/styles/field-manual-fonts.d.ts +0 -1
- package/dist/styles/field-manual.styles.d.ts +0 -1
- package/dist/talent-calculator/index.d.ts +0 -1
- package/dist/talent-calculator/render-model.d.ts +0 -1
- package/dist/talent-calculator/selection-state.d.ts +0 -1
- package/dist/talent-calculator/talent-calculator.d.ts +0 -1
- package/dist/talent-calculator/talent-calculator.styles.d.ts +0 -1
- package/dist/talent-calculator/types.d.ts +0 -1
- package/dist/talent-calculator.js +0 -2
- package/dist/tooltip/index.d.ts +0 -1
- package/dist/tooltip/positioning.d.ts +0 -1
- package/dist/tooltip/rich-text.d.ts +0 -1
- package/dist/tooltip/tooltip.d.ts +0 -1
- package/dist/tooltip/tooltip.styles.d.ts +0 -1
- package/dist/tooltip/types.d.ts +0 -1
- package/dist/tooltip.js +0 -2
- package/package.json +8 -15
- package/dist/chunks/data-source-XbksqUrw.js.map +0 -1
- package/dist/chunks/decorate-B_ZTN9li.js.map +0 -1
- package/dist/chunks/dungeon-cast-browser-CSnu3gC5.js.map +0 -1
- package/dist/chunks/dungeon-map-CutIcCVP.js.map +0 -1
- package/dist/chunks/talent-calculator-Dxuc2dZ8.js.map +0 -1
- package/dist/chunks/tooltip-DoQVSnOn.js.map +0 -1
- package/dist/data/cast-data-source.d.ts.map +0 -1
- package/dist/data/data-source.d.ts.map +0 -1
- package/dist/data/package-cast-data-source.d.ts.map +0 -1
- package/dist/data/package-data-source.d.ts.map +0 -1
- package/dist/data/package-talent-data-source.d.ts.map +0 -1
- package/dist/data/talent-data-source.d.ts.map +0 -1
- package/dist/dungeon-cast-browser/dungeon-cast-browser.d.ts.map +0 -1
- package/dist/dungeon-cast-browser/dungeon-cast-browser.styles.d.ts.map +0 -1
- package/dist/dungeon-cast-browser/index.d.ts.map +0 -1
- package/dist/dungeon-cast-browser/render-model.d.ts.map +0 -1
- package/dist/dungeon-cast-browser/types.d.ts.map +0 -1
- package/dist/dungeon-cast-browser.js.map +0 -1
- package/dist/dungeon-map/dungeon-map.d.ts.map +0 -1
- package/dist/dungeon-map/dungeon-map.styles.d.ts.map +0 -1
- package/dist/dungeon-map/index.d.ts.map +0 -1
- package/dist/dungeon-map/layout.d.ts.map +0 -1
- package/dist/dungeon-map/render-model.d.ts.map +0 -1
- package/dist/dungeon-map/types.d.ts.map +0 -1
- package/dist/dungeon-map/viewport-controller.d.ts.map +0 -1
- package/dist/dungeon-map.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/react/dungeon-cast-browser.d.ts.map +0 -1
- package/dist/react/dungeon-cast-browser.js.map +0 -1
- package/dist/react/dungeon-map.d.ts.map +0 -1
- package/dist/react/dungeon-map.js.map +0 -1
- package/dist/react/index.d.ts.map +0 -1
- package/dist/react/talent-calculator.d.ts.map +0 -1
- package/dist/react/talent-calculator.js.map +0 -1
- package/dist/react/tooltip.d.ts.map +0 -1
- package/dist/react/tooltip.js.map +0 -1
- package/dist/styles/field-manual-fonts.d.ts.map +0 -1
- package/dist/styles/field-manual.styles.d.ts.map +0 -1
- package/dist/talent-calculator/index.d.ts.map +0 -1
- package/dist/talent-calculator/render-model.d.ts.map +0 -1
- package/dist/talent-calculator/selection-state.d.ts.map +0 -1
- package/dist/talent-calculator/talent-calculator.d.ts.map +0 -1
- package/dist/talent-calculator/talent-calculator.styles.d.ts.map +0 -1
- package/dist/talent-calculator/types.d.ts.map +0 -1
- package/dist/talent-calculator.js.map +0 -1
- package/dist/tooltip/index.d.ts.map +0 -1
- package/dist/tooltip/positioning.d.ts.map +0 -1
- package/dist/tooltip/rich-text.d.ts.map +0 -1
- package/dist/tooltip/tooltip.d.ts.map +0 -1
- package/dist/tooltip/tooltip.styles.d.ts.map +0 -1
- package/dist/tooltip/types.d.ts.map +0 -1
- package/dist/tooltip.js.map +0 -1
package/README.md
CHANGED
|
@@ -94,10 +94,9 @@ request. See `THIRD_PARTY_LICENSES.md` for the SIL Open Font License notice.
|
|
|
94
94
|
|
|
95
95
|
## Data and asset versions
|
|
96
96
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
consuming application's lockfile when reproducible data and image updates matter.
|
|
97
|
+
Version 0.4.1 targets `@crockery/fellowship-data@^2.0.0` and requires manifest
|
|
98
|
+
schema 2. The monorepo workspace keeps Components and Data changes atomic;
|
|
99
|
+
published packages retain independent versions.
|
|
101
100
|
|
|
102
101
|
Dataset JSON stays out of the component library's initial JavaScript path and published tarball.
|
|
103
102
|
Each data-driven component supports:
|
|
@@ -116,17 +115,18 @@ client methods through `dataSource`.
|
|
|
116
115
|
## Development
|
|
117
116
|
|
|
118
117
|
```sh
|
|
119
|
-
pnpm install
|
|
120
|
-
pnpm
|
|
121
|
-
pnpm test
|
|
122
|
-
pnpm build
|
|
123
|
-
pnpm pack:check
|
|
118
|
+
pnpm install --frozen-lockfile
|
|
119
|
+
pnpm dev:components
|
|
120
|
+
pnpm --filter @crockery/fellowship-components test
|
|
121
|
+
pnpm --filter @crockery/fellowship-components build
|
|
122
|
+
pnpm --filter @crockery/fellowship-components pack:check
|
|
124
123
|
```
|
|
125
124
|
|
|
126
125
|
Current Chromium, Firefox, and Safari/WebKit are supported. Add a Changeset with
|
|
127
|
-
`pnpm changeset` for every user-facing change
|
|
128
|
-
|
|
129
|
-
|
|
126
|
+
`pnpm changeset` from the monorepo root for every user-facing change. Merging
|
|
127
|
+
the generated version pull request publishes through trusted OIDC publishing.
|
|
128
|
+
The private repository means npm provenance attestations are unavailable.
|
|
129
|
+
Maintainers should follow [`RELEASING.md`](RELEASING.md).
|
|
130
130
|
|
|
131
131
|
## License
|
|
132
132
|
|
package/RELEASING.md
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
# Releasing
|
|
1
|
+
# Releasing Fellowship packages
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
change:
|
|
3
|
+
The private `Crockery/fellowscript` monorepo owns Data and Components releases.
|
|
4
|
+
Run Changesets from its root for every consumer-facing change:
|
|
5
5
|
|
|
6
6
|
```sh
|
|
7
7
|
pnpm changeset
|
|
8
8
|
```
|
|
9
9
|
|
|
10
|
-
The Release workflow maintains
|
|
11
|
-
|
|
10
|
+
The root Release workflow maintains one Changesets version pull request against
|
|
11
|
+
`master`. Merging it publishes independently versioned packages in dependency
|
|
12
|
+
order. If Data is changing, its R2 assets are uploaded and verified before npm
|
|
13
|
+
publishing begins.
|
|
12
14
|
|
|
13
15
|
## Trusted publishing
|
|
14
16
|
|
|
@@ -16,23 +18,22 @@ Trusted publishing is enabled on npm with:
|
|
|
16
18
|
|
|
17
19
|
- Provider: GitHub Actions
|
|
18
20
|
- Organization or user: `Crockery`
|
|
19
|
-
- Repository: `
|
|
21
|
+
- Repository: `fellowscript`
|
|
20
22
|
- Workflow filename: `release.yml`
|
|
21
23
|
- Environment: none
|
|
22
24
|
- Allowed action: `npm publish`
|
|
23
25
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
create release tags manually.
|
|
26
|
+
Do not add an `NPM_TOKEN`: npm authenticates the release job through its GitHub
|
|
27
|
+
OIDC identity. npm does not create provenance attestations for public packages
|
|
28
|
+
published from a private repository.
|
|
28
29
|
|
|
29
30
|
## Routine releases
|
|
30
31
|
|
|
31
|
-
1. Merge consumer-facing changes and their changesets into `
|
|
32
|
+
1. Merge consumer-facing changes and their changesets into `master`.
|
|
32
33
|
2. Review the Changesets version pull request, including its generated changelog.
|
|
33
|
-
3. Merge the version pull request after
|
|
34
|
-
4. Confirm
|
|
35
|
-
|
|
34
|
+
3. Merge the version pull request after the full release verification succeeds.
|
|
35
|
+
4. Confirm Data's `_release.json` marker and exact npm versions before relying
|
|
36
|
+
on the release.
|
|
36
37
|
|
|
37
38
|
Never reuse a version number. If a release is defective, publish a corrective patch. Deprecate a
|
|
38
39
|
bad version with `npm deprecate` when consumers need an explicit warning; unpublish only when npm's
|
|
@@ -2,4 +2,3 @@ export type { DungeonCastData } from "@crockery/fellowship-data/client";
|
|
|
2
2
|
import type { FellowshipDataClient } from "@crockery/fellowship-data/client";
|
|
3
3
|
/** @deprecated Use the corresponding `FellowshipDataClient` methods. */
|
|
4
4
|
export type FellowshipCastDataSource = Pick<FellowshipDataClient, "loadDungeonCasts" | "resolveAssetUrl">;
|
|
5
|
-
//# sourceMappingURL=cast-data-source.d.ts.map
|
|
@@ -5,4 +5,3 @@ import type { FellowshipDataClient } from "@crockery/fellowship-data/client";
|
|
|
5
5
|
export declare const assertSupportedFellowshipDataSchema: (schemaVersion: number) => void;
|
|
6
6
|
/** @deprecated Use the corresponding `FellowshipDataClient` methods. */
|
|
7
7
|
export type FellowshipDataSource = Pick<FellowshipDataClient, "loadDungeon" | "resolveAssetUrl">;
|
|
8
|
-
//# sourceMappingURL=data-source.d.ts.map
|
|
@@ -5,4 +5,3 @@ export interface PackageFellowshipCastDataSourceOptions {
|
|
|
5
5
|
}
|
|
6
6
|
/** @deprecated Use `createPackageFellowshipDataClient` from `@crockery/fellowship-data/client`. */
|
|
7
7
|
export declare const createPackageFellowshipCastDataSource: (options?: PackageFellowshipCastDataSourceOptions) => FellowshipCastDataSource;
|
|
8
|
-
//# sourceMappingURL=package-cast-data-source.d.ts.map
|
|
@@ -5,4 +5,3 @@ export interface PackageFellowshipDataSourceOptions {
|
|
|
5
5
|
}
|
|
6
6
|
/** @deprecated Use `createPackageFellowshipDataClient` from `@crockery/fellowship-data/client`. */
|
|
7
7
|
export declare const createPackageFellowshipDataSource: (options?: PackageFellowshipDataSourceOptions) => FellowshipDataSource;
|
|
8
|
-
//# sourceMappingURL=package-data-source.d.ts.map
|
|
@@ -5,4 +5,3 @@ export interface PackageFellowshipTalentDataSourceOptions {
|
|
|
5
5
|
}
|
|
6
6
|
/** @deprecated Use `createPackageFellowshipDataClient` from `@crockery/fellowship-data/client`. */
|
|
7
7
|
export declare const createPackageFellowshipTalentDataSource: (options?: PackageFellowshipTalentDataSourceOptions) => FellowshipTalentDataSource;
|
|
8
|
-
//# sourceMappingURL=package-talent-data-source.d.ts.map
|
|
@@ -2,4 +2,3 @@ export type { TalentCalculatorData } from "@crockery/fellowship-data/client";
|
|
|
2
2
|
import type { FellowshipDataClient } from "@crockery/fellowship-data/client";
|
|
3
3
|
/** @deprecated Use the corresponding `FellowshipDataClient` methods. */
|
|
4
4
|
export type FellowshipTalentDataSource = Pick<FellowshipDataClient, "loadHeroTalents" | "resolveAssetUrl">;
|
|
5
|
-
//# sourceMappingURL=talent-data-source.d.ts.map
|
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
export { defineFellowshipDungeonCastBrowser, FellowshipDungeonCastBrowserElement, } from "./dungeon-cast-browser.js";
|
|
2
2
|
export { castIdentityKey, createDungeonCastBrowserModel } from "./render-model.js";
|
|
3
3
|
export type { CastCapabilityLabel, ConfiguredCastFilter, DungeonCastBrowserModel, DungeonCastEnemyModel, DungeonCastModel, FellowshipCastBrowserErrorDetail, FellowshipCastBrowserErrorEvent, FellowshipCastBrowserReadyDetail, FellowshipCastBrowserReadyEvent, FellowshipCastIdentity, FellowshipCastSelectedDetail, FellowshipCastSelectedEvent, FellowshipDungeonCastBrowserProperties, } from "./types.js";
|
|
4
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -2,4 +2,3 @@ import type { DungeonCastData, FellowshipCastDataSource } from "../data/cast-dat
|
|
|
2
2
|
import type { DungeonCastBrowserModel, FellowshipCastIdentity } from "./types.js";
|
|
3
3
|
export declare const castIdentityKey: ({ enemyId, abilityId }: FellowshipCastIdentity) => string;
|
|
4
4
|
export declare const createDungeonCastBrowserModel: (data: DungeonCastData, source: FellowshipCastDataSource) => DungeonCastBrowserModel;
|
|
5
|
-
//# sourceMappingURL=render-model.d.ts.map
|
|
@@ -3,5 +3,3 @@ import { i as e, n as t, r as n, t as r } from "./chunks/dungeon-cast-browser-CS
|
|
|
3
3
|
t();
|
|
4
4
|
//#endregion
|
|
5
5
|
export { r as FellowshipDungeonCastBrowserElement, n as castIdentityKey, e as createDungeonCastBrowserModel, t as defineFellowshipDungeonCastBrowser };
|
|
6
|
-
|
|
7
|
-
//# sourceMappingURL=dungeon-cast-browser.js.map
|
|
@@ -2,4 +2,3 @@ export { FellowshipDungeonMapElement, defineFellowshipDungeonMap } from "./dunge
|
|
|
2
2
|
export { createDungeonMapRenderModel, humanizeMapLabel } from "./render-model.js";
|
|
3
3
|
export { ViewportController } from "./viewport-controller.js";
|
|
4
4
|
export type { DungeonMapEnemyModel, DungeonMapEnemyRenderContext, DungeonMapGroupModel, DungeonMapGroupRenderContext, DungeonMapRenderModel, DungeonMapWarning, FellowshipDungeonMapProperties, FellowshipMapErrorDetail, FellowshipMapImageChangeDetail, FellowshipMapReadyDetail, FellowshipMapViewportChangeDetail, FellowshipMapWarningDetail, LitEnemyRenderer, LitGroupRenderer, MapLabelFormatter, NormalizedRect, ViewportState, } from "./types.js";
|
|
5
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -4,4 +4,3 @@ import type { DungeonMapRenderModel } from "./types.js";
|
|
|
4
4
|
export declare const isValidMapPosition: (position: Position2D | null) => position is Position2D;
|
|
5
5
|
export declare const createDungeonMapRenderModel: (data: DungeonMapData, mapImage: ImageAssetRef, source: FellowshipDataSource) => DungeonMapRenderModel;
|
|
6
6
|
export declare const humanizeMapLabel: (mapImage: ImageAssetRef, dungeon: Dungeon) => string;
|
|
7
|
-
//# sourceMappingURL=render-model.d.ts.map
|
package/dist/dungeon-map.js
CHANGED
|
@@ -3,5 +3,3 @@ import { a as e, i as t, n, r, t as i } from "./chunks/dungeon-map-CutIcCVP.js";
|
|
|
3
3
|
n();
|
|
4
4
|
//#endregion
|
|
5
5
|
export { i as FellowshipDungeonMapElement, r as ViewportController, t as createDungeonMapRenderModel, n as defineFellowshipDungeonMap, e as humanizeMapLabel };
|
|
6
|
-
|
|
7
|
-
//# sourceMappingURL=dungeon-map.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -19,4 +19,3 @@ export interface DungeonMapViewerProps extends Omit<NativeDungeonMapProps, "chil
|
|
|
19
19
|
}
|
|
20
20
|
export declare const DungeonMapViewer: React.ForwardRefExoticComponent<Omit<DungeonMapViewerProps, "ref"> & React.RefAttributes<FellowshipDungeonMapElement>>;
|
|
21
21
|
export default DungeonMapViewer;
|
|
22
|
-
//# sourceMappingURL=dungeon-map.d.ts.map
|
package/dist/react/index.d.ts
CHANGED
|
@@ -6,4 +6,3 @@ export { TalentCalculator } from "./talent-calculator.js";
|
|
|
6
6
|
export type { ReactTalentRenderer, TalentCalculatorProps } from "./talent-calculator.js";
|
|
7
7
|
export { Tooltip } from "./tooltip.js";
|
|
8
8
|
export type { TooltipProps } from "./tooltip.js";
|
|
9
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -19,4 +19,3 @@ export interface TalentCalculatorProps extends Omit<NativeTalentCalculatorProps,
|
|
|
19
19
|
}
|
|
20
20
|
export declare const TalentCalculator: React.ForwardRefExoticComponent<Omit<TalentCalculatorProps, "ref"> & React.RefAttributes<FellowshipTalentCalculatorElement>>;
|
|
21
21
|
export default TalentCalculator;
|
|
22
|
-
//# sourceMappingURL=talent-calculator.d.ts.map
|
package/dist/react/tooltip.d.ts
CHANGED
|
@@ -12,4 +12,3 @@ export interface TooltipProps extends Omit<NativeTooltipProps, "children" | "con
|
|
|
12
12
|
}
|
|
13
13
|
export declare const Tooltip: React.ForwardRefExoticComponent<Omit<TooltipProps, "ref"> & React.RefAttributes<FellowshipTooltipElement>>;
|
|
14
14
|
export default Tooltip;
|
|
15
|
-
//# sourceMappingURL=tooltip.d.ts.map
|
package/dist/react/tooltip.js
CHANGED
|
@@ -2,4 +2,3 @@ export { createTalentCalculatorRenderModel, talentRowLabel } from "./render-mode
|
|
|
2
2
|
export { canSelectTalent, createTalentCalculatorSelectionState, MAX_TALENT_POINTS, normalizeSelectedTalentIds, normalizeTalentPoints, } from "./selection-state.js";
|
|
3
3
|
export { FellowshipTalentCalculatorElement, defineFellowshipTalentCalculator, talentSlotName, } from "./talent-calculator.js";
|
|
4
4
|
export type { FellowshipTalentCalculatorProperties, FellowshipTalentsErrorDetail, FellowshipTalentsErrorEvent, FellowshipTalentsReadyDetail, FellowshipTalentsReadyEvent, FellowshipTalentsWarningDetail, FellowshipTalentsWarningEvent, LitTalentRenderer, TalentCalculatorRenderModel, TalentCalculatorRowModel, TalentCalculatorSelectionState, TalentCalculatorTalentModel, TalentCalculatorTalentRenderContext, TalentCalculatorWarning, TalentCalculatorWarningCode, TalentPointsChangeDetail, TalentPointsChangeEvent, TalentPointsChangeSource, TalentSelectionChangeDetail, TalentSelectionChangeEvent, TalentSelectionChangeSource, } from "./types.js";
|
|
5
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -2,4 +2,3 @@ import type { FellowshipTalentDataSource, TalentCalculatorData } from "../data/t
|
|
|
2
2
|
import type { TalentCalculatorRenderModel } from "./types.js";
|
|
3
3
|
export declare const talentRowLabel: (row: number) => string;
|
|
4
4
|
export declare const createTalentCalculatorRenderModel: (data: TalentCalculatorData, source: FellowshipTalentDataSource) => TalentCalculatorRenderModel;
|
|
5
|
-
//# sourceMappingURL=render-model.d.ts.map
|
|
@@ -7,4 +7,3 @@ export declare const normalizeSelectedTalentIds: (model: TalentCalculatorRenderM
|
|
|
7
7
|
};
|
|
8
8
|
export declare const createTalentCalculatorSelectionState: (model: TalentCalculatorRenderModel, selectedTalentIds: readonly string[], talentPoints: number) => TalentCalculatorSelectionState;
|
|
9
9
|
export declare const canSelectTalent: (pointCost: number | null, state: TalentCalculatorSelectionState) => boolean;
|
|
10
|
-
//# sourceMappingURL=selection-state.d.ts.map
|
|
@@ -3,5 +3,3 @@ import { a as e, c as t, i as n, l as r, n as i, o as a, r as o, s, t as c, u as
|
|
|
3
3
|
i();
|
|
4
4
|
//#endregion
|
|
5
5
|
export { c as FellowshipTalentCalculatorElement, n as MAX_TALENT_POINTS, e as canSelectTalent, r as createTalentCalculatorRenderModel, a as createTalentCalculatorSelectionState, i as defineFellowshipTalentCalculator, s as normalizeSelectedTalentIds, t as normalizeTalentPoints, l as talentRowLabel, o as talentSlotName };
|
|
6
|
-
|
|
7
|
-
//# sourceMappingURL=talent-calculator.js.map
|
package/dist/tooltip/index.d.ts
CHANGED
|
@@ -3,4 +3,3 @@ export type { TooltipPosition, TooltipPositionOptions, TooltipRect } from "./pos
|
|
|
3
3
|
export { resolveFellowshipRichText, stripFellowshipRichText } from "./rich-text.js";
|
|
4
4
|
export { FellowshipTooltipElement, defineFellowshipTooltip } from "./tooltip.js";
|
|
5
5
|
export type { FellowshipRichTextDocument, FellowshipRichTextSegment, FellowshipTextTone, FellowshipTooltipPlacement, FellowshipTooltipToggleDetail, FellowshipTooltipToggleEvent, ResolvedTooltipPlacement, } from "./types.js";
|
|
6
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -20,4 +20,3 @@ export interface TooltipPositionOptions {
|
|
|
20
20
|
readonly margin?: number;
|
|
21
21
|
}
|
|
22
22
|
export declare const calculateTooltipPosition: (trigger: TooltipRect, tooltip: Pick<TooltipRect, "width" | "height">, options: TooltipPositionOptions) => TooltipPosition;
|
|
23
|
-
//# sourceMappingURL=positioning.d.ts.map
|
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
import type { FellowshipRichTextDocument } from "./types.js";
|
|
2
2
|
export declare const resolveFellowshipRichText: (value: string) => FellowshipRichTextDocument;
|
|
3
3
|
export declare const stripFellowshipRichText: (value: string) => string;
|
|
4
|
-
//# sourceMappingURL=rich-text.d.ts.map
|
package/dist/tooltip/types.d.ts
CHANGED
package/dist/tooltip.js
CHANGED
|
@@ -3,5 +3,3 @@ import { a as e, i as t, n, r, t as i } from "./chunks/tooltip-DoQVSnOn.js";
|
|
|
3
3
|
n();
|
|
4
4
|
//#endregion
|
|
5
5
|
export { i as FellowshipTooltipElement, r as calculateTooltipPosition, n as defineFellowshipTooltip, t as resolveFellowshipRichText, e as stripFellowshipRichText };
|
|
6
|
-
|
|
7
|
-
//# sourceMappingURL=tooltip.js.map
|
package/package.json
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crockery/fellowship-components",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Lit web components for rendering Fellowship game data.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
|
-
"url": "git+https://github.com/Crockery/
|
|
7
|
+
"url": "git+https://github.com/Crockery/fellowscript.git",
|
|
8
|
+
"directory": "packages/fellowship-components"
|
|
8
9
|
},
|
|
9
|
-
"bugs": {
|
|
10
|
-
"url": "https://github.com/Crockery/fellowship-components/issues"
|
|
11
|
-
},
|
|
12
|
-
"homepage": "https://github.com/Crockery/fellowship-components#readme",
|
|
13
10
|
"keywords": [
|
|
14
11
|
"fellowship",
|
|
15
12
|
"web-components",
|
|
@@ -99,12 +96,12 @@
|
|
|
99
96
|
"access": "public"
|
|
100
97
|
},
|
|
101
98
|
"engines": {
|
|
102
|
-
"node": "
|
|
99
|
+
"node": ">=24"
|
|
103
100
|
},
|
|
104
101
|
"dependencies": {
|
|
105
|
-
"@crockery/fellowship-data": "^1.3.0",
|
|
106
102
|
"@lit/react": "^1.0.8",
|
|
107
|
-
"lit": "^3.3.3"
|
|
103
|
+
"lit": "^3.3.3",
|
|
104
|
+
"@crockery/fellowship-data": "^2.0.0"
|
|
108
105
|
},
|
|
109
106
|
"peerDependencies": {
|
|
110
107
|
"react": ">=18 <20",
|
|
@@ -120,8 +117,7 @@
|
|
|
120
117
|
},
|
|
121
118
|
"devDependencies": {
|
|
122
119
|
"@arethetypeswrong/cli": "^0.18.5",
|
|
123
|
-
"@biomejs/biome": "
|
|
124
|
-
"@changesets/cli": "^2.31.0",
|
|
120
|
+
"@biomejs/biome": "2.5.3",
|
|
125
121
|
"@fontsource/ibm-plex-mono": "5.2.7",
|
|
126
122
|
"@fontsource/ibm-plex-sans-condensed": "5.2.8",
|
|
127
123
|
"@ladle/react": "^5.1.1",
|
|
@@ -151,9 +147,6 @@
|
|
|
151
147
|
"ladle": "ladle serve",
|
|
152
148
|
"ladle:build": "ladle build",
|
|
153
149
|
"package:lint": "publint --strict --pack npm && attw --pack . --profile esm-only",
|
|
154
|
-
"pack:check": "pnpm build && node scripts/check-build.mjs &&
|
|
155
|
-
"changeset": "changeset",
|
|
156
|
-
"version-packages": "changeset version",
|
|
157
|
-
"release": "changeset publish"
|
|
150
|
+
"pack:check": "pnpm build && node scripts/check-build.mjs && node scripts/check-package-files.mjs && pnpm package:lint"
|
|
158
151
|
}
|
|
159
152
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"data-source-XbksqUrw.js","names":[],"sources":["../../src/data/data-source.ts"],"sourcesContent":["import { FellowshipDataError } from \"@crockery/fellowship-data/client\";\nexport { FellowshipDataError };\nexport type {\n DungeonMapData,\n FellowshipDataErrorCode,\n} from \"@crockery/fellowship-data/client\";\n\nimport type { FellowshipDataClient } from \"@crockery/fellowship-data/client\";\n\nconst supportedSchemaVersion = 2;\n\nexport const assertSupportedFellowshipDataSchema = (schemaVersion: number): void => {\n if (schemaVersion === supportedSchemaVersion) return;\n\n throw new FellowshipDataError(\n \"unsupported-schema\",\n `Unsupported fellowship-data schema version: ${String(schemaVersion)}.`,\n );\n};\n\n/** @deprecated Use the corresponding `FellowshipDataClient` methods. */\nexport type FellowshipDataSource = Pick<FellowshipDataClient, \"loadDungeon\" | \"resolveAssetUrl\">;\n"],"mappings":";;AASA,IAAM,IAAyB,GAElB,KAAuC,MAAgC;CAC9E,UAAkB,GAEtB,MAAM,IAAI,EACR,sBACA,+CAA+C,OAAO,CAAa,EAAE,EACvE;AACF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"decorate-B_ZTN9li.js","names":[],"sources":["../../src/styles/field-manual.styles.ts","../../node_modules/.pnpm/@fontsource+ibm-plex-mono@5.2.7/node_modules/@fontsource/ibm-plex-mono/files/ibm-plex-mono-latin-500-normal.woff2?fellowship-font-url","../../node_modules/.pnpm/@fontsource+ibm-plex-mono@5.2.7/node_modules/@fontsource/ibm-plex-mono/files/ibm-plex-mono-latin-600-normal.woff2?fellowship-font-url","../../node_modules/.pnpm/@fontsource+ibm-plex-sans-condensed@5.2.8/node_modules/@fontsource/ibm-plex-sans-condensed/files/ibm-plex-sans-condensed-latin-400-normal.woff2?fellowship-font-url","../../node_modules/.pnpm/@fontsource+ibm-plex-sans-condensed@5.2.8/node_modules/@fontsource/ibm-plex-sans-condensed/files/ibm-plex-sans-condensed-latin-500-normal.woff2?fellowship-font-url","../../node_modules/.pnpm/@fontsource+ibm-plex-sans-condensed@5.2.8/node_modules/@fontsource/ibm-plex-sans-condensed/files/ibm-plex-sans-condensed-latin-600-normal.woff2?fellowship-font-url","../../node_modules/.pnpm/@fontsource+ibm-plex-sans-condensed@5.2.8/node_modules/@fontsource/ibm-plex-sans-condensed/files/ibm-plex-sans-condensed-latin-700-normal.woff2?fellowship-font-url","../../src/styles/field-manual-fonts.ts"],"sourcesContent":["import { css } from \"lit\";\n\n/** Shared internal aliases for the public Expedition Field Manual theme tokens. */\nexport const fieldManualStyles = css`\n :host {\n --_fellowship-field-canvas: var(--fellowship-field-canvas, #0b0f13);\n --_fellowship-field-surface: var(--fellowship-field-surface, #10161c);\n --_fellowship-field-surface-raised: var(--fellowship-field-surface-raised, #151c23);\n --_fellowship-field-inset: var(--fellowship-field-inset, #080c10);\n --_fellowship-field-ink: var(--fellowship-field-ink, #f1eee5);\n --_fellowship-field-muted: var(--fellowship-field-muted, #b7b4aa);\n --_fellowship-field-tertiary: var(--fellowship-field-tertiary, #858a8e);\n --_fellowship-field-border: var(\n --fellowship-field-border,\n rgb(241 238 229 / 10%)\n );\n --_fellowship-field-border-strong: var(\n --fellowship-field-border-strong,\n rgb(241 238 229 / 18%)\n );\n --_fellowship-field-accent: var(--fellowship-field-accent, #69c4d4);\n --_fellowship-field-focus: var(--fellowship-field-focus, #a8e6ee);\n --_fellowship-field-ember: var(--fellowship-field-ember, #d9784c);\n --_fellowship-field-brass: var(--fellowship-field-brass, #c1a36a);\n --_fellowship-field-font-family: var(\n --fellowship-field-font-family,\n \"Fellowship Field\",\n \"Arial Narrow\",\n sans-serif\n );\n --_fellowship-field-mono-font-family: var(\n --fellowship-field-mono-font-family,\n \"Fellowship Tactical\",\n ui-monospace,\n monospace\n );\n --_fellowship-field-radius: var(--fellowship-field-radius, 6px);\n }\n`;\n","export default import.meta.ROLLUP_FILE_URL_FKNdLzKnlftW3t_gzo81yw;","export default import.meta.ROLLUP_FILE_URL_P4DPfwIRieI8P6q8r4JZRw;","export default import.meta.ROLLUP_FILE_URL_WPGYjwIlzWVNM1bYhOc83w;","export default import.meta.ROLLUP_FILE_URL_cn7IAAGY294pWGc7MpElVg;","export default import.meta.ROLLUP_FILE_URL_8HSUfh7cJHNFxCkInNzNXw;","export default import.meta.ROLLUP_FILE_URL_VRAku6fjghkApIISiBWPzg;","import mono500Url from \"@fontsource/ibm-plex-mono/files/ibm-plex-mono-latin-500-normal.woff2?url\";\nimport mono600Url from \"@fontsource/ibm-plex-mono/files/ibm-plex-mono-latin-600-normal.woff2?url\";\nimport field400Url from \"@fontsource/ibm-plex-sans-condensed/files/ibm-plex-sans-condensed-latin-400-normal.woff2?url\";\nimport field500Url from \"@fontsource/ibm-plex-sans-condensed/files/ibm-plex-sans-condensed-latin-500-normal.woff2?url\";\nimport field600Url from \"@fontsource/ibm-plex-sans-condensed/files/ibm-plex-sans-condensed-latin-600-normal.woff2?url\";\nimport field700Url from \"@fontsource/ibm-plex-sans-condensed/files/ibm-plex-sans-condensed-latin-700-normal.woff2?url\";\n\ninterface FieldManualFontAsset {\n readonly family: \"Fellowship Field\" | \"Fellowship Tactical\";\n readonly weight: \"400\" | \"500\" | \"600\" | \"700\";\n readonly url: string;\n}\n\nconst fieldManualFontAssets: readonly FieldManualFontAsset[] = [\n { family: \"Fellowship Field\", weight: \"400\", url: field400Url },\n { family: \"Fellowship Field\", weight: \"500\", url: field500Url },\n { family: \"Fellowship Field\", weight: \"600\", url: field600Url },\n { family: \"Fellowship Field\", weight: \"700\", url: field700Url },\n { family: \"Fellowship Tactical\", weight: \"500\", url: mono500Url },\n { family: \"Fellowship Tactical\", weight: \"600\", url: mono600Url },\n];\n\nconst installedDocuments = new WeakSet<Document>();\n\n/** Makes the bundled field-manual faces available to a component's owner document. */\nexport const installFieldManualFonts = (document: Document): void => {\n if (installedDocuments.has(document)) {\n return;\n }\n\n const FontFaceConstructor = document.defaultView?.FontFace;\n if (!FontFaceConstructor || !document.fonts) {\n return;\n }\n\n const faces = fieldManualFontAssets.map(\n ({ family, weight, url }) =>\n new FontFaceConstructor(family, `url(${JSON.stringify(url)}) format(\"woff2\")`, {\n display: \"swap\",\n style: \"normal\",\n weight,\n }),\n );\n for (const face of faces) {\n document.fonts.add(face);\n }\n installedDocuments.add(document);\n};\n"],"x_google_ignoreList":[1,2,3,4,5,6],"mappings":";;AAGA,IAAa,IAAoB,CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GCHpC,IAAA,IAAA,IAAA,2DAAA,OAAA,KAAA,GAAA,CAAA,CAAA,MCAA,IAAA,IAAA,IAAA,2DAAA,OAAA,KAAA,GAAA,CAAA,CAAA,MCAA,IAAA,IAAA,IAAA,qEAAA,OAAA,KAAA,GAAA,CAAA,CAAA,MCAA,IAAA,IAAA,IAAA,qEAAA,OAAA,KAAA,GAAA,CAAA,CAAA,MCAA,IAAA,IAAA,IAAA,qEAAA,OAAA,KAAA,GAAA,CAAA,CAAA,MCAA,IAAA,IAAA,IAAA,qEAAA,OAAA,KAAA,GAAA,CAAA,CAAA,MCaM,IAAyD;CAC7D;EAAE,QAAQ;EAAoB,QAAQ;EAAO,KAAK;CAAY;CAC9D;EAAE,QAAQ;EAAoB,QAAQ;EAAO,KAAK;CAAY;CAC9D;EAAE,QAAQ;EAAoB,QAAQ;EAAO,KAAK;CAAY;CAC9D;EAAE,QAAQ;EAAoB,QAAQ;EAAO,KAAK;CAAY;CAC9D;EAAE,QAAQ;EAAuB,QAAQ;EAAO,KAAK;CAAW;CAChE;EAAE,QAAQ;EAAuB,QAAQ;EAAO,KAAK;CAAW;AAClE,GAEM,oBAAqB,IAAI,QAAkB,GAGpC,KAA2B,MAA6B;CACnE,IAAI,EAAmB,IAAI,CAAQ,GACjC;CAGF,IAAM,IAAsB,EAAS,aAAa;CAClD,IAAI,CAAC,KAAuB,CAAC,EAAS,OACpC;CAGF,IAAM,IAAQ,EAAsB,KACjC,EAAE,WAAQ,WAAQ,aACjB,IAAI,EAAoB,GAAQ,OAAO,KAAK,UAAU,CAAG,EAAE,oBAAoB;EAC7E,SAAS;EACT,OAAO;EACP;CACF,CAAC,CACL;CACA,KAAK,IAAM,KAAQ,GACjB,EAAS,MAAM,IAAI,CAAI;CAEzB,EAAmB,IAAI,CAAQ;AACjC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dungeon-cast-browser-CSnu3gC5.js","names":["#abortController","#loadDungeonCasts","#renderStatus","#visibleEnemies","#handleSearch","#renderEnemy","#renderEmptySearch","#loadToken","#sameIdentity","#renderCast","#selectCast","#handleCastKeydown","#handleAbilityImageError","#statusCard"],"sources":["../../src/data/package-cast-data-source.ts","../../src/dungeon-cast-browser/dungeon-cast-browser.styles.ts","../../src/dungeon-cast-browser/render-model.ts","../../src/dungeon-cast-browser/dungeon-cast-browser.ts"],"sourcesContent":["import { createPackageFellowshipDataClient } from \"@crockery/fellowship-data/client\";\n\nimport type { FellowshipCastDataSource } from \"./cast-data-source.js\";\n\n/** @deprecated Create a package Fellowship data client instead. */\nexport interface PackageFellowshipCastDataSourceOptions {\n readonly assetBaseUrl?: string;\n}\n\n/** @deprecated Use `createPackageFellowshipDataClient` from `@crockery/fellowship-data/client`. */\nexport const createPackageFellowshipCastDataSource = (\n options: PackageFellowshipCastDataSourceOptions = {},\n): FellowshipCastDataSource => {\n const client = createPackageFellowshipDataClient(options);\n return {\n loadDungeonCasts: (dungeonId, signal) => client.loadDungeonCasts(dungeonId, signal),\n resolveAssetUrl: (asset) => client.resolveAssetUrl(asset),\n };\n};\n","import { css } from \"lit\";\n\nexport const dungeonCastBrowserStyles = css`\n :host {\n --fellowship-cast-canvas: var(--_fellowship-field-canvas);\n --fellowship-cast-surface: var(--_fellowship-field-surface);\n --fellowship-cast-raised: var(--_fellowship-field-surface-raised);\n --fellowship-cast-ink: var(--_fellowship-field-ink);\n --fellowship-cast-muted: var(--_fellowship-field-muted);\n --fellowship-cast-tertiary: var(--_fellowship-field-tertiary);\n --fellowship-cast-border: var(--_fellowship-field-border);\n --fellowship-cast-border-strong: var(--_fellowship-field-border-strong);\n --fellowship-cast-interrupt: var(--_fellowship-field-accent);\n --fellowship-cast-stop: var(--_fellowship-field-brass);\n --fellowship-cast-focus: var(--_fellowship-field-focus);\n --fellowship-cast-font-family: var(--_fellowship-field-font-family);\n --fellowship-cast-tactical-font-family: var(--_fellowship-field-mono-font-family);\n\n display: block;\n inline-size: 100%;\n min-block-size: 320px;\n color: var(--fellowship-cast-ink);\n font-family: var(--fellowship-cast-font-family);\n container-type: inline-size;\n -webkit-font-smoothing: antialiased;\n }\n\n :host([hidden]) {\n display: none;\n }\n\n :host([fill]) {\n min-block-size: 0;\n block-size: 100%;\n overflow: hidden;\n }\n\n *,\n *::before,\n *::after {\n box-sizing: border-box;\n }\n\n .browser {\n min-block-size: inherit;\n overflow: hidden;\n border: 1px solid var(--fellowship-cast-border);\n border-radius: calc(var(--_fellowship-field-radius) + 2px);\n background: var(--fellowship-cast-canvas);\n }\n\n :host([fill]) .browser {\n display: grid;\n grid-template-rows: auto minmax(0, 1fr);\n min-block-size: 0;\n block-size: 100%;\n }\n\n .toolbar {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n gap: 12px;\n align-items: end;\n padding: 16px;\n border-block-end: 1px solid var(--fellowship-cast-border);\n background: var(--fellowship-cast-surface);\n }\n\n .eyebrow,\n .summary,\n .enemy-id,\n .ability-id,\n .capability,\n .marker {\n font-family: var(--fellowship-cast-tactical-font-family);\n }\n\n .eyebrow {\n margin: 0 0 4px;\n color: var(--fellowship-cast-interrupt);\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.12em;\n text-transform: uppercase;\n }\n\n h2 {\n margin: 0;\n font-size: clamp(18px, 3cqi, 24px);\n font-weight: 600;\n letter-spacing: 0.01em;\n line-height: 1.08;\n }\n\n .summary {\n margin: 6px 0 0;\n color: var(--fellowship-cast-tertiary);\n font-size: 11px;\n font-variant-numeric: tabular-nums;\n letter-spacing: 0.04em;\n }\n\n .search-label {\n display: grid;\n gap: 4px;\n min-inline-size: min(240px, 38cqi);\n color: var(--fellowship-cast-muted);\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.04em;\n }\n\n .search-input {\n min-block-size: 44px;\n inline-size: 100%;\n border: 1px solid var(--fellowship-cast-border-strong);\n border-radius: var(--_fellowship-field-radius);\n background: var(--_fellowship-field-inset);\n color: var(--fellowship-cast-ink);\n font: inherit;\n font-size: 14px;\n padding-inline: 12px;\n }\n\n .search-input::placeholder {\n color: var(--fellowship-cast-tertiary);\n }\n\n .search-input:focus-visible,\n .cast-row:focus-visible,\n .retry-button:focus-visible {\n outline: 2px solid var(--fellowship-cast-focus);\n outline-offset: 2px;\n }\n\n .enemy-list {\n display: grid;\n }\n\n :host([fill]) .enemy-list {\n min-block-size: 0;\n align-content: start;\n overflow-y: auto;\n overscroll-behavior: contain;\n }\n\n .enemy {\n min-inline-size: 0;\n border-block-end: 1px solid var(--fellowship-cast-border);\n }\n\n .enemy:last-child {\n border-block-end: 0;\n }\n\n .enemy-header {\n display: grid;\n grid-template-columns: 4px minmax(0, 1fr) auto;\n gap: 12px;\n align-items: center;\n min-block-size: 52px;\n padding: 8px 16px;\n background: color-mix(in srgb, var(--fellowship-cast-raised) 72%, transparent);\n }\n\n .enemy-rule {\n align-self: stretch;\n background: var(--fellowship-cast-interrupt);\n }\n\n .enemy-name {\n overflow: hidden;\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n line-height: 1.15;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .enemy-id {\n overflow: hidden;\n margin: 3px 0 0;\n color: var(--fellowship-cast-tertiary);\n font-size: 10px;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .enemy-count {\n color: var(--fellowship-cast-muted);\n font-family: var(--fellowship-cast-tactical-font-family);\n font-size: 10px;\n font-variant-numeric: tabular-nums;\n }\n\n .cast-list {\n display: grid;\n margin: 0;\n padding: 0;\n list-style: none;\n }\n\n .cast-list > li + li {\n border-block-start: 1px solid var(--fellowship-cast-border);\n }\n\n .cast-row {\n position: relative;\n display: grid;\n grid-template-columns: 40px minmax(0, 1fr) auto auto;\n gap: 12px;\n align-items: center;\n inline-size: 100%;\n min-block-size: 64px;\n padding: 8px 16px 8px 28px;\n border: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: start;\n cursor: pointer;\n transition: background-color 140ms cubic-bezier(0.23, 1, 0.32, 1);\n }\n\n .cast-row:not(:disabled):hover {\n background: color-mix(in srgb, var(--fellowship-cast-interrupt) 7%, transparent);\n }\n\n .cast-row[aria-pressed=\"true\"] {\n background: color-mix(in srgb, var(--fellowship-cast-interrupt) 11%, transparent);\n }\n\n .cast-row[aria-pressed=\"true\"]::before {\n position: absolute;\n inset: 12px auto 12px 0;\n inline-size: 3px;\n background: var(--fellowship-cast-interrupt);\n content: \"\";\n }\n\n .cast-row:disabled {\n color: var(--fellowship-cast-tertiary);\n cursor: not-allowed;\n }\n\n .ability-image,\n .ability-fallback {\n inline-size: 40px;\n block-size: 40px;\n border: 1px solid var(--fellowship-cast-border-strong);\n border-radius: 4px;\n background: var(--fellowship-cast-raised);\n }\n\n .ability-image {\n display: block;\n object-fit: cover;\n }\n\n .ability-fallback {\n display: grid;\n place-items: center;\n color: var(--fellowship-cast-muted);\n font-family: var(--fellowship-cast-tactical-font-family);\n font-size: 11px;\n font-weight: 600;\n }\n\n .ability-image[hidden],\n .ability-fallback[hidden] {\n display: none;\n }\n\n .ability-copy {\n min-inline-size: 0;\n }\n\n .ability-name {\n display: block;\n overflow: hidden;\n font-size: 14px;\n font-weight: 600;\n line-height: 1.15;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .ability-id {\n display: block;\n overflow: hidden;\n margin-block-start: 4px;\n color: var(--fellowship-cast-tertiary);\n font-size: 10px;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .capability {\n min-inline-size: 102px;\n padding: 5px 8px;\n border: 1px solid currentColor;\n border-radius: 999px;\n color: var(--fellowship-cast-interrupt);\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.04em;\n text-align: center;\n white-space: nowrap;\n }\n\n .capability[data-kind=\"varies\"] {\n border-style: dashed;\n }\n\n .capability[data-kind=\"stop\"] {\n color: var(--fellowship-cast-stop);\n }\n\n .capability[data-kind=\"none\"] {\n color: var(--fellowship-cast-tertiary);\n }\n\n .marker {\n min-inline-size: 72px;\n color: var(--fellowship-cast-stop);\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.06em;\n text-align: end;\n text-transform: uppercase;\n }\n\n .marker[data-empty=\"true\"] {\n visibility: hidden;\n }\n\n .status {\n display: grid;\n min-block-size: 280px;\n padding: 32px;\n place-items: center;\n text-align: center;\n }\n\n :host([fill]) .status {\n min-block-size: 0;\n }\n\n .status-card {\n display: grid;\n max-inline-size: 360px;\n gap: 8px;\n justify-items: center;\n }\n\n .status-mark {\n inline-size: 32px;\n block-size: 4px;\n margin-block-end: 8px;\n background: var(--fellowship-cast-interrupt);\n }\n\n .status-title {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n }\n\n .status-copy {\n margin: 0;\n color: var(--fellowship-cast-muted);\n font-size: 14px;\n line-height: 1.45;\n }\n\n .retry-button {\n min-block-size: 44px;\n margin-block-start: 8px;\n padding-inline: 16px;\n border: 1px solid var(--fellowship-cast-interrupt);\n border-radius: var(--_fellowship-field-radius);\n background: transparent;\n color: var(--fellowship-cast-ink);\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n }\n\n @container (max-width: 560px) {\n .toolbar {\n grid-template-columns: 1fr;\n }\n\n .search-label {\n min-inline-size: 0;\n }\n\n .cast-row {\n grid-template-columns: 40px minmax(0, 1fr) auto;\n padding-inline: 16px;\n }\n\n .marker {\n position: absolute;\n inset: 5px 8px auto auto;\n min-inline-size: 0;\n font-size: 8px;\n }\n\n .ability-id,\n .enemy-id {\n display: none;\n }\n\n .capability {\n min-inline-size: 0;\n padding-inline: 6px;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .cast-row {\n transition: none;\n }\n }\n`;\n","import type { Ability, ImageAssetRef } from \"@crockery/fellowship-data\";\n\nimport type { DungeonCastData, FellowshipCastDataSource } from \"../data/cast-data-source.js\";\nimport type {\n CastCapabilityLabel,\n DungeonCastBrowserModel,\n DungeonCastEnemyModel,\n DungeonCastModel,\n FellowshipCastIdentity,\n} from \"./types.js\";\n\nexport const castIdentityKey = ({ enemyId, abilityId }: FellowshipCastIdentity): string =>\n `${enemyId}\\u0000${abilityId}`;\n\nconst abilityImage = (ability: Ability): ImageAssetRef | null =>\n ability.images.find(({ size }) => size === \"200\") ?? ability.images[0] ?? null;\n\nconst capabilityLabel = (\n canInterrupt: boolean,\n interruptVaries: boolean,\n canStop: boolean,\n): CastCapabilityLabel => {\n if (interruptVaries) return \"Interrupt varies\";\n if (canInterrupt) return \"Interrupt\";\n if (canStop) return \"Stop\";\n return \"No response\";\n};\n\nexport const createDungeonCastBrowserModel = (\n data: DungeonCastData,\n source: FellowshipCastDataSource,\n): DungeonCastBrowserModel => {\n const seenEnemyIds = new Set<string>();\n const enemies: DungeonCastEnemyModel[] = [];\n\n for (const placement of data.dungeon.enemies) {\n if (seenEnemyIds.has(placement.id)) continue;\n seenEnemyIds.add(placement.id);\n\n const enemy = data.enemies.get(placement.id);\n if (!enemy) continue;\n\n const casts: DungeonCastModel[] = (data.abilitiesByEnemy.get(enemy.id) ?? [])\n .filter((ability) => ability.castInterruptibility !== undefined)\n .map((ability) => {\n const canInterrupt = ability.castInterruptibility !== \"never\";\n const interruptVaries = ability.castInterruptibility === \"sometimes\";\n const canStop = enemy.canBeControlled;\n const image = abilityImage(ability);\n let imageUrl: string | null = null;\n if (image) {\n try {\n imageUrl = source.resolveAssetUrl(image);\n } catch {\n imageUrl = null;\n }\n }\n return {\n identity: { enemyId: enemy.id, abilityId: ability.id },\n ability,\n enemy,\n canInterrupt,\n interruptVaries,\n canStop,\n actionable: canInterrupt || canStop,\n capabilityLabel: capabilityLabel(canInterrupt, interruptVaries, canStop),\n imageUrl,\n };\n });\n\n if (casts.some(({ actionable }) => actionable)) enemies.push({ enemy, casts });\n }\n\n return {\n dungeon: data.dungeon,\n enemies,\n castCount: enemies.reduce((total, enemy) => total + enemy.casts.length, 0),\n };\n};\n","import { html, LitElement, nothing, type PropertyValues, type TemplateResult } from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { repeat } from \"lit/directives/repeat.js\";\n\nimport type { FellowshipCastDataSource } from \"../data/cast-data-source.js\";\nimport { assertSupportedFellowshipDataSchema, FellowshipDataError } from \"../data/data-source.js\";\nimport { createPackageFellowshipCastDataSource } from \"../data/package-cast-data-source.js\";\nimport { installFieldManualFonts } from \"../styles/field-manual-fonts.js\";\nimport { fieldManualStyles } from \"../styles/field-manual.styles.js\";\nimport { dungeonCastBrowserStyles } from \"./dungeon-cast-browser.styles.js\";\nimport { castIdentityKey, createDungeonCastBrowserModel } from \"./render-model.js\";\nimport type {\n ConfiguredCastFilter,\n DungeonCastBrowserModel,\n DungeonCastEnemyModel,\n DungeonCastModel,\n FellowshipCastBrowserErrorDetail,\n FellowshipCastBrowserReadyDetail,\n FellowshipCastIdentity,\n FellowshipCastSelectedDetail,\n} from \"./types.js\";\n\ntype ComponentStatus = \"empty\" | \"loading\" | \"ready\" | \"error\";\n\nconst eventOptions = { bubbles: true, composed: true } as const;\n\n/**\n * @fires fellowship-cast-browser-ready - Fired after dungeon casts have been loaded and joined.\n * @fires fellowship-cast-browser-error - Fired when dungeon cast data cannot be loaded.\n * @fires fellowship-cast-selected - Fired when a user selects an actionable cast.\n */\n@customElement(\"fellowship-dungeon-cast-browser\")\nexport class FellowshipDungeonCastBrowserElement extends LitElement {\n static override styles = [fieldManualStyles, dungeonCastBrowserStyles];\n\n @property({ type: String, attribute: \"dungeon-id\" }) dungeonId = \"\";\n @property({ attribute: false }) selectedCast: FellowshipCastIdentity | null = null;\n @property({ attribute: false }) configuredCasts: readonly FellowshipCastIdentity[] = [];\n @property({ type: String, attribute: \"configured-filter\" })\n configuredFilter: ConfiguredCastFilter = \"all\";\n @property({ type: Boolean, reflect: true }) fill = false;\n @property({ type: String, attribute: \"asset-base-url\" }) assetBaseUrl: string | null = null;\n @property({ attribute: false }) dataSource: FellowshipCastDataSource | null = null;\n\n @state() private _status: ComponentStatus = \"empty\";\n @state() private _error: FellowshipCastBrowserErrorDetail | null = null;\n @state() private _model: DungeonCastBrowserModel | null = null;\n @state() private _query = \"\";\n\n #abortController: AbortController | null = null;\n #loadToken = 0;\n\n override connectedCallback(): void {\n super.connectedCallback();\n installFieldManualFonts(this.ownerDocument);\n }\n\n override disconnectedCallback(): void {\n this.#abortController?.abort();\n super.disconnectedCallback();\n }\n\n protected override updated(changed: PropertyValues<this>): void {\n super.updated(changed);\n if (changed.has(\"dungeonId\") || changed.has(\"dataSource\") || changed.has(\"assetBaseUrl\")) {\n queueMicrotask(() => {\n if (this.isConnected) void this.#loadDungeonCasts();\n });\n }\n }\n\n retry(): void {\n void this.#loadDungeonCasts();\n }\n\n get renderModel(): DungeonCastBrowserModel | null {\n return this._model;\n }\n\n override render(): TemplateResult {\n if (this._status !== \"ready\" || !this._model) {\n return html`<section class=\"browser\" aria-label=\"Dungeon cast browser\">${this.#renderStatus()}</section>`;\n }\n\n const visibleEnemies = this.#visibleEnemies(this._model);\n return html`\n <section class=\"browser\" aria-label=${`${this._model.dungeon.name ?? this._model.dungeon.id} casts`}>\n <header class=\"toolbar\" part=\"toolbar\">\n <div>\n <p class=\"eyebrow\">Dungeon cast index</p>\n <h2>${this._model.dungeon.name ?? this._model.dungeon.id}</h2>\n <p class=\"summary\">\n ${this._model.enemies.length} enemies · ${this._model.castCount} cast-bearing abilities\n </p>\n </div>\n <label class=\"search-label\">\n Search casts\n <input\n class=\"search-input\"\n type=\"search\"\n placeholder=\"Enemy or ability\"\n .value=${this._query}\n @input=${this.#handleSearch}\n />\n </label>\n </header>\n ${\n visibleEnemies.length > 0\n ? html`<div class=\"enemy-list\" part=\"enemy-list\">${repeat(\n visibleEnemies,\n ({ enemy }) => enemy.id,\n (enemy) => this.#renderEnemy(enemy),\n )}</div>`\n : this.#renderEmptySearch()\n }\n </section>\n `;\n }\n\n async #loadDungeonCasts(): Promise<void> {\n const dungeonId = this.dungeonId.trim();\n const token = ++this.#loadToken;\n this.#abortController?.abort();\n this.#abortController = new AbortController();\n this._model = null;\n this._error = null;\n this._query = \"\";\n\n if (!dungeonId) {\n this._status = \"empty\";\n return;\n }\n\n this._status = \"loading\";\n const source =\n this.dataSource ??\n createPackageFellowshipCastDataSource(\n this.assetBaseUrl ? { assetBaseUrl: this.assetBaseUrl } : {},\n );\n\n try {\n const data = await source.loadDungeonCasts(dungeonId, this.#abortController.signal);\n if (token !== this.#loadToken || this.#abortController.signal.aborted) return;\n assertSupportedFellowshipDataSchema(data.manifest.schemaVersion);\n const model = createDungeonCastBrowserModel(data, source);\n this._model = model;\n this._status = \"ready\";\n this.dispatchEvent(\n new CustomEvent<FellowshipCastBrowserReadyDetail>(\"fellowship-cast-browser-ready\", {\n ...eventOptions,\n detail: { model, data },\n }),\n );\n } catch (error: unknown) {\n if (token !== this.#loadToken || this.#abortController.signal.aborted) return;\n const detail: FellowshipCastBrowserErrorDetail = {\n code:\n error instanceof FellowshipDataError\n ? error.code\n : ((error as { code?: string }).code ?? \"data-load-failed\"),\n message: error instanceof Error ? error.message : String(error),\n ...(error instanceof Error && error.cause !== undefined ? { cause: error.cause } : {}),\n };\n this._error = detail;\n this._status = \"error\";\n this.dispatchEvent(\n new CustomEvent<FellowshipCastBrowserErrorDetail>(\"fellowship-cast-browser-error\", {\n ...eventOptions,\n detail,\n }),\n );\n }\n }\n\n #visibleEnemies(model: DungeonCastBrowserModel): readonly DungeonCastEnemyModel[] {\n const query = this._query.trim().toLocaleLowerCase();\n const configuredFilter =\n this.configuredFilter === \"configured\" || this.configuredFilter === \"unconfigured\"\n ? this.configuredFilter\n : \"all\";\n return model.enemies.flatMap((enemy) => {\n const enemyMatches = `${enemy.enemy.name ?? \"\"} ${enemy.enemy.id}`\n .toLocaleLowerCase()\n .includes(query);\n const casts = enemy.casts.filter((cast) => {\n const queryMatches =\n !query ||\n enemyMatches ||\n `${cast.ability.name ?? \"\"} ${cast.ability.id}`.toLocaleLowerCase().includes(query);\n if (!queryMatches) return false;\n const configured = this.configuredCasts.some((identity) =>\n this.#sameIdentity(identity, cast.identity),\n );\n return (\n configuredFilter === \"all\" ||\n (configuredFilter === \"configured\" && configured) ||\n (configuredFilter === \"unconfigured\" && !configured)\n );\n });\n return casts.length > 0 ? [{ ...enemy, casts }] : [];\n });\n }\n\n #renderEnemy(model: DungeonCastEnemyModel): TemplateResult {\n return html`\n <article class=\"enemy\" part=\"enemy\">\n <header class=\"enemy-header\" part=\"enemy-header\">\n <span class=\"enemy-rule\" aria-hidden=\"true\"></span>\n <div>\n <h3 class=\"enemy-name\">${model.enemy.name ?? model.enemy.id}</h3>\n <p class=\"enemy-id\">${model.enemy.id}</p>\n </div>\n <span class=\"enemy-count\">${model.casts.length} ${model.casts.length === 1 ? \"cast\" : \"casts\"}</span>\n </header>\n <ul class=\"cast-list\">\n ${repeat(\n model.casts,\n ({ identity }) => castIdentityKey(identity),\n (cast) => html`<li>${this.#renderCast(cast)}</li>`,\n )}\n </ul>\n </article>\n `;\n }\n\n #renderCast(cast: DungeonCastModel): TemplateResult {\n const selected = this.#sameIdentity(this.selectedCast, cast.identity);\n const configured = this.configuredCasts.some((identity) =>\n this.#sameIdentity(identity, cast.identity),\n );\n const capabilityKind = cast.interruptVaries\n ? \"varies\"\n : cast.canInterrupt\n ? \"interrupt\"\n : cast.canStop\n ? \"stop\"\n : \"none\";\n const fallback = (cast.ability.name ?? cast.ability.id)\n .split(/\\s+/)\n .map((part) => part[0])\n .join(\"\")\n .slice(0, 2)\n .toUpperCase();\n\n return html`\n <button\n class=\"cast-row\"\n part=\"cast\"\n type=\"button\"\n ?disabled=${!cast.actionable}\n aria-pressed=${String(selected)}\n data-configured=${String(configured)}\n @click=${() => this.#selectCast(cast)}\n @keydown=${this.#handleCastKeydown}\n >\n ${\n cast.imageUrl\n ? html`<img\n class=\"ability-image\"\n part=\"cast-icon\"\n src=${cast.imageUrl}\n alt=\"\"\n @error=${this.#handleAbilityImageError}\n /><span\n class=\"ability-fallback\"\n part=\"cast-icon-fallback\"\n aria-hidden=\"true\"\n hidden\n >${fallback}</span\n >`\n : html`<span class=\"ability-fallback\" part=\"cast-icon-fallback\" aria-hidden=\"true\">${fallback}</span>`\n }\n <span class=\"ability-copy\">\n <span class=\"ability-name\">${cast.ability.name ?? cast.ability.id}</span>\n <span class=\"ability-id\">${cast.ability.id}</span>\n </span>\n <span class=\"capability\" data-kind=${capabilityKind}>${cast.capabilityLabel}</span>\n <span class=\"marker\" data-empty=${String(!configured)}>${configured ? \"Configured\" : nothing}</span>\n </button>\n `;\n }\n\n #renderStatus(): TemplateResult {\n if (this._status === \"loading\") {\n return this.#statusCard(\n \"Loading cast index\",\n \"Joining dungeon enemies with their cast data.\",\n );\n }\n if (this._status === \"error\") {\n return html`\n <div class=\"status\" role=\"alert\">\n <div class=\"status-card\">\n <span class=\"status-mark\" aria-hidden=\"true\"></span>\n <h2 class=\"status-title\">Cast data unavailable</h2>\n <p class=\"status-copy\">${this._error?.message ?? \"The dungeon cast index could not be loaded.\"}</p>\n <button class=\"retry-button\" type=\"button\" @click=${this.retry}>Retry</button>\n </div>\n </div>\n `;\n }\n if (this._status === \"ready\") {\n return this.#statusCard(\n \"No actionable casts\",\n \"This dungeon has no enemies with casts that can be interrupted or stopped.\",\n );\n }\n return this.#statusCard(\"Select a dungeon\", \"Choose a dungeon to inspect enemy casts.\");\n }\n\n #renderEmptySearch(): TemplateResult {\n return this.#statusCard(\n \"No matching casts\",\n `No enemy or ability matches “${this._query.trim()}”.`,\n );\n }\n\n #statusCard(title: string, copy: string): TemplateResult {\n return html`\n <div class=\"status\">\n <div class=\"status-card\">\n <span class=\"status-mark\" aria-hidden=\"true\"></span>\n <h2 class=\"status-title\">${title}</h2>\n <p class=\"status-copy\">${copy}</p>\n </div>\n </div>\n `;\n }\n\n #sameIdentity(left: FellowshipCastIdentity | null, right: FellowshipCastIdentity): boolean {\n return left?.enemyId === right.enemyId && left.abilityId === right.abilityId;\n }\n\n #selectCast(cast: DungeonCastModel): void {\n if (!cast.actionable) return;\n this.dispatchEvent(\n new CustomEvent<FellowshipCastSelectedDetail>(\"fellowship-cast-selected\", {\n ...eventOptions,\n detail: { cast },\n }),\n );\n }\n\n #handleSearch = (event: InputEvent): void => {\n this._query = (event.currentTarget as HTMLInputElement).value;\n };\n\n #handleAbilityImageError = (event: Event): void => {\n const image = event.currentTarget as HTMLImageElement;\n image.hidden = true;\n const fallback = image.nextElementSibling;\n if (fallback instanceof HTMLElement) fallback.hidden = false;\n };\n\n #handleCastKeydown = (event: KeyboardEvent): void => {\n const movement =\n event.key === \"ArrowDown\" || event.key === \"ArrowRight\"\n ? 1\n : event.key === \"ArrowUp\" || event.key === \"ArrowLeft\"\n ? -1\n : 0;\n if (movement === 0 && event.key !== \"Home\" && event.key !== \"End\") return;\n const buttons = [\n ...this.renderRoot.querySelectorAll<HTMLButtonElement>(\".cast-row:not(:disabled)\"),\n ];\n if (buttons.length === 0) return;\n const current = buttons.indexOf(event.currentTarget as HTMLButtonElement);\n const nextIndex =\n event.key === \"Home\"\n ? 0\n : event.key === \"End\"\n ? buttons.length - 1\n : (current + movement + buttons.length) % buttons.length;\n buttons[nextIndex]?.focus();\n event.preventDefault();\n };\n}\n\nexport const defineFellowshipDungeonCastBrowser = (): void => {\n if (\n typeof globalThis.customElements !== \"undefined\" &&\n !globalThis.customElements.get(\"fellowship-dungeon-cast-browser\")\n ) {\n globalThis.customElements.define(\n \"fellowship-dungeon-cast-browser\",\n FellowshipDungeonCastBrowserElement,\n );\n }\n};\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"fellowship-dungeon-cast-browser\": FellowshipDungeonCastBrowserElement;\n }\n}\n"],"mappings":"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"}
|