@optare/react 0.1.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.
- package/LICENSE +21 -0
- package/README.md +110 -0
- package/dist/index.cjs +1510 -0
- package/dist/index.d.cts +396 -0
- package/dist/index.d.ts +396 -0
- package/dist/index.js +1477 -0
- package/package.json +44 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Optare
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# @optare/react
|
|
2
|
+
|
|
3
|
+
React bindings for Optare — a provider, session hooks, and drop-in **white-label**
|
|
4
|
+
sign-in / sign-up / account components. Built on [`@optare/client`](../client).
|
|
5
|
+
|
|
6
|
+
The entire integration contract is one string: a publishable key (`pk_live_…`).
|
|
7
|
+
It is **not** a secret — it ships in your browser bundle — so the SDK uses it to
|
|
8
|
+
look up, from a public endpoint, where the auth API lives and what the project's
|
|
9
|
+
branding is (logo, name, primary colour, corner radius). That is how a customer
|
|
10
|
+
gets a branded login screen without hosting anything.
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install @optare/react
|
|
16
|
+
# peer deps: react >= 18, react-dom >= 18
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Quick start
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
import { OptareProvider, SignIn, AccountButton, useSession } from "@optare/react";
|
|
23
|
+
|
|
24
|
+
function Root() {
|
|
25
|
+
return (
|
|
26
|
+
<OptareProvider publishableKey={import.meta.env.VITE_OPTARE_PK}>
|
|
27
|
+
<App />
|
|
28
|
+
</OptareProvider>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function App() {
|
|
33
|
+
const { isPending, isAuthenticated, user } = useSession();
|
|
34
|
+
if (isPending) return null;
|
|
35
|
+
return isAuthenticated ? (
|
|
36
|
+
<>
|
|
37
|
+
<p>Hello {user?.name}</p>
|
|
38
|
+
<AccountButton />
|
|
39
|
+
</>
|
|
40
|
+
) : (
|
|
41
|
+
<SignIn onSuccess={() => location.assign("/dashboard")} />
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Nothing above configures branding — the provider resolves it from the key and
|
|
47
|
+
every component renders against `--optare-*` CSS variables you can override.
|
|
48
|
+
|
|
49
|
+
## SSR
|
|
50
|
+
|
|
51
|
+
Resolve the config on the server and hand it to the provider as `bootstrap` to
|
|
52
|
+
skip the client-side fetch:
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
import { resolveOptareConfig } from "@optare/react";
|
|
56
|
+
|
|
57
|
+
const bootstrap = await resolveOptareConfig({ publishableKey: process.env.OPTARE_PK! });
|
|
58
|
+
// ...serialize `bootstrap` into the page, then:
|
|
59
|
+
<OptareProvider publishableKey={pk} bootstrap={bootstrap}>{children}</OptareProvider>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## API
|
|
63
|
+
|
|
64
|
+
### `<OptareProvider>`
|
|
65
|
+
|
|
66
|
+
| prop | type | notes |
|
|
67
|
+
|---|---|---|
|
|
68
|
+
| `publishableKey` | `string` | required |
|
|
69
|
+
| `bootstrap` | `OptareBootstrap` | pre-resolved config; skips the network |
|
|
70
|
+
| `baseURL` | `string` | override the auth API origin (self-hosted / preview) |
|
|
71
|
+
| `configURL` | `string` | where `GET /api/public/config` lives; defaults to `baseURL` then the hosted origin |
|
|
72
|
+
| `fetch` | `typeof fetch` | custom fetch (tests, RN) |
|
|
73
|
+
| `loadingFallback` / `errorFallback` | `ReactNode` \| `(err, retry) => ReactNode` | optional gates; default is optimistic (render children, expose `status`) |
|
|
74
|
+
|
|
75
|
+
### Hooks
|
|
76
|
+
|
|
77
|
+
- `useOptare()` — `{ status, error, bootstrap, branding, project, cssVars, auth, retry }`
|
|
78
|
+
- `useOptareAuth()` — the better-auth React client (throws until `status === "ready"`)
|
|
79
|
+
- `useSession()` — `{ data, user, isPending, isAuthenticated, error, refetch }`
|
|
80
|
+
- `useUser()` — the current user or `null`
|
|
81
|
+
- `useSignOut()` — `{ signOut, isPending, error }`
|
|
82
|
+
- `useActiveOrganization()` — `{ activeOrganizationId, setActive, isPending }`
|
|
83
|
+
- `useBranding()` / `useOptareConfig()`
|
|
84
|
+
|
|
85
|
+
### Components
|
|
86
|
+
|
|
87
|
+
- `<SignIn />` — email + password, optional magic-link path, 2FA-challenge
|
|
88
|
+
callback (`onTwoFactor`), `onSuccess` / `redirectTo`.
|
|
89
|
+
- `<SignUp />` — name + email + password with a strength meter; the landing
|
|
90
|
+
organization is decided server-side from the publishable key (F6).
|
|
91
|
+
`onVerificationRequired` fires when an email must be confirmed first.
|
|
92
|
+
- `<AccountButton />` — avatar + dropdown (profile slot, sign out); renders
|
|
93
|
+
`signInSlot` (or nothing) when signed out.
|
|
94
|
+
|
|
95
|
+
### Theming
|
|
96
|
+
|
|
97
|
+
`brandingToCssVars(branding)` returns the `--optare-*` map the provider applies.
|
|
98
|
+
All colour/length values from branding are sanitised (`safeColor`, `safeLength`)
|
|
99
|
+
so a project's branding string can never inject CSS. Override any variable in
|
|
100
|
+
your own stylesheet, or pass `style` / `className` to a component.
|
|
101
|
+
|
|
102
|
+
## Server-side
|
|
103
|
+
|
|
104
|
+
`sk_live_` management calls and offline JWT verification are **not** in this
|
|
105
|
+
package — use [`@optare/node`](../node).
|
|
106
|
+
|
|
107
|
+
## Versioning
|
|
108
|
+
|
|
109
|
+
See [`docs/SDK_VERSIONING.md`](../../docs/SDK_VERSIONING.md). Pre-1.0: minor =
|
|
110
|
+
breaking, patch = fixes.
|