UNPKG

@payfit/unity-components

Version:

187 lines (142 loc) 7.47 kB
--- name: unity-migrate-from-midnight description: > Load when replacing @payfit/midnight UI with Unity. Use it to choose Unity equivalents, avoid obsolete Midnight patterns, and route unclear component mappings to unity-find-component. type: lifecycle library: '@payfit/unity-components' library_version: '2.x' sources: - 'PayFit/hr-apps:libs/shared/unity/components/src/components/tooltip/Tooltip.tsx' - 'PayFit/hr-apps:libs/shared/unity/components/src/components/button/Button.tsx' - 'PayFit/hr-apps:AGENTS.md' --- Convert a legacy `@payfit/midnight` screen to Unity. The table below covers the highest-traffic mappings; the exhaustive ~85-row map lives in `references/midnight-component-map.md`. When a Midnight component is not in either, fall through to `unity-find-component`. ## Equivalency Map (high-traffic) | Midnight | Unity | Notes | | ---------------------- | -------------------------------------------- | -------------------------------------------------------------------- | | `Button` | `Button` | Prop renames apply (see below) | | `Box` | `Flex` (or `Grid` for 2D) | No 1:1 layout box; use `Flex` with `direction`/`gap`/`align` | | `Modal` | `Dialog` + `DialogContent` + `DialogActions` | Use `PromoDialog` for marketing dialogs (requires `PromoDialogHero`) | | `Link` | `RawLink` (base) or `Link` (tanstack-router) | Pick the router-aware one when navigating inside the app | | `Heading` | `Text` with `variant="heading*"` | No dedicated `Heading`; typography is a `Text` variant | | `Badge` | `Badge` | `color``variant`; Unity Badge is the chip with intent colors | | `Pill` | `Pill` | Unity Pill is numeric-only with fewer colors; same indicator intent | | `transition('smooth')` | `uy:transition-*` / `uy:duration-*` classes | No JS helper; use TailwindCSS utilities | For everything else, see `references/midnight-component-map.md`. When a target is unclear, switch to `unity-find-component` rather than guessing. Do not invent Unity component names from Midnight ones. ## Prop renames Confirmed renames from `Button.tsx` and the React Aria base classes Unity extends: | Midnight | Unity | Mechanism | | ----------------- | ---------------- | ------------------------------------------------------ | | `visual="danger"` | `color="danger"` | Color/intent prop renamed on `Button`, `Pill`, `Alert` | | `onClick={fn}` | `onPress={fn}` | React Aria press events (touch/keyboard parity) | | `disabled` | `isDisabled` | React Aria boolean convention | Do not auto-extend this table. If a prop is not listed, look at the Unity component source — many props are unchanged and adding speculative renames produces silent default behavior. ## Accessibility deltas Unity enforces several WCAG rules that Midnight allowed: - **Tooltip on disabled control — rejected at the library level.** `Tooltip` ignores or removes the trigger when the wrapped control is disabled, because disabled controls are not focusable and therefore the tooltip is unreachable by keyboard or screen reader. See the `## Common Mistakes` entry below for the replacement. - **Dialog focus management.** Unity `Dialog` traps focus, restores it on close, and requires an accessible title. Midnight `Modal` was looser about both. - **Autocomplete keyboard navigation.** Unity `Autocomplete` follows the ARIA combobox pattern (Arrow keys, Home/End, Escape to dismiss). If Midnight code relied on click-only interactions, those still work, but do not strip the keyboard handlers when porting. ## Forms Midnight-era screens commonly use React Hook Form. When porting, replace the form with `useTanstackUnityForm` and the Tanstack-bound `*Field` components (`TextField`, `SelectField`, `NumberField`, etc.). The legacy RHF `useUnityForm` + `*Field` wrappers in the same package index are deprecated and will be removed after the rebrand — do not pause on the RHF intermediate step. See `unity-tanstack-form`. ## Common Mistakes ### CRITICAL Wrap disabled button in Tooltip (Midnight-era pattern) Wrong: ```tsx <Tooltip title="Disabled because …"> <Button isDisabled>Submit</Button> </Tooltip> ``` Correct: ```tsx <Button isDisabled>Submit</Button> <Text variant="bodySmall" color="content.neutral.low"> Disabled because … </Text> // Or, if you must explain inline, gate the tooltip on enabled state: {isDisabled ? <Button isDisabled>Submit</Button> : <Tooltip title="…"><Button>Submit</Button></Tooltip>} ``` Midnight allowed `Tooltip` on disabled buttons; Unity enforces the WCAG rule that disabled controls must not have tooltips because they are not keyboard-focusable, so the tooltip is unreachable — Unity's `Tooltip` component rejects this pairing at the library level. Source: libs/shared/unity/components/src/components/tooltip/Tooltip.tsx; maintainer interview (Unity enforces) ### HIGH Assume Midnight props map 1:1 to Unity Wrong: ```tsx <Button visual="danger" onClick={handleDelete}> Delete </Button> ``` Correct: ```tsx <Button color="danger" onPress={handleDelete}> Delete </Button> ``` `visual` is the Midnight intent prop and `color` is the Unity one; `onClick` still type-checks on the underlying DOM node but bypasses React Aria's touch and keyboard press handling, so keyboard activations silently no-op. Source: libs/shared/unity/components/src/components/button/Button.tsx ### MEDIUM Leave Midnight + Unity side-by-side in the same screen Wrong: ```tsx import { Button } from '@payfit/midnight' import { Dialog } from '@payfit/unity-components' ``` Correct: ```tsx import { Button, Dialog } from '@payfit/unity-components' ``` Midnight and Unity ship divergent theme tokens — colors, spacing, and typography differ — so a mixed screen renders with mismatched scales and the visual regression lands silently because both stylesheets are valid. Source: AGENTS.md migration awareness; maintainer interview ### MEDIUM Port Midnight transition utility instead of using uy: classes Wrong: ```tsx import { transition } from '@payfit/midnight' <Flex transition={transition('smooth')}> ``` Correct: ```tsx <Flex className="uy:transition-all uy:duration-200 uy:ease-out"> ``` Unity has no JS transition helper; the migration target is TailwindCSS 4 transition utilities under the `uy:` prefix, and porting the Midnight function leaves a dead import that the new theme tokens never honor. Source: no Unity equivalent for Midnight transition helpers ## See also - `references/midnight-component-map.md` — exhaustive Midnight → Unity map (v1 + v2 surfaces, ~85 rows, grouped by category) - `unity-find-component` — decision tree for any Midnight component still ambiguous after consulting the full map - `unity-overlays` — full a11y constraints for `Dialog`, `Tooltip`, `Popover`, `Menu` - `unity-tanstack-form` — replacement path for RHF forms in the migrated screen