Stop the button's chip sitting on top of the name underneath it #115
@@ -622,6 +622,14 @@ button,
|
|||||||
margin-top: 0.6rem;
|
margin-top: 0.6rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The button's chip sits in this puck's top-right corner, on a layer above the text.
|
||||||
|
Reserving its width means a long name ends in an ellipsis before it reaches the
|
||||||
|
chip, rather than disappearing underneath one — on the one seat at the table a
|
||||||
|
dealer looks at most. */
|
||||||
|
.seat.seatHasButton .seatPuckName {
|
||||||
|
padding-right: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
.seatPuckCards {
|
.seatPuckCards {
|
||||||
font-size: 0.68rem;
|
font-size: 0.68rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
|||||||
@@ -408,6 +408,12 @@ const Render = {
|
|||||||
const dealerChip = node.querySelector(".dealerChip");
|
const dealerChip = node.querySelector(".dealerChip");
|
||||||
const hasButton = index === dealerIndex;
|
const hasButton = index === dealerIndex;
|
||||||
dealerChip.classList.toggle("active", hasButton);
|
dealerChip.classList.toggle("active", hasButton);
|
||||||
|
// Marked on the seat as well as the chip, so the puck's own text can keep
|
||||||
|
// out from under it. A name is centred across the whole puck and the chip
|
||||||
|
// sits in the corner on a layer above: measured, "Christopher" on the
|
||||||
|
// button lost 20px of its 64px box to the chip and showed no ellipsis,
|
||||||
|
// because the text believed it had the room it was painted out of.
|
||||||
|
node.classList.toggle("seatHasButton", hasButton);
|
||||||
dealerChip.classList.toggle("hidden", !!this.state.dedicatedDealer);
|
dealerChip.classList.toggle("hidden", !!this.state.dedicatedDealer);
|
||||||
// Every one of these announced itself as "D", so a screen reader heard a row
|
// Every one of these announced itself as "D", so a screen reader heard a row
|
||||||
// of nine identical buttons and couldn't tell which seat held the real one.
|
// of nine identical buttons and couldn't tell which seat held the real one.
|
||||||
|
|||||||
@@ -739,6 +739,44 @@ const LayoutAudit = {
|
|||||||
return { name: "hidden means hidden", offenders };
|
return { name: "hidden means hidden", offenders };
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// A seat's name, painted under the decoration on its own puck.
|
||||||
|
//
|
||||||
|
// The chip that marks the button sits in the puck's top-right corner on a layer
|
||||||
|
// above the text, and the name is centred across the whole width. A long one
|
||||||
|
// therefore ran underneath it and stopped — measured, "Christopher" on the button
|
||||||
|
// lost 20px of its 64px box and showed no ellipsis, because as far as the text was
|
||||||
|
// concerned it had all the room it needed. Nothing else here would have caught it:
|
||||||
|
// the occlusion check is about controls a thumb has to reach, and this is a label
|
||||||
|
// a dealer has to read.
|
||||||
|
seatLabelsClear() {
|
||||||
|
const offenders = [];
|
||||||
|
document.querySelectorAll(".seat").forEach(seat => {
|
||||||
|
const name = seat.querySelector(".seatPuckName");
|
||||||
|
if (!name || !name.textContent.trim()) return;
|
||||||
|
const box = name.getBoundingClientRect();
|
||||||
|
if (!box.width || !box.height) return;
|
||||||
|
// Padding is room the text has already been kept out of, so it is not
|
||||||
|
// somewhere the text can be covered.
|
||||||
|
const style = getComputedStyle(name);
|
||||||
|
const textLeft = box.left + parseFloat(style.paddingLeft || 0);
|
||||||
|
const textRight = box.right - parseFloat(style.paddingRight || 0);
|
||||||
|
|
||||||
|
seat.querySelectorAll(".dealerChip, .blindBadge").forEach(mark => {
|
||||||
|
const over = mark.getBoundingClientRect();
|
||||||
|
if (!over.width || !over.height) return;
|
||||||
|
const marked = getComputedStyle(mark);
|
||||||
|
if (marked.display === "none" || marked.visibility === "hidden" ||
|
||||||
|
parseFloat(marked.opacity) < 0.05) return;
|
||||||
|
const covered = Math.min(textRight, over.right) - Math.max(textLeft, over.left);
|
||||||
|
const vertical = Math.min(box.bottom, over.bottom) - Math.max(box.top, over.top);
|
||||||
|
if (covered > 1 && vertical > 1) {
|
||||||
|
offenders.push(`${this.describe(name)} :: ${Math.round(covered)}px under ${this.describe(mark)}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return { name: "seat names aren't painted under their own badges", offenders };
|
||||||
|
},
|
||||||
|
|
||||||
// ---- Runner ----
|
// ---- Runner ----
|
||||||
|
|
||||||
// Every check this file knows how to make, every time.
|
// Every check this file knows how to make, every time.
|
||||||
@@ -768,6 +806,7 @@ const LayoutAudit = {
|
|||||||
this.seatOwnership(),
|
this.seatOwnership(),
|
||||||
this.oneDealerButton(),
|
this.oneDealerButton(),
|
||||||
this.hiddenButPainted(),
|
this.hiddenButPainted(),
|
||||||
|
this.seatLabelsClear(),
|
||||||
this.contrast(options.contrast),
|
this.contrast(options.contrast),
|
||||||
this.touchTargets(options.minimumTarget, options.touchTargets),
|
this.touchTargets(options.minimumTarget, options.touchTargets),
|
||||||
];
|
];
|
||||||
|
|||||||
Reference in New Issue
Block a user