Skip to content

Commit

Permalink
Update nanostore, copy createSearchParams as utils
Browse files Browse the repository at this point in the history
  • Loading branch information
tordans committed Apr 3, 2024
1 parent 6472429 commit 3d2e27b
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 13 deletions.
20 changes: 10 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@
"@aws-sdk/client-s3": "^3.540.0",
"@headlessui/react": "^1.7.18",
"@nanostores/react": "^0.7.2",
"@nanostores/router": "^0.13.0",
"@nanostores/router": "^0.14.1",
"@turf/turf": "^7.0.0-alpha.114",
"astro": "^4.5.15",
"maplibre-gl": "^4.1.2",
"nanostores": "^0.9.5",
"nanostores": "^0.10.2",
"pmtiles": "^3.0.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
2 changes: 1 addition & 1 deletion src/components/BaseMap/store.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createSearchParams } from '@nanostores/router'
import { createSearchParams } from '@components/store/createSearchParams'
import { atom } from 'nanostores'
import type { MapGeoJSONFeature } from 'react-map-gl/maplibre'

Expand Down
2 changes: 2 additions & 0 deletions src/components/store/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Copied from https://github.com/nanostores/router/blob/0.13.0/index.js
Following the recommendation from https://github.com/nanostores/router/issues/30#issuecomment-1962767150
124 changes: 124 additions & 0 deletions src/components/store/createSearchParams.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import type { WritableAtom } from 'nanostores'
import { atom, onMount } from 'nanostores'

function isRouterClick(event: MouseEvent, link: HTMLAnchorElement) {
return (
link &&
event.button === 0 && // Left mouse button
link.target !== '_blank' && // Not for new tab
link.origin === location.origin && // Not external link
link.rel !== 'external' && // Not external link
link.target !== '_self' && // Now manually disabled
!link.download && // Not download link
!event.altKey && // Not download link by user
!event.metaKey && // Not open in new tab by user
!event.ctrlKey && // Not open in new tab by user
!event.shiftKey && // Not open in new window by user
!event.defaultPrevented // Click was not cancelled
)
}

export interface SearchParamsOptions {
links?: boolean
}

/**
* Store to watch for `?search` URL part changes.
*
* It will track history API and clicks on page’s links.
*/
export interface SearchParamsStore extends WritableAtom<Record<string, string>> {
/**
* Change `?search` URL part and update store value.
*
* ```js
* searchParams.open({ sort: 'name', type: 'small' })
* ```
*
* @param path Absolute URL (`https://example.com/a`)
* or domain-less URL (`/a`).
* @param redirect Don’t add entry to the navigation history.
*/
open(params: Record<string, string | number>, redirect?: boolean): void
}

/**
* Create {@link SearchParamsStore} store to watch for `?search` URL part.
*
* ```js
* export const searchParams = createSearchParams()
* ```
*
* @param opts Options.
*/
export function createSearchParams(opts?: SearchParamsOptions): SearchParamsStore {
const store = atom({}) as SearchParamsStore

const set = store.set
if (process.env.NODE_ENV !== 'production') {
// @ts-expect-error
delete store.set
}

let prev: string
const update = (href: string) => {
const url = new URL(href)
if (prev === url.search) return undefined
prev = url.search
set(Object.fromEntries(url.searchParams))
}

store.open = (params, redirect) => {
// @ts-expect-error our input type allow values of number which seems to work, so lets ignore the error
const urlParams = new URLSearchParams(params)
let search = urlParams.toString()
if (search) search = '?' + search

if (prev === search) return
prev = search

if (typeof history !== 'undefined') {
let href = location.pathname + search + location.hash
if (typeof history !== 'undefined') {
if (redirect) {
history.replaceState(null, '', href)
} else {
history.pushState(null, '', href)
}
}
}
set(Object.fromEntries(urlParams.entries()))
}

const click = (event: any) => {
const link = event.target.closest('a')
if (isRouterClick(event, link)) {
if (link.search !== prev) {
prev = link.search
set(Object.fromEntries(new URL(link.href).searchParams))
}
if (link.pathname === location.pathname && link.hash === location.hash) {
event.preventDefault()
history.pushState(null, '', link.href)
}
}
}

const popstate = () => {
update(location.href)
}

if (typeof window !== 'undefined' && typeof location !== 'undefined') {
onMount(store, () => {
popstate()
if (opts?.links !== false) document.body.addEventListener('click', click)
window.addEventListener('popstate', popstate)
return () => {
document.body.removeEventListener('click', click)
window.removeEventListener('popstate', popstate)
}
})
}

return store
}

0 comments on commit 3d2e27b

Please sign in to comment.