@base316/react 0.1.0 → 0.3.0

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.
Files changed (72) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README.md +29 -15
  3. package/dist/index.cjs +4361 -166
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.d.ts +48 -0
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +4344 -164
  8. package/dist/index.js.map +1 -1
  9. package/dist/manifest.json +1176 -0
  10. package/dist/src/AcceptInvitation.d.ts +27 -0
  11. package/dist/src/AcceptInvitation.d.ts.map +1 -0
  12. package/dist/src/ActiveSessions.d.ts +21 -0
  13. package/dist/src/ActiveSessions.d.ts.map +1 -0
  14. package/dist/src/ApiKeyManager.d.ts +22 -0
  15. package/dist/src/ApiKeyManager.d.ts.map +1 -0
  16. package/dist/src/Chart.d.ts +42 -0
  17. package/dist/src/Chart.d.ts.map +1 -0
  18. package/dist/src/DataTable.d.ts +56 -0
  19. package/dist/src/DataTable.d.ts.map +1 -0
  20. package/dist/src/DeviceApproval.d.ts +30 -0
  21. package/dist/src/DeviceApproval.d.ts.map +1 -0
  22. package/dist/src/ForgotPassword.d.ts +24 -0
  23. package/dist/src/ForgotPassword.d.ts.map +1 -0
  24. package/dist/src/Invoices.d.ts.map +1 -1
  25. package/dist/src/Kanban.d.ts +40 -0
  26. package/dist/src/Kanban.d.ts.map +1 -0
  27. package/dist/src/PasskeyManager.d.ts.map +1 -1
  28. package/dist/src/PayInvoice.d.ts +41 -0
  29. package/dist/src/PayInvoice.d.ts.map +1 -0
  30. package/dist/src/PricingTable.d.ts +43 -11
  31. package/dist/src/PricingTable.d.ts.map +1 -1
  32. package/dist/src/PrivacyControls.d.ts +28 -0
  33. package/dist/src/PrivacyControls.d.ts.map +1 -0
  34. package/dist/src/RecordDetail.d.ts +31 -0
  35. package/dist/src/RecordDetail.d.ts.map +1 -0
  36. package/dist/src/RecordForm.d.ts +32 -0
  37. package/dist/src/RecordForm.d.ts.map +1 -0
  38. package/dist/src/RelationPicker.d.ts +23 -0
  39. package/dist/src/RelationPicker.d.ts.map +1 -0
  40. package/dist/src/ResetPassword.d.ts +24 -0
  41. package/dist/src/ResetPassword.d.ts.map +1 -0
  42. package/dist/src/SignIn.d.ts +20 -2
  43. package/dist/src/SignIn.d.ts.map +1 -1
  44. package/dist/src/SignUp.d.ts.map +1 -1
  45. package/dist/src/SubscriptionManager.d.ts.map +1 -1
  46. package/dist/src/TeamMembers.d.ts +49 -0
  47. package/dist/src/TeamMembers.d.ts.map +1 -0
  48. package/dist/src/TwoFactorManager.d.ts +38 -0
  49. package/dist/src/TwoFactorManager.d.ts.map +1 -0
  50. package/dist/src/VerifyEmail.d.ts +24 -0
  51. package/dist/src/VerifyEmail.d.ts.map +1 -0
  52. package/dist/src/appearance.d.ts +2 -2
  53. package/dist/src/appearance.d.ts.map +1 -1
  54. package/dist/src/confirm.d.ts +32 -0
  55. package/dist/src/confirm.d.ts.map +1 -0
  56. package/dist/src/fields.d.ts +44 -0
  57. package/dist/src/fields.d.ts.map +1 -0
  58. package/dist/src/manifest.d.ts +84 -0
  59. package/dist/src/manifest.d.ts.map +1 -0
  60. package/dist/src/provider.d.ts +13 -1
  61. package/dist/src/provider.d.ts.map +1 -1
  62. package/dist/src/test/harness.d.ts +204 -0
  63. package/dist/src/test/harness.d.ts.map +1 -0
  64. package/dist/src/test/setup.d.ts +2 -0
  65. package/dist/src/test/setup.d.ts.map +1 -0
  66. package/dist/src/useCollection.d.ts +79 -0
  67. package/dist/src/useCollection.d.ts.map +1 -0
  68. package/dist/src/usePaymentLink.d.ts +41 -0
  69. package/dist/src/usePaymentLink.d.ts.map +1 -0
  70. package/dist/src/usePlans.d.ts +74 -0
  71. package/dist/src/usePlans.d.ts.map +1 -0
  72. package/package.json +36 -28
