@imfusion/web-ui 0.5.1-dev.17.g60f2cb91 → 0.5.1-dev.19.g11b806f9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imfusion/web-ui",
3
- "version": "0.5.1-dev.17.g60f2cb91",
3
+ "version": "0.5.1-dev.19.g11b806f9",
4
4
  "description": "The official Web UI component library for ImFusion web apps",
5
5
  "author": "ImFusion GmbH",
6
6
  "license": "UNLICENSED",
@@ -12,7 +12,6 @@ src/
12
12
  <topic>.ts # queryOptions / mutationOptions
13
13
  query-key.ts # key factory, topic as the first segment
14
14
  types.ts # Zod schemas + z.infer types
15
- use-<thing>.ts # hooks wrapping the options for components
16
15
  http/ # transport: client, error normalisation — the only transport-aware place
17
16
  ```
18
17
 
@@ -65,19 +64,8 @@ export const userQueryOptions = () =>
65
64
  });
66
65
  ```
67
66
 
68
- The hook a component consumes:
69
-
70
- ```ts
71
- // api/user/use-user.ts
72
- import { useSuspenseQuery } from "@tanstack/react-query";
73
-
74
- import { userQueryOptions } from "./user";
75
-
76
- export const useUser = () => useSuspenseQuery(userQueryOptions());
77
- ```
78
-
79
- The options and their hook can start colocated in one file — options right beside the hook that consumes them — and split
80
- into separate files when the topic's complexity demands it.
67
+ Components consume query options directly with `useSuspenseQuery` (prefetched routes) or `useQuery` (secondary data). No
68
+ wrapper hooks — the options function is the reusable unit.
81
69
 
82
70
  Mutations follow the same shape with `mutationOptions`, the dirtied topic first in the `mutationKey`:
83
71
 
@@ -90,8 +78,86 @@ export const updateUserMutationOptions = () =>
90
78
  });
91
79
  ```
92
80
 
93
- Routes prefetch in the `loader` with `context.queryClient.ensureQueryData(userQueryOptions())`, components read with the
94
- `useSuspenseQuery` hook. Give the route a `pendingComponent`; let errors bubble to the nearest `errorComponent`.
81
+ The root route types the router context so every loader can reach the query client via DI:
82
+
83
+ ```ts
84
+ // routes/__root.tsx
85
+ import { Outlet, createRootRouteWithContext } from "@tanstack/react-router";
86
+ import type { QueryClient } from "@tanstack/react-query";
87
+
88
+ interface RouterContext {
89
+ queryClient: QueryClient;
90
+ }
91
+
92
+ export const Route = createRootRouteWithContext<RouterContext>()({
93
+ component: () => <Outlet />
94
+ });
95
+ ```
96
+
97
+ The router is created with that context filled in:
98
+
99
+ ```ts
100
+ // router.ts
101
+ import { createRouter } from "@tanstack/react-router";
102
+ import { routeTree } from "./routeTree.gen";
103
+ import { createQueryClient } from "./query-client";
104
+
105
+ const queryClient = createQueryClient();
106
+
107
+ export const router = createRouter({
108
+ routeTree,
109
+ context: { queryClient }
110
+ });
111
+ ```
112
+
113
+ A route prefetches in the `loader`, reads with `useSuspenseQuery`, and provides a `pendingComponent`; errors bubble to the
114
+ nearest `errorComponent`:
115
+
116
+ ```tsx
117
+ // routes/me.tsx
118
+ import { createFileRoute } from "@tanstack/react-router";
119
+ import { useSuspenseQuery } from "@tanstack/react-query";
120
+
121
+ import { userQueryOptions } from "#/api/user/user";
122
+
123
+ export const Route = createFileRoute("/me")({
124
+ loader: ({ context }) => context.queryClient.ensureQueryData(userQueryOptions()),
125
+ pendingComponent: () => <p>Loading…</p>,
126
+ component: MePage
127
+ });
128
+
129
+ function MePage() {
130
+ const { data: user } = useSuspenseQuery(userQueryOptions());
131
+ return <h1>{user.name}</h1>;
132
+ }
133
+ ```
134
+
135
+ Mutations use `useMutation` with the options factory. Manual invalidation is unnecessary when automatic invalidation is on
136
+ (see below):
137
+
138
+ ```tsx
139
+ // components/user-settings.tsx
140
+ import { useMutation } from "@tanstack/react-query";
141
+ import { useSuspenseQuery } from "@tanstack/react-query";
142
+
143
+ import { userQueryOptions, updateUserMutationOptions } from "#/api/user/user";
144
+
145
+ function UserSettings() {
146
+ const { data: user } = useSuspenseQuery(userQueryOptions());
147
+ const updateUser = useMutation(updateUserMutationOptions());
148
+
149
+ return (
150
+ <form
151
+ onSubmit={e => {
152
+ e.preventDefault();
153
+ updateUser.mutate({ name: "New Name" });
154
+ }}
155
+ >
156
+ <input defaultValue={user.name} />
157
+ </form>
158
+ );
159
+ }
160
+ ```
95
161
 
96
162
  ## Automatic invalidation
97
163