Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(react-dom): add InView, useInView #1184

Merged
merged 944 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
944 commits
Select commit Hold shift + click to select a range
f82a3e9
chore(*): last update for v1
manudeli May 14, 2024
b944727
v2 (#629)
manudeli May 14, 2024
f151056
chore(*): update navigation for v2
manudeli May 14, 2024
8330a6b
fix(react-query): fix SuspenseQuery, SuspenseInfiniteQuery's return t…
manudeli May 21, 2024
42136e4
chore: version packages (#888)
github-actions[bot] May 21, 2024
be1b7ee
fix(react): change return type of Consumers as JSX.Element (#891)
manudeli May 25, 2024
f36d0f6
chore: version packages (#892)
github-actions[bot] May 25, 2024
988e73b
docs: update README.md
manudeli May 25, 2024
39b4f1b
fix(react-query): easier to know constraint @tanstack/react-query v4 …
manudeli May 25, 2024
f7cc9fd
chore: version packages (#894)
github-actions[bot] May 25, 2024
1d9ecbc
ci(.github): add workflow to check broken link
manudeli May 25, 2024
9a64f22
docs(suspensive.org): fix broken links
manudeli May 25, 2024
1ec3f22
ci(.github): add broken-link-checker as dependencies
manudeli May 30, 2024
8c5844b
fix(react): return type of Delay should be JSX.Element (#898)
manudeli May 31, 2024
3004226
chore: version packages (#899)
github-actions[bot] May 31, 2024
e029885
docs: update README.md
manudeli Jun 1, 2024
d6f0f4e
ci: update labeler
manudeli Jun 8, 2024
d780032
chore: update turbo version
manudeli Jun 13, 2024
b4a03b3
fix(visualization): build error
manudeli Jun 13, 2024
0c86892
chore(*): Suspensive with Toss (#912)
manudeli Jun 13, 2024
40e4132
docs(*): fix typos (#910)
apeltop Jun 13, 2024
c6c0640
fix(react-query): improved TypeScript engine halt due to return type …
gwansikk Jun 13, 2024
faa231a
chore: version packages (#913)
github-actions[bot] Jun 13, 2024
8ad03e0
chore: update deps (#915)
manudeli Jun 13, 2024
bb1b254
docs(suspensive.org): update footer copyright (#917)
manudeli Jun 14, 2024
0cd2185
docs(v1.suspensive.org): update copyright (#918)
manudeli Jun 14, 2024
0d682c4
docs: update vercel deployment status
manudeli Jun 14, 2024
26013ac
Merge remote-tracking branch 'origin/v1'
manudeli Jun 14, 2024
1e7fbbe
chore(react-query): update JSDoc for `useSuspenseQueries`, `useSuspen…
gwansikk Jun 14, 2024
56fbcfb
chore: version packages (#924)
github-actions[bot] Jun 14, 2024
fc09a01
chore: update deps
manudeli Jun 16, 2024
306c94d
fix(react-query): update QueryErrorBoundary's jsdoc (#925)
manudeli Jun 16, 2024
0d9eac1
chore: version packages (#927)
github-actions[bot] Jun 16, 2024
db12e28
ci(broken-link-checker): add default url
manudeli Jun 16, 2024
2594ab3
docs(suspensive.org): fix typo (#928)
bicochan Jun 17, 2024
db95088
ci(*): add eslint-plugin-react-compiler to prepare react 19 (#934)
manudeli Jun 17, 2024
77478e2
chore: version packages (#935)
github-actions[bot] Jun 17, 2024
19e3c61
ci(ci): add codspeed (#936)
manudeli Jun 17, 2024
c665762
ci(react): update benchmark field of vitest.config.ts (#937)
manudeli Jun 17, 2024
da91ddd
chore: update deps (#939)
manudeli Jun 17, 2024
6248459
feat(react-query): add SuspenseQueries (#938)
manudeli Jun 17, 2024
ae54b50
chore: version packages (#945)
github-actions[bot] Jun 17, 2024
ddfca6e
chore(react-query): update SuspenseQueries as public api
manudeli Jun 17, 2024
5297afa
chore: version packages (#947)
github-actions[bot] Jun 17, 2024
77463c2
docs: fix broken link in `README.md` (#948)
gwansikk Jun 18, 2024
26dd707
docs(suspensive.org): update docs for `<SuspenseQueries/>`, `<Suspens…
gwansikk Jun 18, 2024
7619dec
chore(changeset): pre enter beta
manudeli Jun 18, 2024
2fd8108
fix(react-query): depend on @suspensive/react-query-4,5 to support @t…
manudeli Jun 19, 2024
0ce2c79
chore: version packages (beta) (#951)
github-actions[bot] Jun 19, 2024
8d8a2d6
feat(react-query): universal react-query for suspensive 4 and 5 (#953)
gwansikk Jun 21, 2024
3e6db9d
chore: version packages (beta) (#954)
github-actions[bot] Jun 21, 2024
43837a3
chore(changeset): pre exit (#957)
manudeli Jun 23, 2024
c159d25
chore: update
manudeli Jun 23, 2024
20119f8
chore: version packages (#958)
github-actions[bot] Jun 23, 2024
8eb8892
feat(suspensive.org): add Sandpack component (#963)
kangju2000 Jun 24, 2024
aa9008b
chore: delete changeset (#965)
kangju2000 Jun 24, 2024
d87a482
fix(react): add `<ClientOnly/>` internally (#964)
Collection50 Jun 24, 2024
ec57398
chore: version packages (#968)
github-actions[bot] Jun 24, 2024
0051a0e
fix(react): improved useTimeout and added usePreservedCallback (#966)
ssi02014 Jun 24, 2024
806f4f5
chore: version packages (#969)
github-actions[bot] Jun 24, 2024
80289d5
docs(react-query): update react-query for universal (#971)
gwansikk Jun 24, 2024
42af7d0
chore: revert pnpm lockfile (#973)
kangju2000 Jun 25, 2024
c9815d4
refactor(react-query): only TypeScript & src, dist (#970)
jungwoo3490 Jun 25, 2024
2c0e755
chore: version packages (#974)
github-actions[bot] Jun 25, 2024
09e957c
feat(configs): add options for scripts (#978)
gwansikk Jun 26, 2024
54cf646
chore: version packages (#980)
github-actions[bot] Jun 26, 2024
1bc423d
test(react-image): add test case for error handling while image loadi…
saul-atomrigs Jun 27, 2024
af960fc
chore: version packages (#988)
github-actions[bot] Jun 27, 2024
5a34768
chore(package.json): add concurrency option for dev script (#992)
manudeli Jun 27, 2024
c10c852
chore(pnpm): update version (#991)
manudeli Jun 27, 2024
990058f
docs(suspensive.org): add x link (#993)
manudeli Jun 27, 2024
424b0ec
chore(suspensive.org): remove unnecessary theme property from _meta.j…
kangju2000 Jun 27, 2024
cfd09f5
docs(suspensive.org): add examples to the ErrorBoundary documentation…
kangju2000 Jun 27, 2024
c693ee8
feat(react-query): use commander.js to provide an improved CLI (#976)
gwansikk Jun 27, 2024
025e660
fix(changeset): fix version of @suspensive/react-query-* with @suspen…
manudeli Jun 27, 2024
8e7e260
chore: version packages (#997)
github-actions[bot] Jun 27, 2024
8862c2a
test(react-image): add test code for `SuspenseImage` (#999)
saul-atomrigs Jun 28, 2024
1771317
chore: version packages (#1001)
github-actions[bot] Jun 28, 2024
c515da6
docs(suspensive.org): add ErrorBoundaryGroup examples using sandpack …
kangju2000 Jun 28, 2024
0991644
docs(suspensive.org): add sandpack examples to useSuspenseQuery, useS…
kangju2000 Jun 28, 2024
647fa47
docs: update `README.md` for root, react-query (#994)
gwansikk Jun 28, 2024
46cae9e
chore: version packages (#1004)
github-actions[bot] Jun 28, 2024
8249f32
test(react-await): improve test coverage for `await.spec.tsx` (`unsub…
saul-atomrigs Jun 29, 2024
f83a1c9
docs(suspensive.org): add sandpack examples to queryOptions (#1010)
kangju2000 Jun 30, 2024
e236070
fix(react-query-4): correct package.json's repository directory (#1013)
manudeli Jun 30, 2024
6205401
chore: version packages (#1014)
github-actions[bot] Jun 30, 2024
fce0d25
docs(suspensive.org): add contributors page (#1011)
manudeli Jun 30, 2024
c8b7d96
docs(suspensive.org): add sandpack example to wrap (#1017)
kangju2000 Jul 1, 2024
c5efd53
docs(suspensive.org): add sandpack examples to SuspenseQuery, Suspens…
kangju2000 Jul 1, 2024
2309449
test(react-query): add tests for commands, switchVersion, copy, packa…
gwansikk Jul 1, 2024
a4f3604
chore: version packages (#1023)
github-actions[bot] Jul 1, 2024
b29131a
feat(react-query): more descriptions for cli status (#1024)
gwansikk Jul 1, 2024
7c2d6e8
chore: version packages (#1026)
github-actions[bot] Jul 1, 2024
b6ab860
chore: update deps (#1030)
manudeli Jul 3, 2024
f83c00a
Revert "chore: update deps (#1030)"
manudeli Jul 4, 2024
451ec67
chore: update deps (#1033)
manudeli Jul 4, 2024
51671ca
docs(suspensive.org): add docs for cli (#1032)
gwansikk Jul 4, 2024
9966b3d
feat(@suspensive/react-query-5): add combine prop of `<SuspenseQuerie…
manudeli Jul 5, 2024
c1fa51a
chore: version packages (#1038)
github-actions[bot] Jul 5, 2024
35f9f6a
fix(react-query): remove experimental in jsdoc (#1039)
manudeli Jul 5, 2024
1fffa0f
chore: version packages (#1041)
github-actions[bot] Jul 5, 2024
421fa2e
chore(suspensive.org): add bigsaigon333(Donghee Kim) as maintainer (#…
manudeli Jul 5, 2024
e9c3234
feat(suspensive.org): add bubble chart for contributors page (#1043)
saul-atomrigs Jul 7, 2024
ed632c9
feat(react-query): add infiniteQueryOptions (#1044)
gwansikk Jul 7, 2024
f00a4b1
chore: update former maintainers
manudeli Jul 7, 2024
bf2ac03
chore: version packages (#1046)
github-actions[bot] Jul 8, 2024
cb94914
feat(jotai): add @suspensive/jotai package (#1042)
gwansikk Jul 8, 2024
edfde9f
chore: version packages (#1049)
github-actions[bot] Jul 8, 2024
a84bfb2
chore(suspensive.org): image optimization by sharp (#1050)
manudeli Jul 8, 2024
b4ee908
fix(suspensive.org): add defense code for github contributors fetchin…
saul-atomrigs Jul 8, 2024
6e3deeb
fix(suspensive.org): add fallback for response with 202 status code (…
manudeli Jul 8, 2024
b1e9495
feat(react-await): add `awaitOptions` (#1059)
SEOKKAMONI Jul 10, 2024
f1a3962
chore: version packages (#1060)
github-actions[bot] Jul 10, 2024
8ecc552
feat(promise): add new package @suspensive/promise (#1063)
manudeli Jul 10, 2024
df5cedb
chore: version packages (#1064)
github-actions[bot] Jul 10, 2024
2216377
fix(react): add defineSuspense util function (#1065)
ssi02014 Jul 10, 2024
f67be25
chore: version packages (#1067)
github-actions[bot] Jul 10, 2024
3fc22eb
feat(react-await): Separate useAwait, AwaitClient and add useAwait do…
SEOKKAMONI Jul 11, 2024
7eb9e9b
chore: version packages (#1070)
github-actions[bot] Jul 11, 2024
32bd5ab
feat(promise): add SuspensePromise, useSuspensePromise, promiseOption…
SEOKKAMONI Jul 13, 2024
97752bc
chore: version packages (#1078)
github-actions[bot] Jul 13, 2024
44d73f9
chore(*): vitest v2 (#1075)
manudeli Jul 13, 2024
d5b732e
feat(promise): remove @suspensive/promise package (#1079)
SEOKKAMONI Jul 13, 2024
f78700e
feat(cache): add @suspensive/cache (#1080)
manudeli Jul 13, 2024
02f0aec
test(react): improve `ErrorBoundary` test code (#1081)
jgjgill Jul 13, 2024
6848e8d
docs(suspensive.org): add docs for shouldCatch at `ErrorBoundary` (#1…
jgjgill Jul 14, 2024
6cae782
chore: version packages (#1086)
github-actions[bot] Jul 14, 2024
a7c5c58
feat(cache): add CacheStore, useCacheStore, CacheStoreProvider, useCa…
SEOKKAMONI Jul 15, 2024
97e7022
chore: version packages (#1087)
github-actions[bot] Jul 15, 2024
be21828
feat(cache): add DataTag type to cacheOptions (#1089)
SEOKKAMONI Jul 15, 2024
aaddaf4
chore: version packages (#1090)
github-actions[bot] Jul 15, 2024
fff4d7b
feat(react-query): add `<Mutation/>` (#1095)
manudeli Jul 17, 2024
c591968
chore: version packages (#1097)
github-actions[bot] Jul 17, 2024
78f9e1f
docs(suspensive.org): add docs for @suspensive/jotai (#1084)
gwansikk Jul 18, 2024
fd2a280
chore(turbo): use tui
manudeli Jul 18, 2024
8dcd88f
feat(react-query): add cli status result table (#1100)
gwansikk Jul 18, 2024
4b17387
chore: version packages (#1103)
github-actions[bot] Jul 18, 2024
6484583
chore: update script `ci:test:watch` of package.json
manudeli Jul 18, 2024
2326b13
feat(utils): add @suspensive/utils (#1110)
manudeli Jul 19, 2024
00a9233
chore: version packages (#1111)
github-actions[bot] Jul 19, 2024
f9fb719
feat(react): improve ClientOnly by useSyncExternalStore (#1105)
manudeli Jul 19, 2024
7d0bfd4
chore: version packages (#1112)
github-actions[bot] Jul 19, 2024
86a4640
docs: update README.md
manudeli Jul 19, 2024
a1882b8
feat(react-await): remove react-await package (#1114)
SEOKKAMONI Jul 19, 2024
ef312c7
docs(suspensive.org): add jotai, cache to the docs changelog (#1115)
SEOKKAMONI Jul 19, 2024
e946dcf
chore(*): broken eslint by tsconfig
manudeli Jul 21, 2024
8fc0080
chore(*): add knip (#1118)
SEOKKAMONI Jul 21, 2024
fe0e81b
docs(suspensive.org): update doc about clientOnly prop
manudeli Jul 22, 2024
7b8a4c9
docs(visualization): add how we remove Suspense clientOnly re-render …
manudeli Jul 22, 2024
ec92987
docs(suspensive.org): update tanstack query compatibility doc (#1117)
gwansikk Jul 22, 2024
e38c785
docs(suspensive.org): reduce chance to misunderstanding @suspensive/r…
manudeli Jul 22, 2024
67492ac
refactor(react-query): parse api list for status table from build fil…
gwansikk Jul 23, 2024
c1b88cf
chore: version packages (#1120)
github-actions[bot] Jul 23, 2024
737d8d4
chore: add compressed-size-action (#1124)
kangju2000 Jul 24, 2024
429c504
chore: update compressed-size-action pattern to include specific file…
kangju2000 Jul 24, 2024
39d8919
chore: update compressed-size-action pattern to check size of visuali…
kangju2000 Jul 24, 2024
f2b612d
fix(size-comment): remove create-issue: false to diff Pull Request's …
manudeli Jul 25, 2024
85e6371
ci: merge size-comment to ci.yml
manudeli Jul 25, 2024
89a6528
fix(react): deprecate DevMode (#1123)
manudeli Jul 25, 2024
0edc3e3
chore: version packages (#1129)
github-actions[bot] Jul 25, 2024
51f6a49
fix(react-query): peerDeps @suspensive/react version (#1130)
manudeli Jul 25, 2024
83f685c
chore: version packages (#1131)
github-actions[bot] Jul 25, 2024
8449980
chore(suspensive.org): add SEOKKAMONI(Seokjin Kim) as maintainer (#1134)
SEOKKAMONI Jul 25, 2024
2b74302
chore: increase the speed of the size action in CI (#1132)
kangju2000 Jul 25, 2024
ff91b56
refactor(react-query): improve status table (#1137)
gwansikk Jul 25, 2024
e0fe28d
chore: version packages (#1139)
github-actions[bot] Jul 25, 2024
314410e
feat(react-query): add re-export tanstack query functions (#1138)
gwansikk Jul 25, 2024
e5ed2be
fix(react-query): fixed dependencies
manudeli Jul 25, 2024
1876995
chore(pnpm): version down (#1142)
manudeli Jul 25, 2024
c9067ee
Update package.json (#1143)
manudeli Jul 25, 2024
04eafd3
chore: version packages (#1141)
github-actions[bot] Jul 25, 2024
eb5d257
feat(cache): add `remove` method to CacheStore (#1140)
SEOKKAMONI Jul 26, 2024
5008ad3
chore: version packages (#1146)
github-actions[bot] Jul 26, 2024
9ecaa7b
docs(suspensive.org): add _document.tsx to include Sandpack CSS (#1145)
kangju2000 Jul 26, 2024
951084a
docs(suspensive.org): fix typo Image -> SuspenseImage (#1148)
SEOKKAMONI Jul 26, 2024
47068d8
test(cache): Improve tests for CacheStore (#1147)
SEOKKAMONI Jul 27, 2024
148cdac
chore(eslint): update
manudeli Jul 27, 2024
fe7cb5e
test(react-query): add test code for copy function (#1151)
fe-dudu Jul 27, 2024
7714f92
chore: update permissions in CI (#1152)
kangju2000 Jul 27, 2024
cbbb6ff
chore: update README.md (#1154)
manudeli Jul 28, 2024
06c6222
test(react): add test code for the Wrap class (#1156)
fe-dudu Jul 28, 2024
49546cf
test(react): improve `ErrorBoundaryGroup` test code (#1157)
jgjgill Jul 28, 2024
aa84c20
chore: remove actions-next-bundle analyzer in CI (#1159)
kangju2000 Jul 28, 2024
53657b2
feat(react-native): initialization (#1150)
manudeli Jul 30, 2024
d29bf9f
feat(react): add ClientOnly (#1162)
Collection50 Jul 30, 2024
6beeb4c
chore: version packages (#1163)
github-actions[bot] Jul 30, 2024
1e5256d
feat(react): add DefaultProps & DefaultPropsProvider (#1160)
manudeli Jul 30, 2024
8073197
chore: version packages (#1164)
github-actions[bot] Jul 30, 2024
0eb7cfc
chore(deps): update
manudeli Aug 1, 2024
16c051a
docs(suspensive.org): add punctuation marks to a document (#1168)
SID12g Aug 1, 2024
637475b
ci(knip): separately (#1174)
manudeli Aug 1, 2024
adbb765
ci(react-native): fix jest (#1175)
manudeli Aug 2, 2024
414afdb
docs(suspensive.org): modify punctuation marks and spaces in the docu…
SID12g Aug 3, 2024
d1125a3
chore: update ISSUE_TEMPLATE
manudeli Aug 3, 2024
f79b96c
fix(*): remove unnecessary devDeps(react-dom, @types/react-dom) (#1180)
manudeli Aug 3, 2024
81546ce
chore: version packages (#1181)
github-actions[bot] Aug 3, 2024
6859215
feat(react-dom): init @suspensive/react-dom (#1182)
manudeli Aug 3, 2024
ebe1c8e
chore: version packages (#1183)
github-actions[bot] Aug 3, 2024
49d515d
feat(react-dom): add InView, useInView
manudeli Aug 3, 2024
09aa204
Merge remote-tracking branch 'origin/main' into react-dom/feat/InView
manudeli Aug 3, 2024
10b3212
Merge branch 'main' into react-dom/feat/InView
manudeli Aug 4, 2024
d271c26
Merge branch 'main' into react-dom/feat/InView
manudeli Aug 9, 2024
67c2f1a
Merge branch 'main' into react-dom/feat/InView
manudeli Aug 12, 2024
d391363
Merge branch 'main' into react-dom/feat/InView
manudeli Aug 13, 2024
574c6af
Merge branch 'main' into react-dom/feat/InView
manudeli Aug 14, 2024
f626780
Merge branch 'main' into react-dom/feat/InView
manudeli Aug 14, 2024
c8186aa
Merge branch 'main' into react-dom/feat/InView
manudeli Aug 16, 2024
adeea5d
Merge branch 'main' into react-dom/feat/InView
manudeli Aug 17, 2024
c73ade8
Merge branch 'main' into react-dom/feat/InView
manudeli Aug 17, 2024
03be679
Merge branch 'main' into react-dom/feat/InView
manudeli Aug 18, 2024
5386c54
Merge branch 'main' into react-dom/feat/InView
manudeli Aug 19, 2024
91396a3
Merge branch 'main' into react-dom/feat/InView
manudeli Aug 20, 2024
be5a9ce
Merge branch 'main' into react-dom/feat/InView
manudeli Aug 20, 2024
bd757fb
Merge branch 'main' into react-dom/feat/InView
manudeli Aug 21, 2024
5ee9563
Merge branch 'main' into react-dom/feat/InView
manudeli Aug 21, 2024
902137b
chore: update
manudeli Aug 21, 2024
bcbb6f1
chore: update
manudeli Aug 21, 2024
93fed8d
Merge branch 'main' into react-dom/feat/InView
manudeli Aug 22, 2024
9883af7
Merge branch 'main' into react-dom/feat/InView
manudeli Aug 23, 2024
61d89f1
Merge branch 'main' into react-dom/feat/InView
manudeli Aug 24, 2024
e7ab9e1
Merge branch 'main' into react-dom/feat/InView
manudeli Aug 24, 2024
f12e139
Merge branch 'main' into react-dom/feat/InView
manudeli Aug 25, 2024
ecc874d
chore: update
manudeli Aug 24, 2024
3b8ae43
chore: update
manudeli Aug 25, 2024
b369b1f
chore: update
manudeli Aug 25, 2024
dd577a7
chore: update
manudeli Aug 25, 2024
79b272e
chore: update
manudeli Aug 25, 2024
eb138ba
chore: update
manudeli Aug 25, 2024
7f77521
chore: update
manudeli Aug 25, 2024
ab187be
chore: update
manudeli Aug 25, 2024
631cadc
chore: update
manudeli Aug 25, 2024
2910ab6
Merge remote-tracking branch 'origin/main' into react-dom/feat/InView
manudeli Aug 26, 2024
18dc71b
Merge remote-tracking branch 'origin/main' into react-dom/feat/InView
manudeli Aug 29, 2024
ed00d6f
chore: update
manudeli Aug 29, 2024
2374331
Merge remote-tracking branch 'origin/main' into react-dom/feat/InView
manudeli Aug 31, 2024
bbe9f85
Merge branch 'main' into react-dom/feat/InView
manudeli Sep 1, 2024
6c3b1dd
Merge branch 'main' into react-dom/feat/InView
manudeli Sep 1, 2024
d3c8b7d
Merge branch 'main' into react-dom/feat/InView
manudeli Sep 1, 2024
8503722
Merge remote-tracking branch 'origin/main' into react-dom/feat/InView
manudeli Sep 1, 2024
b2cf0c6
Update packages/react-dom/src/setup.spec.ts
manudeli Sep 1, 2024
2d3ae3f
Update examples/visualization/src/app/layout.tsx
manudeli Sep 1, 2024
6337f05
chore: update
manudeli Sep 1, 2024
989402b
chore: remove isPlainChildren
manudeli Sep 1, 2024
361b0be
Update examples/visualization/src/app/react-dom/InView/page.tsx
manudeli Sep 1, 2024
98225a1
fix(react-dom): remove PlainChildren
manudeli Sep 1, 2024
62b3b65
chore: update
manudeli Sep 1, 2024
376f6e2
chore: update
manudeli Sep 1, 2024
2d5f327
chore: update
manudeli Sep 1, 2024
1316e53
Merge branch 'main' into react-dom/feat/InView
manudeli Sep 4, 2024
26910b7
Merge remote-tracking branch 'origin/main' into react-dom/feat/InView
manudeli Sep 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions configs/eslint-config/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,16 +85,13 @@
{
files: ['**/*.spec.ts*', '**/*.test.ts*', '**/*.test-d.ts*'],
plugins: { vitest },
rules: {
...vitest.configs.recommended.rules,
'vitest/expect-expect': 'warn',
},
rules: vitest.configs.recommended.rules,
settings: { vitest: { typecheck: true } },
},
jestDom.configs['flat/recommended'] as unknown as ReturnType<typeof tseslint.config>[number],

Check warning on line 91 in configs/eslint-config/src/index.ts

View workflow job for this annotation

GitHub Actions / Check quality (ci:eslint)

Unsafe member access .configs on an `error` typed value
{
plugins: {
import: importPlugin,

Check warning on line 94 in configs/eslint-config/src/index.ts

View workflow job for this annotation

GitHub Actions / Check quality (ci:eslint)

Unsafe assignment of an error typed value
},
rules: {
'sort-imports': ['error', { ignoreDeclarationSort: true }],
Expand All @@ -121,8 +118,8 @@
},
{
plugins: {
'react-hooks': reactHooks.configs.recommended,

Check warning on line 121 in configs/eslint-config/src/index.ts

View workflow job for this annotation

GitHub Actions / Check quality (ci:eslint)

Unsafe assignment of an error typed value

Check warning on line 121 in configs/eslint-config/src/index.ts

View workflow job for this annotation

GitHub Actions / Check quality (ci:eslint)

Unsafe member access .configs on an `error` typed value
'react-compiler': reactCompiler,

Check warning on line 122 in configs/eslint-config/src/index.ts

View workflow job for this annotation

GitHub Actions / Check quality (ci:eslint)

Unsafe assignment of an error typed value
},
languageOptions: {
globals: {
Expand All @@ -142,5 +139,5 @@

export const suspensiveNextTypeScriptConfig: ReturnType<typeof tseslint.config> = [
...suspensiveReactTypeScriptConfig,
{ plugins: { 'plugin:@next/next/recommended': next.configs.recommended } },

Check warning on line 142 in configs/eslint-config/src/index.ts

View workflow job for this annotation

GitHub Actions / Check quality (ci:eslint)

Unsafe assignment of an error typed value

Check warning on line 142 in configs/eslint-config/src/index.ts

View workflow job for this annotation

GitHub Actions / Check quality (ci:eslint)

Unsafe member access .configs on an `error` typed value
]
1 change: 1 addition & 0 deletions examples/visualization/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"dependencies": {
"@suspensive/cache": "workspace:*",
"@suspensive/react": "workspace:*",
"@suspensive/react-dom": "workspace:*",
"@suspensive/react-image": "workspace:*",
"@suspensive/react-query": "workspace:*",
"@tanstack/react-query": "catalog:react-query4",
Expand Down
8 changes: 8 additions & 0 deletions examples/visualization/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ export default function RootLayout({ children }: { children: React.ReactNode })
</li>
</details>
</li>
<li>
<details>
<summary>@suspensive/react-dom</summary>
<li>
<Link href="/react-dom/InView">{`<InView/>`}</Link>
</li>
</details>
</li>
<li>
<details>
<summary>@suspensive/react-query</summary>
Expand Down
24 changes: 24 additions & 0 deletions examples/visualization/src/app/react-dom/InView/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use client'

import { InView } from '@suspensive/react-dom'

export default function Page() {
return (
<div>
{Array.from({ length: 200 }).map((_, i) => (
// eslint-disable-next-line @eslint-react/no-duplicate-key
<InView key={i} threshold={0.8} delay={200} triggerOnce initialInView>
{({ inView, ref }) => (
<div ref={ref}>
{inView ? (
<div className="mt-2 h-14 w-96 bg-white" />
) : (
<div className="mt-2 h-14 w-96 animate-pulse bg-[#ffffff80]" />
)}
</div>
)}
</InView>
))}
</div>
)
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"@types/node": "^20.14.13",
"@vitest/browser": "^2.0.5",
"@vitest/coverage-istanbul": "^2.0.5",
"@vitest/coverage-v8": "^2.0.5",
"@vitest/ui": "^2.0.5",
"broken-link-checker": "^0.7.8",
"eslint": "^9.9.1",
Expand Down
4 changes: 3 additions & 1 deletion packages/react-dom/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@
"@suspensive/tsconfig": "workspace:*",
"@suspensive/tsup": "workspace:*",
"@types/react": "catalog:react18",
"react": "catalog:react18"
"@types/react-dom": "catalog:react18",
"react": "catalog:react18",
"react-dom": "catalog:react18"
},
"peerDependencies": {
"react": "^18"
Expand Down
56 changes: 56 additions & 0 deletions packages/react-dom/src/InView.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { render, screen } from '@testing-library/react'
import { InView } from './InView'
import { mockAllIsIntersecting } from './test-utils'

describe('<InView/>', () => {
it('should render <InView /> intersecting', () => {
const callback = vi.fn()
render(<InView onChange={callback}>{({ inView, ref }) => <div ref={ref}>{inView.toString()}</div>}</InView>)

mockAllIsIntersecting(false)
expect(callback).toHaveBeenLastCalledWith(false, expect.objectContaining({ isIntersecting: false }))

mockAllIsIntersecting(true)
expect(callback).toHaveBeenLastCalledWith(true, expect.objectContaining({ isIntersecting: true }))
})

// eslint-disable-next-line vitest/expect-expect
it('should handle initialInView', () => {
const cb = vi.fn()
render(
<InView initialInView onChange={cb}>
{({ inView }) => <span>InView: {inView.toString()}</span>}
</InView>
)
screen.getByText('InView: true')
})

// eslint-disable-next-line vitest/expect-expect
it('should unobserve old node', () => {
const { rerender } = render(
<InView>
{({ inView, ref }) => (
<div key="1" ref={ref}>
Inview: {inView.toString()}
</div>
)}
</InView>
)
rerender(
<InView>
{({ inView, ref }) => (
<div key="2" ref={ref}>
Inview: {inView.toString()}
</div>
)}
</InView>
)
mockAllIsIntersecting(true)
})

// eslint-disable-next-line vitest/expect-expect
it('should ensure node exists before observing and unobserving', () => {
const { unmount } = render(<InView>{() => null}</InView>)
unmount()
})
})
9 changes: 9 additions & 0 deletions packages/react-dom/src/InView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { type InViewOptions, useInView } from './useInView'

interface InViewProps extends InViewOptions {
children: (inViewResult: ReturnType<typeof useInView>) => React.ReactNode
}

export function InView({ children, ...options }: InViewProps) {
return <>{children(useInView(options))}</>
}
11 changes: 0 additions & 11 deletions packages/react-dom/src/TestText.spec.tsx

This file was deleted.

1 change: 0 additions & 1 deletion packages/react-dom/src/TestText.tsx

This file was deleted.

43 changes: 43 additions & 0 deletions packages/react-dom/src/browser/browser.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { cleanup, render, screen } from '@testing-library/react/pure'
import { type InViewOptions, useInView } from '../useInView'

afterEach(() => {
cleanup()
})

const HookComponent = ({ options }: { options?: InViewOptions }) => {
const div = useInView(options)

return (
<div ref={div.ref} data-testid="wrapper" style={{ height: 200, background: 'cyan' }} data-inview={div.inView}>
InView block
</div>
)
}

test('should come into view on after rendering', async () => {
render(<HookComponent />)
const wrapper = screen.getByTestId('wrapper')
await expect.element(wrapper).toHaveAttribute('data-inview', 'true')
})

test('should come into view after scrolling', async () => {
render(
<>
<div style={{ height: window.innerHeight }} />
<HookComponent />
<div style={{ height: window.innerHeight }} />
</>
)
const wrapper = screen.getByTestId('wrapper')

// Should not be inside the view
expect(wrapper).toHaveAttribute('data-inview', 'false')

// Scroll so the element comes into view
window.scrollTo(0, window.innerHeight)
// Should not be updated until intersection observer triggers
expect(wrapper).toHaveAttribute('data-inview', 'false')

await expect.element(wrapper).toHaveAttribute('data-inview', 'true')
})
3 changes: 2 additions & 1 deletion packages/react-dom/src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { TestText } from './TestText'
export { InView } from './InView'
export { useInView } from './useInView'
185 changes: 185 additions & 0 deletions packages/react-dom/src/test-utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
import * as React from 'react'
import * as DeprecatedReactTestUtils from 'react-dom/test-utils'

declare global {
// eslint-disable-next-line no-var
var IS_REACT_ACT_ENVIRONMENT: boolean
// eslint-disable-next-line no-var
var jest: { fn: typeof vi.fn } | undefined
}

const act = typeof React.act === 'function' ? React.act : DeprecatedReactTestUtils.act

type Item = {
callback: IntersectionObserverCallback
elements: Set<Element>
created: number
}

let isMocking = false

const observers = new Map<IntersectionObserver, Item>()

// If we are running in a valid testing environment, we can mock the IntersectionObserver.
if (typeof beforeAll !== 'undefined' && typeof afterEach !== 'undefined') {
beforeAll(() => {
// Use the exposed mock function. Currently, only supports Jest (`jest.fn`) and Vitest with globals (`vi.fn`).
if (typeof jest !== 'undefined') setupIntersectionMocking(jest.fn)
else if (typeof vi !== 'undefined') {
setupIntersectionMocking(vi.fn)
}
})

afterEach(() => {
resetIntersectionMocking()
})
}

function warnOnMissingSetup() {
if (isMocking) return
console.error(
`React Intersection Observer was not configured to handle mocking.
Outside Jest and Vitest, you might need to manually configure it by calling setupIntersectionMocking() and resetIntersectionMocking() in your test setup file.

// test-setup.js
import { resetIntersectionMocking, setupIntersectionMocking } from 'react-intersection-observer/test-utils';

beforeEach(() => {
setupIntersectionMocking(vi.fn);
});

afterEach(() => {
resetIntersectionMocking();
});`
)
}

function setupIntersectionMocking(mockFn: typeof vi.fn) {
global.IntersectionObserver = mockFn((cb, options = {}) => {
const item = {
callback: cb,
elements: new Set<Element>(),
created: Date.now(),
}
const instance: IntersectionObserver = {
thresholds: Array.isArray(options.threshold) ? options.threshold : [options.threshold ?? 0],
root: options.root ?? null,
rootMargin: options.rootMargin ?? '',
observe: mockFn((element: Element) => {
item.elements.add(element)
}),
unobserve: mockFn((element: Element) => {
item.elements.delete(element)
}),
disconnect: mockFn(() => {
observers.delete(instance)
}),
takeRecords: mockFn(),
}

observers.set(instance, item)

return instance
})

isMocking = true
}

function resetIntersectionMocking() {
if (
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
global.IntersectionObserver &&
'mockClear' in global.IntersectionObserver &&
typeof global.IntersectionObserver.mockClear === 'function'
) {
global.IntersectionObserver.mockClear()
}
observers.clear()
}

function triggerIntersection(
elements: Element[],
trigger: boolean | number,
observer: IntersectionObserver,
item: Item
) {
const entries: IntersectionObserverEntry[] = []

const isIntersecting =
typeof trigger === 'number' ? observer.thresholds.some((threshold) => trigger >= threshold) : trigger

let ratio: number

if (typeof trigger === 'number') {
const intersectedThresholds = observer.thresholds.filter((threshold) => trigger >= threshold)
ratio = intersectedThresholds.length > 0 ? intersectedThresholds[intersectedThresholds.length - 1] : 0
} else {
ratio = trigger ? 1 : 0
}

for (const element of elements) {
entries.push(<IntersectionObserverEntry>{
boundingClientRect: element.getBoundingClientRect(),
intersectionRatio: ratio,
intersectionRect: isIntersecting
? element.getBoundingClientRect()
: {
bottom: 0,
height: 0,
left: 0,
right: 0,
top: 0,
width: 0,
x: 0,
y: 0,
toJSON() {},
},
isIntersecting,
rootBounds: observer.root instanceof Element ? observer.root.getBoundingClientRect() : null,
target: element,
time: Date.now() - item.created,
})
}

// Trigger the IntersectionObserver callback with all the entries
if (
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
act &&
Boolean(global.IS_REACT_ACT_ENVIRONMENT)
)
act(() => item.callback(entries, observer))
else item.callback(entries, observer)
}

export function mockAllIsIntersecting(isIntersecting: boolean | number) {
warnOnMissingSetup()
for (const [observer, item] of observers) {
triggerIntersection(Array.from(item.elements), isIntersecting, observer, item)
}
}

export function mockIsIntersecting(element: Element, isIntersecting: boolean | number) {
warnOnMissingSetup()
const observer = intersectionMockInstance(element)
if (
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
!observer
) {
throw new Error('No IntersectionObserver instance found for element. Is it still mounted in the DOM?')
}
const item = observers.get(observer)
if (item) {
triggerIntersection([element], isIntersecting, observer, item)
}
}

export function intersectionMockInstance(element: Element): IntersectionObserver {
warnOnMissingSetup()
for (const [observer, item] of observers) {
if (item.elements.has(element)) {
return observer
}
}

throw new Error('Failed to find IntersectionObserver for element. Is it being observed?')
}
Loading
Loading