mirror of
https://github.com/tiennm99/noitu.git
synced 2026-10-11 03:13:45 +00:00
feat(web): make the rejection row's suggestion and report real touch targets
The suggestion and report pills sat at 2px padding on 0.8rem text, under WCAG's 24px minimum, on the two taps most worth making under a running clock. They move onto their own line at a 36px floor, and the suggestion reads as primary weight since it is almost certainly the word the player meant. The fill-only behaviour and the field's uncontrolled-input invariant are unchanged.
This commit is contained in:
1 parent
4fe7ef4f11
commit
a95938d611
1 file changed
+71
-24
@@ -223,17 +223,26 @@
|
|||||||
clock, with nothing to compare against. -->
|
clock, with nothing to compare against. -->
|
||||||
<p class="rejection" id="word-rejection" role="alert">
|
<p class="rejection" id="word-rejection" role="alert">
|
||||||
<strong>{game.state.rejection.word}</strong> — {game.state.rejection.message}
|
<strong>{game.state.rejection.word}</strong> — {game.state.rejection.message}
|
||||||
{#if game.state.rejection.suggestion}
|
|
||||||
<!-- Corrects typing, not vocabulary: the server only ever offers this
|
|
||||||
for a word that differs from a real one by diacritics alone. -->
|
|
||||||
<button type="button" class="suggestion" onclick={useSuggestion}>
|
|
||||||
{fill(t.suggestionPrompt, { word: game.state.rejection.suggestion })}
|
|
||||||
</button>
|
|
||||||
{/if}
|
|
||||||
{#if game.state.rejection.reason === RejectReason.NOT_IN_DICTIONARY}
|
|
||||||
<button type="button" class="report" onclick={report}>{t.reportWord}</button>
|
|
||||||
{/if}
|
|
||||||
</p>
|
</p>
|
||||||
|
{#if game.state.rejection.suggestion || game.state.rejection.reason === RejectReason.NOT_IN_DICTIONARY}
|
||||||
|
<!-- Their own line, at a real tap size: under the clock these are the
|
||||||
|
two most valuable taps on the board, and the pills they used to be
|
||||||
|
were under WCAG's 24px minimum. -->
|
||||||
|
<div class="fixes">
|
||||||
|
{#if game.state.rejection.suggestion}
|
||||||
|
<!-- Corrects typing, not vocabulary: the server only ever offers
|
||||||
|
this for a word that differs from a real one by diacritics
|
||||||
|
alone — primary weight because it is almost certainly the
|
||||||
|
word the player meant. -->
|
||||||
|
<button type="button" class="fix suggestion" onclick={useSuggestion}>
|
||||||
|
{fill(t.suggestionPrompt, { word: game.state.rejection.suggestion })}
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
{#if game.state.rejection.reason === RejectReason.NOT_IN_DICTIONARY}
|
||||||
|
<button type="button" class="fix report" onclick={report}>{t.reportWord}</button>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if game.state.reportConfirmation}
|
{#if game.state.reportConfirmation}
|
||||||
@@ -251,13 +260,13 @@
|
|||||||
input {
|
input {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
padding: 14px;
|
padding: var(--space-4);
|
||||||
border: 1px solid var(--border-strong);
|
border: 1px solid var(--border-strong);
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
background: var(--surface);
|
background: var(--surface);
|
||||||
/* 16px or larger stops iOS Safari zooming the page on focus, which on a
|
/* 16px or larger stops iOS Safari zooming the page on focus, which on a
|
||||||
phone hides half the board behind the keyboard. */
|
phone hides half the board behind the keyboard. */
|
||||||
font-size: var(--text-6);
|
font-size: var(--text-3);
|
||||||
/* Whatever does not fit ends in an ellipsis rather than against the
|
/* Whatever does not fit ends in an ellipsis rather than against the
|
||||||
edge of the box. */
|
edge of the box. */
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
@@ -275,12 +284,21 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
padding: 14px var(--space-5);
|
padding: var(--space-4) var(--space-5);
|
||||||
border: 0;
|
border: 0;
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
background: var(--accent);
|
background: var(--accent);
|
||||||
color: var(--accent-text);
|
color: var(--accent-text);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
transition: background-color 150ms ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover:not(:disabled) {
|
||||||
|
background: var(--accent-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
button:active:not(:disabled) {
|
||||||
|
background: var(--accent-pressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
button:disabled {
|
button:disabled {
|
||||||
@@ -294,34 +312,63 @@
|
|||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
gap: 4px var(--space-2);
|
gap: 4px var(--space-2);
|
||||||
margin: var(--space-2) 0 0;
|
margin: var(--space-2) 0 0;
|
||||||
padding: 10px var(--space-3);
|
padding: var(--space-3) var(--space-3);
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
background: var(--danger-soft);
|
background: var(--danger-soft);
|
||||||
color: var(--danger);
|
color: var(--danger);
|
||||||
font-size: var(--text-5);
|
font-size: var(--text-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.rejection strong {
|
.rejection strong {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.suggestion,
|
.fixes {
|
||||||
.report {
|
display: flex;
|
||||||
padding: 2px var(--space-2);
|
flex-direction: column;
|
||||||
border: 1px solid currentColor;
|
gap: var(--space-2);
|
||||||
|
margin-top: var(--space-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fix {
|
||||||
|
min-height: 36px;
|
||||||
|
padding: var(--space-1) var(--space-3);
|
||||||
|
border: 1px solid var(--border-strong);
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
background: none;
|
background: var(--surface);
|
||||||
color: inherit;
|
color: var(--text);
|
||||||
font-size: var(--text-3);
|
font-size: var(--text-2);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
text-align: left;
|
||||||
|
transition: background-color 150ms ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fix:hover {
|
||||||
|
background: var(--surface-alt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Primary weight: of the two, this is the one tap that almost certainly
|
||||||
|
finishes the turn. */
|
||||||
|
.fix.suggestion {
|
||||||
|
border-color: transparent;
|
||||||
|
background: var(--accent);
|
||||||
|
color: var(--accent-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fix.suggestion:hover {
|
||||||
|
background: var(--accent-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fix.suggestion:active {
|
||||||
|
background: var(--accent-pressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
.report-confirmation {
|
.report-confirmation {
|
||||||
margin: var(--space-2) 0 0;
|
margin: var(--space-2) 0 0;
|
||||||
padding: 10px var(--space-3);
|
padding: var(--space-3) var(--space-3);
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
background: var(--accent-soft);
|
background: var(--accent-soft);
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
font-size: var(--text-5);
|
font-size: var(--text-2);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
Reference in new issue
Block a user