mirror of
https://github.com/LukeHagar/unicorn-utterances.git
synced 2025-12-06 04:21:55 +00:00
chore: get things to stop throwing errors
This commit is contained in:
@@ -28,7 +28,7 @@ export default defineConfig({
|
|||||||
site: siteUrl,
|
site: siteUrl,
|
||||||
integrations: [
|
integrations: [
|
||||||
image(),
|
image(),
|
||||||
preact(),
|
preact({ compat: true }),
|
||||||
mdx(),
|
mdx(),
|
||||||
sitemap({
|
sitemap({
|
||||||
changefreq: ChangeFreq.DAILY,
|
changefreq: ChangeFreq.DAILY,
|
||||||
@@ -46,6 +46,7 @@ export default defineConfig({
|
|||||||
vite: {
|
vite: {
|
||||||
ssr: {
|
ssr: {
|
||||||
external: ["svgo"],
|
external: ["svgo"],
|
||||||
|
noExternal: ["@floating-ui/react", "@floating-ui/react-dom"],
|
||||||
},
|
},
|
||||||
plugins: [svgr()],
|
plugins: [svgr()],
|
||||||
},
|
},
|
||||||
|
|||||||
119
package-lock.json
generated
119
package-lock.json
generated
@@ -9,6 +9,7 @@
|
|||||||
"version": "0.3.0-alpha.1",
|
"version": "0.3.0-alpha.1",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@floating-ui/react": "^0.24.3",
|
||||||
"medium-zoom": "^1.0.8",
|
"medium-zoom": "^1.0.8",
|
||||||
"preact": "^10.15.1"
|
"preact": "^10.15.1"
|
||||||
},
|
},
|
||||||
@@ -25,7 +26,6 @@
|
|||||||
"@testing-library/preact": "^3.2.3",
|
"@testing-library/preact": "^3.2.3",
|
||||||
"@types/jest": "^29.4.0",
|
"@types/jest": "^29.4.0",
|
||||||
"@types/node": "^18.13.0",
|
"@types/node": "^18.13.0",
|
||||||
"@types/react": "^18.0.33",
|
|
||||||
"@types/uuid": "^9.0.2",
|
"@types/uuid": "^9.0.2",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.60.0",
|
"@typescript-eslint/eslint-plugin": "^5.60.0",
|
||||||
"@typescript-eslint/parser": "^5.60.0",
|
"@typescript-eslint/parser": "^5.60.0",
|
||||||
@@ -60,7 +60,6 @@
|
|||||||
"prettier-plugin-astro": "^0.10.0",
|
"prettier-plugin-astro": "^0.10.0",
|
||||||
"probe-image-size": "^7.2.3",
|
"probe-image-size": "^7.2.3",
|
||||||
"puppeteer-core": "^10.4.0",
|
"puppeteer-core": "^10.4.0",
|
||||||
"react": "^18.2.0",
|
|
||||||
"rehype-raw": "^6.1.1",
|
"rehype-raw": "^6.1.1",
|
||||||
"rehype-retext": "^3.0.2",
|
"rehype-retext": "^3.0.2",
|
||||||
"rehype-slug-custom-id": "^1.1.0",
|
"rehype-slug-custom-id": "^1.1.0",
|
||||||
@@ -1226,6 +1225,45 @@
|
|||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@floating-ui/core": {
|
||||||
|
"version": "1.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.3.1.tgz",
|
||||||
|
"integrity": "sha512-Bu+AMaXNjrpjh41znzHqaz3r2Nr8hHuHZT6V2LBKMhyMl0FgKA62PNYbqnfgmzOhoWZj70Zecisbo4H1rotP5g=="
|
||||||
|
},
|
||||||
|
"node_modules/@floating-ui/dom": {
|
||||||
|
"version": "1.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.4.2.tgz",
|
||||||
|
"integrity": "sha512-VKmvHVatWnewmGGy+7Mdy4cTJX71Pli6v/Wjb5RQBuq5wjUYx+Ef+kRThi8qggZqDgD8CogCpqhRoVp3+yQk+g==",
|
||||||
|
"dependencies": {
|
||||||
|
"@floating-ui/core": "^1.3.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@floating-ui/react": {
|
||||||
|
"version": "0.24.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.24.3.tgz",
|
||||||
|
"integrity": "sha512-wWC9duiog4HmbgKSKObDRuXqMjZR/6m75MIG+slm5CVWbridAjK9STcnCsGYmdpK78H/GmzYj4ADVP8paZVLYQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@floating-ui/react-dom": "^2.0.1",
|
||||||
|
"aria-hidden": "^1.1.3",
|
||||||
|
"tabbable": "^6.0.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.8.0",
|
||||||
|
"react-dom": ">=16.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@floating-ui/react-dom": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-rZtAmSht4Lry6gdhAJDrCp/6rKN7++JnL1/Anbr/DdeyYXQPxvg/ivrbYvJulbRf4vL8b212suwMM2lxbv+RQA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@floating-ui/dom": "^1.3.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.8.0",
|
||||||
|
"react-dom": ">=16.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@gar/promisify": {
|
"node_modules/@gar/promisify": {
|
||||||
"version": "1.1.3",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
|
||||||
@@ -3478,23 +3516,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/prop-types": {
|
|
||||||
"version": "15.7.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
|
|
||||||
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/@types/react": {
|
|
||||||
"version": "18.0.33",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.33.tgz",
|
|
||||||
"integrity": "sha512-sHxzVxeanvQyQ1lr8NSHaj0kDzcNiGpILEVt69g9S31/7PfMvNCKLKcsHw4lYKjs3cGNJjXSP4mYzX43QlnjNA==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@types/prop-types": "*",
|
|
||||||
"@types/scheduler": "*",
|
|
||||||
"csstype": "^3.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/resolve": {
|
"node_modules/@types/resolve": {
|
||||||
"version": "1.20.2",
|
"version": "1.20.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
|
||||||
@@ -3516,12 +3537,6 @@
|
|||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/scheduler": {
|
|
||||||
"version": "0.16.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
|
|
||||||
"integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/@types/semver": {
|
"node_modules/@types/semver": {
|
||||||
"version": "7.5.0",
|
"version": "7.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz",
|
||||||
@@ -4303,6 +4318,17 @@
|
|||||||
"sprintf-js": "~1.0.2"
|
"sprintf-js": "~1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/aria-hidden": {
|
||||||
|
"version": "1.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.3.tgz",
|
||||||
|
"integrity": "sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/aria-query": {
|
"node_modules/aria-query": {
|
||||||
"version": "5.1.3",
|
"version": "5.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz",
|
||||||
@@ -6323,12 +6349,6 @@
|
|||||||
"integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==",
|
"integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/csstype": {
|
|
||||||
"version": "3.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
|
|
||||||
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/damerau-levenshtein": {
|
"node_modules/damerau-levenshtein": {
|
||||||
"version": "1.0.8",
|
"version": "1.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
|
||||||
@@ -13044,8 +13064,7 @@
|
|||||||
"node_modules/js-tokens": {
|
"node_modules/js-tokens": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/js-yaml": {
|
"node_modules/js-yaml": {
|
||||||
"version": "3.14.1",
|
"version": "3.14.1",
|
||||||
@@ -13867,7 +13886,7 @@
|
|||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||||
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
|
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
|
||||||
"dev": true,
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"js-tokens": "^3.0.0 || ^4.0.0"
|
"js-tokens": "^3.0.0 || ^4.0.0"
|
||||||
},
|
},
|
||||||
@@ -17077,7 +17096,7 @@
|
|||||||
"version": "18.2.0",
|
"version": "18.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
|
||||||
"integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
|
"integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
|
||||||
"dev": true,
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"loose-envify": "^1.1.0"
|
"loose-envify": "^1.1.0"
|
||||||
},
|
},
|
||||||
@@ -17085,6 +17104,19 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-dom": {
|
||||||
|
"version": "18.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
|
||||||
|
"integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"loose-envify": "^1.1.0",
|
||||||
|
"scheduler": "^0.23.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^18.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-is": {
|
"node_modules/react-is": {
|
||||||
"version": "17.0.2",
|
"version": "17.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
||||||
@@ -18460,6 +18492,15 @@
|
|||||||
"node": ">=v12.22.7"
|
"node": ">=v12.22.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/scheduler": {
|
||||||
|
"version": "0.23.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
|
||||||
|
"integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"loose-envify": "^1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/section-matter": {
|
"node_modules/section-matter": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz",
|
||||||
@@ -19602,6 +19643,11 @@
|
|||||||
"url": "https://opencollective.com/unts"
|
"url": "https://opencollective.com/unts"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/tabbable": {
|
||||||
|
"version": "6.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.1.2.tgz",
|
||||||
|
"integrity": "sha512-qCN98uP7i9z0fIS4amQ5zbGBOq+OSigYeGvPy7NDk8Y9yncqDZ9pRPgfsc2PJIVM9RrJj7GIfuRgmjoUU9zTHQ=="
|
||||||
|
},
|
||||||
"node_modules/tar": {
|
"node_modules/tar": {
|
||||||
"version": "6.1.11",
|
"version": "6.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
|
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
|
||||||
@@ -20076,8 +20122,7 @@
|
|||||||
"node_modules/tslib": {
|
"node_modules/tslib": {
|
||||||
"version": "2.5.3",
|
"version": "2.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz",
|
||||||
"integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==",
|
"integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/tsutils": {
|
"node_modules/tsutils": {
|
||||||
"version": "3.21.0",
|
"version": "3.21.0",
|
||||||
|
|||||||
@@ -52,7 +52,6 @@
|
|||||||
"@testing-library/preact": "^3.2.3",
|
"@testing-library/preact": "^3.2.3",
|
||||||
"@types/jest": "^29.4.0",
|
"@types/jest": "^29.4.0",
|
||||||
"@types/node": "^18.13.0",
|
"@types/node": "^18.13.0",
|
||||||
"@types/react": "^18.0.33",
|
|
||||||
"@types/uuid": "^9.0.2",
|
"@types/uuid": "^9.0.2",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.60.0",
|
"@typescript-eslint/eslint-plugin": "^5.60.0",
|
||||||
"@typescript-eslint/parser": "^5.60.0",
|
"@typescript-eslint/parser": "^5.60.0",
|
||||||
@@ -85,7 +84,6 @@
|
|||||||
"prettier": "^2.8.8",
|
"prettier": "^2.8.8",
|
||||||
"prettier-plugin-astro": "^0.10.0",
|
"prettier-plugin-astro": "^0.10.0",
|
||||||
"puppeteer-core": "^10.4.0",
|
"puppeteer-core": "^10.4.0",
|
||||||
"react": "^18.2.0",
|
|
||||||
"rehype-raw": "^6.1.1",
|
"rehype-raw": "^6.1.1",
|
||||||
"rehype-retext": "^3.0.2",
|
"rehype-retext": "^3.0.2",
|
||||||
"rehype-slug-custom-id": "^1.1.0",
|
"rehype-slug-custom-id": "^1.1.0",
|
||||||
@@ -114,7 +112,12 @@
|
|||||||
"*.{js,ts,astro,jsx}": "prettier --write"
|
"*.{js,ts,astro,jsx}": "prettier --write"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@floating-ui/react": "^0.24.3",
|
||||||
"medium-zoom": "^1.0.8",
|
"medium-zoom": "^1.0.8",
|
||||||
"preact": "^10.15.1"
|
"preact": "^10.15.1"
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"react": "npm:@preact/compat@latest",
|
||||||
|
"react-dom": "npm:@preact/compat@latest"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
37
src/components/pagination/pagination-popover.tsx
Normal file
37
src/components/pagination/pagination-popover.tsx
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import { useClick, useFloating, useInteractions } from "@floating-ui/react";
|
||||||
|
import { useState } from "preact/hooks";
|
||||||
|
import { Fragment } from "preact";
|
||||||
|
import { createPortal } from "preact/compat";
|
||||||
|
|
||||||
|
export function PaginationPopover() {
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
|
||||||
|
const { refs, floatingStyles, context } = useFloating({
|
||||||
|
open: isOpen,
|
||||||
|
onOpenChange: setIsOpen,
|
||||||
|
});
|
||||||
|
|
||||||
|
const click = useClick(context);
|
||||||
|
|
||||||
|
const { getReferenceProps, getFloatingProps } = useInteractions([click]);
|
||||||
|
|
||||||
|
const portal = createPortal(
|
||||||
|
<div
|
||||||
|
ref={refs.setFloating}
|
||||||
|
style={floatingStyles as never}
|
||||||
|
{...getFloatingProps()}
|
||||||
|
>
|
||||||
|
Floating element
|
||||||
|
</div>,
|
||||||
|
document.querySelector("body")
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<div ref={refs.setReference} {...getReferenceProps()}>
|
||||||
|
Reference element
|
||||||
|
</div>
|
||||||
|
{isOpen && portal}
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -4,6 +4,8 @@ import { Button } from "components/base";
|
|||||||
import forward from "src/icons/forward.svg?raw";
|
import forward from "src/icons/forward.svg?raw";
|
||||||
import back from "src/icons/back.svg?raw";
|
import back from "src/icons/back.svg?raw";
|
||||||
import more from "src/icons/more-horizontal.svg?raw";
|
import more from "src/icons/more-horizontal.svg?raw";
|
||||||
|
import { PaginationPopover } from "components/pagination/pagination-popover";
|
||||||
|
import { useEffect, useState } from "preact/hooks";
|
||||||
|
|
||||||
const PAGE_BUTTON_COUNT = 6;
|
const PAGE_BUTTON_COUNT = 6;
|
||||||
|
|
||||||
@@ -15,11 +17,13 @@ interface PaginationProps {
|
|||||||
getPageHref?: (pageNum: number) => string;
|
getPageHref?: (pageNum: number) => string;
|
||||||
}
|
}
|
||||||
|
|
||||||
function PaginationButton(props: { pageNum: number, selected: boolean, href: string }) {
|
function PaginationButton(props: {
|
||||||
|
pageNum: number;
|
||||||
|
selected: boolean;
|
||||||
|
href: string;
|
||||||
|
}) {
|
||||||
return (
|
return (
|
||||||
<li
|
<li className={`${styles.paginationItem}`}>
|
||||||
className={`${styles.paginationItem}`}
|
|
||||||
>
|
|
||||||
<a
|
<a
|
||||||
className={`text-style-body-medium-bold ${styles.paginationButton} ${
|
className={`text-style-body-medium-bold ${styles.paginationButton} ${
|
||||||
props.selected ? styles.selected : ""
|
props.selected ? styles.selected : ""
|
||||||
@@ -31,20 +35,35 @@ function PaginationButton(props: { pageNum: number, selected: boolean, href: str
|
|||||||
{props.pageNum + ""}
|
{props.pageNum + ""}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function PaginationMenu(props: Pick<PaginationProps, "page" | "getPageHref">) {
|
function PaginationMenu(props: Pick<PaginationProps, "page" | "getPageHref">) {
|
||||||
return (
|
return (
|
||||||
<li
|
<li className={`${styles.paginationItem}`}>
|
||||||
className={`${styles.paginationItem}`}
|
|
||||||
>
|
|
||||||
<button
|
<button
|
||||||
className={`text-style-body-medium-bold ${styles.paginationButton} ${styles.paginationIconButton}`}
|
className={`text-style-body-medium-bold ${styles.paginationButton} ${styles.paginationIconButton}`}
|
||||||
dangerouslySetInnerHTML={{ __html: more }}
|
dangerouslySetInnerHTML={{ __html: more }}
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
)
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This prevents the pagination menu from rendering on SSR, which throws errors
|
||||||
|
*/
|
||||||
|
function PaginationMenuWrapper(
|
||||||
|
props: Pick<PaginationProps, "page" | "getPageHref">
|
||||||
|
) {
|
||||||
|
const [shouldRender, setShouldRender] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setShouldRender(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!shouldRender) return null;
|
||||||
|
|
||||||
|
return <PaginationMenu {...props} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Pagination = ({
|
export const Pagination = ({
|
||||||
@@ -55,8 +74,7 @@ export const Pagination = ({
|
|||||||
getPageHref = (pageNum: number) => `${rootURL}${pageNum}`,
|
getPageHref = (pageNum: number) => `${rootURL}${pageNum}`,
|
||||||
}: PaginationProps) => {
|
}: PaginationProps) => {
|
||||||
// if there's only one page, don't render anything
|
// if there's only one page, don't render anything
|
||||||
if (page.currentPage === 1 && page.lastPage < 2)
|
if (page.currentPage === 1 && page.lastPage < 2) return <></>;
|
||||||
return <></>;
|
|
||||||
|
|
||||||
const isPreviousEnabled = page.currentPage > 1;
|
const isPreviousEnabled = page.currentPage > 1;
|
||||||
const isNextEnabled = page.currentPage < page.lastPage;
|
const isNextEnabled = page.currentPage < page.lastPage;
|
||||||
@@ -66,63 +84,62 @@ export const Pagination = ({
|
|||||||
// if the current page is close to the end, dots should be before so that the end is continuous
|
// if the current page is close to the end, dots should be before so that the end is continuous
|
||||||
const isDotsFirst = page.lastPage - page.currentPage < PAGE_BUTTON_COUNT;
|
const isDotsFirst = page.lastPage - page.currentPage < PAGE_BUTTON_COUNT;
|
||||||
|
|
||||||
const firstPageNum = Math.max(2, Math.min(page.lastPage - PAGE_BUTTON_COUNT, page.currentPage - 1));
|
const firstPageNum = Math.max(
|
||||||
|
2,
|
||||||
|
Math.min(page.lastPage - PAGE_BUTTON_COUNT, page.currentPage - 1)
|
||||||
|
);
|
||||||
const pages = [
|
const pages = [
|
||||||
// first page is always displayed
|
// first page is always displayed
|
||||||
1,
|
1,
|
||||||
isDotsFirst && "...",
|
isDotsFirst && "...",
|
||||||
...Array(PAGE_BUTTON_COUNT).fill(0).map((_, i) => i + firstPageNum),
|
...Array(PAGE_BUTTON_COUNT)
|
||||||
|
.fill(0)
|
||||||
|
.map((_, i) => i + firstPageNum),
|
||||||
!isDotsFirst && "...",
|
!isDotsFirst && "...",
|
||||||
// last page is always displayed
|
// last page is always displayed
|
||||||
page.lastPage,
|
page.lastPage,
|
||||||
].filter(
|
].filter(
|
||||||
// ensure that displayed pages are within the desired range
|
// ensure that displayed pages are within the desired range
|
||||||
i => (i === "..." && isDotsEnabled) || (+i > 0 && +i <= page.lastPage)
|
(i) => (i === "..." && isDotsEnabled) || (+i > 0 && +i <= page.lastPage)
|
||||||
);
|
);
|
||||||
|
|
||||||
return <>
|
return (
|
||||||
<div role="navigation" aria-label="Pagination Navigation">
|
<>
|
||||||
<ul
|
<div role="navigation" aria-label="Pagination Navigation">
|
||||||
id={id}
|
<ul id={id} className={`${styles.pagination} ${className}`}>
|
||||||
className={`${styles.pagination} ${className}`}
|
<li className={`${styles.paginationItem}`}>
|
||||||
>
|
<a
|
||||||
<li className={`${styles.paginationItem}`}>
|
className={`text-style-body-medium-bold ${styles.paginationButton} ${styles.paginationIconButton}`}
|
||||||
<a
|
href={getPageHref(page.currentPage - 1)}
|
||||||
className={`text-style-body-medium-bold ${styles.paginationButton} ${styles.paginationIconButton}`}
|
aria-label="Previous"
|
||||||
href={getPageHref(page.currentPage - 1)}
|
aria-disabled={!isPreviousEnabled}
|
||||||
aria-label="Previous"
|
dangerouslySetInnerHTML={{ __html: back }}
|
||||||
aria-disabled={!isPreviousEnabled}
|
/>
|
||||||
dangerouslySetInnerHTML={{ __html: back }}
|
</li>
|
||||||
/>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
{pages.map(pageNum => {
|
{pages.map((pageNum) => {
|
||||||
return typeof pageNum === "number"
|
return typeof pageNum === "number" ? (
|
||||||
? (
|
|
||||||
<PaginationButton
|
<PaginationButton
|
||||||
pageNum={pageNum}
|
pageNum={pageNum}
|
||||||
selected={pageNum === page.currentPage}
|
selected={pageNum === page.currentPage}
|
||||||
href={getPageHref(pageNum)}
|
href={getPageHref(pageNum)}
|
||||||
/>
|
/>
|
||||||
)
|
) : (
|
||||||
: (
|
<PaginationMenuWrapper page={page} getPageHref={getPageHref} />
|
||||||
<PaginationMenu
|
|
||||||
page={page}
|
|
||||||
getPageHref={getPageHref}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
||||||
<li className={`${styles.paginationItem}`}>
|
<li className={`${styles.paginationItem}`}>
|
||||||
<a
|
<a
|
||||||
className={`text-style-body-medium-bold ${styles.paginationButton} ${styles.paginationIconButton}`}
|
className={`text-style-body-medium-bold ${styles.paginationButton} ${styles.paginationIconButton}`}
|
||||||
href={getPageHref(page.currentPage + 1)}
|
href={getPageHref(page.currentPage + 1)}
|
||||||
aria-label="Next"
|
aria-label="Next"
|
||||||
aria-disabled={!isNextEnabled}
|
aria-disabled={!isNextEnabled}
|
||||||
dangerouslySetInnerHTML={{ __html: forward }}
|
dangerouslySetInnerHTML={{ __html: forward }}
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</>;
|
</>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user