@@ -0,0 +1,1176 @@
1
+ {
2
+ "version": 1,
3
+ "composition": {
4
+ "rules": [
5
+ "Everything must be inside Base316Provider. Outside it, hooks throw.",
6
+ "Most components need a signed-in user. Gate on useSession and render SignIn when there is none — see `requires: session` on each entry.",
7
+ "A collection must exist before anything can bind to it. Define one in the dashboard under Collections, or through POST /v1/collections with a secret key.",
8
+ "No component takes a prop you must supply to make it behave. Naming the subject is different: a collection component needs `collection` and a detail view needs `recordId`, because those say *what* to show rather than patch *how* it works. Everything else has a default.",
9
+ "Each component bound to a collection holds its own data — DataTable, Kanban, Chart, RecordForm, RecordDetail, every one. None of them share a cache, so a write in one leaves the others showing what they already had. Put the form inside the table, where New and Edit refresh it; pass `onChanged` to refresh a sibling such as a Chart; or lift `useCollection` and render your own, which is what the hook is for.",
10
+ "Next.js App Router: put Base316Provider in a Client Component wrapper used by the root layout. Every component here is a Client Component; none of them run on the server."
11
+ ],
12
+ "example": "import { Base316Provider, DataTable, RecordForm, SignIn, useSession } from \"@base316/react\";\n\nfunction Jobs() {\n const session = useSession();\n\n // Without this the table renders nothing and looks broken.\n if (!session) return <SignIn />;\n\n return (\n <>\n <DataTable collection=\"jobs\" onSelect={(record) => console.log(record.id)} />\n <RecordForm collection=\"jobs\" />\n </>\n );\n}\n\nexport function App() {\n return (\n <Base316Provider publishableKey={process.env.NEXT_PUBLIC_BASE316_PUBLISHABLE_KEY!}>\n <Jobs />\n </Base316Provider>\n );\n}"
13
+ },
14
+ "components": [
15
+ {
16
+ "name": "Base316Provider",
17
+ "kind": "provider",
18
+ "summary": "Holds the client, the session and the theme. Everything else must be inside it.",
19
+ "useWhen": "Once, around the part of the application that uses any other export here.",
20
+ "requires": [],
21
+ "props": [
22
+ {
23
+ "name": "publishableKey",
24
+ "summary": "The environment's publishable key.",
25
+ "required": true
26
+ },
27
+ {
28
+ "name": "baseUrl",
29
+ "summary": "Where the API lives. Defaults to production.",
30
+ "required": false
31
+ },
32
+ {
33
+ "name": "token",
34
+ "summary": "Supply to own session storage yourself. Left out, the session is kept in localStorage.",
35
+ "required": false
36
+ },
37
+ {
38
+ "name": "onTokenChange",
39
+ "summary": "Called when the session changes. Pair with `token` for an httpOnly cookie.",
40
+ "required": false
41
+ },
42
+ {
43
+ "name": "appearance",
44
+ "summary": "Colours, radius and font as tokens. Restyles everything at once.",
45
+ "required": false
46
+ },
47
+ {
48
+ "name": "tenant",
49
+ "summary": "White-label everything inside for one tenant — `{ organizationId }` or `{ organizationExternalId }`. A firm's name, logo and colours on the screens it runs its clients on; its own branding, then its parent's, then the environment's. Change it when the user switches team.",
50
+ "required": false
51
+ },
52
+ {
53
+ "name": "className",
54
+ "summary": "Your own classes on the wrapper.",
55
+ "required": false
56
+ },
57
+ {
58
+ "name": "style",
59
+ "summary": "Inline styles on the wrapper.",
60
+ "required": false
61
+ }
62
+ ],
63
+ "seeAlso": [
64
+ "useBase316",
65
+ "useSession"
66
+ ]
67
+ },
68
+ {
69
+ "name": "useBase316",
70
+ "kind": "hook",
71
+ "summary": "The client, the session token and the branding, from inside the provider.",
72
+ "useWhen": "Writing a component of your own that needs to call the API directly.",
73
+ "requires": [],
74
+ "props": [],
75
+ "seeAlso": [
76
+ "Base316Provider"
77
+ ]
78
+ },
79
+ {
80
+ "name": "useSession",
81
+ "kind": "hook",
82
+ "summary": "The resolved session, or null. Carries `userId`, `user` (id, email, name, image, and the customer's own declared fields) and `tenants` — every team this person is in, each with their role.",
83
+ "useWhen": "Deciding what to render for a signed-in versus a signed-out visitor.",
84
+ "requires": [],
85
+ "props": []
86
+ },
87
+ {
88
+ "name": "SignIn",
89
+ "kind": "component",
90
+ "summary": "Password, passkey, magic-link and text-message sign-in in one form.",
91
+ "useWhen": "The application renders its own sign-in rather than redirecting to the hosted page.",
92
+ "requires": [],
93
+ "props": [
94
+ {
95
+ "name": "onSignedIn",
96
+ "summary": "Called once a session exists.",
97
+ "required": false
98
+ },
99
+ {
100
+ "name": "passkeys",
101
+ "summary": "Offer passkeys where supported. On by default.",
102
+ "required": false
103
+ },
104
+ {
105
+ "name": "magicLinkRedirectUrl",
106
+ "summary": "Where an emailed link lands, which must be registered on the environment. Without it, magic link is not offered at all.",
107
+ "required": false
108
+ },
109
+ {
110
+ "name": "phone",
111
+ "summary": "Offer signing in with a code sent by text message. Needs text messages switched on for the environment, and its own Twilio account in production.",
112
+ "required": false
113
+ },
114
+ {
115
+ "name": "className",
116
+ "summary": "Your own classes on the wrapper.",
117
+ "required": false
118
+ },
119
+ {
120
+ "name": "style",
121
+ "summary": "Inline styles on the wrapper.",
122
+ "required": false
123
+ }
124
+ ],
125
+ "seeAlso": [
126
+ "SignUp",
127
+ "ForgotPassword"
128
+ ]
129
+ },
130
+ {
131
+ "name": "SignUp",
132
+ "kind": "component",
133
+ "summary": "Create an account with an email and a password.",
134
+ "useWhen": "Alongside SignIn, on a page that registers new users.",
135
+ "requires": [],
136
+ "props": [
137
+ {
138
+ "name": "onSignedUp",
139
+ "summary": "Called after the account is created.",
140
+ "required": false
141
+ },
142
+ {
143
+ "name": "className",
144
+ "summary": "Your own classes on the wrapper.",
145
+ "required": false
146
+ },
147
+ {
148
+ "name": "style",
149
+ "summary": "Inline styles on the wrapper.",
150
+ "required": false
151
+ }
152
+ ],
153
+ "seeAlso": [
154
+ "SignIn",
155
+ "VerifyEmail"
156
+ ]
157
+ },
158
+ {
159
+ "name": "ForgotPassword",
160
+ "kind": "component",
161
+ "summary": "Ask for a reset link by email.",
162
+ "useWhen": "Linked from a sign-in form.",
163
+ "requires": [],
164
+ "props": [
165
+ {
166
+ "name": "onSent",
167
+ "summary": "Called with the address after the request.",
168
+ "required": false
169
+ },
170
+ {
171
+ "name": "signInUrl",
172
+ "summary": "Renders a link back to sign-in.",
173
+ "required": false
174
+ },
175
+ {
176
+ "name": "className",
177
+ "summary": "Your own classes on the wrapper.",
178
+ "required": false
179
+ },
180
+ {
181
+ "name": "style",
182
+ "summary": "Inline styles on the wrapper.",
183
+ "required": false
184
+ }
185
+ ],
186
+ "seeAlso": [
187
+ "ResetPassword"
188
+ ]
189
+ },
190
+ {
191
+ "name": "ResetPassword",
192
+ "kind": "component",
193
+ "summary": "Set a new password from an emailed link.",
194
+ "useWhen": "On the page the reset link lands on.",
195
+ "requires": [],
196
+ "props": [
197
+ {
198
+ "name": "token",
199
+ "summary": "Read from `?token=` when omitted, and removed from the URL.",
200
+ "required": false
201
+ },
202
+ {
203
+ "name": "onReset",
204
+ "summary": "Called once the password is changed.",
205
+ "required": false
206
+ },
207
+ {
208
+ "name": "signInUrl",
209
+ "summary": "Renders a link onward to sign-in.",
210
+ "required": false
211
+ },
212
+ {
213
+ "name": "className",
214
+ "summary": "Your own classes on the wrapper.",
215
+ "required": false
216
+ },
217
+ {
218
+ "name": "style",
219
+ "summary": "Inline styles on the wrapper.",
220
+ "required": false
221
+ }
222
+ ],
223
+ "whenUnmet": "With no token in the URL or props, explains that the link is needed.",
224
+ "seeAlso": [
225
+ "ForgotPassword"
226
+ ]
227
+ },
228
+ {
229
+ "name": "VerifyEmail",
230
+ "kind": "component",
231
+ "summary": "Confirm an address from an emailed link.",
232
+ "useWhen": "On the page the verification link lands on.",
233
+ "requires": [],
234
+ "props": [
235
+ {
236
+ "name": "token",
237
+ "summary": "Read from `?token=` when omitted, and removed from the URL.",
238
+ "required": false
239
+ },
240
+ {
241
+ "name": "onVerified",
242
+ "summary": "Called once confirmed.",
243
+ "required": false
244
+ },
245
+ {
246
+ "name": "continueUrl",
247
+ "summary": "Renders a link onward.",
248
+ "required": false
249
+ },
250
+ {
251
+ "name": "className",
252
+ "summary": "Your own classes on the wrapper.",
253
+ "required": false
254
+ },
255
+ {
256
+ "name": "style",
257
+ "summary": "Inline styles on the wrapper.",
258
+ "required": false
259
+ }
260
+ ],
261
+ "seeAlso": [
262
+ "SignUp"
263
+ ]
264
+ },
265
+ {
266
+ "name": "UserProfile",
267
+ "kind": "component",
268
+ "summary": "Name, email and the customer's own declared fields.",
269
+ "useWhen": "An account settings page.",
270
+ "requires": [
271
+ "session"
272
+ ],
273
+ "props": [],
274
+ "whenUnmet": "Renders nothing without a session.",
275
+ "seeAlso": [
276
+ "ActiveSessions",
277
+ "TwoFactorManager",
278
+ "PasskeyManager"
279
+ ]
280
+ },
281
+ {
282
+ "name": "ActiveSessions",
283
+ "kind": "component",
284
+ "summary": "Where the account is signed in, and a button to end the other devices.",
285
+ "useWhen": "A security settings page.",
286
+ "requires": [
287
+ "session"
288
+ ],
289
+ "props": [
290
+ {
291
+ "name": "onRevoked",
292
+ "summary": "Called with the number of sessions ended.",
293
+ "required": false
294
+ },
295
+ {
296
+ "name": "className",
297
+ "summary": "Your own classes on the wrapper.",
298
+ "required": false
299
+ },
300
+ {
301
+ "name": "style",
302
+ "summary": "Inline styles on the wrapper.",
303
+ "required": false
304
+ }
305
+ ],
306
+ "whenUnmet": "Renders nothing without a session.",
307
+ "seeAlso": [
308
+ "TwoFactorManager"
309
+ ]
310
+ },
311
+ {
312
+ "name": "DeviceApproval",
313
+ "kind": "component",
314
+ "summary": "Approve a sign-in that started on a CLI, a TV, or anything with no browser.",
315
+ "useWhen": "You point a device's verification URI at a page in your own app. Put this on that page.",
316
+ "requires": [
317
+ "session"
318
+ ],
319
+ "props": [
320
+ {
321
+ "name": "userCode",
322
+ "summary": "The code, when the URL already carries it. Skips the entry step; without it the person types the code.",
323
+ "required": false
324
+ },
325
+ {
326
+ "name": "onDecided",
327
+ "summary": "Called with whether they approved.",
328
+ "required": false
329
+ },
330
+ {
331
+ "name": "className",
332
+ "summary": "Your own classes on the wrapper.",
333
+ "required": false
334
+ },
335
+ {
336
+ "name": "style",
337
+ "summary": "Inline styles on the wrapper.",
338
+ "required": false
339
+ }
340
+ ],
341
+ "whenUnmet": "Renders nothing without a session — there is nobody to approve as, and collecting a code first would fail at the step that matters.",
342
+ "seeAlso": [
343
+ "SignIn",
344
+ "ActiveSessions"
345
+ ]
346
+ },
347
+ {
348
+ "name": "PrivacyControls",
349
+ "kind": "component",
350
+ "summary": "Download a copy of everything held about you, or delete your account.",
351
+ "useWhen": "An account settings page. These are the two things a privacy notice promises and most products never build.",
352
+ "requires": [
353
+ "session"
354
+ ],
355
+ "props": [
356
+ {
357
+ "name": "confirmWord",
358
+ "summary": "What must be typed to confirm deletion. Defaults to the English word, which is wrong in every other language.",
359
+ "required": false
360
+ },
361
+ {
362
+ "name": "onErased",
363
+ "summary": "Called once the account is gone. Sign them out and send them somewhere.",
364
+ "required": false
365
+ },
366
+ {
367
+ "name": "className",
368
+ "summary": "Your own classes on the wrapper.",
369
+ "required": false
370
+ },
371
+ {
372
+ "name": "style",
373
+ "summary": "Inline styles on the wrapper.",
374
+ "required": false
375
+ }
376
+ ],
377
+ "whenUnmet": "Renders nothing without a session.",
378
+ "seeAlso": [
379
+ "UserProfile",
380
+ "ActiveSessions"
381
+ ]
382
+ },
383
+ {
384
+ "name": "TwoFactorManager",
385
+ "kind": "component",
386
+ "summary": "Turn two-factor authentication on or off, by authenticator app, a code to the inbox or a code by text message.",
387
+ "useWhen": "A security settings page. The app is strongest; the emailed or texted code is the one people who will not install an app actually use.",
388
+ "requires": [
389
+ "session"
390
+ ],
391
+ "props": [
392
+ {
393
+ "name": "enabled",
394
+ "summary": "Whether a factor already exists, which decides which side is shown.",
395
+ "required": false
396
+ },
397
+ {
398
+ "name": "allowSms",
399
+ "summary": "Offer a code by text message. Off by default: it only works once the environment can send one.",
400
+ "required": false
401
+ },
402
+ {
403
+ "name": "onEnabled",
404
+ "summary": "Called once a factor is confirmed.",
405
+ "required": false
406
+ },
407
+ {
408
+ "name": "onDisabled",
409
+ "summary": "Called once it is removed.",
410
+ "required": false
411
+ },
412
+ {
413
+ "name": "className",
414
+ "summary": "Your own classes on the wrapper.",
415
+ "required": false
416
+ },
417
+ {
418
+ "name": "style",
419
+ "summary": "Inline styles on the wrapper.",
420
+ "required": false
421
+ }
422
+ ],
423
+ "whenUnmet": "Renders nothing without a session.",
424
+ "seeAlso": [
425
+ "ActiveSessions",
426
+ "PasskeyManager"
427
+ ]
428
+ },
429
+ {
430
+ "name": "PasskeyManager",
431
+ "kind": "component",
432
+ "summary": "Add and remove passkeys.",
433
+ "useWhen": "A security settings page, beside two-factor.",
434
+ "requires": [
435
+ "session"
436
+ ],
437
+ "props": [
438
+ {
439
+ "name": "title",
440
+ "summary": "Heading text.",
441
+ "required": false
442
+ },
443
+ {
444
+ "name": "className",
445
+ "summary": "Your own classes on the wrapper.",
446
+ "required": false
447
+ },
448
+ {
449
+ "name": "style",
450
+ "summary": "Inline styles on the wrapper.",
451
+ "required": false
452
+ }
453
+ ],
454
+ "whenUnmet": "Renders nothing without a session.",
455
+ "seeAlso": [
456
+ "TwoFactorManager"
457
+ ]
458
+ },
459
+ {
460
+ "name": "Branding",
461
+ "kind": "component",
462
+ "summary": "The logo, name and tagline — the environment's, or the tenant's when the provider is given a `tenant`.",
463
+ "useWhen": "Above a sign-in form, so your pages match the hosted ones.",
464
+ "requires": [],
465
+ "props": [
466
+ {
467
+ "name": "showTagline",
468
+ "summary": "Include the tagline under the name.",
469
+ "required": false
470
+ },
471
+ {
472
+ "name": "className",
473
+ "summary": "Your own classes on the wrapper.",
474
+ "required": false
475
+ },
476
+ {
477
+ "name": "style",
478
+ "summary": "Inline styles on the wrapper.",
479
+ "required": false
480
+ }
481
+ ]
482
+ },
483
+ {
484
+ "name": "TeamMembers",
485
+ "kind": "component",
486
+ "summary": "Who is in a team, who has been invited, and the way in and out. A team reached only through the organization that manages it says so, and offers nothing to leave.",
487
+ "useWhen": "A Team or Members settings page. One component covers the list, the pending invitations, the invite box and leaving.",
488
+ "requires": [
489
+ "session"
490
+ ],
491
+ "props": [
492
+ {
493
+ "name": "organizationId",
494
+ "summary": "Which team. Defaults to the only one this person is in; with several it says so rather than guessing.",
495
+ "required": false
496
+ },
497
+ {
498
+ "name": "onInvited",
499
+ "summary": "Called with `{ email, token, url }` — the address invited, the raw token, and the accept URL when `acceptUrl` was given. This is where your application sends the email. Without a handler the link is shown on screen instead, because the token is returned once and cannot be fetched again.",
500
+ "required": false
501
+ },
502
+ {
503
+ "name": "acceptUrl",
504
+ "summary": "The page hosting AcceptInvitation. The component appends `?invitation=<token>` and hands the finished link back as `url` on onInvited; without it, onInvited gets the raw token and you build the link yourself.",
505
+ "required": false
506
+ },
507
+ {
508
+ "name": "onLeft",
509
+ "summary": "Called after the viewer leaves the team.",
510
+ "required": false
511
+ },
512
+ {
513
+ "name": "className",
514
+ "summary": "Your own classes on the wrapper.",
515
+ "required": false
516
+ },
517
+ {
518
+ "name": "style",
519
+ "summary": "Inline styles on the wrapper.",
520
+ "required": false
521
+ }
522
+ ],
523
+ "whenUnmet": "Renders nothing without a session. Inviting and removing appear only for somebody whose role grants team.manage.",
524
+ "seeAlso": [
525
+ "AcceptInvitation"
526
+ ]
527
+ },
528
+ {
529
+ "name": "AcceptInvitation",
530
+ "kind": "component",
531
+ "summary": "The other end of an invitation: what it is for, and joining.",
532
+ "useWhen": "On the page an invitation link lands on.",
533
+ "requires": [],
534
+ "props": [
535
+ {
536
+ "name": "token",
537
+ "summary": "Read from `?invitation=` when omitted.",
538
+ "required": false
539
+ },
540
+ {
541
+ "name": "onAccepted",
542
+ "summary": "Called with the organizationId once they have joined.",
543
+ "required": false
544
+ },
545
+ {
546
+ "name": "signUpUrl",
547
+ "summary": "For somebody with no account yet.",
548
+ "required": false
549
+ },
550
+ {
551
+ "name": "signInUrl",
552
+ "summary": "For somebody who has one.",
553
+ "required": false
554
+ },
555
+ {
556
+ "name": "className",
557
+ "summary": "Your own classes on the wrapper.",
558
+ "required": false
559
+ },
560
+ {
561
+ "name": "style",
562
+ "summary": "Inline styles on the wrapper.",
563
+ "required": false
564
+ }
565
+ ],
566
+ "whenUnmet": "Says what the invitation is for without a session, since the point is that they may have no account. Names the address to sign in as when the signed-in one does not match.",
567
+ "seeAlso": [
568
+ "TeamMembers",
569
+ "SignUp"
570
+ ]
571
+ },
572
+ {
573
+ "name": "PricingTable",
574
+ "kind": "component",
575
+ "summary": "The published plans, and completing the purchase.",
576
+ "useWhen": "A pricing page, or an upgrade screen.",
577
+ "requires": [
578
+ "plans",
579
+ "paymentAccount"
580
+ ],
581
+ "props": [
582
+ {
583
+ "name": "onSelectPlan",
584
+ "summary": "Take over what Choose does. Left out, the component changes the plan or starts a checkout itself.",
585
+ "required": false
586
+ },
587
+ {
588
+ "name": "currentPlanVersionId",
589
+ "summary": "Marks the current plan. Discovered from the session when omitted.",
590
+ "required": false
591
+ },
592
+ {
593
+ "name": "featuredPlanKey",
594
+ "summary": "Which plan to present as the default.",
595
+ "required": false
596
+ },
597
+ {
598
+ "name": "signInUrl",
599
+ "summary": "Where a signed-out visitor goes on choosing. Without it the button says so rather than failing.",
600
+ "required": false
601
+ },
602
+ {
603
+ "name": "className",
604
+ "summary": "Your own classes on the wrapper.",
605
+ "required": false
606
+ },
607
+ {
608
+ "name": "style",
609
+ "summary": "Inline styles on the wrapper.",
610
+ "required": false
611
+ }
612
+ ],
613
+ "whenUnmet": "Says plans are unavailable when the catalog is empty.",
614
+ "seeAlso": [
615
+ "SubscriptionManager",
616
+ "usePlans"
617
+ ]
618
+ },
619
+ {
620
+ "name": "usePlans",
621
+ "kind": "hook",
622
+ "summary": "The plans, the current one, and the prorate-or-checkout branch — without markup.",
623
+ "useWhen": "You want your own pricing table but not your own billing logic.",
624
+ "requires": [
625
+ "plans"
626
+ ],
627
+ "props": [],
628
+ "seeAlso": [
629
+ "PricingTable"
630
+ ]
631
+ },
632
+ {
633
+ "name": "SubscriptionManager",
634
+ "kind": "component",
635
+ "summary": "The current plan, its renewal date, and cancelling.",
636
+ "useWhen": "A billing settings page.",
637
+ "requires": [
638
+ "session"
639
+ ],
640
+ "props": [],
641
+ "whenUnmet": "Renders nothing without a session.",
642
+ "seeAlso": [
643
+ "PricingTable",
644
+ "Invoices"
645
+ ]
646
+ },
647
+ {
648
+ "name": "Invoices",
649
+ "kind": "component",
650
+ "summary": "The signed-in user's invoices, newest first.",
651
+ "useWhen": "A billing settings page.",
652
+ "requires": [
653
+ "session"
654
+ ],
655
+ "props": [],
656
+ "whenUnmet": "Renders nothing without a session.",
657
+ "seeAlso": [
658
+ "SubscriptionManager"
659
+ ]
660
+ },
661
+ {
662
+ "name": "PayInvoice",
663
+ "kind": "component",
664
+ "summary": "Pay one invoice from a link, with no account needed.",
665
+ "useWhen": "A page reached from a payment link or a QR code — a walk-up customer.",
666
+ "requires": [
667
+ "paymentAccount"
668
+ ],
669
+ "props": [
670
+ {
671
+ "name": "token",
672
+ "summary": "The link token, from the URL.",
673
+ "required": false
674
+ },
675
+ {
676
+ "name": "environmentId",
677
+ "summary": "Which environment the link belongs to.",
678
+ "required": false
679
+ },
680
+ {
681
+ "name": "onPaid",
682
+ "summary": "Called once payment succeeds.",
683
+ "required": false
684
+ },
685
+ {
686
+ "name": "className",
687
+ "summary": "Your own classes on the wrapper.",
688
+ "required": false
689
+ },
690
+ {
691
+ "name": "style",
692
+ "summary": "Inline styles on the wrapper.",
693
+ "required": false
694
+ }
695
+ ],
696
+ "seeAlso": [
697
+ "usePaymentLink"
698
+ ]
699
+ },
700
+ {
701
+ "name": "usePaymentLink",
702
+ "kind": "hook",
703
+ "summary": "Watches a payment link and reports when it is paid.",
704
+ "useWhen": "Showing your own waiting screen beside a QR code.",
705
+ "requires": [],
706
+ "props": [],
707
+ "seeAlso": [
708
+ "PayInvoice"
709
+ ]
710
+ },
711
+ {
712
+ "name": "ApiKeyManager",
713
+ "kind": "component",
714
+ "summary": "A customer managing their own API credentials and seeing their rate limits.",
715
+ "useWhen": "A developer-settings page inside your application.",
716
+ "requires": [
717
+ "session",
718
+ "apiResource"
719
+ ],
720
+ "props": [
721
+ {
722
+ "name": "audience",
723
+ "summary": "Limit to one protected API. All of them when omitted.",
724
+ "required": false
725
+ },
726
+ {
727
+ "name": "className",
728
+ "summary": "Your own classes on the wrapper.",
729
+ "required": false
730
+ },
731
+ {
732
+ "name": "style",
733
+ "summary": "Inline styles on the wrapper.",
734
+ "required": false
735
+ }
736
+ ],
737
+ "whenUnmet": "Renders nothing without a session; says so when no API resource is defined."
738
+ },
739
+ {
740
+ "name": "DataTable",
741
+ "kind": "component",
742
+ "summary": "A table of a collection's records, with columns derived from its fields.",
743
+ "useWhen": "Listing records. Reach for Kanban instead to group them by a status, or Chart to count or total them over time.",
744
+ "requires": [
745
+ "session",
746
+ "collection"
747
+ ],
748
+ "bindsToCollection": true,
749
+ "props": [
750
+ {
751
+ "name": "collection",
752
+ "summary": "The collection key. Required in practice.",
753
+ "required": false
754
+ },
755
+ {
756
+ "name": "columns",
757
+ "summary": "Which fields to show, in order. Every field when omitted.",
758
+ "required": false
759
+ },
760
+ {
761
+ "name": "renderCell",
762
+ "summary": "Replace the cell for one field.",
763
+ "required": false
764
+ },
765
+ {
766
+ "name": "onSelect",
767
+ "summary": "Row click. Rows are inert without it.",
768
+ "required": false
769
+ },
770
+ {
771
+ "name": "onChanged",
772
+ "summary": "Called after this table creates, edits or deletes a record. The table refreshes itself; use this to refresh anything else on the page bound to the same collection, such as a Chart.",
773
+ "required": false
774
+ },
775
+ {
776
+ "name": "hideSearch",
777
+ "summary": "Hide the search box.",
778
+ "required": false
779
+ },
780
+ {
781
+ "name": "readOnly",
782
+ "summary": "Hide New, Edit and Delete even for a writer.",
783
+ "required": false
784
+ },
785
+ {
786
+ "name": "emptyState",
787
+ "summary": "Shown when there is nothing to list.",
788
+ "required": false
789
+ },
790
+ {
791
+ "name": "className",
792
+ "summary": "Your own classes on the wrapper.",
793
+ "required": false
794
+ },
795
+ {
796
+ "name": "style",
797
+ "summary": "Inline styles on the wrapper.",
798
+ "required": false
799
+ }
800
+ ],
801
+ "whenUnmet": "Without the read permission it says which permission is missing, rather than showing an empty table.",
802
+ "seeAlso": [
803
+ "Kanban",
804
+ "Chart",
805
+ "RecordDetail",
806
+ "RecordForm",
807
+ "useCollection"
808
+ ]
809
+ },
810
+ {
811
+ "name": "Kanban",
812
+ "kind": "component",
813
+ "summary": "A board, grouped by a choice field it finds on its own.",
814
+ "useWhen": "The records move through stages — a status, a pipeline.",
815
+ "requires": [
816
+ "session",
817
+ "collection"
818
+ ],
819
+ "bindsToCollection": true,
820
+ "props": [
821
+ {
822
+ "name": "collection",
823
+ "summary": "The collection key. Required in practice.",
824
+ "required": false
825
+ },
826
+ {
827
+ "name": "groupBy",
828
+ "summary": "Which field makes the columns. Discovered when omitted.",
829
+ "required": false
830
+ },
831
+ {
832
+ "name": "cardFields",
833
+ "summary": "What to show on a card.",
834
+ "required": false
835
+ },
836
+ {
837
+ "name": "onSelect",
838
+ "summary": "Card click.",
839
+ "required": false
840
+ },
841
+ {
842
+ "name": "emptyState",
843
+ "summary": "Shown in a column with nothing in it.",
844
+ "required": false
845
+ },
846
+ {
847
+ "name": "className",
848
+ "summary": "Your own classes on the wrapper.",
849
+ "required": false
850
+ },
851
+ {
852
+ "name": "style",
853
+ "summary": "Inline styles on the wrapper.",
854
+ "required": false
855
+ }
856
+ ],
857
+ "whenUnmet": "A collection with no groupable field says to add a choice field, rather than drawing one column.",
858
+ "seeAlso": [
859
+ "DataTable",
860
+ "Chart"
861
+ ]
862
+ },
863
+ {
864
+ "name": "Chart",
865
+ "kind": "component",
866
+ "summary": "Records over time, counted or totalled.",
867
+ "useWhen": "The question is how many or how much, by day, week or month.",
868
+ "requires": [
869
+ "session",
870
+ "collection"
871
+ ],
872
+ "bindsToCollection": true,
873
+ "props": [
874
+ {
875
+ "name": "collection",
876
+ "summary": "The collection key. Required in practice.",
877
+ "required": false
878
+ },
879
+ {
880
+ "name": "x",
881
+ "summary": "The date field. Discovered when omitted.",
882
+ "required": false
883
+ },
884
+ {
885
+ "name": "y",
886
+ "summary": "What to measure. Counts the records when omitted.",
887
+ "required": false
888
+ },
889
+ {
890
+ "name": "aggregate",
891
+ "summary": "sum, avg, min or max. Defaults to sum.",
892
+ "required": false
893
+ },
894
+ {
895
+ "name": "bucket",
896
+ "summary": "day, week or month. Defaults to day.",
897
+ "required": false
898
+ },
899
+ {
900
+ "name": "title",
901
+ "summary": "Overrides the derived caption.",
902
+ "required": false
903
+ },
904
+ {
905
+ "name": "height",
906
+ "summary": "Plot height in pixels.",
907
+ "required": false
908
+ },
909
+ {
910
+ "name": "className",
911
+ "summary": "Your own classes on the wrapper.",
912
+ "required": false
913
+ },
914
+ {
915
+ "name": "style",
916
+ "summary": "Inline styles on the wrapper.",
917
+ "required": false
918
+ }
919
+ ],
920
+ "whenUnmet": "A collection with no date field says so. A field that cannot be summed is refused rather than quietly counted.",
921
+ "seeAlso": [
922
+ "DataTable",
923
+ "Kanban"
924
+ ]
925
+ },
926
+ {
927
+ "name": "RecordDetail",
928
+ "kind": "component",
929
+ "summary": "One record in full, including the fields a table truncates.",
930
+ "useWhen": "After a row or card is clicked.",
931
+ "requires": [
932
+ "session",
933
+ "collection"
934
+ ],
935
+ "bindsToCollection": true,
936
+ "props": [
937
+ {
938
+ "name": "collection",
939
+ "summary": "The collection key. Required in practice.",
940
+ "required": false
941
+ },
942
+ {
943
+ "name": "recordId",
944
+ "summary": "Which record. Required in practice.",
945
+ "required": false
946
+ },
947
+ {
948
+ "name": "tenant",
949
+ "summary": "Only when the user is in several.",
950
+ "required": false
951
+ },
952
+ {
953
+ "name": "readOnly",
954
+ "summary": "Hide Edit and Delete.",
955
+ "required": false
956
+ },
957
+ {
958
+ "name": "onDeleted",
959
+ "summary": "Called after deletion.",
960
+ "required": false
961
+ },
962
+ {
963
+ "name": "onClose",
964
+ "summary": "Renders a Close button when given.",
965
+ "required": false
966
+ },
967
+ {
968
+ "name": "children",
969
+ "summary": "Rendered under the fields.",
970
+ "required": false
971
+ },
972
+ {
973
+ "name": "className",
974
+ "summary": "Your own classes on the wrapper.",
975
+ "required": false
976
+ },
977
+ {
978
+ "name": "style",
979
+ "summary": "Inline styles on the wrapper.",
980
+ "required": false
981
+ }
982
+ ],
983
+ "seeAlso": [
984
+ "DataTable",
985
+ "RecordForm"
986
+ ]
987
+ },
988
+ {
989
+ "name": "RecordForm",
990
+ "kind": "component",
991
+ "summary": "Create or edit a record, with inputs derived from the field types.",
992
+ "useWhen": "Adding a record, or editing one outside the detail view.",
993
+ "requires": [
994
+ "session",
995
+ "collection"
996
+ ],
997
+ "bindsToCollection": true,
998
+ "props": [
999
+ {
1000
+ "name": "collection",
1001
+ "summary": "The collection key. Required in practice.",
1002
+ "required": false
1003
+ },
1004
+ {
1005
+ "name": "recordId",
1006
+ "summary": "Omit to create, supply to edit.",
1007
+ "required": false
1008
+ },
1009
+ {
1010
+ "name": "tenant",
1011
+ "summary": "Only when the user is in several.",
1012
+ "required": false
1013
+ },
1014
+ {
1015
+ "name": "onSaved",
1016
+ "summary": "Called with the record id. Does not refresh a sibling table — see the composition rules.",
1017
+ "required": false
1018
+ },
1019
+ {
1020
+ "name": "onCancel",
1021
+ "summary": "Renders a Cancel button when given.",
1022
+ "required": false
1023
+ },
1024
+ {
1025
+ "name": "defaults",
1026
+ "summary": "Values to start with. Ignored when editing.",
1027
+ "required": false
1028
+ },
1029
+ {
1030
+ "name": "className",
1031
+ "summary": "Your own classes on the wrapper.",
1032
+ "required": false
1033
+ },
1034
+ {
1035
+ "name": "style",
1036
+ "summary": "Inline styles on the wrapper.",
1037
+ "required": false
1038
+ }
1039
+ ],
1040
+ "whenUnmet": "Computed fields get no input at all, because the server produces them.",
1041
+ "seeAlso": [
1042
+ "RecordDetail",
1043
+ "RelationPicker"
1044
+ ]
1045
+ },
1046
+ {
1047
+ "name": "RelationPicker",
1048
+ "kind": "component",
1049
+ "summary": "Choose a record in another collection by typing its name.",
1050
+ "useWhen": "Building your own form. RecordForm uses this for relation fields already.",
1051
+ "requires": [
1052
+ "session",
1053
+ "collection"
1054
+ ],
1055
+ "props": [
1056
+ {
1057
+ "name": "field",
1058
+ "summary": "The relation field descriptor.",
1059
+ "required": true
1060
+ },
1061
+ {
1062
+ "name": "value",
1063
+ "summary": "The chosen record id, or null.",
1064
+ "required": true
1065
+ },
1066
+ {
1067
+ "name": "onChange",
1068
+ "summary": "Called with the new id.",
1069
+ "required": true
1070
+ },
1071
+ {
1072
+ "name": "error",
1073
+ "summary": "Message shown under the input.",
1074
+ "required": false
1075
+ },
1076
+ {
1077
+ "name": "disabled",
1078
+ "summary": "Read-only.",
1079
+ "required": false
1080
+ },
1081
+ {
1082
+ "name": "tenant",
1083
+ "summary": "Only when the user is in several.",
1084
+ "required": false
1085
+ }
1086
+ ],
1087
+ "seeAlso": [
1088
+ "RecordForm"
1089
+ ]
1090
+ },
1091
+ {
1092
+ "name": "useCollection",
1093
+ "kind": "hook",
1094
+ "summary": "A collection's schema, records, filters, paging, permissions and writes — without markup.",
1095
+ "useWhen": "You want your own table, board or form but not your own data layer.",
1096
+ "requires": [
1097
+ "session",
1098
+ "collection"
1099
+ ],
1100
+ "bindsToCollection": true,
1101
+ "props": [],
1102
+ "seeAlso": [
1103
+ "DataTable",
1104
+ "FieldCell",
1105
+ "FieldInput"
1106
+ ]
1107
+ },
1108
+ {
1109
+ "name": "FieldCell",
1110
+ "kind": "component",
1111
+ "summary": "One field value, rendered the way the tables render it.",
1112
+ "useWhen": "Building your own table over useCollection.",
1113
+ "requires": [],
1114
+ "props": [
1115
+ {
1116
+ "name": "value",
1117
+ "summary": "The stored value.",
1118
+ "required": true
1119
+ },
1120
+ {
1121
+ "name": "field",
1122
+ "summary": "The field descriptor.",
1123
+ "required": true
1124
+ },
1125
+ {
1126
+ "name": "related",
1127
+ "summary": "A relation's resolved label.",
1128
+ "required": false
1129
+ }
1130
+ ],
1131
+ "seeAlso": [
1132
+ "FieldInput",
1133
+ "useCollection"
1134
+ ]
1135
+ },
1136
+ {
1137
+ "name": "FieldInput",
1138
+ "kind": "component",
1139
+ "summary": "The input for one field, chosen by its type.",
1140
+ "useWhen": "Building your own form over useCollection.",
1141
+ "requires": [],
1142
+ "props": [
1143
+ {
1144
+ "name": "value",
1145
+ "summary": "The current value.",
1146
+ "required": true
1147
+ },
1148
+ {
1149
+ "name": "field",
1150
+ "summary": "The field descriptor.",
1151
+ "required": true
1152
+ },
1153
+ {
1154
+ "name": "onChange",
1155
+ "summary": "Called with the new value.",
1156
+ "required": true
1157
+ },
1158
+ {
1159
+ "name": "error",
1160
+ "summary": "Message shown under the input.",
1161
+ "required": false
1162
+ },
1163
+ {
1164
+ "name": "disabled",
1165
+ "summary": "Read-only.",
1166
+ "required": false
1167
+ }
1168
+ ],
1169
+ "whenUnmet": "Renders nothing for a computed field — the server produces those.",
1170
+ "seeAlso": [
1171
+ "FieldCell",
1172
+ "RecordForm"
1173
+ ]
1174
+ }
1175
+ ]
1176
+ }