@base316/react 0.1.0 → 0.2.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 (70) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +15 -15
  3. package/dist/index.cjs +4150 -160
  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 +4136 -165
  8. package/dist/index.js.map +1 -1
  9. package/dist/manifest.json +1161 -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 +11 -1
  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 +29 -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/test/harness.d.ts +204 -0
  61. package/dist/src/test/harness.d.ts.map +1 -0
  62. package/dist/src/test/setup.d.ts +2 -0
  63. package/dist/src/test/setup.d.ts.map +1 -0
  64. package/dist/src/useCollection.d.ts +79 -0
  65. package/dist/src/useCollection.d.ts.map +1 -0
  66. package/dist/src/usePaymentLink.d.ts +41 -0
  67. package/dist/src/usePaymentLink.d.ts.map +1 -0
  68. package/dist/src/usePlans.d.ts +66 -0
  69. package/dist/src/usePlans.d.ts.map +1 -0
  70. package/package.json +36 -28
@@ -0,0 +1,79 @@
1
+ import type { CollectionRecord, CollectionSchema, FieldValue, RecordFilterInput } from "@base316/sdk";
2
+ /**
3
+ * One collection: its shape, its rows, and how to change them.
4
+ *
5
+ * The headless half of every data component. `DataTable`, `RecordForm` and
6
+ * `RecordDetail` are markup over this, and an application with its own design
7
+ * system calls it directly and writes its own — which is the escape hatch that
8
+ * stops a component library from being forked the first time somebody wants a
9
+ * different table.
10
+ *
11
+ * What it does that is worth not rewriting:
12
+ *
13
+ * - loads the schema before the rows, because nothing can render a column
14
+ * without knowing the field types;
15
+ * - keeps filters, sort, search and paging in one place, so they compose
16
+ * instead of fighting;
17
+ * - refetches after a write, so a saved row appears where it belongs rather
18
+ * than where it was;
19
+ * - keeps per-field errors from the server, so a form can put each message
20
+ * under the input that caused it.
21
+ */
22
+ export interface UseCollectionOptions {
23
+ /** Applied on top of whatever the UI sets. For a fixed view of one tenant's data. */
24
+ filters?: RecordFilterInput[];
25
+ sort?: {
26
+ field: string;
27
+ direction?: "asc" | "desc";
28
+ };
29
+ limit?: number;
30
+ /**
31
+ * Load one record instead of a page.
32
+ *
33
+ * Fetched by id rather than filtered for. `id` is not a schema field, so a
34
+ * filter naming it is dropped on the server and the caller quietly gets the
35
+ * first page instead — which works until the record is not on it.
36
+ */
37
+ recordId?: string;
38
+ /**
39
+ * Which tenant to read and write as.
40
+ *
41
+ * Only needed when somebody belongs to several organizations. A user in one
42
+ * is scoped to it automatically.
43
+ */
44
+ tenant?: string;
45
+ }
46
+ export interface UseCollectionResult {
47
+ /** Null until loaded. */
48
+ schema: CollectionSchema | null;
49
+ records: CollectionRecord[];
50
+ loading: boolean;
51
+ /** Set when the collection could not be read at all — missing, or forbidden. */
52
+ error: string | null;
53
+ /** Total matching rows, for "1–25 of 340". */
54
+ total: number;
55
+ /** Whether a further page exists. */
56
+ hasMore: boolean;
57
+ /** Whether this viewer may create, edit and delete. False until the schema loads. */
58
+ canWrite: boolean;
59
+ search: string;
60
+ setSearch: (search: string) => void;
61
+ filters: RecordFilterInput[];
62
+ setFilters: (filters: RecordFilterInput[]) => void;
63
+ sort: {
64
+ field: string;
65
+ direction?: "asc" | "desc";
66
+ } | null;
67
+ /** Ascending, then descending, then off — the order a table header cycles. */
68
+ toggleSort: (field: string) => void;
69
+ loadMore: () => void;
70
+ reload: () => void;
71
+ /** Per-field messages from the last rejected write. */
72
+ fieldErrors: Record<string, string>;
73
+ saving: boolean;
74
+ create: (fields: Record<string, FieldValue>) => Promise<CollectionRecord | null>;
75
+ update: (id: string, fields: Record<string, FieldValue>) => Promise<CollectionRecord | null>;
76
+ remove: (id: string) => Promise<boolean>;
77
+ }
78
+ export declare function useCollection(collection: string, options?: UseCollectionOptions): UseCollectionResult;
79
+ //# sourceMappingURL=useCollection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCollection.d.ts","sourceRoot":"","sources":["../../src/useCollection.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACX,gBAAgB,EAChB,gBAAgB,EAChB,UAAU,EACV,iBAAiB,EACjB,MAAM,cAAc,CAAC;AAKtB;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,WAAW,oBAAoB;IACpC,qFAAqF;IACrF,OAAO,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC9B,IAAI,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;KAAE,CAAC;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IACnC,yBAAyB;IACzB,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAChC,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,gFAAgF;IAChF,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,qFAAqF;IACrF,QAAQ,EAAE,OAAO,CAAC;IAElB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,UAAU,EAAE,CAAC,OAAO,EAAE,iBAAiB,EAAE,KAAK,IAAI,CAAC;IACnD,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC3D,8EAA8E;IAC9E,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAEpC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,IAAI,CAAC;IAEnB,uDAAuD;IACvD,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IACjF,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAC7F,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACzC;AAYD,wBAAgB,aAAa,CAC5B,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,oBAAyB,GAChC,mBAAmB,CAiTrB"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Watch a payment link until it is paid.
3
+ *
4
+ * For the merchant's *screen*, not their server. A webhook tells a backend that
5
+ * a walk-up customer paid; it cannot tell the tablet propped on the counter with
6
+ * the QR code on it. This is what flips that screen over.
7
+ *
8
+ * A poll rather than a socket, matching the rest of the platform: there is no
9
+ * streaming endpoint, and a poll is what survives a tablet sleeping and a phone
10
+ * hopping between wifi and cellular mid-payment.
11
+ *
12
+ * Use it with the token you got back from `invoices.createPaymentLink` on your
13
+ * server. Polling stops on its own once the invoice settles, so a forgotten
14
+ * component does not keep asking for ever.
15
+ */
16
+ export type PaymentLinkStatus = {
17
+ state: "loading";
18
+ } | {
19
+ state: "payable";
20
+ number: string;
21
+ due: string;
22
+ currency: string;
23
+ } | {
24
+ state: "settled";
25
+ number: string;
26
+ }
27
+ /** Unknown, expired, or withdrawn — the API does not say which. */
28
+ | {
29
+ state: "invalid";
30
+ };
31
+ export declare function usePaymentLink({ token, environmentId, intervalMs, onPaid, }: {
32
+ token: string;
33
+ environmentId: string;
34
+ /**
35
+ * How often to ask. The default is chosen against the thing being waited for
36
+ * — somebody tapping a phone a metre away — rather than against server load.
37
+ */
38
+ intervalMs?: number;
39
+ onPaid?: () => void;
40
+ }): PaymentLinkStatus;
41
+ //# sourceMappingURL=usePaymentLink.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePaymentLink.d.ts","sourceRoot":"","sources":["../../src/usePaymentLink.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,MAAM,iBAAiB,GAC1B;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,GACpB;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACnE;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AACtC,mEAAmE;GACjE;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC;AAExB,wBAAgB,cAAc,CAAC,EAC9B,KAAK,EACL,aAAa,EACb,UAAiB,EACjB,MAAM,GACN,EAAE;IACF,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACpB,GAAG,iBAAiB,CA+EpB"}
@@ -0,0 +1,66 @@
1
+ import type { PublicPlan } from "@base316/sdk";
2
+ /**
3
+ * The plans, and what happens when somebody picks one — without any markup.
4
+ *
5
+ * This is the escape hatch that keeps a component library from being forked.
6
+ * `PricingTable` is a few dozen lines of JSX over this hook; an application
7
+ * with its own design system calls the hook directly, renders whatever it
8
+ * likes, and still gets the part that is easy to get wrong:
9
+ *
10
+ * - which plan the signed-in user is actually on,
11
+ * - whether picking one should prorate in place or collect a card,
12
+ * - resolving the customer from the session rather than trusting the browser.
13
+ *
14
+ * The rule the whole library follows: logic lives in a hook, presentation
15
+ * lives in a component, and the component is thin enough to be worth
16
+ * replacing. Fusing the two is what forces a fork the first time somebody
17
+ * wants a different table.
18
+ */
19
+ /** What picking a plan did. Returned so a custom UI can respond in kind. */
20
+ export type SelectPlanOutcome = {
21
+ status: "changed";
22
+ planVersionId: string;
23
+ } | {
24
+ status: "checkout";
25
+ url: string;
26
+ } | {
27
+ status: "needs-sign-in";
28
+ } | {
29
+ status: "failed";
30
+ reason: string;
31
+ };
32
+ export interface UsePlansOptions {
33
+ /**
34
+ * Override the plan shown as current.
35
+ *
36
+ * Discovered from the signed-in user's subscription when omitted.
37
+ */
38
+ currentPlanVersionId?: string | null;
39
+ /**
40
+ * Where a checkout URL should send the browser.
41
+ *
42
+ * Defaults to navigating. Pass `false` to keep `selectPlan` free of side
43
+ * effects and handle the URL from the outcome — a modal checkout, a native
44
+ * shell, or a test.
45
+ */
46
+ navigate?: boolean | ((url: string) => void);
47
+ }
48
+ export interface UsePlansResult {
49
+ /** Null until loaded. Empty means nothing is published yet. */
50
+ plans: PublicPlan[] | null;
51
+ loading: boolean;
52
+ /** True when the catalog could not be read at all. */
53
+ error: boolean;
54
+ /** The plan the viewer is on, discovered or supplied. */
55
+ currentPlanVersionId: string | null;
56
+ /** The plan version currently being acted on, for a pending state. */
57
+ busyPlanVersionId: string | null;
58
+ /** Why the last selection failed, if it did. Cleared on the next attempt. */
59
+ lastError: string | null;
60
+ /** Whether there is a session to bill. */
61
+ signedIn: boolean;
62
+ selectPlan: (plan: PublicPlan) => Promise<SelectPlanOutcome>;
63
+ reload: () => void;
64
+ }
65
+ export declare function usePlans(options?: UsePlansOptions): UsePlansResult;
66
+ //# sourceMappingURL=usePlans.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePlans.d.ts","sourceRoot":"","sources":["../../src/usePlans.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAK/C;;;;;;;;;;;;;;;;GAgBG;AAEH,4EAA4E;AAC5E,MAAM,MAAM,iBAAiB,GAC1B;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAC5C;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,MAAM,EAAE,eAAe,CAAA;CAAE,GAC3B;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAExC,MAAM,WAAW,eAAe;IAC/B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,cAAc;IAC9B,+DAA+D;IAC/D,KAAK,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,sDAAsD;IACtD,KAAK,EAAE,OAAO,CAAC;IACf,yDAAyD;IACzD,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,sEAAsE;IACtE,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,6EAA6E;IAC7E,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,0CAA0C;IAC1C,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC7D,MAAM,EAAE,MAAM,IAAI,CAAC;CACnB;AAaD,wBAAgB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,cAAc,CAyItE"}
package/package.json CHANGED
@@ -1,52 +1,60 @@
1
1
  {
2
2
  "name": "@base316/react",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Drop-in React components for Base316 authentication and billing.",
5
- "sideEffects": false,
6
- "main": "./dist/index.cjs",
7
- "types": "./dist/index.d.ts",
8
- "dependencies": {
9
- "@base316/sdk": "0.1.0"
10
- },
11
- "devDependencies": {
12
- "@types/react": "19.2.18",
13
- "react": "19.2.8",
14
- "tsup": "^8.5.0",
15
- "typescript": "7.0.2",
16
- "vitest": "^5.0.0",
17
- "@repo/tsconfig": "0.0.0"
18
- },
19
- "peerDependencies": {
20
- "react": ">=18"
21
- },
5
+ "homepage": "https://base316.com",
6
+ "bugs": "https://github.com/ThinkfleetAI/base316/issues",
22
7
  "license": "MIT",
23
8
  "repository": {
24
9
  "type": "git",
25
10
  "url": "git+https://github.com/ThinkfleetAI/base316.git",
26
11
  "directory": "packages/react"
27
12
  },
28
- "homepage": "https://base316.com",
29
- "bugs": "https://github.com/ThinkfleetAI/base316/issues",
13
+ "files": [
14
+ "LICENSE",
15
+ "CHANGELOG.md",
16
+ "README.md",
17
+ "dist"
18
+ ],
19
+ "sideEffects": false,
20
+ "main": "./dist/index.cjs",
30
21
  "module": "./dist/index.js",
22
+ "types": "./dist/index.d.ts",
31
23
  "exports": {
32
24
  ".": {
33
25
  "types": "./dist/index.d.ts",
34
26
  "import": "./dist/index.js",
35
27
  "require": "./dist/index.cjs"
36
- }
28
+ },
29
+ "./manifest.json": "./dist/manifest.json"
37
30
  },
