@embeddables/forms 0.0.1 → 0.0.3

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/README.md CHANGED
@@ -13,6 +13,57 @@ and app user id, durable R2 writes run automatically on successful `.set()` and
13
13
  npm install @embeddables/forms @embeddables/core
14
14
  ```
15
15
 
16
+ For React apps, also install `react` (peer dependency) and wrap your tree in
17
+ `EmbeddablesProvider` from `@embeddables/core/react`. The React example below
18
+ also imports `@embeddables/analytics/react`, so install `@embeddables/analytics`
19
+ too if you want the auto-tracking shown there. If omitted, remove the
20
+ `useAnalytics` import, hook call, and `analyticsInstance` option.
21
+
22
+ ## React
23
+
24
+ Import hooks from `@embeddables/forms/react`:
25
+
26
+ ```tsx
27
+ import { EmbeddablesProvider } from '@embeddables/core/react'
28
+ import { useAnalytics } from '@embeddables/analytics/react'
29
+ import { useForms, useForm, useFormField } from '@embeddables/forms/react'
30
+
31
+ function SignupField() {
32
+ const analytics = useAnalytics()
33
+ useForms({ analyticsInstance: analytics ?? undefined })
34
+
35
+ const schema = {
36
+ id: 'signup',
37
+ fields: [{ key: 'email', label: 'Email', type: 'email', validations: { required: true } }],
38
+ } as const
39
+
40
+ const { form } = useForm(schema)
41
+ const { value, error, setValue, onBlur } = useFormField(form, 'email')
42
+
43
+ return (
44
+ <label>
45
+ Email
46
+ <input value={value ?? ''} onChange={(event) => setValue(event.target.value)} onBlur={() => void onBlur()} />
47
+ {error?.[0]}
48
+ </label>
49
+ )
50
+ }
51
+
52
+ export function App() {
53
+ return (
54
+ <EmbeddablesProvider config={{ projectId: 'proj_…', forms: [], experiments: [] }}>
55
+ <SignupField />
56
+ </EmbeddablesProvider>
57
+ )
58
+ }
59
+ ```
60
+
61
+ - `useForms` returns `null` until Core is ready inside `EmbeddablesProvider`.
62
+ - Pass `analyticsInstance` explicitly when you want auto-tracking on `.set()` / `.submit()`. Do not also call `trackEvent` for the same submission or you will double-count `form:submitted`.
63
+ - `useFormField` uses commit-on-blur: local typing updates draft state; `form.set()` runs on blur.
64
+ - One live `FormInstance` per `schema.id` is shared across hooks in the same client.
65
+ - Imperative consumers can also call `form.subscribe(listener)` to observe value and error changes.
66
+
16
67
  ## Quick start
17
68
 
18
69
  ```typescript
@@ -68,6 +119,7 @@ functions, pass validators via `customValidations` on `initForm`.
68
119
  | ------ | ------- |
69
120
  | `set({ … })` | Validate and persist a patch atomically; optional analytics; best-effort durable R2 write when configured |
70
121
  | `get(key)` / `getAll()` | Read declared fields from storage |
122
+ | `getValueByProtocolFieldId(protocolFieldId)` | Read by schema `protocolFieldId` (typed like `get()` for the backing field; `undefined` if unknown or unset) |
71
123
  | `validate({ … })` | Check values without writing or tracking |
72
124
  | `submit()` | Validate all fields, best-effort durable R2 write, and emit `form:submitted` when analytics is configured |
73
125
  | `errors()` | Current validation messages |
@@ -90,7 +142,6 @@ backend writes are also best-effort: a failing persistence request never rejects
90
142
  | ------ | ------- |
91
143
  | `core` | Initialized `@embeddables/core` instance (required) |
92
144
  | `analyticsInstance` | Optional analytics client for event tracking only |
93
- | `baseUrl` | Optional backend URL for durable R2 persistence writes |
94
145
 
95
146
  **`initForm`**
96
147