BankBar.svelte 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. <script lang="ts">
  2. import { isPadDrag } from "./drag";
  3. import { BANKS, PER_BANK } from "./slots";
  4. let {
  5. bank,
  6. counts,
  7. what,
  8. onpick,
  9. ondragbank,
  10. }: {
  11. bank: number;
  12. counts: number[]; // filled slots per bank
  13. what: string; // "pads filled", "slots used"
  14. onpick: (bank: number) => void;
  15. ondragbank?: (bank: number) => void; // a pad dragged over a bank button
  16. } = $props();
  17. </script>
  18. <div class="banks" role="group" aria-label="Banks">
  19. {#each BANKS.split("") as letter, i (letter)}
  20. <button
  21. type="button"
  22. class:on={i === bank}
  23. aria-pressed={i === bank}
  24. aria-label="Bank {letter}, {counts[i]} of {PER_BANK} {what}"
  25. onclick={() => onpick(i)}
  26. ondragover={(e) => {
  27. // Dragging a pad over a bank shows that bank, to drop on its pads.
  28. if (!ondragbank || !isPadDrag(e)) return;
  29. e.preventDefault();
  30. if (e.dataTransfer) e.dataTransfer.dropEffect = "none";
  31. if (i !== bank) ondragbank(i);
  32. }}>{letter}</button
  33. >
  34. {/each}
  35. </div>
  36. <style>
  37. .banks {
  38. display: grid;
  39. grid-template-columns: repeat(8, minmax(0, 1fr));
  40. gap: 6px;
  41. }
  42. button {
  43. height: 36px;
  44. padding: 0;
  45. background: var(--raised);
  46. color: var(--text);
  47. border: 1px solid var(--edge);
  48. border-radius: 6px;
  49. font-family: var(--display);
  50. font-size: 15px;
  51. font-weight: 700;
  52. cursor: pointer;
  53. }
  54. button.on {
  55. background: var(--accent);
  56. color: var(--on-accent);
  57. border-color: var(--accent);
  58. }
  59. </style>