Lite vs Full Managers
Read-only Lite variants of the three Manager components — when to use them and what they save.
Overview
Version 3.8 of @tantainnovative/ndpr-toolkit introduces three new Lite variants of the heavy Manager components: LawfulBasisTrackerLite, ROPAManagerLite, and CrossBorderTransferManagerLite. Each one renders the same list-and-summary view as its Full counterpart, minus every write affordance — no Add, Edit, Archive, Delete, or CSV export. They are purpose-built for read-only surfaces.
The Full components are unchanged. Lite is strictly additive: it ships under a new /lite subpath alongside each feature module, so existing imports keep working exactly as before.
Who is this for?
- Internal compliance dashboards where most users have view-only access.
- Customer-facing transparency pages that disclose processing activities or cross-border transfers.
- Audit or review pages where a separate workflow performs the writes.
- Embedded widgets — e.g. an “active transfers” tile on a home dashboard.
Bundle size comparison
The heavier the Full component, the bigger the win from Lite. The cross-border manager is the standout — almost the entire Full bundle is the 624-row country adequacy dataset, which Lite does not import.
| Module | Full subpath | Lite subpath | Full | Lite | Saved |
|---|---|---|---|---|---|
| Lawful Basis | /lawful-basis | /lawful-basis/lite | 36.7 KB | 12.7 KB | 65% |
| Cross-Border | /cross-border | /cross-border/lite | 53.3 KB | 5.6 KB | 89% |
| ROPA | /ropa | /ropa/lite | 36.9 KB | 13.2 KB | 64% |
Sizes are minified and tree-shaken but pre-gzip. Gzipped delivery sizes are roughly 25–40% of these numbers.
When to use Lite
Reach for Lite when:
- You are rendering a read-only dashboard, audit page, or compliance overview.
- The page is server-rendered and the viewing user cannot edit anyway (e.g. an executive summary).
- You are embedding a compliance widget on a homepage or layout shell where bundle weight matters.
- You are building a customer-facing transparency page disclosing transfers or processing activities.
- Write operations live in a separate admin route that loads the Full component on demand.
Stick with the Full component when:
- The same page needs Add, Edit, Archive, or Delete.
- You rely on the built-in CSV export.
- You need the built-in detail view or validation handlers.
Side-by-side example
Compare the same Lawful Basis page written against the Full component and against the Lite variant. Lite drops all the write callbacks and surfaces one optional onActivityClick for row interactivity.
Full — read + write
import {
LawfulBasisTracker,
useLawfulBasis,
} from '@tantainnovative/ndpr-toolkit/lawful-basis';
export function LawfulBasisPage() {
const {
activities,
addActivity,
updateActivity,
archiveActivity,
} = useLawfulBasis();
return (
<LawfulBasisTracker
activities={activities}
onAddActivity={addActivity}
onUpdateActivity={updateActivity}
onArchiveActivity={archiveActivity}
/>
);
}Lite — read-only
import { LawfulBasisTrackerLite } from
'@tantainnovative/ndpr-toolkit/lawful-basis/lite';
import { useLawfulBasis } from
'@tantainnovative/ndpr-toolkit/hooks';
export function LawfulBasisOverview() {
const { activities } = useLawfulBasis();
return (
<LawfulBasisTrackerLite
activities={activities}
onActivityClick={(a) =>
router.push(`/lawful-basis/${a.id}`)
}
/>
);
}The Lite version saves ~24 KB on this page alone — and the saving compounds across the three modules.
Per-module usage
Lawful Basis
import { LawfulBasisTrackerLite } from
'@tantainnovative/ndpr-toolkit/lawful-basis/lite';
import type { ProcessingActivity } from
'@tantainnovative/ndpr-toolkit';
export function LawfulBasisOverview({ activities }: {
activities: ProcessingActivity[];
}) {
return (
<LawfulBasisTrackerLite
activities={activities}
onActivityClick={(a) => console.log('view', a.id)}
/>
);
}ROPA
import { ROPAManagerLite } from
'@tantainnovative/ndpr-toolkit/ropa/lite';
import type { ProcessingRecord } from
'@tantainnovative/ndpr-toolkit';
export function ROPAOverview({ records }: {
records: ProcessingRecord[];
}) {
return (
<ROPAManagerLite
records={records}
onRecordClick={(r) => console.log('view', r.id)}
/>
);
}Cross-Border Transfers
import { CrossBorderTransferManagerLite } from
'@tantainnovative/ndpr-toolkit/cross-border/lite';
import type { CrossBorderTransfer } from
'@tantainnovative/ndpr-toolkit';
export function TransfersOverview({ transfers }: {
transfers: CrossBorderTransfer[];
}) {
return (
<CrossBorderTransferManagerLite
transfers={transfers}
onTransferClick={(t) => console.log('view', t.id)}
/>
);
}Migration from Full to Lite
Migrating a read-only page is mechanical and isolated to the import statement and the prop set:
- Lawful Basis. Replace
from '@tantainnovative/ndpr-toolkit/lawful-basis'withfrom '@tantainnovative/ndpr-toolkit/lawful-basis/lite', droponAddActivity/onUpdateActivity/onArchiveActivitycallbacks, and addonActivityClickif you want row interactivity. - ROPA. Replace
from '@tantainnovative/ndpr-toolkit/ropa'withfrom '@tantainnovative/ndpr-toolkit/ropa/lite', droponAddRecord/onUpdateRecord/onArchiveRecord/onExportCSVcallbacks, and addonRecordClickif you want row interactivity. - Cross-Border. Replace
from '@tantainnovative/ndpr-toolkit/cross-border'withfrom '@tantainnovative/ndpr-toolkit/cross-border/lite', droponAddTransfer/onUpdateTransfer/onTerminateTransfercallbacks, and addonTransferClickif you want row interactivity.
The unstyled prop and classNames slot object are still supported on every Lite component. The slot list is shorter — only the slots actually used by the list-and-summary view are present.
Caveats
- No mutation. Lite components never call a util that mutates state. There is no built-in form, validation handler, modal, or CSV exporter. If you need any of those, render the Full component on the page that needs them — or load it lazily on user intent.
- Cross-border reads
adequacyStatusdirectly. The Lite cross-border component displaystransfer.adequacyStatusstraight from each transfer record. It does notrecompute adequacy by looking up the destination country in the bundled adequacy map — that map is the bulk of the Full component's 53 KB and is deliberately excluded. If your records contain stale adequacy data, the display will reflect that; keep the value fresh server-side (e.g. viavalidateTransferfrom/server) before persisting. - Type compatibility. Lite consumes the same
ProcessingActivity,ProcessingRecord, andCrossBorderTransfershapes as the Full versions — so swapping is safe at the type level.
See also
- Lawful Basis Tracker component docs
- ROPA component docs
- Cross-Border Transfers component docs
- Server-Side Rendering & RSC — pairing Lite with
/servervalidators.