elements-kit 0.0.8 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/builder/dom.d.mts +1 -1
- package/dist/builder/index.d.mts +1 -1
- package/dist/{index-BGKVkZ6y.d.mts → index-BtqiEEfc.d.mts} +1 -1
- package/dist/{index-Ukqj0EcT.d.mts → index-CKjDUp1B.d.mts} +1 -1
- package/dist/jsx-runtime/index.d.mts +1 -1
- package/dist/magic-string.es-i62WTP6J.mjs +1011 -0
- package/dist/signals/index.d.mts +1 -1
- package/dist/signals/lib/active-element.d.mts +10 -0
- package/dist/signals/lib/active-element.mjs +12 -0
- package/dist/signals/lib/active-element.test.d.mts +1 -0
- package/dist/signals/lib/active-element.test.mjs +39 -0
- package/dist/signals/lib/animation-frames.d.mts +18 -0
- package/dist/signals/lib/animation-frames.mjs +48 -0
- package/dist/signals/lib/animation-frames.test.d.mts +1 -0
- package/dist/signals/lib/animation-frames.test.mjs +52 -0
- package/dist/signals/lib/async-retry.d.mts +21 -0
- package/dist/signals/lib/async-retry.mjs +57 -0
- package/dist/signals/lib/async-retry.test.d.mts +1 -0
- package/dist/signals/lib/async-retry.test.mjs +57 -0
- package/dist/signals/lib/audio.d.mts +21 -0
- package/dist/signals/lib/audio.mjs +35 -0
- package/dist/signals/lib/audio.test.d.mts +1 -0
- package/dist/signals/lib/audio.test.mjs +57 -0
- package/dist/signals/lib/battery.d.mts +17 -0
- package/dist/signals/lib/battery.mjs +45 -0
- package/dist/signals/lib/battery.test.d.mts +1 -0
- package/dist/signals/lib/battery.test.mjs +38 -0
- package/dist/signals/lib/before-unload.d.mts +11 -0
- package/dist/signals/lib/before-unload.mjs +20 -0
- package/dist/signals/lib/before-unload.test.d.mts +1 -0
- package/dist/signals/lib/before-unload.test.mjs +29 -0
- package/dist/signals/lib/clipboard.d.mts +15 -0
- package/dist/signals/lib/clipboard.mjs +25 -0
- package/dist/signals/lib/clipboard.test.d.mts +1 -0
- package/dist/signals/lib/clipboard.test.mjs +53 -0
- package/dist/signals/lib/counter.d.mts +18 -0
- package/dist/signals/lib/counter.mjs +21 -0
- package/dist/signals/lib/counter.test.d.mts +1 -0
- package/dist/signals/lib/counter.test.mjs +74 -0
- package/dist/signals/lib/debounced.d.mts +12 -0
- package/dist/signals/lib/debounced.mjs +20 -0
- package/dist/signals/lib/debounced.test.d.mts +1 -0
- package/dist/signals/lib/debounced.test.mjs +66 -0
- package/dist/signals/lib/document-title.d.mts +10 -0
- package/dist/signals/lib/document-title.mjs +15 -0
- package/dist/signals/lib/document-title.test.d.mts +1 -0
- package/dist/signals/lib/document-title.test.mjs +33 -0
- package/dist/signals/lib/element-rect.d.mts +21 -0
- package/dist/signals/lib/element-rect.mjs +46 -0
- package/dist/signals/lib/element-rect.test.d.mts +1 -0
- package/dist/signals/lib/element-rect.test.mjs +99 -0
- package/dist/signals/lib/element-size.d.mts +16 -0
- package/dist/signals/lib/element-size.mjs +32 -0
- package/dist/signals/lib/element-size.test.d.mts +1 -0
- package/dist/signals/lib/element-size.test.mjs +86 -0
- package/dist/signals/lib/event-driven.d.mts +47 -0
- package/dist/signals/lib/event-driven.mjs +38 -0
- package/dist/signals/lib/event-listener.d.mts +14 -0
- package/dist/signals/lib/event-listener.mjs +28 -0
- package/dist/signals/lib/event-listener.test.d.mts +1 -0
- package/dist/signals/lib/event-listener.test.mjs +58 -0
- package/dist/signals/lib/favicon.d.mts +10 -0
- package/dist/signals/lib/favicon.mjs +24 -0
- package/dist/signals/lib/favicon.test.d.mts +1 -0
- package/dist/signals/lib/favicon.test.mjs +28 -0
- package/dist/signals/lib/finite-state-machine.d.mts +22 -0
- package/dist/signals/lib/finite-state-machine.mjs +26 -0
- package/dist/signals/lib/finite-state-machine.test.d.mts +1 -0
- package/dist/signals/lib/finite-state-machine.test.mjs +66 -0
- package/dist/signals/lib/fullscreen.d.mts +15 -0
- package/dist/signals/lib/fullscreen.mjs +24 -0
- package/dist/signals/lib/fullscreen.test.d.mts +1 -0
- package/dist/signals/lib/fullscreen.test.mjs +48 -0
- package/dist/signals/lib/geolocation.d.mts +15 -0
- package/dist/signals/lib/geolocation.mjs +30 -0
- package/dist/signals/lib/geolocation.test.d.mts +1 -0
- package/dist/signals/lib/geolocation.test.mjs +37 -0
- package/dist/signals/lib/hash.d.mts +10 -0
- package/dist/signals/lib/hash.mjs +14 -0
- package/dist/signals/lib/hash.test.d.mts +1 -0
- package/dist/signals/lib/hash.test.mjs +46 -0
- package/dist/signals/lib/hover.d.mts +11 -0
- package/dist/signals/lib/hover.mjs +23 -0
- package/dist/signals/lib/hover.test.d.mts +1 -0
- package/dist/signals/lib/hover.test.mjs +63 -0
- package/dist/signals/lib/intersection-observer.d.mts +8 -0
- package/dist/signals/lib/intersection-observer.mjs +16 -0
- package/dist/signals/lib/intersection-observer.test.d.mts +1 -0
- package/dist/signals/lib/intersection-observer.test.mjs +44 -0
- package/dist/signals/lib/interval.d.mts +18 -0
- package/dist/signals/lib/interval.mjs +38 -0
- package/dist/signals/lib/interval.test.d.mts +1 -0
- package/dist/signals/lib/interval.test.mjs +68 -0
- package/dist/signals/lib/is-document-visible.d.mts +11 -0
- package/dist/signals/lib/is-document-visible.mjs +13 -0
- package/dist/signals/lib/is-document-visible.test.d.mts +1 -0
- package/dist/signals/lib/is-document-visible.test.mjs +58 -0
- package/dist/signals/lib/is-focus-within.d.mts +10 -0
- package/dist/signals/lib/is-focus-within.mjs +28 -0
- package/dist/signals/lib/is-focus-within.test.d.mts +1 -0
- package/dist/signals/lib/is-focus-within.test.mjs +50 -0
- package/dist/signals/lib/is-idle.d.mts +10 -0
- package/dist/signals/lib/is-idle.mjs +37 -0
- package/dist/signals/lib/is-idle.test.d.mts +1 -0
- package/dist/signals/lib/is-idle.test.mjs +50 -0
- package/dist/signals/lib/is-in-viewport.d.mts +10 -0
- package/dist/signals/lib/is-in-viewport.mjs +16 -0
- package/dist/signals/lib/is-in-viewport.test.d.mts +1 -0
- package/dist/signals/lib/is-in-viewport.test.mjs +74 -0
- package/dist/signals/lib/key-press.d.mts +13 -0
- package/dist/signals/lib/key-press.mjs +25 -0
- package/dist/signals/lib/key-press.test.d.mts +1 -0
- package/dist/signals/lib/key-press.test.mjs +52 -0
- package/dist/signals/lib/list.d.mts +19 -0
- package/dist/signals/lib/list.mjs +36 -0
- package/dist/signals/lib/list.test.d.mts +1 -0
- package/dist/signals/lib/list.test.mjs +104 -0
- package/dist/signals/lib/lock-body-scroll.d.mts +8 -0
- package/dist/signals/lib/lock-body-scroll.mjs +17 -0
- package/dist/signals/lib/lock-body-scroll.test.d.mts +1 -0
- package/dist/signals/lib/lock-body-scroll.test.mjs +37 -0
- package/dist/signals/lib/long-press.d.mts +10 -0
- package/dist/signals/lib/long-press.mjs +29 -0
- package/dist/signals/lib/long-press.test.d.mts +1 -0
- package/dist/signals/lib/long-press.test.mjs +52 -0
- package/dist/signals/lib/map.d.mts +18 -0
- package/dist/signals/lib/map.mjs +33 -0
- package/dist/signals/lib/map.test.d.mts +1 -0
- package/dist/signals/lib/map.test.mjs +60 -0
- package/dist/signals/lib/media-devices.d.mts +10 -0
- package/dist/signals/lib/media-devices.mjs +18 -0
- package/dist/signals/lib/media-devices.test.d.mts +1 -0
- package/dist/signals/lib/media-devices.test.mjs +44 -0
- package/dist/signals/lib/media.d.mts +1 -1
- package/dist/signals/lib/media.mjs +3 -10
- package/dist/signals/lib/motion.d.mts +15 -0
- package/dist/signals/lib/motion.mjs +27 -0
- package/dist/signals/lib/motion.test.d.mts +1 -0
- package/dist/signals/lib/motion.test.mjs +51 -0
- package/dist/signals/lib/mouse-position.d.mts +14 -0
- package/dist/signals/lib/mouse-position.mjs +22 -0
- package/dist/signals/lib/mouse-position.test.d.mts +1 -0
- package/dist/signals/lib/mouse-position.test.mjs +44 -0
- package/dist/signals/lib/mouse-wheel.d.mts +10 -0
- package/dist/signals/lib/mouse-wheel.mjs +17 -0
- package/dist/signals/lib/mouse-wheel.test.d.mts +1 -0
- package/dist/signals/lib/mouse-wheel.test.mjs +38 -0
- package/dist/signals/lib/mutation-observer.d.mts +8 -0
- package/dist/signals/lib/mutation-observer.mjs +16 -0
- package/dist/signals/lib/mutation-observer.test.d.mts +1 -0
- package/dist/signals/lib/mutation-observer.test.mjs +46 -0
- package/dist/signals/lib/network-state.d.mts +17 -0
- package/dist/signals/lib/network-state.mjs +34 -0
- package/dist/signals/lib/network-state.test.d.mts +1 -0
- package/dist/signals/lib/network-state.test.mjs +61 -0
- package/dist/signals/lib/on-click-outside.d.mts +11 -0
- package/dist/signals/lib/on-click-outside.mjs +20 -0
- package/dist/signals/lib/on-click-outside.test.d.mts +1 -0
- package/dist/signals/lib/on-click-outside.test.mjs +54 -0
- package/dist/signals/lib/orientation.d.mts +13 -0
- package/dist/signals/lib/orientation.mjs +20 -0
- package/dist/signals/lib/orientation.test.d.mts +1 -0
- package/dist/signals/lib/orientation.test.mjs +43 -0
- package/dist/signals/lib/page-leave.d.mts +8 -0
- package/dist/signals/lib/page-leave.mjs +12 -0
- package/dist/signals/lib/page-leave.test.d.mts +1 -0
- package/dist/signals/lib/page-leave.test.mjs +29 -0
- package/dist/signals/lib/permission.d.mts +14 -0
- package/dist/signals/lib/permission.mjs +26 -0
- package/dist/signals/lib/permission.test.d.mts +1 -0
- package/dist/signals/lib/permission.test.mjs +50 -0
- package/dist/signals/lib/persisted-state.d.mts +11 -0
- package/dist/signals/lib/persisted-state.mjs +25 -0
- package/dist/signals/lib/persisted-state.test.d.mts +1 -0
- package/dist/signals/lib/persisted-state.test.mjs +70 -0
- package/dist/signals/lib/pressed-keys.d.mts +10 -0
- package/dist/signals/lib/pressed-keys.mjs +32 -0
- package/dist/signals/lib/pressed-keys.test.d.mts +1 -0
- package/dist/signals/lib/pressed-keys.test.mjs +54 -0
- package/dist/signals/lib/previous-distinct.d.mts +10 -0
- package/dist/signals/lib/previous-distinct.mjs +22 -0
- package/dist/signals/lib/previous-distinct.test.d.mts +1 -0
- package/dist/signals/lib/previous-distinct.test.mjs +50 -0
- package/dist/signals/lib/previous.d.mts +10 -0
- package/dist/signals/lib/previous.mjs +18 -0
- package/dist/signals/lib/previous.test.d.mts +1 -0
- package/dist/signals/lib/previous.test.mjs +47 -0
- package/dist/signals/lib/queue.d.mts +17 -0
- package/dist/signals/lib/queue.mjs +28 -0
- package/dist/signals/lib/queue.test.d.mts +1 -0
- package/dist/signals/lib/queue.test.mjs +61 -0
- package/dist/signals/lib/raf.d.mts +17 -0
- package/dist/signals/lib/raf.mjs +38 -0
- package/dist/signals/lib/raf.test.d.mts +1 -0
- package/dist/signals/lib/raf.test.mjs +58 -0
- package/dist/signals/lib/react.d.mts +1 -1
- package/dist/signals/lib/resize-observer.d.mts +8 -0
- package/dist/signals/lib/resize-observer.mjs +16 -0
- package/dist/signals/lib/resize-observer.test.d.mts +1 -0
- package/dist/signals/lib/resize-observer.test.mjs +44 -0
- package/dist/signals/lib/resource.d.mts +23 -0
- package/dist/signals/lib/resource.mjs +43 -0
- package/dist/signals/lib/resource.test.d.mts +1 -0
- package/dist/signals/lib/resource.test.mjs +56 -0
- package/dist/signals/lib/scroll-state.d.mts +19 -0
- package/dist/signals/lib/scroll-state.mjs +46 -0
- package/dist/signals/lib/scroll-state.test.d.mts +1 -0
- package/dist/signals/lib/scroll-state.test.mjs +94 -0
- package/dist/signals/lib/scrolling.d.mts +12 -0
- package/dist/signals/lib/scrolling.mjs +26 -0
- package/dist/signals/lib/scrolling.test.d.mts +1 -0
- package/dist/signals/lib/scrolling.test.mjs +57 -0
- package/dist/signals/lib/search-params.d.mts +16 -0
- package/dist/signals/lib/search-params.mjs +37 -0
- package/dist/signals/lib/search-params.test.d.mts +1 -0
- package/dist/signals/lib/search-params.test.mjs +56 -0
- package/dist/signals/lib/set.d.mts +18 -0
- package/dist/signals/lib/set.mjs +38 -0
- package/dist/signals/lib/set.test.d.mts +1 -0
- package/dist/signals/lib/set.test.mjs +70 -0
- package/dist/signals/lib/start-typing.d.mts +9 -0
- package/dist/signals/lib/start-typing.mjs +39 -0
- package/dist/signals/lib/start-typing.test.d.mts +1 -0
- package/dist/signals/lib/start-typing.test.mjs +64 -0
- package/dist/signals/lib/state-history.d.mts +21 -0
- package/dist/signals/lib/state-history.mjs +61 -0
- package/dist/signals/lib/state-history.test.d.mts +1 -0
- package/dist/signals/lib/state-history.test.mjs +106 -0
- package/dist/signals/lib/state-validator.d.mts +16 -0
- package/dist/signals/lib/state-validator.mjs +21 -0
- package/dist/signals/lib/state-validator.test.d.mts +1 -0
- package/dist/signals/lib/state-validator.test.mjs +41 -0
- package/dist/signals/lib/throttled.d.mts +13 -0
- package/dist/signals/lib/throttled.mjs +45 -0
- package/dist/signals/lib/throttled.test.d.mts +1 -0
- package/dist/signals/lib/throttled.test.mjs +56 -0
- package/dist/signals/lib/timeout.d.mts +16 -0
- package/dist/signals/lib/timeout.mjs +39 -0
- package/dist/signals/lib/timeout.test.d.mts +1 -0
- package/dist/signals/lib/timeout.test.mjs +64 -0
- package/dist/signals/lib/toggle.d.mts +12 -0
- package/dist/signals/lib/toggle.mjs +12 -0
- package/dist/signals/lib/toggle.test.d.mts +1 -0
- package/dist/signals/lib/toggle.test.mjs +43 -0
- package/dist/signals/lib/video.d.mts +21 -0
- package/dist/signals/lib/video.mjs +35 -0
- package/dist/signals/lib/video.test.d.mts +1 -0
- package/dist/signals/lib/video.test.mjs +51 -0
- package/dist/signals/lib/watch.d.mts +16 -0
- package/dist/signals/lib/watch.mjs +31 -0
- package/dist/signals/lib/watch.test.d.mts +1 -0
- package/dist/signals/lib/watch.test.mjs +51 -0
- package/dist/signals/lib/window-size.d.mts +14 -0
- package/dist/signals/lib/window-size.mjs +21 -0
- package/dist/signals/lib/window-size.test.d.mts +1 -0
- package/dist/signals/lib/window-size.test.mjs +50 -0
- package/dist/slot.d.mts +1 -1
- package/dist/test.BmQO5GaM-CR2qjV1t.mjs +13314 -0
- package/package.json +1 -1
- /package/dist/{polyfill-BW_B2r6i.d.mts → polyfill-AFIi9kAN.d.mts} +0 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { n as Signal, t as Computed } from "../../index-BtqiEEfc.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/signals/lib/event-driven.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* A subscribe function: registers a `notify` callback and returns an
|
|
6
|
+
* unsubscribe cleanup. Same contract as `useSyncExternalStore`.
|
|
7
|
+
*/
|
|
8
|
+
type Subscribe = (notify: () => void) => () => void;
|
|
9
|
+
/**
|
|
10
|
+
* Returns a `Subscribe` for one or more DOM events on a target.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* const [playing, stop] = sync(fromEvent(el, ["play", "pause"]), () => !el.paused);
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
declare function fromEvent(target: EventTarget, events: string | string[]): Subscribe;
|
|
18
|
+
/**
|
|
19
|
+
* Keeps a reactive value in sync with an external source by re-reading
|
|
20
|
+
* `getter` whenever `subscribe` notifies of a change.
|
|
21
|
+
*
|
|
22
|
+
* Returns a `[value, cleanup]` tuple.
|
|
23
|
+
*
|
|
24
|
+
* Without `setter` → value is `Computed<T>` (read-only).
|
|
25
|
+
* With `setter` → value is `Signal<T>` (writable).
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* const [playing, stop] = sync(fromEvent(el, ["play", "pause"]), () => !el.paused);
|
|
30
|
+
*
|
|
31
|
+
* const [volume, stopVolume] = sync(
|
|
32
|
+
* fromEvent(el, "volumechange"),
|
|
33
|
+
* () => el.volume,
|
|
34
|
+
* (v) => { el.volume = v; },
|
|
35
|
+
* );
|
|
36
|
+
*
|
|
37
|
+
* // Any external store
|
|
38
|
+
* const [data, unsub] = sync(
|
|
39
|
+
* (notify) => { store.on("change", notify); return () => store.off("change", notify); },
|
|
40
|
+
* () => store.getSnapshot(),
|
|
41
|
+
* );
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
declare function sync<T>(subscribe: Subscribe, getter: () => T): [Computed<T>, () => void];
|
|
45
|
+
declare function sync<T>(subscribe: Subscribe, getter: () => T, setter: (value: T) => void): [Signal<T>, () => void];
|
|
46
|
+
//#endregion
|
|
47
|
+
export { Subscribe, fromEvent, sync };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { d as onCleanup, f as signal, i as computed, p as trigger } from "../../signals-CLAPw8kk.mjs";
|
|
2
|
+
//#region src/signals/lib/event-driven.ts
|
|
3
|
+
/**
|
|
4
|
+
* Returns a `Subscribe` for one or more DOM events on a target.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* const [playing, stop] = sync(fromEvent(el, ["play", "pause"]), () => !el.paused);
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
function fromEvent(target, events) {
|
|
12
|
+
return (notify) => {
|
|
13
|
+
const evts = Array.isArray(events) ? events : [events];
|
|
14
|
+
evts.forEach((ev) => target.addEventListener(ev, notify));
|
|
15
|
+
return () => evts.forEach((ev) => target.removeEventListener(ev, notify));
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function sync(subscribe, getter, setter) {
|
|
19
|
+
const tick = signal(void 0);
|
|
20
|
+
const value = computed(() => {
|
|
21
|
+
tick();
|
|
22
|
+
return getter();
|
|
23
|
+
});
|
|
24
|
+
value();
|
|
25
|
+
const cleanup = subscribe(() => trigger(tick));
|
|
26
|
+
onCleanup(cleanup);
|
|
27
|
+
if (setter) {
|
|
28
|
+
const proxy = (v) => {
|
|
29
|
+
if (v === void 0) return value();
|
|
30
|
+
setter(v);
|
|
31
|
+
return v;
|
|
32
|
+
};
|
|
33
|
+
return [proxy, cleanup];
|
|
34
|
+
}
|
|
35
|
+
return [value, cleanup];
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
export { fromEvent, sync };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/signals/lib/event-listener.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Attaches a type-safe event listener to a target, with automatic cleanup.
|
|
4
|
+
*
|
|
5
|
+
* When called inside an `effect` or `effectScope` the listener is removed
|
|
6
|
+
* when the scope is disposed. When the target is a reactive getter the
|
|
7
|
+
* listener is re-registered whenever the target changes.
|
|
8
|
+
*/
|
|
9
|
+
declare function createEventListener<K extends keyof HTMLElementEventMap>(target: HTMLElement | (() => HTMLElement | null), type: K, handler: (e: HTMLElementEventMap[K]) => void, options?: AddEventListenerOptions): () => void;
|
|
10
|
+
declare function createEventListener<K extends keyof DocumentEventMap>(target: Document | (() => Document | null), type: K, handler: (e: DocumentEventMap[K]) => void, options?: AddEventListenerOptions): () => void;
|
|
11
|
+
declare function createEventListener<K extends keyof WindowEventMap>(target: Window | (() => Window | null), type: K, handler: (e: WindowEventMap[K]) => void, options?: AddEventListenerOptions): () => void;
|
|
12
|
+
declare function createEventListener(target: EventTarget | (() => EventTarget | null), type: string, handler: EventListener, options?: AddEventListenerOptions): () => void;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { createEventListener };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { a as effect, d as onCleanup } from "../../signals-CLAPw8kk.mjs";
|
|
2
|
+
//#region src/signals/lib/event-listener.ts
|
|
3
|
+
function createEventListener(target, type, handler, options) {
|
|
4
|
+
const add = (t) => options !== void 0 ? t.addEventListener(type, handler, options) : t.addEventListener(type, handler);
|
|
5
|
+
const del = (t) => options !== void 0 ? t.removeEventListener(type, handler, options) : t.removeEventListener(type, handler);
|
|
6
|
+
if (typeof target === "function") {
|
|
7
|
+
let currentRemove = () => {};
|
|
8
|
+
const stopEffect = effect(() => {
|
|
9
|
+
const el = target();
|
|
10
|
+
if (!el) return;
|
|
11
|
+
add(el);
|
|
12
|
+
const remove = () => del(el);
|
|
13
|
+
onCleanup(remove);
|
|
14
|
+
currentRemove = remove;
|
|
15
|
+
});
|
|
16
|
+
return () => {
|
|
17
|
+
stopEffect();
|
|
18
|
+
currentRemove();
|
|
19
|
+
};
|
|
20
|
+
} else {
|
|
21
|
+
const remove = () => del(target);
|
|
22
|
+
add(target);
|
|
23
|
+
onCleanup(remove);
|
|
24
|
+
return remove;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
export { createEventListener };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { a as effect, f as signal, o as effectScope } from "../../signals-CLAPw8kk.mjs";
|
|
2
|
+
import { a as describe, n as vi, o as it, r as afterEach, t as globalExpect } from "../../test.BmQO5GaM-CR2qjV1t.mjs";
|
|
3
|
+
import { createEventListener } from "./event-listener.mjs";
|
|
4
|
+
//#region src/signals/lib/event-listener.test.ts
|
|
5
|
+
afterEach(() => {
|
|
6
|
+
document.body.innerHTML = "";
|
|
7
|
+
});
|
|
8
|
+
describe("createEventListener", () => {
|
|
9
|
+
it("fires the handler when the event is dispatched", () => {
|
|
10
|
+
const el = document.createElement("div");
|
|
11
|
+
document.body.appendChild(el);
|
|
12
|
+
const handler = vi.fn();
|
|
13
|
+
effect(() => {
|
|
14
|
+
createEventListener(el, "click", handler);
|
|
15
|
+
});
|
|
16
|
+
el.dispatchEvent(new MouseEvent("click", { bubbles: true }));
|
|
17
|
+
globalExpect(handler).toHaveBeenCalledOnce();
|
|
18
|
+
});
|
|
19
|
+
it("removes the listener when the enclosing effect is disposed", () => {
|
|
20
|
+
const el = document.createElement("div");
|
|
21
|
+
document.body.appendChild(el);
|
|
22
|
+
const handler = vi.fn();
|
|
23
|
+
effect(() => {
|
|
24
|
+
createEventListener(el, "click", handler);
|
|
25
|
+
})();
|
|
26
|
+
el.dispatchEvent(new MouseEvent("click", { bubbles: true }));
|
|
27
|
+
globalExpect(handler).not.toHaveBeenCalled();
|
|
28
|
+
});
|
|
29
|
+
it("removes the listener when the enclosing scope is disposed", () => {
|
|
30
|
+
const el = document.createElement("div");
|
|
31
|
+
document.body.appendChild(el);
|
|
32
|
+
const handler = vi.fn();
|
|
33
|
+
effectScope(() => {
|
|
34
|
+
createEventListener(el, "click", handler);
|
|
35
|
+
})();
|
|
36
|
+
el.dispatchEvent(new MouseEvent("click", { bubbles: true }));
|
|
37
|
+
globalExpect(handler).not.toHaveBeenCalled();
|
|
38
|
+
});
|
|
39
|
+
it("re-registers the listener when a reactive target changes", () => {
|
|
40
|
+
const el1 = document.createElement("div");
|
|
41
|
+
const el2 = document.createElement("div");
|
|
42
|
+
document.body.append(el1, el2);
|
|
43
|
+
const target = signal(el1);
|
|
44
|
+
const handler = vi.fn();
|
|
45
|
+
effectScope(() => {
|
|
46
|
+
createEventListener(() => target(), "click", handler);
|
|
47
|
+
});
|
|
48
|
+
el1.dispatchEvent(new MouseEvent("click"));
|
|
49
|
+
globalExpect(handler).toHaveBeenCalledTimes(1);
|
|
50
|
+
target(el2);
|
|
51
|
+
el1.dispatchEvent(new MouseEvent("click"));
|
|
52
|
+
globalExpect(handler).toHaveBeenCalledTimes(1);
|
|
53
|
+
el2.dispatchEvent(new MouseEvent("click"));
|
|
54
|
+
globalExpect(handler).toHaveBeenCalledTimes(2);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
//#endregion
|
|
58
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { n as Signal } from "../../index-BtqiEEfc.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/signals/lib/favicon.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Returns a writable `Signal<string>` whose value is reflected as the page's
|
|
6
|
+
* favicon `href`. Writing the signal swaps the `<link rel="icon">` element.
|
|
7
|
+
*/
|
|
8
|
+
declare function createFavicon(initial?: string): Signal<string>;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { createFavicon };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { a as effect, f as signal } from "../../signals-CLAPw8kk.mjs";
|
|
2
|
+
//#region src/signals/lib/favicon.ts
|
|
3
|
+
/**
|
|
4
|
+
* Returns a writable `Signal<string>` whose value is reflected as the page's
|
|
5
|
+
* favicon `href`. Writing the signal swaps the `<link rel="icon">` element.
|
|
6
|
+
*/
|
|
7
|
+
function createFavicon(initial) {
|
|
8
|
+
const getLink = () => {
|
|
9
|
+
let link = document.querySelector("link[rel~='icon']");
|
|
10
|
+
if (!link) {
|
|
11
|
+
link = document.createElement("link");
|
|
12
|
+
link.rel = "icon";
|
|
13
|
+
document.head.appendChild(link);
|
|
14
|
+
}
|
|
15
|
+
return link;
|
|
16
|
+
};
|
|
17
|
+
const href = signal(initial ?? (typeof document !== "undefined" ? getLink().href || "" : ""));
|
|
18
|
+
effect(() => {
|
|
19
|
+
if (typeof document !== "undefined") getLink().href = href();
|
|
20
|
+
});
|
|
21
|
+
return href;
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { createFavicon };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { o as effectScope } from "../../signals-CLAPw8kk.mjs";
|
|
2
|
+
import { a as describe, o as it, r as afterEach, t as globalExpect } from "../../test.BmQO5GaM-CR2qjV1t.mjs";
|
|
3
|
+
import { createFavicon } from "./favicon.mjs";
|
|
4
|
+
//#region src/signals/lib/favicon.test.ts
|
|
5
|
+
afterEach(() => {
|
|
6
|
+
document.head.innerHTML = "";
|
|
7
|
+
document.body.innerHTML = "";
|
|
8
|
+
});
|
|
9
|
+
describe("createFavicon", () => {
|
|
10
|
+
it("creates a link element if none exists", () => {
|
|
11
|
+
effectScope(() => {
|
|
12
|
+
createFavicon("/icon.png");
|
|
13
|
+
});
|
|
14
|
+
const link = document.querySelector("link[rel~='icon']");
|
|
15
|
+
globalExpect(link).not.toBeNull();
|
|
16
|
+
globalExpect(link?.href).toContain("/icon.png");
|
|
17
|
+
});
|
|
18
|
+
it("updates favicon href when signal changes", () => {
|
|
19
|
+
let fav;
|
|
20
|
+
effectScope(() => {
|
|
21
|
+
fav = createFavicon("/old.png");
|
|
22
|
+
});
|
|
23
|
+
fav("/new.png");
|
|
24
|
+
globalExpect(document.querySelector("link[rel~='icon']")?.href).toContain("/new.png");
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
//#endregion
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { t as Computed } from "../../index-BtqiEEfc.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/signals/lib/finite-state-machine.d.ts
|
|
4
|
+
type Transitions<S extends string, E extends string> = Partial<Record<S, Partial<Record<E, S>>>>;
|
|
5
|
+
type StateHooks<S extends string> = Partial<Record<S, {
|
|
6
|
+
enter?: () => void;
|
|
7
|
+
exit?: () => void;
|
|
8
|
+
}>>;
|
|
9
|
+
type FSMResult<S extends string, E extends string> = {
|
|
10
|
+
state: Computed<S>;
|
|
11
|
+
send(event: E): void;
|
|
12
|
+
can(event: E): boolean;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Type-safe finite state machine with optional `enter` / `exit` lifecycle
|
|
16
|
+
* hooks per state.
|
|
17
|
+
*/
|
|
18
|
+
declare function createFiniteStateMachine<S extends string, E extends string>(initial: S, transitions: Transitions<S, E>, options?: {
|
|
19
|
+
on?: StateHooks<S>;
|
|
20
|
+
}): FSMResult<S, E>;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { createFiniteStateMachine };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { f as signal } from "../../signals-CLAPw8kk.mjs";
|
|
2
|
+
//#region src/signals/lib/finite-state-machine.ts
|
|
3
|
+
/**
|
|
4
|
+
* Type-safe finite state machine with optional `enter` / `exit` lifecycle
|
|
5
|
+
* hooks per state.
|
|
6
|
+
*/
|
|
7
|
+
function createFiniteStateMachine(initial, transitions, options) {
|
|
8
|
+
const state = signal(initial);
|
|
9
|
+
options?.on?.[initial]?.enter?.();
|
|
10
|
+
const send = (event) => {
|
|
11
|
+
const current = state();
|
|
12
|
+
const next = transitions[current]?.[event];
|
|
13
|
+
if (next === void 0 || next === current) return;
|
|
14
|
+
options?.on?.[current]?.exit?.();
|
|
15
|
+
state(next);
|
|
16
|
+
options?.on?.[next]?.enter?.();
|
|
17
|
+
};
|
|
18
|
+
const can = (event) => transitions[state()]?.[event] !== void 0;
|
|
19
|
+
return {
|
|
20
|
+
state,
|
|
21
|
+
send,
|
|
22
|
+
can
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
export { createFiniteStateMachine };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { o as effectScope } from "../../signals-CLAPw8kk.mjs";
|
|
2
|
+
import { a as describe, n as vi, o as it, r as afterEach, t as globalExpect } from "../../test.BmQO5GaM-CR2qjV1t.mjs";
|
|
3
|
+
import { createFiniteStateMachine } from "./finite-state-machine.mjs";
|
|
4
|
+
//#region src/signals/lib/finite-state-machine.test.ts
|
|
5
|
+
afterEach(() => {
|
|
6
|
+
document.body.innerHTML = "";
|
|
7
|
+
});
|
|
8
|
+
const transitions = {
|
|
9
|
+
red: { GO: "green" },
|
|
10
|
+
green: { SLOW: "yellow" },
|
|
11
|
+
yellow: { STOP: "red" }
|
|
12
|
+
};
|
|
13
|
+
describe("createFiniteStateMachine", () => {
|
|
14
|
+
it("starts in the initial state", () => {
|
|
15
|
+
let fsm;
|
|
16
|
+
effectScope(() => {
|
|
17
|
+
fsm = createFiniteStateMachine("red", transitions);
|
|
18
|
+
});
|
|
19
|
+
globalExpect(fsm.state()).toBe("red");
|
|
20
|
+
});
|
|
21
|
+
it("transitions on valid event", () => {
|
|
22
|
+
let fsm;
|
|
23
|
+
effectScope(() => {
|
|
24
|
+
fsm = createFiniteStateMachine("red", transitions);
|
|
25
|
+
});
|
|
26
|
+
fsm.send("GO");
|
|
27
|
+
globalExpect(fsm.state()).toBe("green");
|
|
28
|
+
});
|
|
29
|
+
it("does not transition on invalid event", () => {
|
|
30
|
+
let fsm;
|
|
31
|
+
effectScope(() => {
|
|
32
|
+
fsm = createFiniteStateMachine("red", transitions);
|
|
33
|
+
});
|
|
34
|
+
fsm.send("SLOW");
|
|
35
|
+
globalExpect(fsm.state()).toBe("red");
|
|
36
|
+
});
|
|
37
|
+
it("can() returns true for valid transition", () => {
|
|
38
|
+
let fsm;
|
|
39
|
+
effectScope(() => {
|
|
40
|
+
fsm = createFiniteStateMachine("red", transitions);
|
|
41
|
+
});
|
|
42
|
+
globalExpect(fsm.can("GO")).toBe(true);
|
|
43
|
+
globalExpect(fsm.can("SLOW")).toBe(false);
|
|
44
|
+
});
|
|
45
|
+
it("calls enter/exit hooks on transition", () => {
|
|
46
|
+
const enterRed = vi.fn();
|
|
47
|
+
const exitRed = vi.fn();
|
|
48
|
+
const enterGreen = vi.fn();
|
|
49
|
+
let fsm;
|
|
50
|
+
effectScope(() => {
|
|
51
|
+
fsm = createFiniteStateMachine("red", transitions, { on: {
|
|
52
|
+
red: {
|
|
53
|
+
enter: enterRed,
|
|
54
|
+
exit: exitRed
|
|
55
|
+
},
|
|
56
|
+
green: { enter: enterGreen }
|
|
57
|
+
} });
|
|
58
|
+
});
|
|
59
|
+
globalExpect(enterRed).toHaveBeenCalledOnce();
|
|
60
|
+
fsm.send("GO");
|
|
61
|
+
globalExpect(exitRed).toHaveBeenCalledOnce();
|
|
62
|
+
globalExpect(enterGreen).toHaveBeenCalledOnce();
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
//#endregion
|
|
66
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { t as Computed } from "../../index-BtqiEEfc.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/signals/lib/fullscreen.d.ts
|
|
4
|
+
type FullscreenResult = {
|
|
5
|
+
isFullscreen: Computed<boolean>;
|
|
6
|
+
enter(): Promise<void>;
|
|
7
|
+
exit(): Promise<void>;
|
|
8
|
+
toggle(): Promise<void>;
|
|
9
|
+
} & Disposable;
|
|
10
|
+
/**
|
|
11
|
+
* Wraps the Fullscreen API. `target` defaults to `document.documentElement`.
|
|
12
|
+
*/
|
|
13
|
+
declare function createFullscreen(target?: Element | (() => Element | null)): FullscreenResult;
|
|
14
|
+
//#endregion
|
|
15
|
+
export { createFullscreen };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { fromEvent, sync } from "./event-driven.mjs";
|
|
2
|
+
//#region src/signals/lib/fullscreen.ts
|
|
3
|
+
/**
|
|
4
|
+
* Wraps the Fullscreen API. `target` defaults to `document.documentElement`.
|
|
5
|
+
*/
|
|
6
|
+
function createFullscreen(target) {
|
|
7
|
+
const getTarget = () => {
|
|
8
|
+
if (!target) return document.documentElement;
|
|
9
|
+
return typeof target === "function" ? target() ?? document.documentElement : target;
|
|
10
|
+
};
|
|
11
|
+
const [isFullscreen, cleanup] = sync(fromEvent(document, "fullscreenchange"), () => !!document.fullscreenElement);
|
|
12
|
+
const enter = () => getTarget().requestFullscreen();
|
|
13
|
+
const exit = () => document.exitFullscreen();
|
|
14
|
+
const toggle = () => isFullscreen() ? exit() : enter();
|
|
15
|
+
return {
|
|
16
|
+
isFullscreen,
|
|
17
|
+
enter,
|
|
18
|
+
exit,
|
|
19
|
+
toggle,
|
|
20
|
+
[Symbol.dispose]: cleanup
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { createFullscreen };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { o as effectScope } from "../../signals-CLAPw8kk.mjs";
|
|
2
|
+
import { a as describe, n as vi, o as it, r as afterEach, t as globalExpect } from "../../test.BmQO5GaM-CR2qjV1t.mjs";
|
|
3
|
+
import { createFullscreen } from "./fullscreen.mjs";
|
|
4
|
+
//#region src/signals/lib/fullscreen.test.ts
|
|
5
|
+
afterEach(() => {
|
|
6
|
+
document.body.innerHTML = "";
|
|
7
|
+
vi.restoreAllMocks();
|
|
8
|
+
});
|
|
9
|
+
describe("createFullscreen", () => {
|
|
10
|
+
it("starts with current fullscreen state", () => {
|
|
11
|
+
Object.defineProperty(document, "fullscreenElement", {
|
|
12
|
+
configurable: true,
|
|
13
|
+
get: () => null
|
|
14
|
+
});
|
|
15
|
+
let f;
|
|
16
|
+
effectScope(() => {
|
|
17
|
+
f = createFullscreen();
|
|
18
|
+
});
|
|
19
|
+
globalExpect(f.isFullscreen()).toBe(false);
|
|
20
|
+
});
|
|
21
|
+
it("updates isFullscreen on fullscreenchange event", () => {
|
|
22
|
+
Object.defineProperty(document, "fullscreenElement", {
|
|
23
|
+
configurable: true,
|
|
24
|
+
get: () => null
|
|
25
|
+
});
|
|
26
|
+
let f;
|
|
27
|
+
effectScope(() => {
|
|
28
|
+
f = createFullscreen();
|
|
29
|
+
});
|
|
30
|
+
Object.defineProperty(document, "fullscreenElement", {
|
|
31
|
+
configurable: true,
|
|
32
|
+
get: () => document.documentElement
|
|
33
|
+
});
|
|
34
|
+
document.dispatchEvent(new Event("fullscreenchange"));
|
|
35
|
+
globalExpect(f.isFullscreen()).toBe(true);
|
|
36
|
+
});
|
|
37
|
+
it("removes event listener on Symbol.dispose", () => {
|
|
38
|
+
const removeSpy = vi.spyOn(document, "removeEventListener");
|
|
39
|
+
let f;
|
|
40
|
+
effectScope(() => {
|
|
41
|
+
f = createFullscreen();
|
|
42
|
+
});
|
|
43
|
+
f[Symbol.dispose]();
|
|
44
|
+
globalExpect(removeSpy).toHaveBeenCalledWith("fullscreenchange", globalExpect.any(Function));
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
//#endregion
|
|
48
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { t as Computed } from "../../index-BtqiEEfc.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/signals/lib/geolocation.d.ts
|
|
4
|
+
type GeolocationResult = {
|
|
5
|
+
position: Computed<GeolocationPosition | null>;
|
|
6
|
+
error: Computed<GeolocationPositionError | null>;
|
|
7
|
+
loading: Computed<boolean>;
|
|
8
|
+
} & Disposable;
|
|
9
|
+
/**
|
|
10
|
+
* Exposes the Geolocation API as reactive signals.
|
|
11
|
+
* Begins watching the position immediately.
|
|
12
|
+
*/
|
|
13
|
+
declare function createGeolocation(options?: PositionOptions): GeolocationResult;
|
|
14
|
+
//#endregion
|
|
15
|
+
export { createGeolocation };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { d as onCleanup, f as signal } from "../../signals-CLAPw8kk.mjs";
|
|
2
|
+
//#region src/signals/lib/geolocation.ts
|
|
3
|
+
/**
|
|
4
|
+
* Exposes the Geolocation API as reactive signals.
|
|
5
|
+
* Begins watching the position immediately.
|
|
6
|
+
*/
|
|
7
|
+
function createGeolocation(options) {
|
|
8
|
+
const position = signal(null);
|
|
9
|
+
const error = signal(null);
|
|
10
|
+
const loading = signal(true);
|
|
11
|
+
const onSuccess = (pos) => {
|
|
12
|
+
position(pos);
|
|
13
|
+
error(null);
|
|
14
|
+
loading(false);
|
|
15
|
+
};
|
|
16
|
+
const onError = (err) => {
|
|
17
|
+
error(err);
|
|
18
|
+
loading(false);
|
|
19
|
+
};
|
|
20
|
+
const watchId = navigator.geolocation.watchPosition(onSuccess, onError, options);
|
|
21
|
+
const cleanup = () => navigator.geolocation.clearWatch(watchId);
|
|
22
|
+
onCleanup(cleanup);
|
|
23
|
+
return Object.assign({
|
|
24
|
+
position,
|
|
25
|
+
error,
|
|
26
|
+
loading
|
|
27
|
+
}, { [Symbol.dispose]: cleanup });
|
|
28
|
+
}
|
|
29
|
+
//#endregion
|
|
30
|
+
export { createGeolocation };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { o as effectScope } from "../../signals-CLAPw8kk.mjs";
|
|
2
|
+
import { a as describe, n as vi, o as it, r as afterEach, t as globalExpect } from "../../test.BmQO5GaM-CR2qjV1t.mjs";
|
|
3
|
+
import { createGeolocation } from "./geolocation.mjs";
|
|
4
|
+
//#region src/signals/lib/geolocation.test.ts
|
|
5
|
+
afterEach(() => {
|
|
6
|
+
document.body.innerHTML = "";
|
|
7
|
+
vi.unstubAllGlobals();
|
|
8
|
+
});
|
|
9
|
+
describe("createGeolocation", () => {
|
|
10
|
+
it("starts with null position and loading true", () => {
|
|
11
|
+
vi.stubGlobal("navigator", { geolocation: {
|
|
12
|
+
watchPosition: vi.fn().mockReturnValue(1),
|
|
13
|
+
clearWatch: vi.fn()
|
|
14
|
+
} });
|
|
15
|
+
let g;
|
|
16
|
+
effectScope(() => {
|
|
17
|
+
g = createGeolocation();
|
|
18
|
+
});
|
|
19
|
+
globalExpect(g.position()).toBeNull();
|
|
20
|
+
globalExpect(g.loading()).toBe(true);
|
|
21
|
+
});
|
|
22
|
+
it("calls clearWatch on Symbol.dispose", () => {
|
|
23
|
+
const clearWatch = vi.fn();
|
|
24
|
+
vi.stubGlobal("navigator", { geolocation: {
|
|
25
|
+
watchPosition: vi.fn().mockReturnValue(42),
|
|
26
|
+
clearWatch
|
|
27
|
+
} });
|
|
28
|
+
let g;
|
|
29
|
+
effectScope(() => {
|
|
30
|
+
g = createGeolocation();
|
|
31
|
+
});
|
|
32
|
+
g[Symbol.dispose]();
|
|
33
|
+
globalExpect(clearWatch).toHaveBeenCalledWith(42);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
//#endregion
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { n as Signal } from "../../index-BtqiEEfc.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/signals/lib/hash.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Returns a writable `Signal<string>` that stays in sync with `location.hash`
|
|
6
|
+
* (including the leading `#`). Writing the signal updates `location.hash`.
|
|
7
|
+
*/
|
|
8
|
+
declare function createHash(): Signal<string> & Disposable;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { createHash };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { fromEvent, sync } from "./event-driven.mjs";
|
|
2
|
+
//#region src/signals/lib/hash.ts
|
|
3
|
+
/**
|
|
4
|
+
* Returns a writable `Signal<string>` that stays in sync with `location.hash`
|
|
5
|
+
* (including the leading `#`). Writing the signal updates `location.hash`.
|
|
6
|
+
*/
|
|
7
|
+
function createHash() {
|
|
8
|
+
const [hash, cleanup] = sync(fromEvent(window, "hashchange"), () => typeof location !== "undefined" ? location.hash : "", (v) => {
|
|
9
|
+
location.hash = v;
|
|
10
|
+
});
|
|
11
|
+
return Object.assign(hash, { [Symbol.dispose]: cleanup });
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { createHash };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { o as effectScope } from "../../signals-CLAPw8kk.mjs";
|
|
2
|
+
import { a as describe, n as vi, o as it, r as afterEach, t as globalExpect } from "../../test.BmQO5GaM-CR2qjV1t.mjs";
|
|
3
|
+
import { createHash } from "./hash.mjs";
|
|
4
|
+
//#region src/signals/lib/hash.test.ts
|
|
5
|
+
afterEach(() => {
|
|
6
|
+
document.body.innerHTML = "";
|
|
7
|
+
location.hash = "";
|
|
8
|
+
vi.useRealTimers();
|
|
9
|
+
});
|
|
10
|
+
describe("createHash", () => {
|
|
11
|
+
it("reads the current location.hash", () => {
|
|
12
|
+
let h;
|
|
13
|
+
effectScope(() => {
|
|
14
|
+
h = createHash();
|
|
15
|
+
});
|
|
16
|
+
globalExpect(typeof h()).toBe("string");
|
|
17
|
+
});
|
|
18
|
+
it("updates when hash changes via hashchange event", () => {
|
|
19
|
+
let h;
|
|
20
|
+
effectScope(() => {
|
|
21
|
+
h = createHash();
|
|
22
|
+
});
|
|
23
|
+
location.hash = "#section";
|
|
24
|
+
window.dispatchEvent(new HashChangeEvent("hashchange"));
|
|
25
|
+
globalExpect(h()).toBe("#section");
|
|
26
|
+
});
|
|
27
|
+
it("writing the signal updates location.hash", () => {
|
|
28
|
+
let h;
|
|
29
|
+
effectScope(() => {
|
|
30
|
+
h = createHash();
|
|
31
|
+
});
|
|
32
|
+
h("#new");
|
|
33
|
+
globalExpect(location.hash).toBe("#new");
|
|
34
|
+
});
|
|
35
|
+
it("removes event listener on Symbol.dispose", () => {
|
|
36
|
+
const removeSpy = vi.spyOn(window, "removeEventListener");
|
|
37
|
+
let h;
|
|
38
|
+
effectScope(() => {
|
|
39
|
+
h = createHash();
|
|
40
|
+
});
|
|
41
|
+
h[Symbol.dispose]();
|
|
42
|
+
globalExpect(removeSpy).toHaveBeenCalledWith("hashchange", globalExpect.any(Function));
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
//#endregion
|
|
46
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { t as Computed } from "../../index-BtqiEEfc.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/signals/lib/hover.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Returns a `Computed<boolean>` that is `true` while the pointer is over
|
|
6
|
+
* `target`. Uses `pointerenter` / `pointerleave` so it works for both mouse
|
|
7
|
+
* and touch/stylus input.
|
|
8
|
+
*/
|
|
9
|
+
declare function createHover(target: Element | (() => Element | null)): Computed<boolean> & Disposable;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { createHover };
|