diff --git a/packages/web/src/index.css b/packages/web/src/index.css index d8f66be6..17bb4060 100644 --- a/packages/web/src/index.css +++ b/packages/web/src/index.css @@ -266,10 +266,53 @@ td { white-space: nowrap; } -tbody { - td { - color: var(--color-text-tertiary); - } +tbody td { + color: var(--color-text-tertiary); +} + +/* Checkbox column */ +td:first-child, +th:first-child { + width: 36px; + text-align: center; + padding: 0.75rem 0.5rem; +} + +/* Row selection highlight */ +tr.selected-row { + background-color: var(--color-surface); + font-weight: 500; + border-left: 2px solid var(--color-brand); +} + +/* Checkbox style */ +input[type="checkbox"].row-checkbox, +#select-all { + accent-color: var(--color-brand); + width: 1.15em; + height: 1.15em; + cursor: pointer; + border-radius: 2px; +} + +/* Filter button style - matches "How to use" button */ +#filter-selected { + flex: 0 0 auto; + cursor: pointer; + border: none; + background-color: var(--color-brand); + color: var(--color-text-invert); + font-size: 0.8125rem; + line-height: 1.1; + height: 2rem; + padding: 0.5rem 0.75rem; + border-radius: 0.25rem; +} +#filter-selected:disabled { + opacity: 0.5; + cursor: not-allowed; +} + td:nth-child(1) { font-weight: 500; @@ -410,7 +453,7 @@ tbody { .modality-icon:hover::after { opacity: 1; } -} + dialog::backdrop { backdrop-filter: blur(8px); diff --git a/packages/web/src/index.ts b/packages/web/src/index.ts index 393ee535..f59855e8 100644 --- a/packages/web/src/index.ts +++ b/packages/web/src/index.ts @@ -1,3 +1,5 @@ +import { initializeSelection } from "./selection.js"; + const modal = document.getElementById("modal") as HTMLDialogElement; const modalClose = document.getElementById("close")!; const help = document.getElementById("help")!; @@ -236,5 +238,8 @@ function initializeFromURL() { })(); } -document.addEventListener("DOMContentLoaded", initializeFromURL); +document.addEventListener("DOMContentLoaded", () => { + initializeFromURL(); + initializeSelection(); +}); window.addEventListener("popstate", initializeFromURL); diff --git a/packages/web/src/render.tsx b/packages/web/src/render.tsx index fffd5bdc..e27bcc71 100644 --- a/packages/web/src/render.tsx +++ b/packages/web/src/render.tsx @@ -206,12 +206,14 @@ export const Rendered = renderToString( ⌘K +
Provider | @@ -321,7 +323,10 @@ export const Rendered = renderToString( modelA.name.localeCompare(modelB.name) ) .map(([modelId, model]) => ( -|
---|---|
+ + |
{renderProviderLogo(providerId)}
@@ -520,5 +525,6 @@ export const Rendered = renderToString(
+
);
diff --git a/packages/web/src/selection.ts b/packages/web/src/selection.ts
new file mode 100644
index 00000000..af8fee70
--- /dev/null
+++ b/packages/web/src/selection.ts
@@ -0,0 +1,103 @@
+// Selection and Filter Logic for Models Table
+export function initializeSelection() {
+ const rowCheckboxes = () => Array.from(document.querySelectorAll('.row-checkbox')) as HTMLInputElement[];
+ const selectAll = document.getElementById('select-all') as HTMLInputElement;
+ const filterBtn = document.getElementById('filter-selected') as HTMLButtonElement;
+ const selected = new Set |