diff --git a/.changeset/bright-tigers-switch.md b/.changeset/bright-tigers-switch.md new file mode 100644 index 000000000..30d00e8a0 --- /dev/null +++ b/.changeset/bright-tigers-switch.md @@ -0,0 +1,5 @@ +--- +"@solid-primitives/pagination": patch +--- + +fix keyboard focus loss diff --git a/.storybook/ui/controls.tsx b/.storybook/ui/controls.tsx index 73aaaf553..42d469ab5 100644 --- a/.storybook/ui/controls.tsx +++ b/.storybook/ui/controls.tsx @@ -1,8 +1,11 @@ -import type { JSX } from "solid-js"; +import type { JSX } from "@solidjs/web"; import { colors, font, radii } from "./tokens.js"; export const Button = (props: { - onClick?: () => void; + "aria-current"?: "page"; + "aria-label"?: string; + onClick?: (ev: MouseEvent) => void; + onKeyUp?: (ev: KeyboardEvent) => void; children: JSX.Element; variant?: "primary" | "secondary" | "outline" | "ghost"; color?: string; @@ -12,9 +15,12 @@ export const Button = (props: { ref?: HTMLButtonElement | ((el: HTMLButtonElement) => void); }) => ( - )} - - -); +}) => { + const [props, page] = createPagination(() => barProps.options); + return (<> + + + ); +} export const CreatePaginationStory = meta.story({ name: "createPagination", @@ -69,41 +72,42 @@ export const CreatePaginationStory = meta.story({ render: () => { const [totalPages, setTotalPages] = createSignal(20); const [maxVisible, setMaxVisible] = createSignal(7); - const [paginationProps, page, _setPage] = createPagination(() => ({ + const paginationOptions = createMemo(() => ({ pages: totalPages(), maxPages: maxVisible(), })); - + return ( - - - - -
- - {([5, 7, 10] as const).map(n => ( - - ))} - -
-
- - {([10, 20, 50] as const).map(n => ( - - ))} - -
-
+

Error: {err}

}> + + + +
+ + {([5, 7, 10] as const).map(n => ( + + ))} + +
+
+ + {([10, 20, 50] as const).map(n => ( + + ))} + +
+
+
); }, }); diff --git a/packages/pagination/test/index.test.ts b/packages/pagination/test/index.test.tsx similarity index 85% rename from packages/pagination/test/index.test.ts rename to packages/pagination/test/index.test.tsx index 5d22ec361..658681360 100644 --- a/packages/pagination/test/index.test.ts +++ b/packages/pagination/test/index.test.tsx @@ -1,5 +1,6 @@ import { describe, test, expect } from "vitest"; -import { createMemo, createRoot, createSignal, flush } from "solid-js"; +import { createMemo, createRoot, createSignal, flush, For } from "solid-js"; +import { render } from "@solidjs/web"; import { createInfiniteScroll, createPagination, @@ -193,6 +194,37 @@ describe("createPagination", () => { expect(page()).toBe(8); dispose(); }); + + test("sets the focus after going to a new page", async () => { + const originalFocus = HTMLElement.prototype.focus; + let current = document.body; + HTMLElement.prototype.focus = function() { + current = this; + originalFocus.call(this); + }; + const container = document.createElement('div'); + document.body.appendChild(container); + const Pagination = () => { + const [pagination] = createPagination({ pages: 10, maxPages: 5, initialPage: 1 }); + return ; + }; + const dispose = render(() => , container); + const activeButton = container?.querySelector('nav button[aria-current="page"]'); + activeButton instanceof HTMLElement && activeButton.focus(); + for (var i = 0; i < 5; i++) { + await new Promise(r => setTimeout(r, 15)); + current?.dispatchEvent(new KeyboardEvent("keydown", { bubbles: true, charCode: 0, code: "ArrowRight", key: "ArrowRight", keyCode: 39 })); + current?.dispatchEvent(new KeyboardEvent("keyup", { bubbles: true, charCode: 0, code: "ArrowRight", key: "ArrowRight", keyCode: 39 })); + await new Promise(r => setTimeout(r, 45)); + expect(current.getAttribute("aria-current")).toBe("page"); + } + queueMicrotask(dispose); + HTMLElement.prototype.focus = originalFocus; + }); }); describe("createSegment", () => {