Skip to content

Commit d56cca9

Browse files
committed
yarr usePreloadedQuery bug fix
1 parent 0184151 commit d56cca9

14 files changed

+541
-52
lines changed

graphql.config.js

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
module.exports = {
2+
projects: {
3+
default: {
4+
schema: [
5+
'./schema/schema.graphql',
6+
'./schema/relay-extensions.graphql',
7+
],
8+
extensions: {
9+
languageService: {
10+
useSchemaFileDefinitions: true,
11+
},
12+
},
13+
},
14+
},
15+
}

index.html

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
</head>
1010
<body>
1111
<div id="app"><!--app-html--></div>
12+
<script>window.require = () => {}</script>
1213
<script type="module" src="/src/entry-client.tsx"></script>
1314
</body>
1415
</html>

package.json

+3
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,23 @@
2626
"h3": "^0.3.9",
2727
"http-proxy-middleware": "^2.0.2",
2828
"matcher": "^5.0.0",
29+
"node-fetch": "^3.2.0",
2930
"ohmyfetch": "^0.4.15",
3031
"react": "rc",
3132
"react-dom": "rc",
3233
"react-error-boundary": "^3.1.4",
3334
"react-relay": "^13.0.2",
3435
"react-relay-network-modern": "^6.2.1",
3536
"react-ssr-prepass": "^1.5.0",
37+
"react-virtuoso": "^2.6.0",
3638
"regenerator-runtime": "^0.13.9",
3739
"relay-runtime": "^13.0.2",
3840
"serve-static": "^1.14.2",
3941
"typescript": "^4.5.5",
4042
"vite": "^2.7.13",
4143
"vite-plugin-ssr": "^0.3.51",
4244
"vite-ssr": "^0.15.0",
45+
"whatwg-fetch": "^3.6.2",
4346
"yarr": "^2.0.4"
4447
},
4548
"devDependencies": {

schema/relay-extensions.graphql

+242
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
# Copyright (c) Meta Platforms, Inc. and affiliates.
2+
#
3+
# This source code is licensed under the MIT license found in the
4+
# LICENSE file in the root directory of this source tree.
5+
6+
directive @relay_test_operation on QUERY | MUTATION | SUBSCRIPTION
7+
8+
"""
9+
(Relay only)
10+
11+
The hooks APIs that Relay exposes allow you to read data from the store only
12+
during the render phase. In order to read data from outside of the render
13+
phase (or from outside of React), Relay exposes the `@inline` directive. The
14+
data from a fragment annotated with `@inline` can be read using `readInlineData`.
15+
16+
[Read More](https://relay.dev/docs/api-reference/graphql-and-directives/#inline)
17+
"""
18+
directive @inline on FRAGMENT_DEFINITION
19+
20+
directive @no_inline(raw_response_type: Boolean) on FRAGMENT_DEFINITION
21+
22+
"""
23+
(Relay only)
24+
25+
A directive added to queries which tells Relay to generate types that cover
26+
the `optimisticResponse` parameter to `commitMutation`.
27+
28+
[Read More](https://relay.dev/docs/glossary/#raw_response_type)
29+
"""
30+
directive @raw_response_type on QUERY | MUTATION | SUBSCRIPTION
31+
32+
directive @DEPRECATED__relay_ignore_unused_variables_error on QUERY | MUTATION | SUBSCRIPTION
33+
34+
"""
35+
(Relay Only)
36+
37+
For use with [`useRefetchableFragment`](https://relay.dev/docs/api-reference/use-refetchable-fragment/).
38+
39+
The @refetchable directive can only be added to fragments that are
40+
"refetchable", that is, on fragments that are declared on Viewer or Query
41+
types, or on a type that implements `Node` (i.e. a type that has an id).
42+
43+
[Read More](https://relay.dev/docs/api-reference/use-refetchable-fragment/#arguments)
44+
"""
45+
directive @refetchable(
46+
queryName: String!
47+
directives: [String!]
48+
) on FRAGMENT_DEFINITION
49+
50+
"""
51+
(Relay Only)
52+
53+
A directive that modifies queries and which causes Relay to generate
54+
`$Parameters.js` files and preloadable concrete requests. Required if the
55+
query is going to be used as part of an entry point.
56+
57+
The `hackPreloader` argument is FB only and generates a Hack preloader file.
58+
59+
[Read More](https://relay.dev/docs/glossary/#preloadable)
60+
"""
61+
directive @preloadable(hackPreloader: Boolean = false) on QUERY
62+
63+
"""
64+
(Relay Only)
65+
66+
A directive that allows you to turn off Relay's data masking.
67+
68+
Read more
69+
[here](https://relay.dev/docs/api-reference/graphql-and-directives/#relayplural-boolean)
70+
and
71+
[here](https://relay.dev/docs/api-reference/graphql-and-directives/#relaymask-boolean).
72+
"""
73+
directive @relay(
74+
mask: Boolean
75+
plural: Boolean
76+
) on FRAGMENT_DEFINITION | FRAGMENT_SPREAD
77+
78+
# Handles
79+
# prettier-ignore
80+
directive @__clientField(
81+
filters: [String!]
82+
handle: String!
83+
key: String
84+
) repeatable on FIELD
85+
86+
# MatchTransform
87+
"""
88+
(Relay Only)
89+
90+
A directive that, when used in combination with `@module`, allows users to
91+
download specific JS components alongside the rest of the GraphQL payload if
92+
the field decorated with [`@match`](https://relay.dev/docs/glossary/#match)
93+
has a certain type. See [3D](https://relay.dev/docs/glossary/#3d).
94+
95+
[Read More](https://relay.dev/docs/glossary/#match)
96+
"""
97+
directive @match(key: String) on FIELD
98+
99+
"""
100+
(Relay Only)
101+
102+
A directive that, when used in combination with
103+
[`@match`](https://relay.dev/docs/glossary/#match), allows users to specify
104+
which JS components to download if the field decorated with @match has a
105+
certain type. See [3D](https://relay.dev/docs/glossary/#3d).
106+
107+
[Read More](https://relay.dev/docs/glossary/#module)
108+
"""
109+
directive @module(name: String!) on FRAGMENT_SPREAD
110+
111+
# ConnectionTransform
112+
"""
113+
(Relay Only)
114+
115+
A directive which declares that a field implements the connection spec.
116+
117+
[Read More](https://relay.dev/docs/guided-tour/list-data/pagination/)
118+
"""
119+
directive @connection(
120+
key: String!
121+
filters: [String]
122+
handler: String
123+
dynamicKey_UNSTABLE: String
124+
) on FIELD
125+
126+
directive @stream_connection(
127+
key: String!
128+
filters: [String]
129+
handler: String
130+
label: String
131+
initial_count: Int!
132+
if: Boolean = true
133+
use_customized_batch: Boolean = false
134+
dynamicKey_UNSTABLE: String
135+
) on FIELD
136+
137+
# RequiredTransform
138+
enum RequiredFieldAction {
139+
NONE
140+
LOG
141+
THROW
142+
}
143+
144+
"""
145+
(Relay Only)
146+
147+
`@required` is a directive you can add to fields in your Relay queries to
148+
declare how null values should be handled at runtime. You can think of it as
149+
saying "if this field is ever null, its parent field is invalid and should be
150+
null".
151+
152+
[Read More](https://www.internalfb.com/intern/staticdocs/relay/docs/guides/required-directive/) (FB only)
153+
"""
154+
directive @required(action: RequiredFieldAction!) on FIELD
155+
156+
# DeclarativeConnection
157+
"""
158+
(Relay Only)
159+
160+
For use within mutations. After the mutation request is complete, this field
161+
will be removed from the store.
162+
163+
[Read More](https://relay.dev/docs/guided-tour/updating-data/graphql-mutations/#updating-data-once-a-request-is-complete)
164+
"""
165+
directive @deleteRecord on FIELD
166+
167+
"""
168+
(Relay Only)
169+
170+
For use within mutations. After the mutation request is complete, this edge
171+
will be removed from its parent connection.
172+
173+
[Read More](https://relay.dev/docs/guided-tour/updating-data/graphql-mutations/#updating-data-once-a-request-is-complete)
174+
"""
175+
directive @deleteEdge(connections: [ID!]!) on FIELD
176+
177+
"""
178+
(Relay Only)
179+
180+
For use within mutations. After the mutation request is complete, this edge
181+
will be appended to its parent connection.
182+
183+
[Read More](https://relay.dev/docs/guided-tour/updating-data/graphql-mutations/#updating-data-once-a-request-is-complete)
184+
"""
185+
directive @appendEdge(connections: [ID!]!) on FIELD
186+
187+
"""
188+
(Relay Only)
189+
190+
For use within mutations. After the mutation request is complete, this edge
191+
will be prepended to its parent connection.
192+
193+
[Read More](https://relay.dev/docs/guided-tour/updating-data/graphql-mutations/#updating-data-once-a-request-is-complete)
194+
"""
195+
directive @prependEdge(connections: [ID!]!) on FIELD
196+
197+
"""
198+
(Relay Only)
199+
200+
For use within mutations. After the mutation request is complete, this node
201+
will be appended to its parent connection.
202+
203+
[Read More](https://relay.dev/docs/guided-tour/updating-data/graphql-mutations/#updating-data-once-a-request-is-complete)
204+
"""
205+
directive @appendNode(connections: [ID!]!, edgeTypeName: String!) on FIELD
206+
207+
"""
208+
(Relay Only)
209+
210+
For use within mutations. After the mutation request is complete, this node
211+
will be prepended to its parent connection.
212+
213+
[Read More](https://relay.dev/docs/guided-tour/updating-data/graphql-mutations/#updating-data-once-a-request-is-complete)
214+
"""
215+
directive @prependNode(connections: [ID!]!, edgeTypeName: String!) on FIELD
216+
217+
# RelayClientComponentTransform
218+
directive @relay_client_component on FRAGMENT_SPREAD
219+
220+
# RelayResolver
221+
directive @relay_resolver(
222+
fragment_name: String!
223+
import_path: String!
224+
) on FIELD_DEFINITION
225+
226+
"""
227+
(Relay Only)
228+
229+
Marks a given query or fragment as updatable.
230+
231+
[Read More](https://fb.quip.com/4FZaADvkQPPl)
232+
"""
233+
directive @updatable on QUERY | FRAGMENT_DEFINITION
234+
235+
"""
236+
(Relay Only)
237+
238+
Marks a given fragment as assignable.
239+
240+
[Read More](https://fb.quip.com/4FZaADvkQPPl)
241+
"""
242+
directive @assignable on FRAGMENT_DEFINITION

src/components/InfinateScrollGrid.tsx

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import React, { forwardRef, useRef } from "react";
2+
import {
3+
ItemContent,
4+
ItemProps,
5+
Virtuoso,
6+
VirtuosoHandle
7+
} from "react-virtuoso";
8+
9+
type InfinateScrollGridProps<D> = {
10+
data: readonly D[];
11+
endReached?: (index: number) => void;
12+
itemContent?: ItemContent<D>;
13+
hasMoreData?: boolean;
14+
};
15+
16+
const List = forwardRef<HTMLDivElement>(
17+
(
18+
{
19+
style,
20+
...props
21+
}: React.DetailedHTMLProps<
22+
React.HTMLAttributes<HTMLDivElement>,
23+
HTMLDivElement
24+
>,
25+
ref
26+
) => {
27+
return (
28+
<div
29+
className="snap-y first:mt-4 px-4 space-y-4 box"
30+
style={{
31+
...style,
32+
marginTop: undefined,
33+
}}
34+
{...props}
35+
ref={ref}
36+
/>
37+
);
38+
}
39+
);
40+
41+
const FancyScroller = React.forwardRef(
42+
({ children, ...props }, ref: React.Ref<HTMLDivElement>) => {
43+
return (
44+
<div style={{ border: "1px solid pink" }}>
45+
<div {...props} ref={ref}>
46+
{children}
47+
</div>
48+
</div>
49+
);
50+
}
51+
);
52+
53+
const Item = forwardRef<HTMLDivElement, ItemProps>((props, ref) => {
54+
return <div className="snap-start" {...props} ref={ref} />;
55+
});
56+
57+
export function InfinateScrollGrid<D>({
58+
data,
59+
itemContent,
60+
hasMoreData,
61+
endReached,
62+
}: InfinateScrollGridProps<D>) {
63+
const virtuoso = useRef<VirtuosoHandle>(null);
64+
return (
65+
<Virtuoso
66+
ref={virtuoso}
67+
className="w-96"
68+
style={{
69+
height: 600,
70+
outline: "1px solid black",
71+
}}
72+
data={data}
73+
endReached={endReached}
74+
itemContent={itemContent}
75+
components={{
76+
Scroller: FancyScroller,
77+
List,
78+
Item,
79+
Footer: () => {
80+
return (
81+
<div
82+
style={{
83+
padding: "2rem",
84+
display: "flex",
85+
justifyContent: "center",
86+
}}
87+
>
88+
{hasMoreData && "Loading..."}
89+
</div>
90+
);
91+
},
92+
}}
93+
/>
94+
);
95+
}

0 commit comments

Comments
 (0)