partforge 0.150.0 → 0.150.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/package.json
CHANGED
package/src/framework/app.css
CHANGED
|
@@ -835,14 +835,16 @@ button.action:focus-visible, .adv-toggle:focus-visible, .sec-title:focus-visible
|
|
|
835
835
|
.pf-card-lab-row { display: flex; justify-content: space-between; align-items: baseline; }
|
|
836
836
|
.pf-card-lab { font-size: 12px; color: var(--pf-muted); }
|
|
837
837
|
.pf-card-val { font-size: 12px; color: var(--pf-text-2); font-variant-numeric: tabular-nums; }
|
|
838
|
-
.pf-card-
|
|
839
|
-
.pf-card-
|
|
838
|
+
.pf-card-val.preview { color: var(--pf-text); }
|
|
839
|
+
.pf-card-tiles { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 4px 2px; }
|
|
840
|
+
.pf-card-tile { display: grid; justify-items: center; align-content: start; gap: 4px; border: 0; background: none; padding: 4px 1px 3px; border-radius: 8px; cursor: pointer; font: inherit; color: var(--pf-text-2); }
|
|
840
841
|
.pf-card-tile:hover { background: var(--pf-surface-2); }
|
|
841
842
|
.pf-card-tile[aria-pressed="true"] { background: var(--pf-accent-soft); color: var(--pf-accent); }
|
|
842
|
-
.pf-card-ball { position: relative; width:
|
|
843
|
+
.pf-card-ball { position: relative; width: 36px; height: 36px; border-radius: 50%; overflow: hidden; background: radial-gradient(circle at 35% 30%, color-mix(in oklab, var(--pf-swatch) 72%, white) 0, var(--pf-swatch) 48%, color-mix(in oklab, var(--pf-swatch) 68%, black) 100%); box-shadow: inset 0 -1px 2px rgb(0 0 0 / .25); }
|
|
843
844
|
.pf-card-ball img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
|
|
844
845
|
.pf-card-ball img[hidden] { display: none; }
|
|
845
|
-
|
|
846
|
+
/* Two lines at most; the Material row names the hovered tile in full. */
|
|
847
|
+
.pf-card-tile-label { font-size: 10.5px; line-height: 1.15; max-width: 100%; min-height: 2.3em; text-align: center; overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; }
|
|
846
848
|
.pf-card-unknown { margin: 0; font-size: 11px; color: var(--pf-err); font-family: var(--pf-mono); }
|
|
847
849
|
.pf-card-unknown[hidden] { display: none; }
|
|
848
850
|
.pf-card-colors { display: grid; grid-template-columns: repeat(10, minmax(0, 1fr)); gap: 6px; }
|
|
@@ -206,6 +206,30 @@ export function attachAppearanceCard(parts, { onBack, onClose, onGone, getSaveSt
|
|
|
206
206
|
const ownColor = known(id) && !PRESETS[id].tintable && typeof parts.getState(name)?.override?.color === "number";
|
|
207
207
|
parts.setDisplay(name, ownColor ? { material: id, color: null } : { material: id });
|
|
208
208
|
});
|
|
209
|
+
// The Material row names the tile under the pointer (or keyboard focus),
|
|
210
|
+
// then the part's material again: a tile's own label clamps to two lines,
|
|
211
|
+
// so this is where a long name reads in full. A touch names nothing — a tap
|
|
212
|
+
// applies the tile, and the row then names it as the material anyway.
|
|
213
|
+
let previewLabel = null;
|
|
214
|
+
const showMaterialName = () => {
|
|
215
|
+
matVal.textContent = previewLabel ?? row?.materialLabel ?? "None";
|
|
216
|
+
matVal.classList.toggle("preview", previewLabel !== null);
|
|
217
|
+
};
|
|
218
|
+
const previewFrom = (e) => {
|
|
219
|
+
const t = e.target.closest?.(".pf-card-tile");
|
|
220
|
+
previewLabel = t ? t.title : null;
|
|
221
|
+
showMaterialName();
|
|
222
|
+
};
|
|
223
|
+
const previewEnd = (e) => {
|
|
224
|
+
const t = e.target.closest?.(".pf-card-tile");
|
|
225
|
+
if (!t || t.contains(e.relatedTarget)) return;
|
|
226
|
+
previewLabel = null;
|
|
227
|
+
showMaterialName();
|
|
228
|
+
};
|
|
229
|
+
tiles.addEventListener("pointerover", (e) => { if (e.pointerType !== "touch") previewFrom(e); });
|
|
230
|
+
tiles.addEventListener("pointerout", (e) => { if (e.pointerType !== "touch") previewEnd(e); });
|
|
231
|
+
tiles.addEventListener("focusin", previewFrom);
|
|
232
|
+
tiles.addEventListener("focusout", previewEnd);
|
|
209
233
|
colors.addEventListener("click", (e) => {
|
|
210
234
|
const b = e.target.closest(".pf-card-color");
|
|
211
235
|
if (!b || !name) return;
|
|
@@ -238,7 +262,7 @@ export function attachAppearanceCard(parts, { onBack, onClose, onGone, getSaveSt
|
|
|
238
262
|
see.value = String(pct); seeVal.textContent = `${pct}%`;
|
|
239
263
|
const m = state.effective.material;
|
|
240
264
|
for (const t of tiles.children) t.setAttribute("aria-pressed", String(known(m) && t.dataset.material === m));
|
|
241
|
-
|
|
265
|
+
showMaterialName();
|
|
242
266
|
unknown.hidden = !(m != null && !known(m));
|
|
243
267
|
unknown.textContent = unknown.hidden ? "" : String(m);
|
|
244
268
|
const color = row.color;
|
|
@@ -320,7 +344,7 @@ export function attachAppearanceCard(parts, { onBack, onClose, onGone, getSaveSt
|
|
|
320
344
|
element: root,
|
|
321
345
|
show(next) {
|
|
322
346
|
if (!parts.list().some((r) => r.name === next)) return false;
|
|
323
|
-
name = next;
|
|
347
|
+
name = next; previewLabel = null;
|
|
324
348
|
render();
|
|
325
349
|
return true;
|
|
326
350
|
},
|