38
- "files": [
39
- "LICENSE",
40
- "README.md",
41
- "dist"
42
- ],
43
31
  "publishConfig": {
44
32
  "access": "public"
45
33
  },
34
+ "dependencies": {
35
+ "@base316/sdk": "0.2.0"
36
+ },
37
+ "devDependencies": {
38
+ "@testing-library/dom": "^10.4.2",
39
+ "@testing-library/react": "^16.3.3",
40
+ "@testing-library/user-event": "^14.6.7",
41
+ "@types/react": "19.2.18",
42
+ "jsdom": "^30.0.1",
43
+ "react": "19.2.8",
44
+ "react-dom": "19.2.8",
45
+ "tsup": "^8.5.0",
46
+ "tsx": "^4.23.13",
47
+ "typescript": "7.0.2",
48
+ "vitest": "^5.0.0",
49
+ "@repo/tsconfig": "0.0.0"
50
+ },
51
+ "peerDependencies": {
52
+ "react": ">=18"
53
+ },
46
54
  "scripts": {
47
- "build": "tsup && tsc -p tsconfig.build.json",
55
+ "build": "tsup && tsc -p tsconfig.build.json && tsx scripts/emit-manifest.ts",
48
56
  "clean": "git clean -xdf .cache .turbo dist node_modules",
49
- "test": "vitest run --passWithNoTests",
57
+ "test": "vitest run",
50
58
  "type-check": "tsc --noEmit"
51
59
  }
52
60
  }