@crockery/fellowship-components 0.4.1 → 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 +38 -22
- package/RELEASING.md +2 -2
- package/THIRD_PARTY_LICENSES.md +12 -0
- package/dist/assets/dm-mono-latin-400-normal-4GdczIuU.woff2 +0 -0
- package/dist/assets/dm-mono-latin-500-normal-DRMDZjhP.woff2 +0 -0
- package/dist/assets/syne-latin-700-normal-AF3Rs61n.woff2 +0 -0
- package/dist/assets/syne-latin-800-normal-EehdNYzx.woff2 +0 -0
- package/dist/chunks/decorate-DyMgX_Uh.js +9 -0
- package/dist/chunks/{dungeon-cast-browser-CSnu3gC5.js → dungeon-cast-browser-DdG8klca.js} +62 -58
- package/dist/chunks/{dungeon-map-CutIcCVP.js → dungeon-map-D0-DAjZ9.js} +130 -131
- package/dist/chunks/{decorate-B_ZTN9li.js → field-manual-fonts-DTFloVFe.js} +18 -23
- package/dist/chunks/gear-planner-uQOpm4QI.js +1701 -0
- package/dist/chunks/{talent-calculator-Dxuc2dZ8.js → talent-calculator-DbU6P1AP.js} +36 -35
- package/dist/chunks/tooltip-C3SSJw-t.js +482 -0
- package/dist/data/cast-data-source.d.ts +1 -1
- package/dist/data/data-source.d.ts +1 -1
- package/dist/data/package-cast-data-source.d.ts +1 -5
- package/dist/data/package-data-source.d.ts +1 -5
- package/dist/data/package-talent-data-source.d.ts +1 -5
- package/dist/data/talent-data-source.d.ts +1 -1
- package/dist/dungeon-cast-browser/dungeon-cast-browser.d.ts +2 -1
- package/dist/dungeon-cast-browser/render-model.d.ts +3 -2
- package/dist/dungeon-cast-browser/types.d.ts +2 -2
- package/dist/dungeon-cast-browser.js +1 -1
- package/dist/dungeon-map/dungeon-map.d.ts +2 -1
- package/dist/dungeon-map/render-model.d.ts +3 -3
- package/dist/dungeon-map/types.d.ts +2 -2
- package/dist/dungeon-map.js +1 -1
- package/dist/gear-planner/gear-planner.d.ts +36 -0
- package/dist/gear-planner/gear-planner.styles.d.ts +1 -0
- package/dist/gear-planner/gear-position.d.ts +20 -0
- package/dist/gear-planner/index.d.ts +2 -0
- package/dist/gear-planner/item-workbench.d.ts +18 -0
- package/dist/gear-planner/item-workbench.styles.d.ts +1 -0
- package/dist/gear-planner/types.d.ts +24 -0
- package/dist/gear-planner.js +5 -0
- package/dist/index.d.ts +6 -5
- package/dist/index.js +9 -7
- package/dist/react/dungeon-cast-browser.d.ts +8 -3
- package/dist/react/dungeon-cast-browser.js +11 -4
- package/dist/react/dungeon-map.d.ts +3 -1
- package/dist/react/dungeon-map.js +1 -1
- package/dist/react/gear-planner.d.ts +14 -0
- package/dist/react/gear-planner.js +23 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react/talent-calculator.d.ts +3 -1
- package/dist/react/talent-calculator.js +1 -1
- package/dist/react/tooltip.js +1 -1
- package/dist/react.js +2 -1
- package/dist/styles/dungeon-poster-fonts.d.ts +2 -0
- package/dist/styles/dungeon-poster.styles.d.ts +7 -0
- package/dist/talent-calculator/render-model.d.ts +3 -2
- package/dist/talent-calculator/talent-calculator.d.ts +2 -1
- package/dist/talent-calculator/types.d.ts +2 -2
- package/dist/talent-calculator.js +1 -1
- package/dist/tooltip.js +3 -3
- package/package.json +15 -4
- package/src/dungeon-cast-browser/README.md +10 -4
- package/src/dungeon-map/README.md +5 -6
- package/src/gear-planner/README.md +44 -0
- package/src/talent-calculator/README.md +5 -6
- package/src/tooltip/README.md +5 -6
- package/dist/chunks/data-source-XbksqUrw.js +0 -7
- package/dist/chunks/tooltip-DoQVSnOn.js +0 -410
|
@@ -66,10 +66,11 @@ map loading, canvas drawing, positioning, and viewport interactions.
|
|
|
66
66
|
|
|
67
67
|
## Data and assets
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
Provide the application-owned image resolver separately from the data source:
|
|
70
70
|
|
|
71
71
|
```ts
|
|
72
|
-
map.
|
|
72
|
+
map.resolveAssetUrl = (asset) =>
|
|
73
|
+
new URL(asset.path, "https://static.example.com/fellowship/").href;
|
|
73
74
|
```
|
|
74
75
|
|
|
75
76
|
Replace `dataSource` for filtered, experimental, remote, or application-owned data:
|
|
@@ -83,9 +84,6 @@ const source: FellowshipDataSource = {
|
|
|
83
84
|
async loadDungeon(dungeonId, signal) {
|
|
84
85
|
return applicationData.loadDungeon(dungeonId, signal);
|
|
85
86
|
},
|
|
86
|
-
resolveAssetUrl(asset) {
|
|
87
|
-
return new URL(asset.path, "https://static.example.com/").href;
|
|
88
|
-
},
|
|
89
87
|
};
|
|
90
88
|
|
|
91
89
|
map.dataSource = source;
|
|
@@ -97,7 +95,8 @@ map.dataSource = source;
|
|
|
97
95
|
|
|
98
96
|
- `dungeonId: string`
|
|
99
97
|
- `mapImageId: string | null`
|
|
100
|
-
- `
|
|
98
|
+
- `resolveAssetUrl: ImageAssetUrlResolver` — required and assigned as a
|
|
99
|
+
JavaScript property.
|
|
101
100
|
- `dataSource: FellowshipDataSource | null` — `null` uses the package provider.
|
|
102
101
|
- `renderEnemy: LitEnemyRenderer | null`
|
|
103
102
|
- `renderGroup: LitGroupRenderer | null`
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Gear Planner
|
|
2
|
+
|
|
3
|
+
`<fellowship-gear-planner>` is a controlled, responsive editor for serializable
|
|
4
|
+
Fellowship loadouts.
|
|
5
|
+
|
|
6
|
+
```ts
|
|
7
|
+
import gearPlannerData, {
|
|
8
|
+
createEmptyGearPlannerBuild,
|
|
9
|
+
} from "@crockery/fellowship-data/gear-planner";
|
|
10
|
+
import "@crockery/fellowship-components/gear-planner";
|
|
11
|
+
|
|
12
|
+
const planner = document.querySelector("fellowship-gear-planner");
|
|
13
|
+
planner.data = gearPlannerData;
|
|
14
|
+
planner.build = createEmptyGearPlannerBuild(
|
|
15
|
+
gearPlannerData,
|
|
16
|
+
gearPlannerData.heroes[0].hero.id,
|
|
17
|
+
);
|
|
18
|
+
planner.resolveAssetUrl = (asset) =>
|
|
19
|
+
new URL(asset.path, "https://static.example.com/fellowship/").href;
|
|
20
|
+
planner.addEventListener("fellowship-gear-build-change", (event) => {
|
|
21
|
+
planner.build = event.detail.build;
|
|
22
|
+
});
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The element never persists or mutates `build`. Its public properties are
|
|
26
|
+
`data`, `build`, `loading`, `error`, and the required `resolveAssetUrl`
|
|
27
|
+
callback.
|
|
28
|
+
`fellowship-gear-build-change` bubbles and is composed; its detail includes the
|
|
29
|
+
complete proposed build, change source, and affected position.
|
|
30
|
+
`fellowship-gear-planner-error` reports recoverable presentation failures.
|
|
31
|
+
|
|
32
|
+
The React wrapper is exported from
|
|
33
|
+
`@crockery/fellowship-components/react/gear-planner` as `GearPlanner`, with
|
|
34
|
+
`onBuildChange` and `onPlannerError` event props.
|
|
35
|
+
|
|
36
|
+
At 1200px and above, the component renders summary and slot rails around a
|
|
37
|
+
persistent workbench. Below 1200px it uses Traits & gems, Gear, and Bonuses tabs,
|
|
38
|
+
with configuration in a full-height focus-contained editor. Item choices are
|
|
39
|
+
filtered by the Data package, all changes are immediate, and unsupported
|
|
40
|
+
mechanics remain visibly excluded from exact totals.
|
|
41
|
+
|
|
42
|
+
The planner uses the public `--fellowship-poster-*` Dungeon Poster tokens and
|
|
43
|
+
bundled Syne/DM Mono faces. It maintains 44px controls, visible focus, reduced
|
|
44
|
+
motion, canonical mobile position order, and accessible equipped-item tooltips.
|
|
@@ -102,22 +102,20 @@ continues to own button semantics and selection state.
|
|
|
102
102
|
|
|
103
103
|
## Data and assets
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
Provide an image resolver and optionally replace the data provider:
|
|
106
106
|
|
|
107
107
|
```ts
|
|
108
108
|
import type { FellowshipTalentDataSource } from "@crockery/fellowship-components/talent-calculator";
|
|
109
109
|
|
|
110
110
|
declare const applicationTalentData: FellowshipTalentDataSource;
|
|
111
111
|
|
|
112
|
-
calculator.
|
|
112
|
+
calculator.resolveAssetUrl = (asset) =>
|
|
113
|
+
new URL(asset.path, "https://static.example.com/fellowship/").href;
|
|
113
114
|
|
|
114
115
|
const source: FellowshipTalentDataSource = {
|
|
115
116
|
async loadHeroTalents(heroId, signal) {
|
|
116
117
|
return applicationTalentData.loadHeroTalents(heroId, signal);
|
|
117
118
|
},
|
|
118
|
-
resolveAssetUrl(asset) {
|
|
119
|
-
return new URL(asset.path, "https://static.example.com/").href;
|
|
120
|
-
},
|
|
121
119
|
};
|
|
122
120
|
|
|
123
121
|
calculator.dataSource = source;
|
|
@@ -131,7 +129,8 @@ calculator.dataSource = source;
|
|
|
131
129
|
- `talentPoints: number` — defaults to `14`, normalized from `0` through
|
|
132
130
|
`MAX_TALENT_POINTS`.
|
|
133
131
|
- `selectedTalentIds: readonly string[]`
|
|
134
|
-
- `
|
|
132
|
+
- `resolveAssetUrl: ImageAssetUrlResolver` — required and assigned as a
|
|
133
|
+
JavaScript property.
|
|
135
134
|
- `dataSource: FellowshipTalentDataSource | null`
|
|
136
135
|
- `renderTalent: LitTalentRenderer | null`
|
|
137
136
|
- `showPointControls: boolean` — defaults to `true`.
|
package/src/tooltip/README.md
CHANGED
|
@@ -48,8 +48,9 @@ Pass a React node to the wrapper's `content` prop to fill the named content slot
|
|
|
48
48
|
- Positioning maintains an 8px trigger gap and viewport collision margin.
|
|
49
49
|
- The native Popover API is used when available, with a fixed-position fallback.
|
|
50
50
|
|
|
51
|
-
Tooltip content is noninteractive and uses `role="tooltip"`. The first slotted
|
|
52
|
-
|
|
51
|
+
Tooltip content is noninteractive and uses `role="tooltip"`. The first slotted
|
|
52
|
+
trigger receives a stable `aria-describedby` relationship to the tooltip
|
|
53
|
+
surface while connected; any existing relationship is preserved and restored.
|
|
53
54
|
|
|
54
55
|
## API
|
|
55
56
|
|
|
@@ -101,10 +102,8 @@ import {
|
|
|
101
102
|
|
|
102
103
|
## Theming
|
|
103
104
|
|
|
104
|
-
The tooltip inherits the shared `--fellowship-
|
|
105
|
-
`--fellowship-tooltip-*` overrides.
|
|
106
|
-
warning `#D4A761`, effect `#AFA1CA`, resource `#7CB2C2`, healing `#82B997`, Meiko primary
|
|
107
|
-
`#C892A0`, and Meiko secondary `#8DBAB7`.
|
|
105
|
+
The tooltip inherits the shared `--fellowship-poster-*` Dungeon Poster
|
|
106
|
+
foundation and exposes the established `--fellowship-tooltip-*` overrides.
|
|
108
107
|
|
|
109
108
|
CSS parts: `trigger`, `surface`, `arrow`, `heading`, `content`, and `paragraph`.
|
|
110
109
|
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { FellowshipDataError as e } from "@crockery/fellowship-data/client";
|
|
2
|
-
//#region src/data/data-source.ts
|
|
3
|
-
var t = 2, n = (n) => {
|
|
4
|
-
if (n !== t) throw new e("unsupported-schema", `Unsupported fellowship-data schema version: ${String(n)}.`);
|
|
5
|
-
};
|
|
6
|
-
//#endregion
|
|
7
|
-
export { n, e as t };
|
|
@@ -1,410 +0,0 @@
|
|
|
1
|
-
import { n as e, r as t, t as n } from "./decorate-B_ZTN9li.js";
|
|
2
|
-
import { LitElement as r, css as i, html as a, nothing as o } from "lit";
|
|
3
|
-
import { customElement as s, property as c, query as l, state as u } from "lit/decorators.js";
|
|
4
|
-
import { repeat as d } from "lit/directives/repeat.js";
|
|
5
|
-
import { styleMap as f } from "lit/directives/style-map.js";
|
|
6
|
-
//#region src/tooltip/rich-text.ts
|
|
7
|
-
var p = {
|
|
8
|
-
bold: "strong",
|
|
9
|
-
"rt.bold": "strong",
|
|
10
|
-
"rt.absorb": "ability",
|
|
11
|
-
"rt.warning": "warning",
|
|
12
|
-
"rt.effect": "effect",
|
|
13
|
-
"rt.mana": "resource",
|
|
14
|
-
"rt.heal": "healing",
|
|
15
|
-
"rt.meikoability1": "meiko-primary",
|
|
16
|
-
"rt.meikoability2": "meiko-secondary"
|
|
17
|
-
}, m = (e, t, n) => {
|
|
18
|
-
let r = t.replace(/\r\n?/g, "\n").split(/\n{2,}/);
|
|
19
|
-
r.forEach((t, i) => {
|
|
20
|
-
let a = e.at(-1);
|
|
21
|
-
if (t.length > 0) {
|
|
22
|
-
let e = a.at(-1);
|
|
23
|
-
e?.tone === n ? a[a.length - 1] = {
|
|
24
|
-
text: `${e.text}${t}`,
|
|
25
|
-
tone: n
|
|
26
|
-
} : a.push({
|
|
27
|
-
text: t,
|
|
28
|
-
tone: n
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
i < r.length - 1 && e.push([]);
|
|
32
|
-
});
|
|
33
|
-
}, h = (e) => {
|
|
34
|
-
let t = [[]], n = ["default"], r = e.split(/(<\/?[^>]+>|<\/>)/g);
|
|
35
|
-
for (let e of r) {
|
|
36
|
-
if (!e) continue;
|
|
37
|
-
if (e === "</>") {
|
|
38
|
-
n.length > 1 && n.pop();
|
|
39
|
-
continue;
|
|
40
|
-
}
|
|
41
|
-
if (e.match(/^<\/\s*([^>\s]+)\s*>$/)) {
|
|
42
|
-
n.length > 1 && n.pop();
|
|
43
|
-
continue;
|
|
44
|
-
}
|
|
45
|
-
let r = e.match(/^<\s*([^/][^>\s]*)\s*>$/);
|
|
46
|
-
if (r) {
|
|
47
|
-
let e = r[1]?.toLowerCase() ?? "";
|
|
48
|
-
n.push(p[e] ?? "default");
|
|
49
|
-
continue;
|
|
50
|
-
}
|
|
51
|
-
m(t, e, n.at(-1) ?? "default");
|
|
52
|
-
}
|
|
53
|
-
return t;
|
|
54
|
-
}, g = (e) => h(e).map((e) => e.map(({ text: e }) => e).join("")).join("\n\n").trim(), _ = (e, t, n) => Math.min(Math.max(e, t), Math.max(t, n)), v = (e, t, n) => {
|
|
55
|
-
let r = n.gap ?? 8, i = n.margin ?? 8, a = {
|
|
56
|
-
top: e.top - i,
|
|
57
|
-
bottom: n.viewportHeight - e.bottom - i,
|
|
58
|
-
right: n.viewportWidth - e.right - i,
|
|
59
|
-
left: e.left - i
|
|
60
|
-
}, o = {
|
|
61
|
-
top: t.height + r,
|
|
62
|
-
bottom: t.height + r,
|
|
63
|
-
right: t.width + r,
|
|
64
|
-
left: t.width + r
|
|
65
|
-
}, s = [
|
|
66
|
-
"top",
|
|
67
|
-
"bottom",
|
|
68
|
-
"right",
|
|
69
|
-
"left"
|
|
70
|
-
], c = n.placement ?? "auto", l = c === "auto" ? s.find((e) => a[e] >= o[e]) ?? [...s].sort((e, t) => a[t] - a[e])[0] : c, u = e.left + e.width / 2 - t.width / 2, d = e.top + e.height / 2 - t.height / 2, f = l === "left" ? e.left - t.width - r : l === "right" ? e.right + r : u, p = l === "top" ? e.top - t.height - r : l === "bottom" ? e.bottom + r : d;
|
|
71
|
-
return {
|
|
72
|
-
placement: l,
|
|
73
|
-
x: Math.round(_(f, i, n.viewportWidth - t.width - i)),
|
|
74
|
-
y: Math.round(_(p, i, n.viewportHeight - t.height - i))
|
|
75
|
-
};
|
|
76
|
-
}, y = i`
|
|
77
|
-
:host {
|
|
78
|
-
--fellowship-tooltip-void: var(--_fellowship-field-surface-raised);
|
|
79
|
-
--fellowship-tooltip-ink: var(--_fellowship-field-ink);
|
|
80
|
-
--fellowship-tooltip-muted-ink: var(--_fellowship-field-muted);
|
|
81
|
-
--fellowship-tooltip-border: var(--_fellowship-field-border-strong);
|
|
82
|
-
--fellowship-tooltip-focus: var(--_fellowship-field-focus);
|
|
83
|
-
--fellowship-tooltip-ability: #76c5d2;
|
|
84
|
-
--fellowship-tooltip-warning: #d4a761;
|
|
85
|
-
--fellowship-tooltip-effect: #afa1ca;
|
|
86
|
-
--fellowship-tooltip-resource: #7cb2c2;
|
|
87
|
-
--fellowship-tooltip-healing: #82b997;
|
|
88
|
-
--fellowship-tooltip-meiko-primary: #c892a0;
|
|
89
|
-
--fellowship-tooltip-meiko-secondary: #8dbab7;
|
|
90
|
-
--fellowship-tooltip-font-family: var(--_fellowship-field-font-family);
|
|
91
|
-
--fellowship-tooltip-radius: var(--_fellowship-field-radius);
|
|
92
|
-
--fellowship-tooltip-max-width: 360px;
|
|
93
|
-
|
|
94
|
-
display: inline-block;
|
|
95
|
-
min-width: 0;
|
|
96
|
-
color: var(--fellowship-tooltip-ink);
|
|
97
|
-
font-family: var(--fellowship-tooltip-font-family);
|
|
98
|
-
-webkit-font-smoothing: antialiased;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
:host([hidden]) {
|
|
102
|
-
display: none;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
.trigger {
|
|
106
|
-
display: contents;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
.surface {
|
|
110
|
-
position: fixed;
|
|
111
|
-
z-index: 2147483647;
|
|
112
|
-
box-sizing: border-box;
|
|
113
|
-
display: none;
|
|
114
|
-
overflow: visible;
|
|
115
|
-
width: max-content;
|
|
116
|
-
max-width: min(var(--fellowship-tooltip-max-width), calc(100vw - 16px));
|
|
117
|
-
margin: 0;
|
|
118
|
-
padding: 12px 14px 14px;
|
|
119
|
-
border: 1px solid var(--fellowship-tooltip-border);
|
|
120
|
-
border-radius: var(--fellowship-tooltip-radius);
|
|
121
|
-
background: var(--fellowship-tooltip-void);
|
|
122
|
-
color: var(--fellowship-tooltip-ink);
|
|
123
|
-
box-shadow: 0 8px 24px rgb(0 0 0 / 34%);
|
|
124
|
-
opacity: 0;
|
|
125
|
-
transform: translateY(4px) scale(0.98);
|
|
126
|
-
transform-origin: bottom center;
|
|
127
|
-
transition:
|
|
128
|
-
opacity 140ms cubic-bezier(0.23, 1, 0.32, 1),
|
|
129
|
-
transform 140ms cubic-bezier(0.23, 1, 0.32, 1);
|
|
130
|
-
pointer-events: none;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
.surface[data-open="true"] {
|
|
134
|
-
display: block;
|
|
135
|
-
opacity: 1;
|
|
136
|
-
transform: translateY(0) scale(1);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
.surface[data-placement="bottom"] {
|
|
140
|
-
transform-origin: top center;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
.surface[data-placement="left"] {
|
|
144
|
-
transform-origin: center right;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
.surface[data-placement="right"] {
|
|
148
|
-
transform-origin: center left;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
.heading {
|
|
152
|
-
position: relative;
|
|
153
|
-
margin: 0 0 6px;
|
|
154
|
-
padding-left: 12px;
|
|
155
|
-
color: var(--fellowship-tooltip-ink);
|
|
156
|
-
font-size: 14px;
|
|
157
|
-
font-weight: 600;
|
|
158
|
-
line-height: 20px;
|
|
159
|
-
text-wrap: balance;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
.heading::before {
|
|
163
|
-
position: absolute;
|
|
164
|
-
inset: 4px auto 4px 0;
|
|
165
|
-
width: 2px;
|
|
166
|
-
background: var(--_fellowship-field-accent);
|
|
167
|
-
content: "";
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
.content {
|
|
171
|
-
color: var(--fellowship-tooltip-muted-ink);
|
|
172
|
-
font-size: 13px;
|
|
173
|
-
font-weight: 400;
|
|
174
|
-
line-height: 20px;
|
|
175
|
-
text-wrap: pretty;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
.paragraph {
|
|
179
|
-
margin: 0;
|
|
180
|
-
white-space: pre-line;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
.paragraph + .paragraph {
|
|
184
|
-
margin-top: 8px;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
[data-tone="strong"] {
|
|
188
|
-
color: var(--fellowship-tooltip-ink);
|
|
189
|
-
font-weight: 600;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
[data-tone="ability"] {
|
|
193
|
-
color: var(--fellowship-tooltip-ability);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
[data-tone="warning"] {
|
|
197
|
-
color: var(--fellowship-tooltip-warning);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
[data-tone="effect"] {
|
|
201
|
-
color: var(--fellowship-tooltip-effect);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
[data-tone="resource"] {
|
|
205
|
-
color: var(--fellowship-tooltip-resource);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
[data-tone="healing"] {
|
|
209
|
-
color: var(--fellowship-tooltip-healing);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
[data-tone="meiko-primary"] {
|
|
213
|
-
color: var(--fellowship-tooltip-meiko-primary);
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
[data-tone="meiko-secondary"] {
|
|
217
|
-
color: var(--fellowship-tooltip-meiko-secondary);
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
.arrow {
|
|
221
|
-
position: absolute;
|
|
222
|
-
width: 8px;
|
|
223
|
-
height: 8px;
|
|
224
|
-
border: solid var(--fellowship-tooltip-border);
|
|
225
|
-
background: var(--fellowship-tooltip-void);
|
|
226
|
-
transform: rotate(45deg);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
.surface[data-placement="top"] .arrow {
|
|
230
|
-
bottom: -5px;
|
|
231
|
-
left: calc(50% - 4px);
|
|
232
|
-
border-width: 0 1px 1px 0;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
.surface[data-placement="bottom"] .arrow {
|
|
236
|
-
top: -5px;
|
|
237
|
-
left: calc(50% - 4px);
|
|
238
|
-
border-width: 1px 0 0 1px;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
.surface[data-placement="left"] .arrow {
|
|
242
|
-
top: calc(50% - 4px);
|
|
243
|
-
right: -5px;
|
|
244
|
-
border-width: 1px 1px 0 0;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
.surface[data-placement="right"] .arrow {
|
|
248
|
-
top: calc(50% - 4px);
|
|
249
|
-
left: -5px;
|
|
250
|
-
border-width: 0 0 1px 1px;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
@media (prefers-reduced-motion: reduce) {
|
|
254
|
-
.surface {
|
|
255
|
-
transition: opacity 100ms linear;
|
|
256
|
-
transform: none;
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
`, b = {
|
|
260
|
-
bubbles: !0,
|
|
261
|
-
composed: !0
|
|
262
|
-
}, x = class extends r {
|
|
263
|
-
constructor(...e) {
|
|
264
|
-
super(...e), this.heading = null, this.text = null, this.placement = "auto", this.openDelay = 250, this.disabled = !1, this._open = !1, this._position = {
|
|
265
|
-
x: 0,
|
|
266
|
-
y: 0
|
|
267
|
-
}, this._resolvedPlacement = "top", this._paragraphs = [], this.#e = null, this.#t = null, this.#n = null, this.#r = !1, this.#i = null, this.#o = () => {
|
|
268
|
-
if (!this._open || !this.#t || !this._surface) return;
|
|
269
|
-
let e = v(this.#t.getBoundingClientRect(), this._surface.getBoundingClientRect(), {
|
|
270
|
-
placement: this.placement,
|
|
271
|
-
viewportWidth: window.innerWidth,
|
|
272
|
-
viewportHeight: window.innerHeight
|
|
273
|
-
});
|
|
274
|
-
e.x === this._position.x && e.y === this._position.y && e.placement === this._resolvedPlacement || (this._position = {
|
|
275
|
-
x: e.x,
|
|
276
|
-
y: e.y
|
|
277
|
-
}, this._resolvedPlacement = e.placement);
|
|
278
|
-
}, this.#l = () => {
|
|
279
|
-
this.disabled || this._open || (this.#_(), this.#e = window.setTimeout(() => {
|
|
280
|
-
this.#e = null, this.#a(!0, "pointer");
|
|
281
|
-
}, Math.max(0, this.openDelay)));
|
|
282
|
-
}, this.#u = () => {
|
|
283
|
-
this.#_(), this._open && this.#a(!1, "pointer");
|
|
284
|
-
}, this.#d = () => {
|
|
285
|
-
this.#_(), !this.disabled && !this._open && this.#a(!0, "focus");
|
|
286
|
-
}, this.#f = (e) => {
|
|
287
|
-
!this.contains(e.relatedTarget) && this._open && this.#a(!1, "focus");
|
|
288
|
-
}, this.#p = (e) => {
|
|
289
|
-
e.key === "Escape" && this._open && (e.stopPropagation(), this.#a(!1, "escape"));
|
|
290
|
-
}, this.#m = (e) => {
|
|
291
|
-
let t = e.currentTarget.assignedElements({ flatten: !0 })[0];
|
|
292
|
-
this.#g(), this.#t = t instanceof HTMLElement ? t : null, this.#h();
|
|
293
|
-
};
|
|
294
|
-
}
|
|
295
|
-
static {
|
|
296
|
-
this.styles = [t, y];
|
|
297
|
-
}
|
|
298
|
-
#e;
|
|
299
|
-
#t;
|
|
300
|
-
#n;
|
|
301
|
-
#r;
|
|
302
|
-
#i;
|
|
303
|
-
connectedCallback() {
|
|
304
|
-
super.connectedCallback(), e(this.ownerDocument), this.#i ??= new ResizeObserver(() => this.#o());
|
|
305
|
-
}
|
|
306
|
-
disconnectedCallback() {
|
|
307
|
-
this.#_(), this.#c(), this.#g(), super.disconnectedCallback();
|
|
308
|
-
}
|
|
309
|
-
updated(e) {
|
|
310
|
-
super.updated(e), (e.has("text") || e.has("heading")) && this.#h(), e.has("disabled") && this.disabled && this._open && this.#a(!1, "disabled"), e.has("placement") && this._open && this.#o();
|
|
311
|
-
}
|
|
312
|
-
willUpdate(e) {
|
|
313
|
-
super.willUpdate(e), e.has("text") && (this._paragraphs = h(this.text ?? ""));
|
|
314
|
-
}
|
|
315
|
-
show() {
|
|
316
|
-
this.disabled || this._open || this.#a(!0, "programmatic");
|
|
317
|
-
}
|
|
318
|
-
hide() {
|
|
319
|
-
this.#_(), this._open && this.#a(!1, "programmatic");
|
|
320
|
-
}
|
|
321
|
-
render() {
|
|
322
|
-
let e = {
|
|
323
|
-
left: `${this._position.x}px`,
|
|
324
|
-
top: `${this._position.y}px`
|
|
325
|
-
};
|
|
326
|
-
return a`
|
|
327
|
-
<span
|
|
328
|
-
class="trigger"
|
|
329
|
-
part="trigger"
|
|
330
|
-
@pointerenter=${this.#l}
|
|
331
|
-
@pointerleave=${this.#u}
|
|
332
|
-
@focusin=${this.#d}
|
|
333
|
-
@focusout=${this.#f}
|
|
334
|
-
@keydown=${this.#p}
|
|
335
|
-
>
|
|
336
|
-
<slot @slotchange=${this.#m}></slot>
|
|
337
|
-
</span>
|
|
338
|
-
<div
|
|
339
|
-
class="surface"
|
|
340
|
-
part="surface"
|
|
341
|
-
role="tooltip"
|
|
342
|
-
popover="manual"
|
|
343
|
-
data-open=${String(this._open)}
|
|
344
|
-
data-placement=${this._resolvedPlacement}
|
|
345
|
-
style=${f(e)}
|
|
346
|
-
>
|
|
347
|
-
<span class="arrow" part="arrow" aria-hidden="true"></span>
|
|
348
|
-
<slot name="content">
|
|
349
|
-
${this.heading ? a`<p class="heading" part="heading">${this.heading}</p>` : o}
|
|
350
|
-
<div class="content" part="content">
|
|
351
|
-
${d(this._paragraphs, (e, t) => t, (e, t) => a`
|
|
352
|
-
<p class="paragraph" part="paragraph">
|
|
353
|
-
${d(e, (e, n) => `${t}:${n}:${e.tone}:${e.text}`, (e) => a`<span data-tone=${e.tone}>${e.text}</span>`)}
|
|
354
|
-
</p>
|
|
355
|
-
`)}
|
|
356
|
-
</div>
|
|
357
|
-
</slot>
|
|
358
|
-
</div>
|
|
359
|
-
`;
|
|
360
|
-
}
|
|
361
|
-
#a(e, t) {
|
|
362
|
-
e !== this._open && (this._open = e, this.updateComplete.then(() => {
|
|
363
|
-
let t = this._surface;
|
|
364
|
-
t && (e ? ("showPopover" in t && !t.matches(":popover-open") && t.showPopover(), this.#s(), this.#o()) : ("hidePopover" in t && t.matches(":popover-open") && t.hidePopover(), this.#c()));
|
|
365
|
-
}), this.dispatchEvent(new CustomEvent("fellowship-tooltip-toggle", {
|
|
366
|
-
...b,
|
|
367
|
-
detail: {
|
|
368
|
-
open: e,
|
|
369
|
-
reason: t
|
|
370
|
-
}
|
|
371
|
-
})));
|
|
372
|
-
}
|
|
373
|
-
#o;
|
|
374
|
-
#s() {
|
|
375
|
-
window.addEventListener("resize", this.#o), window.addEventListener("scroll", this.#o, !0), this.#t && this.#i?.observe(this.#t), this._surface && this.#i?.observe(this._surface);
|
|
376
|
-
}
|
|
377
|
-
#c() {
|
|
378
|
-
window.removeEventListener("resize", this.#o), window.removeEventListener("scroll", this.#o, !0), this.#i?.disconnect();
|
|
379
|
-
}
|
|
380
|
-
#l;
|
|
381
|
-
#u;
|
|
382
|
-
#d;
|
|
383
|
-
#f;
|
|
384
|
-
#p;
|
|
385
|
-
#m;
|
|
386
|
-
#h() {
|
|
387
|
-
if (!this.#t) return;
|
|
388
|
-
this.#r ||= (this.#n = this.#t.getAttribute("aria-description"), !0);
|
|
389
|
-
let e = [this.heading, g(this.text ?? "")].filter(Boolean).join(". ");
|
|
390
|
-
e ? this.#t.setAttribute("aria-description", e) : this.#n === null && this.#t.removeAttribute("aria-description");
|
|
391
|
-
}
|
|
392
|
-
#g() {
|
|
393
|
-
this.#t && (this.#n === null ? this.#t.removeAttribute("aria-description") : this.#t.setAttribute("aria-description", this.#n), this.#t = null, this.#n = null, this.#r = !1);
|
|
394
|
-
}
|
|
395
|
-
#_() {
|
|
396
|
-
this.#e !== null && (window.clearTimeout(this.#e), this.#e = null);
|
|
397
|
-
}
|
|
398
|
-
};
|
|
399
|
-
n([c({ type: String })], x.prototype, "heading", void 0), n([c({ type: String })], x.prototype, "text", void 0), n([c({ type: String })], x.prototype, "placement", void 0), n([c({
|
|
400
|
-
type: Number,
|
|
401
|
-
attribute: "open-delay"
|
|
402
|
-
})], x.prototype, "openDelay", void 0), n([c({
|
|
403
|
-
type: Boolean,
|
|
404
|
-
reflect: !0
|
|
405
|
-
})], x.prototype, "disabled", void 0), n([u()], x.prototype, "_open", void 0), n([u()], x.prototype, "_position", void 0), n([u()], x.prototype, "_resolvedPlacement", void 0), n([u()], x.prototype, "_paragraphs", void 0), n([l(".surface")], x.prototype, "_surface", void 0), x = n([s("fellowship-tooltip")], x);
|
|
406
|
-
var S = () => {
|
|
407
|
-
customElements.get("fellowship-tooltip") || customElements.define("fellowship-tooltip", x);
|
|
408
|
-
};
|
|
409
|
-
//#endregion
|
|
410
|
-
export { g as a, h as i, S as n, v as r, x as t };
|