seitu 0.2.0 → 0.2.1

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.
@@ -50,7 +50,7 @@ export type { LocalStorageValue, LocalStorageValueOptionsWithSchema, LocalStorag
50
50
  * import * as z from 'zod'
51
51
  *
52
52
  * export default function Page() {
53
- * const { value: count } = useSubscription(() => createLocalStorageValue({
53
+ * const count = useSubscription(() => createLocalStorageValue({
54
54
  * key: 'count',
55
55
  * defaultValue: 0,
56
56
  * schema: z.number(),
@@ -37,7 +37,7 @@ export type { LocalStorage, LocalStorageOptions };
37
37
  * })
38
38
  *
39
39
  * export default function Page() {
40
- * const { value } = useSubscription(localStorage)
40
+ * const value = useSubscription(localStorage)
41
41
  * return (
42
42
  * <div>
43
43
  * <span>{value.count}</span>
@@ -56,7 +56,7 @@ export interface MediaQueryOptions<T extends string> {
56
56
  *
57
57
  * // Usage with some function component
58
58
  * function Layout() {
59
- * const { value: matches } = useSubscription(isDesktop)
59
+ * const matches = useSubscription(isDesktop)
60
60
  * return matches ? 'i am desktop' : 'i am mobile'
61
61
  * }
62
62
  * ```
@@ -15,8 +15,10 @@ export interface ScrollState extends Subscribable<ScrollStateValue>, Readable<Sc
15
15
  export interface ScrollStateOptions {
16
16
  /**
17
17
  * The element to observe scroll position on.
18
+ * Accepts an element directly, or a getter function for lazy resolution
19
+ * (useful with React refs that aren't available during render).
18
20
  */
19
- element: Element | null;
21
+ element: Element | null | (() => Element | null);
20
22
  /**
21
23
  * Which scroll axis to track.
22
24
  * @default 'both'
@@ -52,33 +54,47 @@ export interface ScrollStateOptions {
52
54
  * console.log(state)
53
55
  * ```
54
56
  *
55
- * @example React
57
+ * @example React (with useRef)
56
58
  * ```tsx twoslash title="page.tsx"
59
+ * 'use client'
60
+ *
61
+ * import * as React from 'react'
57
62
  * import { scrollState } from 'seitu/web'
58
63
  * import { useSubscription } from 'seitu/react'
59
64
  *
60
- * const scroll = scrollState({
61
- * element: document.querySelector('.container'),
62
- * threshold: 10,
63
- * })
64
- *
65
65
  * function Layout() {
66
- * const { value: state, ref } = useSubscription(scroll)
66
+ * const ref = React.useRef<HTMLDivElement>(null)
67
+ * const state = useSubscription(() => scrollState({
68
+ * element: () => ref.current,
69
+ * threshold: 10,
70
+ * }))
67
71
  *
68
72
  * return (
69
73
  * <div ref={ref}>
70
- * <div>
71
- * {state.top.value ? 'scrolled' : 'at the top'}
72
- * </div>
73
- * <div>
74
- * {state.bottom.value ? 'scrolled' : 'at the bottom'}
75
- * </div>
76
- * <div>
77
- * {state.left.value ? 'scrolled' : 'at the left'}
78
- * </div>
79
- * <div>
80
- * {state.right.value ? 'scrolled' : 'at the right'}
81
- * </div>
74
+ * {state.top.value ? 'at the top' : 'scrolled'}
75
+ * </div>
76
+ * )
77
+ * }
78
+ * ```
79
+ *
80
+ * @example React (with useState)
81
+ * ```tsx twoslash title="page.tsx"
82
+ * 'use client'
83
+ *
84
+ * import * as React from 'react'
85
+ * import { scrollState } from 'seitu/web'
86
+ * import { useSubscription } from 'seitu/react'
87
+ *
88
+ * function Layout() {
89
+ * const [ref, setRef] = React.useState<HTMLDivElement | null>(null)
90
+ * const state = useSubscription(() => scrollState({
91
+ * element: ref,
92
+ * threshold: 10,
93
+ * }), { deps: [ref] })
94
+ *
95
+ * return (
96
+ * <div ref={setRef}>
97
+ * {state.top.value ? 'at the top' : 'scrolled'}
82
98
  * </div>
83
99
  * )
84
100
  * }
@@ -50,7 +50,7 @@ export type { SessionStorageValue, SessionStorageValueOptionsWithSchema, Session
50
50
  * import * as z from 'zod'
51
51
  *
52
52
  * export default function Page() {
53
- * const { value: count } = useSubscription(() => createSessionStorageValue({
53
+ * const count = useSubscription(() => createSessionStorageValue({
54
54
  * key: 'count',
55
55
  * defaultValue: 0,
56
56
  * schema: z.number(),
@@ -37,7 +37,7 @@ export type { SessionStorage, SessionStorageOptions };
37
37
  * })
38
38
  *
39
39
  * export default function Page() {
40
- * const { value } = useSubscription(sessionStorage)
40
+ * const value = useSubscription(sessionStorage)
41
41
  * return (
42
42
  * <div>
43
43
  * <span>{value.count}</span>
package/dist/web.js CHANGED
@@ -114,33 +114,33 @@ var c = {
114
114
  remaining: 0
115
115
  };
116
116
  function l(e) {
117
- let { direction: t = "both", threshold: r = 0 } = e, { subscribe: i, notify: a } = n(), o = () => {
118
- let n = e.element, i = (e, t) => ({
117
+ let { direction: t = "both", threshold: r = 0 } = e, { subscribe: i, notify: a } = n(), o = () => typeof e.element == "function" ? e.element() : e.element, s = () => {
118
+ let e = o(), n = (e, t) => ({
119
119
  value: e,
120
120
  remaining: Math.max(0, t)
121
121
  });
122
- if (!n) return {
122
+ if (!e) return {
123
123
  top: c,
124
124
  bottom: c,
125
125
  left: c,
126
126
  right: c
127
127
  };
128
- let a = n.scrollTop, o = n.scrollHeight - n.scrollTop - n.clientHeight, s = n.scrollLeft, l = n.scrollWidth - n.scrollLeft - n.clientWidth;
128
+ let i = e.scrollTop, a = e.scrollHeight - e.scrollTop - e.clientHeight, s = e.scrollLeft, l = e.scrollWidth - e.scrollLeft - e.clientWidth;
129
129
  return {
130
- top: t === "horizontal" ? c : i(a > r, a),
131
- bottom: t === "horizontal" ? c : i(o <= r, o),
132
- left: t === "vertical" ? c : i(s > r, s),
133
- right: t === "vertical" ? c : i(l <= r, l)
130
+ top: t === "horizontal" ? c : n(i <= r, i),
131
+ bottom: t === "horizontal" ? c : n(a <= r, a),
132
+ left: t === "vertical" ? c : n(s <= r, s),
133
+ right: t === "vertical" ? c : n(l <= r, l)
134
134
  };
135
135
  };
136
136
  return {
137
- get: o,
138
- subscribe: (t) => {
139
- let n = e.element;
140
- if (!n) return t(o()), () => {};
141
- let r = i(() => t(o())), a = () => t(o());
142
- return n.addEventListener("scroll", a, { passive: !0 }), () => {
143
- r(), n.removeEventListener("scroll", a);
137
+ get: s,
138
+ subscribe: (e) => {
139
+ let t = o();
140
+ if (!t) return e(s()), () => {};
141
+ let n = i(() => e(s())), r = () => e(s());
142
+ return t.addEventListener("scroll", r, { passive: !0 }), () => {
143
+ n(), t.removeEventListener("scroll", r);
144
144
  };
145
145
  },
146
146
  "~": {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "seitu",
3
3
  "displayName": "Seitu",
4
4
  "type": "module",
5
- "version": "0.2.0",
5
+ "version": "0.2.1",
6
6
  "private": false,
7
7
  "author": "Valerii Strilets",
8
8
  "license": "MIT",
@@ -57,13 +57,12 @@
57
57
  }
58
58
  },
59
59
  "dependencies": {
60
- "deep-equal": "^2.2.3"
60
+ "fast-equals": "^6.0.0"
61
61
  },
62
62
  "devDependencies": {
63
63
  "@standard-schema/spec": "^1.1.0",
64
64
  "@testing-library/jest-dom": "^6.9.1",
65
65
  "@testing-library/react": "^16.3.2",
66
- "@types/deep-equal": "^1.0.4",
67
66
  "@types/react": "^19.2.14",
68
67
  "@vitejs/plugin-react": "^5.1.4",
69
68
  "happy-dom": "^20.8.3",