@payfit/unity-components 3.6.10 → 3.6.12
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 +7 -7
- package/skills/unity-data-table/SKILL.md +11 -8
- package/skills/unity-layout/SKILL.md +10 -7
- package/skills/unity-migrate-from-midnight/SKILL.md +10 -6
- package/skills/unity-migrate-from-midnight/references/midnight-component-map.md +8 -7
- package/skills/unity-navigation/SKILL.md +16 -13
- package/skills/unity-overlays/SKILL.md +16 -13
- package/skills/unity-tanstack-form/SKILL.md +24 -19
- package/skills/unity-tanstack-form/references/bound-field-components.md +2 -2
- package/skills/unity-tanstack-form/references/patterns.md +1 -1
- package/skills/unity-tanstack-form/references/schema-adapters.md +6 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@payfit/unity-components",
|
|
3
|
-
"version": "3.6.
|
|
3
|
+
"version": "3.6.12",
|
|
4
4
|
"module": "./dist/esm/index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
"@formatjs/intl": "4.1.12",
|
|
104
104
|
"@internationalized/date": "3.12.4",
|
|
105
105
|
"minimatch": "10.2.5",
|
|
106
|
-
"@payfit/unity-illustrations": "3.6.
|
|
106
|
+
"@payfit/unity-illustrations": "3.6.12",
|
|
107
107
|
"@radix-ui/react-avatar": "1.2.6",
|
|
108
108
|
"@radix-ui/react-slot": "1.3.3",
|
|
109
109
|
"@react-aria/interactions": "3.28.1",
|
|
@@ -132,8 +132,8 @@
|
|
|
132
132
|
"zod": "4.6.5"
|
|
133
133
|
},
|
|
134
134
|
"peerDependencies": {
|
|
135
|
-
"@payfit/unity-icons": "3.6.
|
|
136
|
-
"@payfit/unity-themes": "3.6.
|
|
135
|
+
"@payfit/unity-icons": "3.6.12",
|
|
136
|
+
"@payfit/unity-themes": "3.6.12",
|
|
137
137
|
"@storybook/react-vite": "^10",
|
|
138
138
|
"@tanstack/react-query": "^5",
|
|
139
139
|
"@tanstack/form-core": "1.33.5",
|
|
@@ -156,9 +156,9 @@
|
|
|
156
156
|
"@payfit/storybook-addon-console-errors": "0.0.0-use.local",
|
|
157
157
|
"@payfit/storybook-addon-datadog-rum": "0.0.0-use.local",
|
|
158
158
|
"@payfit/storybook-config": "0.0.0-use.local",
|
|
159
|
-
"@payfit/unity-icons": "3.6.
|
|
160
|
-
"@payfit/unity-illustrations": "3.6.
|
|
161
|
-
"@payfit/unity-themes": "3.6.
|
|
159
|
+
"@payfit/unity-icons": "3.6.12",
|
|
160
|
+
"@payfit/unity-illustrations": "3.6.12",
|
|
161
|
+
"@payfit/unity-themes": "3.6.12",
|
|
162
162
|
"@payfit/vite-configs": "0.0.0-use.local",
|
|
163
163
|
"@storybook/addon-a11y": "10.6.0",
|
|
164
164
|
"@storybook/addon-designs": "11.1.4",
|
|
@@ -7,17 +7,20 @@ description: >
|
|
|
7
7
|
metadata:
|
|
8
8
|
type: core
|
|
9
9
|
library: '@payfit/unity-components'
|
|
10
|
-
library_version: '
|
|
10
|
+
library_version: '3.x'
|
|
11
11
|
sources:
|
|
12
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/components/data-table/DataTable.tsx'
|
|
13
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/components/data-table/parts/DataTableRoot.tsx'
|
|
14
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/components/data-table/
|
|
15
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/components/table/Table.tsx'
|
|
16
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/components/filter-toolbar/FilterToolbar.tsx'
|
|
17
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/components/filter/Filter.tsx'
|
|
18
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/docs/guides/
|
|
12
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/modules/tanstack-table/components/data-table/DataTable.tsx'
|
|
13
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/modules/tanstack-table/components/data-table/parts/DataTableRoot.tsx'
|
|
14
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/modules/tanstack-table/components/data-table-bulk-actions/DataTableBulkActions.tsx'
|
|
15
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/core/components/table/Table.tsx'
|
|
16
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/core/components/filter-toolbar/FilterToolbar.tsx'
|
|
17
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/core/components/filter/Filter.tsx'
|
|
18
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/modules/tanstack-table/docs/guides/Building Tables.mdx'
|
|
19
19
|
---
|
|
20
20
|
|
|
21
|
+
This skill targets the current workspace Unity v3 API. Legacy examples are
|
|
22
|
+
migration context.
|
|
23
|
+
|
|
21
24
|
DataTable is the composite (Tanstack Table + Unity Table + pagination + empty
|
|
22
25
|
states + virtualization). Table is the primitive — use only when you have no
|
|
23
26
|
table state to manage.
|
|
@@ -8,16 +8,19 @@ description: >
|
|
|
8
8
|
metadata:
|
|
9
9
|
type: core
|
|
10
10
|
library: '@payfit/unity-components'
|
|
11
|
-
library_version: '
|
|
11
|
+
library_version: '3.x'
|
|
12
12
|
sources:
|
|
13
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/components/page/Page.tsx'
|
|
14
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/components/page/parts/PageHeader.tsx'
|
|
15
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/components/page/parts/PageHeading.tsx'
|
|
16
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/components/flex/Flex.tsx'
|
|
17
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/components/grid/Grid.tsx'
|
|
18
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/components/text/Text.tsx'
|
|
13
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/core/components/page/Page.tsx'
|
|
14
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/core/components/page/parts/PageHeader.tsx'
|
|
15
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/core/components/page/parts/PageHeading.tsx'
|
|
16
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/core/components/flex/Flex.tsx'
|
|
17
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/core/components/grid/Grid.tsx'
|
|
18
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/core/components/text/Text.tsx'
|
|
19
19
|
---
|
|
20
20
|
|
|
21
|
+
This skill targets the current workspace Unity v3 API. Legacy examples are
|
|
22
|
+
migration context.
|
|
23
|
+
|
|
21
24
|
Compose structure with the layout and typography primitives exported by
|
|
22
25
|
`@payfit/unity-components`.
|
|
23
26
|
|
|
@@ -7,13 +7,16 @@ description: >
|
|
|
7
7
|
metadata:
|
|
8
8
|
type: lifecycle
|
|
9
9
|
library: '@payfit/unity-components'
|
|
10
|
-
library_version: '
|
|
10
|
+
library_version: '3.x'
|
|
11
11
|
sources:
|
|
12
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/components/tooltip/Tooltip.tsx'
|
|
13
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/components/button/Button.tsx'
|
|
12
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/core/components/tooltip/Tooltip.tsx'
|
|
13
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/core/components/button/Button.tsx'
|
|
14
14
|
- 'PayFit/hr-apps:AGENTS.md'
|
|
15
15
|
---
|
|
16
16
|
|
|
17
|
+
This skill targets the current workspace Unity v3 API. Legacy examples are
|
|
18
|
+
migration context.
|
|
19
|
+
|
|
17
20
|
Convert a legacy `@payfit/midnight` screen to Unity. The table below
|
|
18
21
|
covers the highest-traffic mappings; the exhaustive ~85-row map lives
|
|
19
22
|
in `references/midnight-component-map.md`. When a Midnight component is
|
|
@@ -73,7 +76,8 @@ Unity enforces several WCAG rules that Midnight allowed:
|
|
|
73
76
|
Midnight-era screens commonly use React Hook Form. When porting, replace
|
|
74
77
|
the form with `useTanstackUnityForm` and the Tanstack-bound `*Field`
|
|
75
78
|
components (`TextField`, `SelectField`, `NumberField`, etc.). The legacy RHF
|
|
76
|
-
`useUnityForm` + `*Field` wrappers
|
|
79
|
+
`useUnityForm` + RHF `*Field` wrappers were removed in Unity v3. Import
|
|
80
|
+
`useTanstackUnityForm` from `@payfit/unity-components/forms`.
|
|
77
81
|
Do not pause on the RHF intermediate step. See `unity-tanstack-form`.
|
|
78
82
|
|
|
79
83
|
## Common Mistakes
|
|
@@ -106,7 +110,7 @@ rule that disabled controls must not have tooltips because they are not
|
|
|
106
110
|
keyboard-focusable, so the tooltip is unreachable — Unity's `Tooltip`
|
|
107
111
|
component rejects this pairing at the library level.
|
|
108
112
|
|
|
109
|
-
Source: libs/shared/unity/components/src/components/tooltip/Tooltip.tsx
|
|
113
|
+
Source: libs/shared/unity/components/src/core/components/tooltip/Tooltip.tsx
|
|
110
114
|
|
|
111
115
|
### HIGH Assume Midnight props map 1:1 to Unity
|
|
112
116
|
|
|
@@ -130,7 +134,7 @@ Correct:
|
|
|
130
134
|
still type-checks on the underlying DOM node but bypasses React Aria's
|
|
131
135
|
touch and keyboard press handling, so keyboard activations silently no-op.
|
|
132
136
|
|
|
133
|
-
Source: libs/shared/unity/components/src/components/button/Button.tsx
|
|
137
|
+
Source: libs/shared/unity/components/src/core/components/button/Button.tsx
|
|
134
138
|
|
|
135
139
|
### MEDIUM Leave Midnight + Unity side-by-side in the same screen
|
|
136
140
|
|
|
@@ -64,18 +64,19 @@ look like a link.
|
|
|
64
64
|
|
|
65
65
|
## Form structure
|
|
66
66
|
|
|
67
|
-
| Midnight | Unity
|
|
68
|
-
| ---------- |
|
|
69
|
-
| `Field` | `
|
|
70
|
-
| `FieldSet` | `Fieldset`
|
|
71
|
-
| `Form` | `Form`
|
|
67
|
+
| Midnight | Unity | Note |
|
|
68
|
+
| ---------- | ------------- | ------------------------------------------------------------------------------------------- |
|
|
69
|
+
| `Field` | `field.Field` | Bound wrapper with `field.FieldLabel` / `field.FieldHelperText` / `field.FieldFeedbackText` |
|
|
70
|
+
| `FieldSet` | `Fieldset` | Casing change (`FieldSet` → `Fieldset`) |
|
|
71
|
+
| `Form` | `form.Form` | Inside `form.AppForm` — see `unity-tanstack-form` |
|
|
72
72
|
|
|
73
73
|
## Form inputs
|
|
74
74
|
|
|
75
75
|
> Form-bound usage is via Tanstack form (`useTanstackUnityForm`), where
|
|
76
76
|
> Unity components are exposed as `<field.*>` after wiring the form
|
|
77
|
-
> hook
|
|
78
|
-
>
|
|
77
|
+
> hook imported from `@payfit/unity-components/forms`. The legacy RHF
|
|
78
|
+
> hook and field wrappers were removed in v3 — see `unity-tanstack-form`
|
|
79
|
+
> for the supported path.
|
|
79
80
|
> The "Unity" column below names the component; how to bind it lives in
|
|
80
81
|
> that skill.
|
|
81
82
|
|
|
@@ -7,17 +7,20 @@ description: >
|
|
|
7
7
|
metadata:
|
|
8
8
|
type: core
|
|
9
9
|
library: '@payfit/unity-components'
|
|
10
|
-
library_version: '
|
|
10
|
+
library_version: '3.x'
|
|
11
11
|
sources:
|
|
12
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/components/link/RawLink.tsx'
|
|
13
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/components/breadcrumbs/Breadcrumbs.tsx'
|
|
14
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/components/pagination/Pagination.tsx'
|
|
15
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/components/tabs/Tabs.tsx'
|
|
16
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/
|
|
17
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/providers/router/RouterProvider.tsx'
|
|
18
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/docs/concepts/
|
|
12
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/core/components/link/RawLink.tsx'
|
|
13
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/core/components/breadcrumbs/Breadcrumbs.tsx'
|
|
14
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/core/components/pagination/Pagination.tsx'
|
|
15
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/core/components/tabs/Tabs.tsx'
|
|
16
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/modules/tanstack-router/index.ts'
|
|
17
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/core/providers/router/RouterProvider.tsx'
|
|
18
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/modules/tanstack-router/docs/concepts/Navigation Patterns Explained.mdx'
|
|
19
19
|
---
|
|
20
20
|
|
|
21
|
+
This skill targets the current workspace Unity v3 API. Legacy examples are
|
|
22
|
+
migration context.
|
|
23
|
+
|
|
21
24
|
Two entry points expose the same components in two flavors. The base entry
|
|
22
25
|
(`@payfit/unity-components`) ships router-agnostic `Raw*` primitives that take
|
|
23
26
|
a plain `href`. The Tanstack integration entry
|
|
@@ -103,7 +106,7 @@ import { Link } from '@payfit/unity-components/integrations/tanstack-router'
|
|
|
103
106
|
|
|
104
107
|
The base export "Link" does not exist; agents alias RawLink and pass to=. The prop is silently ignored and the link does not navigate.
|
|
105
108
|
|
|
106
|
-
Source:
|
|
109
|
+
Source: src/modules/tanstack-router/components/link/Link.tsx (createLink wraps RawLink)
|
|
107
110
|
|
|
108
111
|
### HIGH Pass to= prop to RawLink
|
|
109
112
|
|
|
@@ -126,7 +129,7 @@ import { Link } from '@payfit/unity-components/integrations/tanstack-router'
|
|
|
126
129
|
|
|
127
130
|
RawLink only accepts href. The to prop is silently ignored.
|
|
128
131
|
|
|
129
|
-
Source: components/link/RawLink.tsx
|
|
132
|
+
Source: src/core/components/link/RawLink.tsx
|
|
130
133
|
|
|
131
134
|
### HIGH Expect the v1 monolithic Pagination
|
|
132
135
|
|
|
@@ -156,7 +159,7 @@ import { Pagination, PaginationContent, PaginationItem, RawPaginationLink }
|
|
|
156
159
|
|
|
157
160
|
v2 Pagination is compositional; passing currentPage/pageCount with no children renders an empty container. The old monolithic component (ClientSidePagination) now lives only inside DataTable as an internal — there is no public monolithic export. For standalone pagination, compose it yourself; for paginated tables, use DataTable which has it built in.
|
|
158
161
|
|
|
159
|
-
Source: components/pagination/Pagination.tsx; index.ts
|
|
162
|
+
Source: src/core/components/pagination/Pagination.tsx; index.ts
|
|
160
163
|
|
|
161
164
|
### MEDIUM Forget to wrap BreadcrumbLink in Breadcrumb
|
|
162
165
|
|
|
@@ -180,7 +183,7 @@ Correct:
|
|
|
180
183
|
|
|
181
184
|
Breadcrumbs filters children to Breadcrumb type; loose BreadcrumbLinks are dropped silently.
|
|
182
185
|
|
|
183
|
-
Source: components/breadcrumbs/Breadcrumbs.tsx
|
|
186
|
+
Source: src/core/components/breadcrumbs/Breadcrumbs.tsx
|
|
184
187
|
|
|
185
188
|
### MEDIUM Use Raw\* components without RouterProvider in a non-Tanstack app
|
|
186
189
|
|
|
@@ -207,7 +210,7 @@ Correct:
|
|
|
207
210
|
|
|
208
211
|
Raw\* components consume useRouter() context. Without RouterProvider, isActive checks return undefined and active-link styling is lost.
|
|
209
212
|
|
|
210
|
-
Source: components/link/RawLink.tsx
|
|
213
|
+
Source: src/core/components/link/RawLink.tsx; src/core/providers/router/RouterProvider.tsx
|
|
211
214
|
|
|
212
215
|
## See also
|
|
213
216
|
|
|
@@ -7,17 +7,20 @@ description: >
|
|
|
7
7
|
metadata:
|
|
8
8
|
type: core
|
|
9
9
|
library: '@payfit/unity-components'
|
|
10
|
-
library_version: '
|
|
10
|
+
library_version: '3.x'
|
|
11
11
|
sources:
|
|
12
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/components/dialog/Dialog.tsx'
|
|
13
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/components/side-panel/SidePanel.tsx'
|
|
14
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/components/tooltip/Tooltip.tsx'
|
|
15
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/components/popover/Popover.tsx'
|
|
16
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/components/menu/Menu.tsx'
|
|
17
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/components/promo-dialog/PromoDialog.tsx'
|
|
18
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/components/bottom-sheet/BottomSheet.tsx'
|
|
12
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/core/components/dialog/Dialog.tsx'
|
|
13
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/core/components/side-panel/SidePanel.tsx'
|
|
14
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/core/components/tooltip/Tooltip.tsx'
|
|
15
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/core/components/popover/Popover.tsx'
|
|
16
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/core/components/menu/Menu.tsx'
|
|
17
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/core/components/promo-dialog/PromoDialog.tsx'
|
|
18
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/core/components/bottom-sheet/BottomSheet.tsx'
|
|
19
19
|
---
|
|
20
20
|
|
|
21
|
+
This skill targets the current workspace Unity v3 API. Legacy examples are
|
|
22
|
+
migration context.
|
|
23
|
+
|
|
21
24
|
## Setup
|
|
22
25
|
|
|
23
26
|
Overlays do not require a global provider. Each overlay owns its open state
|
|
@@ -103,7 +106,7 @@ Correct:
|
|
|
103
106
|
|
|
104
107
|
Unity enforces the WCAG rule that disabled controls must not carry tooltips (the disabled element is not keyboard-focusable, so the tooltip is unreachable). This is enforced at the library level, not just policy.
|
|
105
108
|
|
|
106
|
-
Source: components/tooltip/Tooltip.tsx
|
|
109
|
+
Source: src/core/components/tooltip/Tooltip.tsx
|
|
107
110
|
|
|
108
111
|
### MEDIUM Use Dialog for a non-blocking hint
|
|
109
112
|
|
|
@@ -131,7 +134,7 @@ Correct:
|
|
|
131
134
|
|
|
132
135
|
Dialog is modal (focus trap, scroll lock, backdrop) — heavy for a simple informational popover.
|
|
133
136
|
|
|
134
|
-
Source: components/dialog/Dialog.tsx
|
|
137
|
+
Source: src/core/components/dialog/Dialog.tsx (ModalOverlay)
|
|
135
138
|
|
|
136
139
|
### MEDIUM Use Tooltip for interactive content
|
|
137
140
|
|
|
@@ -166,7 +169,7 @@ Correct:
|
|
|
166
169
|
|
|
167
170
|
Tooltip is display-only; placing interactive elements inside breaks focus and event handling.
|
|
168
171
|
|
|
169
|
-
Source: components/tooltip/Tooltip.tsx (no interactive support); components/menu/Menu.tsx
|
|
172
|
+
Source: src/core/components/tooltip/Tooltip.tsx (no interactive support); src/core/components/menu/Menu.tsx
|
|
170
173
|
|
|
171
174
|
### MEDIUM Fight the modal focus trap with custom useEffect focus moves
|
|
172
175
|
|
|
@@ -189,7 +192,7 @@ Correct:
|
|
|
189
192
|
|
|
190
193
|
Dialog manages focus and restoration via React Aria. Calling triggerRef.focus() inside a useEffect produces unpredictable jumps.
|
|
191
194
|
|
|
192
|
-
Source: components/dialog/Dialog.tsx
|
|
195
|
+
Source: src/core/components/dialog/Dialog.tsx
|
|
193
196
|
|
|
194
197
|
### MEDIUM PromoDialog without PromoDialogHero
|
|
195
198
|
|
|
@@ -216,7 +219,7 @@ Correct:
|
|
|
216
219
|
|
|
217
220
|
PromoDialog validates at render and console.errors if the hero is missing; dialog still renders but the layout breaks.
|
|
218
221
|
|
|
219
|
-
Source: components/promo-dialog/PromoDialog.tsx
|
|
222
|
+
Source: src/core/components/promo-dialog/PromoDialog.tsx (console.error guard)
|
|
220
223
|
|
|
221
224
|
## See also
|
|
222
225
|
|
|
@@ -7,23 +7,29 @@ description: >
|
|
|
7
7
|
metadata:
|
|
8
8
|
type: core
|
|
9
9
|
library: '@payfit/unity-components'
|
|
10
|
-
library_version: '
|
|
10
|
+
library_version: '3.x'
|
|
11
11
|
sources:
|
|
12
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/hooks/use-tanstack-form.tsx'
|
|
13
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/
|
|
14
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/components/form/TanstackForm.tsx'
|
|
15
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/components/form-field/TanstackFormField.tsx'
|
|
16
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/adapters/zodAdapter.ts'
|
|
17
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/utils/field-revalidate-logic.ts'
|
|
18
|
-
- 'PayFit/hr-apps:libs/shared/unity/components/src/docs/concepts/
|
|
12
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/modules/tanstack-form/hooks/use-tanstack-form.tsx'
|
|
13
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/docs/guides/migration/Migrating from 2.x to 3.x.mdx'
|
|
14
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/modules/tanstack-form/components/form/TanstackForm.tsx'
|
|
15
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/modules/tanstack-form/components/form-field/TanstackFormField.tsx'
|
|
16
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/modules/tanstack-form/adapters/zodAdapter.ts'
|
|
17
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/modules/tanstack-form/utils/field-revalidate-logic.ts'
|
|
18
|
+
- 'PayFit/hr-apps:libs/shared/unity/components/src/modules/tanstack-form/docs/concepts/Form Architecture Overview.mdx'
|
|
19
19
|
---
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
This skill targets the current workspace Unity v3 API. Legacy examples are
|
|
22
|
+
migration context.
|
|
23
|
+
|
|
24
|
+
Build a Unity v3 form with `useTanstackUnityForm` + Zod. The legacy RHF
|
|
25
|
+
integration (`useUnityForm`) was removed in v3; the wrong example below is
|
|
26
|
+
historical migration context, not a supported API.
|
|
22
27
|
|
|
23
28
|
## Setup
|
|
24
29
|
|
|
25
30
|
```tsx
|
|
26
|
-
import { Button
|
|
31
|
+
import { Button } from '@payfit/unity-components'
|
|
32
|
+
import { useTanstackUnityForm } from '@payfit/unity-components/forms'
|
|
27
33
|
import { z } from 'zod'
|
|
28
34
|
|
|
29
35
|
const schema = z.object({
|
|
@@ -86,17 +92,16 @@ const { methods, Form, FormField } = useUnityForm(schema)
|
|
|
86
92
|
Correct:
|
|
87
93
|
|
|
88
94
|
```tsx
|
|
89
|
-
import { useTanstackUnityForm } from '@payfit/unity-components'
|
|
95
|
+
import { useTanstackUnityForm } from '@payfit/unity-components/forms'
|
|
90
96
|
|
|
91
97
|
const form = useTanstackUnityForm({ validators: { onBlur: schema } })
|
|
92
98
|
```
|
|
93
99
|
|
|
94
|
-
The legacy `
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
author new code with it.
|
|
100
|
+
The legacy `useUnityForm` hook and RHF field wrappers were removed in v3.
|
|
101
|
+
Replace them with `useTanstackUnityForm` and its bound `field.*` components;
|
|
102
|
+
do not mix RHF Controller with Tanstack field components.
|
|
98
103
|
|
|
99
|
-
Source: libs/shared/unity/components/src/
|
|
104
|
+
Source: libs/shared/unity/components/src/docs/guides/migration/Migrating from 2.x to 3.x.mdx (React Hook Form removal)
|
|
100
105
|
|
|
101
106
|
### CRITICAL Omit form.AppForm or form.AppField wrapping
|
|
102
107
|
|
|
@@ -124,7 +129,7 @@ Correct:
|
|
|
124
129
|
|
|
125
130
|
`useFormContext()` and `useFieldContext()` throw without their providers; Tanstack field components silently break (cannot read property of undefined).
|
|
126
131
|
|
|
127
|
-
Source: TanstackForm.tsx
|
|
132
|
+
Source: src/modules/tanstack-form/components/form/TanstackForm.tsx; src/modules/tanstack-form/components/form-field/TanstackFormField.tsx (useFormContext/useFieldContext)
|
|
128
133
|
|
|
129
134
|
### HIGH Subscribe to whole form state instead of a selector
|
|
130
135
|
|
|
@@ -146,7 +151,7 @@ Correct:
|
|
|
146
151
|
|
|
147
152
|
A selector-less subscription re-renders the children on every keystroke anywhere in the form; pass a narrowing selector to scope to the slice you need.
|
|
148
153
|
|
|
149
|
-
Source: use-tanstack-form.stories.tsx
|
|
154
|
+
Source: src/modules/tanstack-form/hooks/use-tanstack-form.stories.tsx (StateIntegration story)
|
|
150
155
|
|
|
151
156
|
### MEDIUM Pick the wrong validation timing
|
|
152
157
|
|
|
@@ -166,7 +171,7 @@ useTanstackUnityForm({ validators: { onBlur: schema } })
|
|
|
166
171
|
|
|
167
172
|
`onChange` fires on every keystroke (jarring) and `onSubmit` waits until submit (errors arrive too late); `onBlur` is the usual default, with `fieldRevalidateLogic` reserved for "blur until first error, then change".
|
|
168
173
|
|
|
169
|
-
Source: use-tanstack-form.stories.tsx
|
|
174
|
+
Source: src/modules/tanstack-form/hooks/use-tanstack-form.stories.tsx; src/modules/tanstack-form/utils/field-revalidate-logic.ts
|
|
170
175
|
|
|
171
176
|
### HIGH Mix Composed and Atomic APIs in one field (or reach for Atomic by default)
|
|
172
177
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Bound field components (Composed API)
|
|
2
2
|
|
|
3
|
-
All 15 Tanstack-bound Composed field components, registered in `src/hooks/use-tanstack-form.tsx` via `createFormHook({ fieldComponents })`. They are exposed on the render-prop `field` object inside `<form.AppField>` WITHOUT the `Tanstack` prefix (e.g. the registered `TanstackTextField` is `field.TextField`).
|
|
3
|
+
All 15 Tanstack-bound Composed field components, registered in `src/modules/tanstack-form/hooks/use-tanstack-form.tsx` via `createFormHook({ fieldComponents })`. They are exposed on the render-prop `field` object inside `<form.AppField>` WITHOUT the `Tanstack` prefix (e.g. the registered `TanstackTextField` is `field.TextField`).
|
|
4
4
|
|
|
5
5
|
The form-usage pattern is identical for every component:
|
|
6
6
|
|
|
@@ -64,4 +64,4 @@ Available on `form` (not `field`):
|
|
|
64
64
|
- `<form.Subscribe selector={…}>` — selector-scoped reactive subscription. Always pass `selector`.
|
|
65
65
|
- `<form.InlineFieldGroup>`, `<form.InlineFieldGroupHeader>`, `<form.InlineFieldGroupReadView>`, `<form.InlineFieldGroupEditView>` — inline edition layout (read view ↔ edit view toggling for grouped fields).
|
|
66
66
|
|
|
67
|
-
For the mapping source of truth see `src/hooks/use-tanstack-form.tsx` (the `createFormHook` call). The keys in `fieldComponents` and `formComponents` are exactly the names exposed on `field` / `form`.
|
|
67
|
+
For the mapping source of truth see `src/modules/tanstack-form/hooks/use-tanstack-form.tsx` (the `createFormHook` call). The keys in `fieldComponents` and `formComponents` are exactly the names exposed on `field` / `form`.
|
|
@@ -55,7 +55,7 @@ Reach for Atomic when you need to interleave custom content between the label an
|
|
|
55
55
|
`validators.onBlur` is the default; use `onChange` only for fields that need live feedback (password strength meter, search-as-you-type). `fieldRevalidateLogic` gives "blur until first error, then change" UX without polluting form-level validators.
|
|
56
56
|
|
|
57
57
|
```tsx
|
|
58
|
-
import { fieldRevalidateLogic, useTanstackUnityForm } from '@payfit/unity-components'
|
|
58
|
+
import { fieldRevalidateLogic, useTanstackUnityForm } from '@payfit/unity-components/forms'
|
|
59
59
|
|
|
60
60
|
const form = useTanstackUnityForm({
|
|
61
61
|
defaultValues: { email: '', password: '' },
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Schema adapters
|
|
2
2
|
|
|
3
|
-
Schema adapters give the form-field organisms a uniform way to ask "is this path required?" across schemas authored in Zod 3, Zod 4, or any Standard Schema v1 implementation. Source: `src/adapters/`.
|
|
3
|
+
Schema adapters give the form-field organisms a uniform way to ask "is this path required?" across schemas authored in Zod 3, Zod 4, or any Standard Schema v1 implementation. Source: `src/modules/tanstack-form/adapters/`.
|
|
4
4
|
|
|
5
5
|
## Common interface
|
|
6
6
|
|
|
@@ -31,7 +31,7 @@ new ZodV3SchemaAdapter(schema: z3.ZodObject<z3.ZodRawShape>)
|
|
|
31
31
|
|
|
32
32
|
- Reads structure from `schema.shape` and `field._def.typeName`.
|
|
33
33
|
- Detects optional with `field instanceof z3.ZodOptional`; unwraps via `field._def.innerType`.
|
|
34
|
-
- Source: `src/adapters/zodAdapter.ts` (lines 6–60).
|
|
34
|
+
- Source: `src/modules/tanstack-form/adapters/zodAdapter.ts` (lines 6–60).
|
|
35
35
|
|
|
36
36
|
### ZodV4SchemaAdapter
|
|
37
37
|
|
|
@@ -43,7 +43,7 @@ new ZodV4SchemaAdapter(schema: z4.ZodObject<z4.ZodRawShape>)
|
|
|
43
43
|
|
|
44
44
|
- Same shape traversal as v3, but uses `field.def.innerType` and `field.def.typeName` (no underscore — Zod 4 renamed `_def` to `def`).
|
|
45
45
|
- `field instanceof z4.ZodOptional` for optionality detection.
|
|
46
|
-
- Source: `src/adapters/zodAdapter.ts` (lines 62–117).
|
|
46
|
+
- Source: `src/modules/tanstack-form/adapters/zodAdapter.ts` (lines 62–117).
|
|
47
47
|
|
|
48
48
|
### StandardSchemaAdapter
|
|
49
49
|
|
|
@@ -55,14 +55,14 @@ new StandardSchemaAdapter(standardSchema: StandardSchemaV1)
|
|
|
55
55
|
|
|
56
56
|
- Stub implementation: `getField()` returns `{ isOptional: false, type: 'unknown', shape: undefined }` for any non-null path. Standard Schema's spec does not expose enough internal structure for richer introspection.
|
|
57
57
|
- Use this only for schemas that aren't Zod (e.g. Valibot, ArkType) — required-field inference will degrade to "always required".
|
|
58
|
-
- Source: `src/adapters/standardSchemaAdapter.ts`.
|
|
58
|
+
- Source: `src/modules/tanstack-form/adapters/standardSchemaAdapter.ts`.
|
|
59
59
|
|
|
60
60
|
## How adapters auto-select
|
|
61
61
|
|
|
62
|
-
`createSchemaAdapter(schema)` (in `src/utils/createSchemaAdapter.ts`) picks an adapter from the schema's structural fingerprint:
|
|
62
|
+
`createSchemaAdapter(schema)` (in `src/modules/tanstack-form/utils/createSchemaAdapter.ts`) picks an adapter from the schema's structural fingerprint:
|
|
63
63
|
|
|
64
64
|
```ts
|
|
65
|
-
import { createSchemaAdapter } from '@payfit/unity-components'
|
|
65
|
+
import { createSchemaAdapter } from '@payfit/unity-components/forms'
|
|
66
66
|
|
|
67
67
|
const adapter = createSchemaAdapter(schema)
|
|
68
68
|
// schema._def && 'def' in schema → ZodV4SchemaAdapter
|