Skip to content

Commit 6bc9007

Browse files
committed
Add Record button and update UI/UX
1 parent 0cbdd74 commit 6bc9007

File tree

2 files changed

+111
-26
lines changed

2 files changed

+111
-26
lines changed

docs/app.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const liveKey = document.getElementById("liveKey");
1111
const liveIndex = document.getElementById("liveIndex");
1212
const liveSlots = document.getElementById("liveSlots");
1313
const clearAllBtn = document.getElementById("clearAllBtn");
14+
const enterBtn = document.getElementById("enterBtn");
1415
const entriesBody = document.getElementById("entriesBody");
1516

1617
let jch = new JumpConsistentHash(5);
@@ -70,7 +71,8 @@ function fmtWhen(ts) {
7071

7172
function renderTable() {
7273
if (!entries.length) {
73-
entriesBody.innerHTML = '<tr class="empty"><td colspan="5">No entries yet. Type a key and press Enter.</td></tr>';
74+
entriesBody.innerHTML =
75+
'<tr class="empty"><td colspan="5">No entries yet. Type a key and press Enter or click Record.</td></tr>';
7476
return;
7577
}
7678
const rows = entries
@@ -171,6 +173,16 @@ slotsInput.addEventListener("input", async () => {
171173
});
172174
clearAllBtn.addEventListener("click", clearAll);
173175

176+
// Record button event listener for all interaction types
177+
if (enterBtn) {
178+
// Handle click events (mouse and touch)
179+
enterBtn.addEventListener("click", async (e) => {
180+
e.preventDefault();
181+
await commitEntry();
182+
keyInput.select();
183+
});
184+
}
185+
174186
// Init
175187
loadSession();
176188
renderTable();

docs/index.html

Lines changed: 98 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -214,9 +214,11 @@
214214
}
215215
}
216216
main {
217-
display: grid;
218-
place-items: start center;
217+
display: flex;
218+
flex-direction: column;
219+
align-items: center;
219220
padding: 16px;
221+
gap: 0;
220222
}
221223
.search-card {
222224
width: min(880px, 92vw);
@@ -231,10 +233,21 @@
231233
}
232234
.controls {
233235
display: grid;
234-
grid-template-columns: 1fr auto;
236+
grid-template-columns: 1fr auto auto;
235237
align-items: center;
236238
gap: 12px;
237239
}
240+
241+
/* Responsive controls for mobile */
242+
@media (max-width: 640px) {
243+
.controls {
244+
grid-template-columns: 1fr;
245+
gap: 16px;
246+
}
247+
.slots-field {
248+
width: 100%;
249+
}
250+
}
238251
.live {
239252
display: flex;
240253
align-items: center;
@@ -247,11 +260,24 @@
247260
.live .value {
248261
color: var(--primary);
249262
}
250-
.actions {
263+
.table-card .actions {
264+
padding: 20px 18px;
265+
border-top: 1px solid var(--outline-variant);
266+
background: color-mix(in srgb, var(--surface) 96%, #0a0e13);
251267
display: flex;
252268
justify-content: flex-end;
253-
gap: 8px;
254-
padding: 8px 0 0;
269+
position: relative;
270+
}
271+
272+
.table-card .actions::before {
273+
content: "";
274+
position: absolute;
275+
top: 0;
276+
left: 18px;
277+
right: 18px;
278+
height: 1px;
279+
background: linear-gradient(to right, transparent, #ff6b6b, transparent);
280+
opacity: 0.3;
255281
}
256282
.table-card {
257283
margin-top: 20px;
@@ -363,9 +389,6 @@
363389
text-align: center;
364390
padding: 8px 12px !important;
365391
}
366-
tfoot td {
367-
padding: 10px 14px;
368-
}
369392
.empty {
370393
text-align: center;
371394
color: #8fa6bf;
@@ -592,9 +615,60 @@
592615

593616
/* Tonal button (Reset session) */
594617
md-filled-tonal-button#clearAllBtn {
595-
--md-filled-tonal-button-container-color: color-mix(in srgb, var(--secondary) 18%, #102018);
596-
--md-filled-tonal-button-label-text-color: color-mix(in srgb, var(--secondary) 85%, #eaffea 15%);
597-
--md-filled-tonal-button-container-shape: 12px;
618+
--md-filled-tonal-button-container-color: color-mix(in srgb, #ff6b6b 20%, #1f0f0f);
619+
--md-filled-tonal-button-label-text-color: color-mix(in srgb, #ff8a8a 90%, #ffefef 10%);
620+
--md-filled-tonal-button-container-shape: 16px;
621+
--md-filled-tonal-button-container-height: 48px;
622+
--md-filled-tonal-button-label-text-font: "Monaspace Krypton", ui-monospace, monospace;
623+
--md-filled-tonal-button-label-text-weight: 600;
624+
--md-filled-tonal-button-label-text-size: 14px;
625+
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
626+
box-shadow: 0 2px 8px rgba(255, 107, 107, 0.15);
627+
border: 1px solid rgba(255, 107, 107, 0.3);
628+
}
629+
630+
md-filled-tonal-button#clearAllBtn:hover {
631+
--md-filled-tonal-button-container-color: color-mix(in srgb, #ff6b6b 25%, #251213);
632+
box-shadow: 0 4px 16px rgba(255, 107, 107, 0.25);
633+
transform: translateY(-2px);
634+
border-color: rgba(255, 107, 107, 0.5);
635+
}
636+
637+
md-filled-tonal-button#clearAllBtn:active {
638+
transform: translateY(0);
639+
box-shadow: 0 2px 8px rgba(255, 107, 107, 0.2);
640+
}
641+
642+
/* Record button with greenish background */
643+
md-filled-button#enterBtn {
644+
--md-filled-button-container-color: color-mix(in srgb, var(--secondary) 85%, #004d33);
645+
--md-filled-button-label-text-color: var(--md-sys-color-on-secondary);
646+
--md-filled-button-container-shape: 16px;
647+
--md-filled-button-container-height: 48px;
648+
--md-filled-button-label-text-font: "Monaspace Krypton", ui-monospace, monospace;
649+
--md-filled-button-label-text-weight: 600;
650+
--md-filled-button-label-text-size: 14px;
651+
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
652+
box-shadow: 0 2px 8px rgba(138, 255, 128, 0.2);
653+
border: 1px solid rgba(138, 255, 128, 0.4);
654+
min-width: 120px;
655+
}
656+
657+
md-filled-button#enterBtn:hover {
658+
--md-filled-button-container-color: color-mix(in srgb, var(--secondary) 90%, #006642);
659+
box-shadow: 0 4px 16px rgba(138, 255, 128, 0.3);
660+
transform: translateY(-2px);
661+
border-color: rgba(138, 255, 128, 0.6);
662+
}
663+
664+
md-filled-button#enterBtn:active {
665+
transform: translateY(0);
666+
box-shadow: 0 2px 8px rgba(138, 255, 128, 0.25);
667+
}
668+
669+
/* Show record button always */
670+
.enter-button-container {
671+
display: block;
598672
}
599673

600674
/* Icon button (row delete) */
@@ -603,14 +677,6 @@
603677
--md-icon-button-hover-state-layer-color: color-mix(in srgb, var(--primary) 18%, transparent);
604678
--md-icon-button-pressed-state-layer-color: color-mix(in srgb, var(--primary) 26%, transparent);
605679
}
606-
.sr-only {
607-
position: absolute;
608-
width: 1px;
609-
height: 1px;
610-
overflow: hidden;
611-
clip: rect(0 0 0 0);
612-
white-space: nowrap;
613-
}
614680
</style>
615681
</head>
616682
<body>
@@ -641,6 +707,12 @@ <h1 class="md-typescale-title-large brand">Jump Consistent Hash</h1>
641707
<input id="slotsInput" class="slots-input" type="number" value="5" min="1" step="1" />
642708
<label for="slotsInput" class="input-label"># slots</label>
643709
</div>
710+
<div class="enter-button-container">
711+
<md-filled-button id="enterBtn" aria-label="Record entry">
712+
<md-icon slot="icon">add</md-icon>
713+
Record
714+
</md-filled-button>
715+
</div>
644716
</div>
645717
<div id="livePanel" class="live md-typescale-body-medium" aria-live="polite">
646718
<div>
@@ -654,11 +726,6 @@ <h1 class="md-typescale-title-large brand">Jump Consistent Hash</h1>
654726
<span class="mono" id="liveSlots">5</span>
655727
</div>
656728
</div>
657-
<div class="actions">
658-
<md-filled-tonal-button id="clearAllBtn" aria-label="Clear session entries"
659-
>Reset session</md-filled-tonal-button
660-
>
661-
</div>
662729
</section>
663730

664731
<section class="table-card" aria-label="Session entries">
@@ -678,6 +745,12 @@ <h1 class="md-typescale-title-large brand">Jump Consistent Hash</h1>
678745
</tr>
679746
</tbody>
680747
</table>
748+
<div class="actions">
749+
<md-filled-tonal-button id="clearAllBtn" aria-label="Clear session entries">
750+
<md-icon slot="icon">clear</md-icon>
751+
Reset session
752+
</md-filled-tonal-button>
753+
</div>
681754
</section>
682755
</main>
683756
<footer class="md-typescale-body-small">

0 commit comments

Comments
 (0)