-
-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
198 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"runed": minor | ||
--- | ||
|
||
change: handle boolean conversion within `IsSupported` to improve DX |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"runed": minor | ||
--- | ||
|
||
feat: `useGeolocation` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./useGeolocation.svelte.js"; |
95 changes: 95 additions & 0 deletions
95
packages/runed/src/lib/utilities/useGeolocation/useGeolocation.svelte.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import { IsSupported } from "../IsSupported/IsSupported.svelte.js"; | ||
|
||
type UseGeolocationOptions = Partial<PositionOptions> & { | ||
/** | ||
* Whether to start the watcher immediately upon creation. If set to `false`, the watcher | ||
* will only start tracking the position when `resume()` is called. | ||
* | ||
* @defaultValue true | ||
*/ | ||
immediate?: boolean; | ||
}; | ||
|
||
type WritableProperties<T> = { | ||
-readonly [P in keyof T]: T[P]; | ||
}; | ||
|
||
/** | ||
* Reactive access to the browser's [Geolocation API](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API). | ||
*/ | ||
export function useGeolocation(options: UseGeolocationOptions = {}) { | ||
const { | ||
enableHighAccuracy = true, | ||
maximumAge = 30000, | ||
timeout = 27000, | ||
immediate = true, | ||
} = options; | ||
|
||
const isSupported = new IsSupported(() => navigator && "geolocation" in navigator); | ||
|
||
let locatedAt = $state<number | null>(null); | ||
let error = $state.raw<GeolocationPositionError | null>(null); | ||
let coords = $state<WritableProperties<Omit<GeolocationPosition["coords"], "toJSON">>>({ | ||
accuracy: 0, | ||
latitude: Number.POSITIVE_INFINITY, | ||
longitude: Number.POSITIVE_INFINITY, | ||
altitude: null, | ||
altitudeAccuracy: null, | ||
heading: null, | ||
speed: null, | ||
}); | ||
let isPaused = $state(false); | ||
|
||
function updatePosition(position: GeolocationPosition) { | ||
locatedAt = position.timestamp; | ||
coords.accuracy = position.coords.accuracy; | ||
coords.altitude = position.coords.altitude; | ||
coords.altitudeAccuracy = position.coords.altitudeAccuracy; | ||
coords.heading = position.coords.heading; | ||
coords.latitude = position.coords.latitude; | ||
coords.longitude = position.coords.longitude; | ||
coords.speed = position.coords.speed; | ||
} | ||
|
||
let watcher: number; | ||
|
||
function resume() { | ||
if (!isSupported.current) return; | ||
watcher = navigator!.geolocation.watchPosition(updatePosition, (err) => (error = err), { | ||
enableHighAccuracy, | ||
maximumAge, | ||
timeout, | ||
}); | ||
isPaused = false; | ||
} | ||
|
||
function pause() { | ||
if (watcher && navigator) navigator.geolocation.clearWatch(watcher); | ||
isPaused = true; | ||
} | ||
|
||
$effect(() => { | ||
if (immediate) resume(); | ||
return () => pause(); | ||
}); | ||
|
||
return { | ||
get isSupported() { | ||
return isSupported.current; | ||
}, | ||
get coords() { | ||
return coords; | ||
}, | ||
get locatedAt() { | ||
return locatedAt; | ||
}, | ||
get error() { | ||
return error; | ||
}, | ||
get isPaused() { | ||
return isPaused; | ||
}, | ||
resume, | ||
pause, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
--- | ||
title: useGeolocation | ||
description: Reactive access to the browser's Geolocation API. | ||
category: Browser | ||
--- | ||
|
||
<script> | ||
import Demo from '$lib/components/demos/use-geolocation.svelte'; | ||
</script> | ||
|
||
`useGeolocation` is a reactive wrapper around the browser's | ||
[Geolocation API](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API). | ||
|
||
## Demo | ||
|
||
<Demo /> | ||
|
||
## Usage | ||
|
||
```svelte | ||
<script lang="ts"> | ||
import { useGeolocation } from "runed"; | ||
const location = useGeolocation(); | ||
</script> | ||
<pre>Coords: {JSON.stringify(location.coords, null, 2)}</pre> | ||
<pre>Located at: {location.locatedAt}</pre> | ||
<pre>Error: {JSON.stringify(location.error, null, 2)}</pre> | ||
<pre>Is Supported: {location.isSupported}</pre> | ||
<button onclick={location.pause} disabled={location.isPaused}>Pause</button> | ||
<button onclick={location.resume} disabled={!location.isPaused}>Resume</button> | ||
``` | ||
|
||
## Type Definitions | ||
|
||
```ts | ||
type UseGeolocationOptions = Partial<PositionOptions> & { | ||
/** | ||
* Whether to start the watcher immediately upon creation. | ||
* If set to `false`, the watcher will only start tracking the position when `resume()` is called. | ||
* | ||
* @defaultValue true | ||
*/ | ||
immediate?: boolean; | ||
}; | ||
|
||
type UseGeolocationReturn = { | ||
readonly isSupported: boolean; | ||
readonly coords: Omit<GeolocationPosition["coords"], "toJSON">; | ||
readonly locatedAt: number | null; | ||
readonly error: GeolocationPositionError | null; | ||
readonly isPaused: boolean; | ||
pause: () => void; | ||
resume: () => void; | ||
}; | ||
``` | ||
|
||
``` | ||
``` |
17 changes: 17 additions & 0 deletions
17
sites/docs/src/lib/components/demos/use-geolocation.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<script lang="ts"> | ||
import { useGeolocation } from "runed"; | ||
import { DemoContainer, Button } from "@svecodocs/kit"; | ||
const location = useGeolocation(); | ||
</script> | ||
|
||
<DemoContainer class="flex flex-col gap-1"> | ||
<pre>Coords: {JSON.stringify(location.coords, null, 2)}</pre> | ||
<pre>Located at: {location.locatedAt}</pre> | ||
<pre>Error: {JSON.stringify(location.error, null, 2)}</pre> | ||
<pre>Is Supported: {location.isSupported}</pre> | ||
<div class="mt-4 flex items-center gap-2"> | ||
<Button size="sm" onclick={location.pause} disabled={location.isPaused}>Pause</Button> | ||
<Button size="sm" onclick={location.resume} disabled={!location.isPaused}>Resume</Button> | ||
</div> | ||
</DemoContainer> |