diff options
Diffstat (limited to 'alpinejs/packages/history/src')
-rw-r--r-- | alpinejs/packages/history/src/index.js | 76 | ||||
-rw-r--r-- | alpinejs/packages/history/src/url.js | 36 |
2 files changed, 112 insertions, 0 deletions
diff --git a/alpinejs/packages/history/src/index.js b/alpinejs/packages/history/src/index.js new file mode 100644 index 0000000..f230d80 --- /dev/null +++ b/alpinejs/packages/history/src/index.js @@ -0,0 +1,76 @@ +export default function history(Alpine) { + Alpine.magic('queryString', (el, { interceptor }) => { + let alias + + return interceptor((initialValue, getter, setter, path, key) => { + let pause = false + let queryKey = alias || path + + let value = initialValue + let url = new URL(window.location.href) + + if (url.searchParams.has(queryKey)) { + value = url.searchParams.get(queryKey) + } + + setter(value) + + let object = { value } + + url.searchParams.set(queryKey, value) + + replace(url.toString(), path, object) + + window.addEventListener('popstate', (e) => { + if (! e.state) return + if (! e.state.alpine) return + + Object.entries(e.state.alpine).forEach(([newKey, { value }]) => { + if (newKey !== key) return + + pause = true + + Alpine.disableEffectScheduling(() => { + setter(value) + }) + + pause = false + }) + }) + + Alpine.effect(() => { + let value = getter() + + if (pause) return + + let object = { value } + + let url = new URL(window.location.href) + + url.searchParams.set(queryKey, value) + + push(url.toString(), path, object) + }) + + return value + }, func => { + func.as = key => { alias = key; return func } + }) + }) +} + +function replace(url, key, object) { + let state = window.history.state || {} + + if (! state.alpine) state.alpine = {} + + state.alpine[key] = object + + window.history.replaceState(state, '', url) +} + +function push(url, key, object) { + let state = { alpine: {...window.history.state.alpine, ...{[key]: object}} } + + window.history.pushState(state, '', url) +} diff --git a/alpinejs/packages/history/src/url.js b/alpinejs/packages/history/src/url.js new file mode 100644 index 0000000..7e2b4b6 --- /dev/null +++ b/alpinejs/packages/history/src/url.js @@ -0,0 +1,36 @@ + +export function hasQueryParam(param) { + let queryParams = new URLSearchParams(window.location.search); + + return queryParams.has(param) +} + +export function getQueryParam(param) { + let queryParams = new URLSearchParams(window.location.search); + + return queryParams.get(param) +} + +export function setQueryParam(param, value) { + let queryParams = new URLSearchParams(window.location.search); + + queryParams.set(param, value) + + let url = urlFromQueryParams(queryParams) + + history.replaceState(history.state, '', url) +} + +function urlFromParams(params = {}) { + let queryParams = new URLSearchParams(window.location.search); + + Object.entries(params).forEach(([key, value]) => { + queryParams.set(key, value) + }) + + let queryString = Array.from(queryParams.entries()).length > 0 + ? '?'+params.toString() + : '' + + return window.location.origin + window.location.pathname + '?'+queryString + window.location.hash +} |