@tantainnovative/ndpr-toolkit 2.4.1 → 3.2.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.
Files changed (192) hide show
  1. package/README.md +226 -246
  2. package/dist/BreachReportForm-DpRrBoxU.d.ts +158 -0
  3. package/dist/BreachReportForm-yJ2Zl6gz.d.mts +158 -0
  4. package/dist/ConsentBanner-CDRT0o2k.d.mts +146 -0
  5. package/dist/ConsentBanner-Vxyt8SCX.d.ts +146 -0
  6. package/dist/{cross-border-entry-BrWVPly6.d.ts → CrossBorderTransferManager-D5Lc0e46.d.ts} +4 -5
  7. package/dist/{cross-border-entry-cCTvpwnT.d.mts → CrossBorderTransferManager-DkZhv9vD.d.mts} +4 -5
  8. package/dist/DPIAQuestionnaire-BkejviPj.d.mts +123 -0
  9. package/dist/DPIAQuestionnaire-DdSqXG3x.d.ts +123 -0
  10. package/dist/DSRRequestForm-BY8PogCU.d.mts +146 -0
  11. package/dist/DSRRequestForm-CHUg9cZh.d.ts +146 -0
  12. package/dist/DSRTracker-C6u_jAaK.d.mts +163 -0
  13. package/dist/DSRTracker-Dr_aT0pg.d.ts +163 -0
  14. package/dist/{lawful-basis-entry-CxZrofwG.d.mts → LawfulBasisTracker-CBqOxX1D.d.mts} +3 -5
  15. package/dist/{lawful-basis-entry-15qjKcNO.d.ts → LawfulBasisTracker-Cg30NbDA.d.ts} +3 -5
  16. package/dist/NDPRDashboard-CLJpEg0X.d.mts +44 -0
  17. package/dist/NDPRDashboard-DDWNd2Ah.d.ts +44 -0
  18. package/dist/{policy-E0fXZkda.d.mts → PolicyExporter-Bgi6nz82.d.mts} +5 -7
  19. package/dist/{policy-D2_jh5-T.d.ts → PolicyExporter-BnvuFncj.d.ts} +5 -7
  20. package/dist/{ropa-entry-B0D7X1GV.d.ts → ROPAManager-BS4eB8Hw.d.mts} +4 -5
  21. package/dist/{ropa-entry-DiOThOc2.d.mts → ROPAManager-qxTrXLkD.d.ts} +4 -5
  22. package/dist/RegulatoryReportGenerator-BUYgzTTT.d.ts +282 -0
  23. package/dist/RegulatoryReportGenerator-DwcHcEFp.d.mts +282 -0
  24. package/dist/StepIndicator-D-nwRTyo.d.mts +171 -0
  25. package/dist/StepIndicator-D9ZATz_O.d.ts +171 -0
  26. package/dist/adapters.d.mts +25 -0
  27. package/dist/adapters.d.ts +25 -0
  28. package/dist/adapters.js +2 -0
  29. package/dist/adapters.mjs +2 -0
  30. package/dist/breach.d.mts +36 -431
  31. package/dist/breach.d.ts +36 -431
  32. package/dist/breach.js +1 -1
  33. package/dist/breach.mjs +1 -1
  34. package/dist/chunk-27NYSWUG.mjs +2 -0
  35. package/dist/chunk-2ORDHJRD.js +2 -0
  36. package/dist/chunk-2W7ARAW2.js +2 -0
  37. package/dist/chunk-3F34NACG.js +2 -0
  38. package/dist/chunk-3UWT64FI.mjs +2 -0
  39. package/dist/chunk-3V23O4ZJ.js +2 -0
  40. package/dist/chunk-3XAUN5IM.mjs +3 -0
  41. package/dist/chunk-44W4H2EY.js +2 -0
  42. package/dist/chunk-5VMHKNJY.js +2 -0
  43. package/dist/chunk-6D3ZUGBB.mjs +2 -0
  44. package/dist/chunk-6E54NSAO.mjs +2 -0
  45. package/dist/chunk-7F5F5YWI.mjs +2 -0
  46. package/dist/chunk-DQLDX5X6.js +316 -0
  47. package/dist/chunk-FR7ZYZXB.js +2 -0
  48. package/dist/chunk-FY5G6DGZ.js +7 -0
  49. package/dist/chunk-G26I6MP5.mjs +2 -0
  50. package/dist/chunk-GCQRHMTQ.mjs +144 -0
  51. package/dist/chunk-GPJVTGHR.mjs +2 -0
  52. package/dist/chunk-GVANK6PL.js +3 -0
  53. package/dist/chunk-HNZK7LY3.mjs +2 -0
  54. package/dist/chunk-IKEPXHCZ.js +2 -0
  55. package/dist/chunk-IQQW52EF.js +2 -0
  56. package/dist/chunk-ISSGO2YT.mjs +72 -0
  57. package/dist/chunk-JZKH5RMC.js +3 -0
  58. package/dist/chunk-KHRBU5K7.js +2 -0
  59. package/dist/chunk-LFNA6WYQ.mjs +2 -0
  60. package/dist/chunk-LU4PFST7.js +144 -0
  61. package/dist/chunk-NPI5T6NH.mjs +7 -0
  62. package/dist/chunk-NPLXE43Q.mjs +2 -0
  63. package/dist/chunk-P7BSBCB3.js +2 -0
  64. package/dist/chunk-PEH5GIMN.js +2 -0
  65. package/dist/chunk-RSUDIFZV.mjs +2 -0
  66. package/dist/chunk-SBNAMPAP.mjs +2 -0
  67. package/dist/chunk-SVCRYM4I.mjs +2 -0
  68. package/dist/chunk-TKBZRULW.mjs +316 -0
  69. package/dist/chunk-TVW6KBVV.mjs +2 -0
  70. package/dist/chunk-U6VWHC46.js +72 -0
  71. package/dist/chunk-UK656RCG.js +2 -0
  72. package/dist/chunk-UNKXYVXY.js +2 -0
  73. package/dist/chunk-UOSEH6DC.js +2 -0
  74. package/dist/chunk-V37BM2LF.js +2 -0
  75. package/dist/chunk-V3MXWGXU.mjs +2 -0
  76. package/dist/chunk-VDZKGCAF.js +2 -0
  77. package/dist/chunk-WLSW4Z4W.mjs +2 -0
  78. package/dist/chunk-XSK4BSZJ.mjs +2 -0
  79. package/dist/chunk-YJCGEOLO.mjs +2 -0
  80. package/dist/chunk-ZCZ5RRZO.js +2 -0
  81. package/dist/chunk-ZQSX5ZHB.mjs +3 -0
  82. package/dist/compliance-score-racQe_E_.d.mts +115 -0
  83. package/dist/compliance-score-racQe_E_.d.ts +115 -0
  84. package/dist/consent.d.mts +67 -295
  85. package/dist/consent.d.ts +67 -295
  86. package/dist/consent.js +1 -1
  87. package/dist/consent.mjs +1 -1
  88. package/dist/core.d.mts +14 -48
  89. package/dist/core.d.ts +14 -48
  90. package/dist/core.js +1 -1
  91. package/dist/core.mjs +1 -1
  92. package/dist/cross-border-BBi9rZyO.d.mts +54 -0
  93. package/dist/cross-border-Dy-U9Hu6.d.ts +54 -0
  94. package/dist/{cross-border-BMcqLvjC.d.mts → cross-border-UyT00llA.d.mts} +1 -52
  95. package/dist/{cross-border-BMcqLvjC.d.ts → cross-border-UyT00llA.d.ts} +1 -52
  96. package/dist/cross-border.d.mts +32 -4
  97. package/dist/cross-border.d.ts +32 -4
  98. package/dist/cross-border.js +1 -1
  99. package/dist/cross-border.mjs +1 -1
  100. package/dist/dpia.d.mts +28 -284
  101. package/dist/dpia.d.ts +28 -284
  102. package/dist/dpia.js +1 -1
  103. package/dist/dpia.mjs +1 -1
  104. package/dist/dsr.d.mts +29 -300
  105. package/dist/dsr.d.ts +29 -300
  106. package/dist/dsr.js +1 -1
  107. package/dist/dsr.mjs +1 -1
  108. package/dist/hooks.d.mts +23 -10
  109. package/dist/hooks.d.ts +23 -10
  110. package/dist/hooks.js +1 -1
  111. package/dist/hooks.mjs +1 -1
  112. package/dist/index.d.mts +28 -19
  113. package/dist/index.d.ts +28 -19
  114. package/dist/index.js +1 -1
  115. package/dist/index.mjs +1 -1
  116. package/dist/lawful-basis.d.mts +31 -4
  117. package/dist/lawful-basis.d.ts +31 -4
  118. package/dist/lawful-basis.js +1 -1
  119. package/dist/lawful-basis.mjs +1 -1
  120. package/dist/policy-engine-C-tShzZH.d.mts +154 -0
  121. package/dist/policy-engine-DSQpT55_.d.ts +154 -0
  122. package/dist/policy-sections-CfNVBLCh.d.mts +54 -0
  123. package/dist/policy-sections-DqH0iZRf.d.ts +54 -0
  124. package/dist/policy.d.mts +117 -4
  125. package/dist/policy.d.ts +117 -4
  126. package/dist/policy.js +1 -1
  127. package/dist/policy.mjs +1 -1
  128. package/dist/presets.d.mts +114 -0
  129. package/dist/presets.d.ts +114 -0
  130. package/dist/presets.js +2 -0
  131. package/dist/presets.mjs +2 -0
  132. package/dist/{ropa-Li6UlL5H.d.ts → ropa-BDTM06tr.d.ts} +1 -49
  133. package/dist/{ropa-DP7pPPql.d.mts → ropa-CFHuT7jE.d.mts} +1 -49
  134. package/dist/ropa-CyynscU6.d.ts +51 -0
  135. package/dist/ropa-NIgxd8uP.d.mts +51 -0
  136. package/dist/ropa.d.mts +30 -4
  137. package/dist/ropa.d.ts +30 -4
  138. package/dist/ropa.js +1 -1
  139. package/dist/ropa.mjs +1 -1
  140. package/dist/sanitize-9mOO_cJW.d.mts +147 -0
  141. package/dist/sanitize-9mOO_cJW.d.ts +147 -0
  142. package/dist/styling-B7CBzYG7.d.ts +165 -0
  143. package/dist/styling-uJLsBbER.d.mts +165 -0
  144. package/dist/types-DK2CoKOC.d.mts +10 -0
  145. package/dist/types-DK2CoKOC.d.ts +10 -0
  146. package/dist/unstyled.d.mts +4 -4
  147. package/dist/unstyled.d.ts +4 -4
  148. package/dist/useAdaptivePolicyWizard-B9Op2gYM.d.ts +52 -0
  149. package/dist/useAdaptivePolicyWizard-N4eUM4Tj.d.mts +52 -0
  150. package/dist/{useBreach-BBSoIcZO.d.mts → useBreach-CPr86Yan.d.mts} +18 -2
  151. package/dist/{useBreach-lFLbSyAN.d.ts → useBreach-DkVXvtJK.d.ts} +18 -2
  152. package/dist/{useConsent-D0pAfTlb.d.ts → useConsent-DCNkIJHR.d.mts} +12 -2
  153. package/dist/{useConsent-DOt2Njst.d.mts → useConsent-dOcELSfX.d.ts} +12 -2
  154. package/dist/{useCrossBorderTransfer-DmtACeqW.d.ts → useCrossBorderTransfer-BGNZt2lk.d.mts} +15 -3
  155. package/dist/{useCrossBorderTransfer-BZVFCXfr.d.mts → useCrossBorderTransfer-COqjgjsu.d.ts} +15 -3
  156. package/dist/{useDPIA-DBsg2yZx.d.ts → useDPIA-Dl16Te3r.d.ts} +13 -2
  157. package/dist/{useDPIA-Da7-Q_yW.d.mts → useDPIA-DzWye8JB.d.mts} +13 -2
  158. package/dist/{useDSR-YYZ6FYFs.d.mts → useDSR-C1LksCfP.d.mts} +13 -2
  159. package/dist/{useDSR-CYI7WCXr.d.ts → useDSR-DZel52O1.d.ts} +13 -2
  160. package/dist/{useDefaultPrivacyPolicy-CUluF_ic.d.mts → useDefaultPrivacyPolicy-BsYttRey.d.mts} +13 -2
  161. package/dist/{useDefaultPrivacyPolicy-B7kTHbZh.d.ts → useDefaultPrivacyPolicy-C-mG-A5S.d.ts} +13 -2
  162. package/dist/{useLawfulBasis-CpWuHtyh.d.mts → useLawfulBasis-CKJ-kw84.d.mts} +13 -2
  163. package/dist/{useLawfulBasis-CCWF9waR.d.ts → useLawfulBasis-DFTmu1ca.d.ts} +13 -2
  164. package/dist/{useROPA-BhJ3kvHp.d.ts → useROPA-BSSU1rfx.d.ts} +14 -2
  165. package/dist/{useROPA-DLFdjkxP.d.mts → useROPA-C2hjaBTz.d.mts} +14 -2
  166. package/package.json +24 -3
  167. package/dist/chunk-2XFAV267.mjs +0 -2
  168. package/dist/chunk-32UIWTGD.js +0 -72
  169. package/dist/chunk-3YCV2BA6.js +0 -2
  170. package/dist/chunk-4A354HL3.js +0 -2
  171. package/dist/chunk-5ZBO2UPH.js +0 -2
  172. package/dist/chunk-6GGGTRDZ.mjs +0 -2
  173. package/dist/chunk-BZTTQS4A.mjs +0 -7
  174. package/dist/chunk-EKVTLHBQ.js +0 -2
  175. package/dist/chunk-GMLNWS2N.mjs +0 -2
  176. package/dist/chunk-IBEKLDBY.mjs +0 -2
  177. package/dist/chunk-ILCNDOBU.js +0 -2
  178. package/dist/chunk-K3GMTMQ6.js +0 -2
  179. package/dist/chunk-L52PDW6O.mjs +0 -2
  180. package/dist/chunk-LI6WJ3LZ.js +0 -2
  181. package/dist/chunk-LXRXDTPI.js +0 -2
  182. package/dist/chunk-NW4A3JW6.mjs +0 -2
  183. package/dist/chunk-OITITR6K.mjs +0 -2
  184. package/dist/chunk-PDJGTQMY.mjs +0 -2
  185. package/dist/chunk-T44JQT2O.mjs +0 -2
  186. package/dist/chunk-TCJCE6WN.js +0 -2
  187. package/dist/chunk-VMJBW3EF.mjs +0 -2
  188. package/dist/chunk-WSHSHIIM.mjs +0 -2
  189. package/dist/chunk-WW3X3ELF.js +0 -2
  190. package/dist/chunk-XMYUYQH7.mjs +0 -72
  191. package/dist/chunk-ZNTMZ6NM.js +0 -7
  192. package/dist/chunk-ZU73VG3X.js +0 -2
package/README.md CHANGED
@@ -7,336 +7,311 @@
7
7
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.0%2B-3178C6.svg)](https://www.typescriptlang.org/)
8
8
  [![Bundle Size](https://img.shields.io/bundlephobia/minzip/@tantainnovative/ndpr-toolkit)](https://bundlephobia.com/package/@tantainnovative/ndpr-toolkit)
9
9
 
10
- Eight production-ready modules covering consent, data subject rights, DPIA, breach notification, privacy policies, lawful basis tracking, cross-border transfers, and ROPA -- everything a data controller or processor needs under the NDPA.
10
+ v3 ships **zero-config presets**, **pluggable storage adapters**, **compound components**, and a **compliance score engine** — eight production-ready modules covering consent, data subject rights, DPIA, breach notification, privacy policies, lawful basis, cross-border transfers, and ROPA.
11
11
 
12
12
  **[Documentation](https://ndprtoolkit.com.ng)** | **[Live Demos](https://ndprtoolkit.com.ng/ndpr-demos)** | **[npm](https://www.npmjs.com/package/@tantainnovative/ndpr-toolkit)**
13
13
 
14
14
  ---
15
15
 
16
- ## Install
16
+ ## The 3-File Quickstart
17
17
 
18
- ```bash
19
- pnpm add @tantainnovative/ndpr-toolkit
20
- ```
18
+ Three files. Full NDPA consent compliance.
21
19
 
22
- ---
23
-
24
- ## Choose Your Import Style
25
-
26
- v2.0 ships modular entry points. Pick the layer you need -- the rest stays out of your bundle.
20
+ **`app/layout.tsx`**
21
+ ```tsx
22
+ import { NDPRConsent } from '@tantainnovative/ndpr-toolkit/presets';
23
+
24
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
25
+ return (
26
+ <html>
27
+ <body>
28
+ {children}
29
+ <NDPRConsent />
30
+ </body>
31
+ </html>
32
+ );
33
+ }
34
+ ```
27
35
 
28
- ### Lightweight (zero UI dependencies)
36
+ **`app/api/consent/route.ts`**
37
+ ```ts
38
+ import { NextRequest, NextResponse } from 'next/server';
29
39
 
30
- Types, validators, and utility functions. Works in any JS/TS environment -- Node, Deno, edge functions, or the browser.
40
+ let store: unknown = null;
31
41
 
32
- ```typescript
33
- import { validateConsent, getLawfulBasisDescription } from '@tantainnovative/ndpr-toolkit/core';
42
+ export async function GET() { return NextResponse.json(store ?? {}); }
43
+ export async function POST(req: NextRequest) {
44
+ store = await req.json();
45
+ return NextResponse.json({ ok: true });
46
+ }
34
47
  ```
35
48
 
36
- ### React Hooks
37
-
38
- Stateful hooks for every module. Requires `react` only -- no Radix, no Tailwind.
49
+ **Persist to your API instead of localStorage:**
50
+ ```tsx
51
+ import { NDPRConsent } from '@tantainnovative/ndpr-toolkit/presets';
52
+ import { apiAdapter } from '@tantainnovative/ndpr-toolkit/adapters';
39
53
 
40
- ```typescript
41
- import { useConsent, useLawfulBasis } from '@tantainnovative/ndpr-toolkit/hooks';
54
+ <NDPRConsent adapter={apiAdapter('/api/consent')} />
42
55
  ```
43
56
 
44
- ### Full UI Components
57
+ That's it. NDPA-compliant consent with server-side persistence in under 20 lines.
45
58
 
46
- Pre-built, styled components. Requires Tailwind CSS plus a handful of Radix primitives.
59
+ ---
47
60
 
48
- ```typescript
49
- import { ConsentBanner, LawfulBasisTracker } from '@tantainnovative/ndpr-toolkit';
61
+ ## Install
62
+
63
+ ```bash
64
+ pnpm add @tantainnovative/ndpr-toolkit
50
65
  ```
51
66
 
52
- Install the UI peer dependencies:
67
+ Install UI peer dependencies (only needed for styled components):
53
68
 
54
69
  ```bash
55
70
  pnpm add @radix-ui/react-switch @radix-ui/react-tabs @radix-ui/react-label @radix-ui/react-slot lucide-react tailwind-merge clsx class-variance-authority
56
71
  ```
57
72
 
58
- ### Per-Module Imports
73
+ Or scaffold instantly with the CLI:
59
74
 
60
- Need just one module? Import it directly to keep your bundle minimal.
61
-
62
- ```typescript
63
- import { ConsentBanner, useConsent } from '@tantainnovative/ndpr-toolkit/consent';
64
- import { BreachReportForm, useBreach } from '@tantainnovative/ndpr-toolkit/breach';
75
+ ```bash
76
+ npx @tantainnovative/create-ndpr
65
77
  ```
66
78
 
67
79
  ---
68
80
 
69
- ## Quick Start
70
-
71
- A consent banner in under 10 lines:
81
+ ## Choose Your Layer
72
82
 
73
- ```tsx
74
- import { useConsent } from '@tantainnovative/ndpr-toolkit/hooks';
75
-
76
- function App() {
77
- const { hasConsent, acceptAll, rejectAll, shouldShowBanner } = useConsent({
78
- options: [
79
- { id: 'essential', label: 'Essential', description: 'Required for the site to function', required: true, purpose: 'Site operation' },
80
- { id: 'analytics', label: 'Analytics', description: 'Help us improve', required: false, purpose: 'Usage analytics' },
81
- ],
82
- });
83
-
84
- if (shouldShowBanner) {
85
- return (
86
- <div>
87
- <p>We use cookies to improve your experience.</p>
88
- <button onClick={acceptAll}>Accept All</button>
89
- <button onClick={rejectAll}>Reject Optional</button>
90
- </div>
91
- );
92
- }
93
-
94
- return <main>{hasConsent('analytics') && <AnalyticsScript />}</main>;
95
- }
96
- ```
97
-
98
- ---
83
+ Pick exactly what your project needs.
99
84
 
100
- ## Styling & Customization
85
+ ### Presets zero-config
101
86
 
102
- Every component supports three styling modes:
103
-
104
- **Default (Tailwind CSS built-in):**
87
+ Drop-in components with sensible defaults. No configuration required.
105
88
 
106
89
  ```tsx
107
- <ConsentBanner options={options} onSave={handleSave} />
90
+ import {
91
+ NDPRConsent, // Consent banner — works with zero props
92
+ NDPRSubjectRights, // DSR request form
93
+ NDPRBreachReport, // Breach report form
94
+ NDPRPrivacyPolicy, // Policy generator wizard
95
+ NDPRDPIA, // DPIA questionnaire
96
+ NDPRComplianceDashboard, // Visual compliance dashboard
97
+ } from '@tantainnovative/ndpr-toolkit/presets';
108
98
  ```
109
99
 
110
- **Override specific sections:**
100
+ ### Components — compound pattern
111
101
 
112
- ```tsx
113
- import { ConsentBanner } from '@tantainnovative/ndpr-toolkit/consent';
102
+ Full control over layout without rebuilding logic.
114
103
 
115
- <ConsentBanner
116
- options={options}
117
- onSave={handleSave}
118
- classNames={{
119
- root: "fixed bottom-0 inset-x-0 bg-white shadow-xl p-6 z-50",
120
- title: "text-xl font-serif text-gray-900",
121
- acceptButton: "bg-green-600 text-white px-6 py-2 rounded-full",
122
- rejectButton: "border border-gray-300 px-6 py-2 rounded-full",
123
- }}
124
- />
104
+ ```tsx
105
+ import { Consent } from '@tantainnovative/ndpr-toolkit/consent';
106
+
107
+ <Consent.Provider options={options} onSave={handleSave}>
108
+ <div className="my-layout">
109
+ <Consent.OptionList />
110
+ <div className="flex gap-2">
111
+ <Consent.AcceptButton />
112
+ <Consent.RejectButton />
113
+ </div>
114
+ </div>
115
+ </Consent.Provider>
125
116
  ```
126
117
 
127
- **Fully unstyled (BYO CSS -- works with Bootstrap, CSS Modules, vanilla CSS):**
118
+ ### Hooks headless
119
+
120
+ Stateful hooks for every module. Bring your own UI entirely.
128
121
 
129
122
  ```tsx
130
- <ConsentBanner
131
- options={options}
132
- onSave={handleSave}
133
- unstyled
134
- classNames={{
135
- root: "my-consent-banner",
136
- acceptButton: "btn btn-primary",
137
- rejectButton: "btn btn-outline-secondary",
138
- }}
139
- />
140
- ```
123
+ import { useConsent } from '@tantainnovative/ndpr-toolkit/hooks';
141
124
 
142
- ### classNames Reference
143
-
144
- | Component | Keys | All classNames |
145
- |-----------|------|----------------|
146
- | ConsentBanner | 14 | root, container, title, description, optionsList, optionItem, optionCheckbox, optionLabel, optionDescription, buttonGroup, acceptButton, rejectButton, customizeButton, saveButton |
147
- | ConsentManager | 9 | root, header, title, description, optionsList, optionItem, toggle, saveButton, resetButton |
148
- | ConsentStorage | 1 | root |
149
- | DSRRequestForm | 11 | root, title, description, form, fieldGroup, label, input, select, textarea, submitButton, successMessage |
150
- | DSRDashboard | 8 | root, header, title, filters, requestList, requestItem, statusBadge, detailPanel |
151
- | DSRTracker | 9 | root, header, title, stats, statCard, table, tableHeader, tableRow, statusBadge |
152
- | DPIAQuestionnaire | 15 | root, header, title, section, sectionTitle, question, questionText, guidance, input, radioGroup, radioOption, navigation, nextButton, prevButton, progressBar |
153
- | DPIAReport | 10 | root, header, title, summary, riskBadge, riskTable, riskRow, recommendation, conclusion, printButton |
154
- | StepIndicator | 7 | root, step, stepActive, stepCompleted, stepPending, connector, label |
155
- | BreachReportForm | 10 | root, title, form, fieldGroup, label, input, select, textarea, submitButton, notice |
156
- | BreachRiskAssessment | 8 | root, header, title, slider, riskBadge, riskScore, notificationStatus, submitButton |
157
- | BreachNotificationManager | 9 | root, header, title, breachList, breachItem, statusBadge, timeline, timelineStep, detailPanel |
158
- | RegulatoryReportGenerator | 9 | root, header, title, reportPreview, field, fieldLabel, fieldValue, generateButton, downloadButton |
159
- | PolicyGenerator | 10 | root, header, title, description, sectionList, sectionItem, form, input, generateButton, complianceNotice |
160
- | PolicyPreview | 9 | root, header, title, description, content, section, sectionTitle, sectionContent, complianceNotice |
161
- | PolicyExporter | 9 | root, header, title, description, formatSelector, formatOption, exportButton, complianceNotice, preview |
162
- | LawfulBasisTracker | 15 | root, header, title, summary, summaryCard, table, tableHeader, tableRow, form, input, select, submitButton, statusBadge, complianceScore, gapAlert |
163
- | CrossBorderTransferManager | 15 | root, header, title, summary, summaryCard, transferList, transferItem, form, input, select, submitButton, riskBadge, statusBadge, detailPanel, approvalStatus |
164
- | ROPAManager | 16 | root, header, title, orgInfo, summary, summaryCard, table, tableHeader, tableRow, form, input, select, submitButton, statusBadge, exportButton, complianceGap |
165
- | **All 19 components** | **169** | |
166
-
167
- Every component follows the same pattern. Pass `classNames` to override specific sections, or set `unstyled` to strip all default styles. Each component exports its ClassNames TypeScript interface for autocomplete support.
125
+ const { hasConsent, acceptAll, rejectAll, shouldShowBanner } = useConsent({ options });
126
+ ```
168
127
 
169
- ---
128
+ ### Core — no React
170
129
 
171
- ## Modules
130
+ Pure TypeScript utilities and validators. Works anywhere — Node, edge functions, Deno.
172
131
 
173
- ### 1. Consent Management
132
+ ```ts
133
+ import { validateConsent, getComplianceScore } from '@tantainnovative/ndpr-toolkit/core';
134
+ ```
174
135
 
175
- **NDPA Sections 25-26** -- Freely given, specific, informed, and unambiguous consent.
136
+ ### Adapters pluggable storage
176
137
 
177
- ```typescript
178
- import { ConsentBanner, ConsentManager, useConsent, validateConsent } from '@tantainnovative/ndpr-toolkit/consent';
179
- ```
138
+ Swap where consent (and other state) is stored without changing any component code.
180
139
 
181
- ```tsx
182
- <ConsentManager
183
- options={[
184
- { id: 'essential', label: 'Essential', description: 'Required for the site to function', required: true, purpose: 'Site operation' },
185
- { id: 'analytics', label: 'Analytics', description: 'Help us improve', required: false, purpose: 'Usage analytics' },
186
- ]}
187
- onSave={(settings) => {
188
- if (settings.consents.analytics) loadAnalytics();
189
- }}
190
- />
140
+ ```ts
141
+ import { apiAdapter, localStorageAdapter, cookieAdapter } from '@tantainnovative/ndpr-toolkit/adapters';
191
142
  ```
192
143
 
193
- **Key exports:** `ConsentBanner`, `ConsentManager`, `ConsentStorage`, `useConsent`, `validateConsent`, `validateConsentOptions`
194
-
195
144
  ---
196
145
 
197
- ### 2. Data Subject Rights (DSR)
146
+ ## Pluggable Storage
198
147
 
199
- **NDPA Part IV, Sections 29-36** -- All 8 rights: information, access, rectification, erasure, restriction, portability, objection, and automated decision-making.
148
+ Every stateful component accepts an `adapter` prop. Built-in adapters ship out of the box.
200
149
 
201
- ```typescript
202
- import { DSRRequestForm, DSRDashboard, useDSR, formatDSRRequest } from '@tantainnovative/ndpr-toolkit/dsr';
150
+ ```ts
151
+ import {
152
+ localStorageAdapter, // default for browsers
153
+ sessionStorageAdapter, // cleared on tab close
154
+ cookieAdapter, // server-readable cookies
155
+ apiAdapter, // HTTP endpoint (any backend)
156
+ memoryAdapter, // in-process, good for SSR / tests
157
+ composeAdapters, // fan-out writes to multiple stores
158
+ } from '@tantainnovative/ndpr-toolkit/adapters';
203
159
  ```
204
160
 
161
+ **localStorage (default browser behaviour):**
205
162
  ```tsx
206
- const { submitRequest, requests } = useDSR({
207
- requestTypes: [
208
- { id: 'access', name: 'Access Request', description: 'Right of access (Section 30)', estimatedCompletionTime: 30, requiresAdditionalInfo: false },
209
- ],
210
- });
163
+ <NDPRConsent adapter={localStorageAdapter('ndpr_consent')} />
211
164
  ```
212
165
 
213
- **Key exports:** `DSRRequestForm`, `DSRDashboard`, `DSRTracker`, `useDSR`, `formatDSRRequest`
214
-
215
- ---
216
-
217
- ### 3. Data Protection Impact Assessment (DPIA)
166
+ **API endpoint:**
167
+ ```tsx
168
+ <NDPRConsent adapter={apiAdapter('/api/consent', {
169
+ headers: { Authorization: `Bearer ${token}` },
170
+ })} />
171
+ ```
218
172
 
219
- **NDPA Section 38-39** -- Mandatory risk assessment for high-risk processing activities.
173
+ **Write to API + keep a local cache:**
174
+ ```tsx
175
+ import { composeAdapters, apiAdapter, localStorageAdapter } from '@tantainnovative/ndpr-toolkit/adapters';
220
176
 
221
- ```typescript
222
- import { DPIAQuestionnaire, DPIAReport, useDPIA, assessDPIARisk } from '@tantainnovative/ndpr-toolkit/dpia';
177
+ <NDPRConsent adapter={composeAdapters(
178
+ apiAdapter('/api/consent'),
179
+ localStorageAdapter('ndpr_consent'),
180
+ )} />
223
181
  ```
224
182
 
183
+ **Cookie (server-readable, for SSR consent gating):**
225
184
  ```tsx
226
- const { currentSection, answers, nextSection, completeDPIA } = useDPIA({
227
- sections: dpiaSections,
228
- onComplete: (result) => saveAssessment(result),
229
- });
185
+ <NDPRConsent adapter={cookieAdapter({ name: 'ndpr_consent', maxAge: 365 * 24 * 60 * 60 })} />
230
186
  ```
231
187
 
232
- **Key exports:** `DPIAQuestionnaire`, `DPIAReport`, `StepIndicator`, `useDPIA`, `assessDPIARisk`
233
-
234
188
  ---
235
189
 
236
- ### 4. Breach Notification
237
-
238
- **NDPA Section 40** -- 72-hour notification to the NDPC, plus data subject notification.
190
+ ## Compliance Score
191
+
192
+ `getComplianceScore()` evaluates your posture across all 8 NDPA modules and returns a 0–100 score with rated gaps and prioritised recommendations.
193
+
194
+ ```ts
195
+ import { getComplianceScore } from '@tantainnovative/ndpr-toolkit/core';
196
+
197
+ const report = getComplianceScore({
198
+ consent: {
199
+ hasConsentMechanism: true,
200
+ hasPurposeSpecification: true,
201
+ hasWithdrawalMechanism: true,
202
+ hasMinorProtection: false,
203
+ consentRecordsRetained: true,
204
+ },
205
+ dsr: {
206
+ hasRequestMechanism: true,
207
+ supportsAccess: true,
208
+ supportsRectification: false,
209
+ supportsErasure: false,
210
+ supportsPortability: false,
211
+ supportsObjection: false,
212
+ maxResponseDays: 30,
213
+ },
214
+ // ... other modules
215
+ });
239
216
 
240
- ```typescript
241
- import { BreachReportForm, BreachNotificationManager, useBreach, calculateBreachSeverity } from '@tantainnovative/ndpr-toolkit/breach';
217
+ console.log(report.score); // e.g. 74
218
+ console.log(report.rating); // "good" | "excellent" | "needs-work" | "critical"
219
+ console.log(report.recommendations[0].priority); // "critical"
242
220
  ```
243
221
 
222
+ Render a live dashboard:
223
+
244
224
  ```tsx
245
- const { reportBreach, reports, assessRisk } = useBreach({
246
- categories: breachCategories,
247
- onReport: (report) => notifyNDPC(report),
248
- });
249
- ```
225
+ import { NDPRComplianceDashboard } from '@tantainnovative/ndpr-toolkit/presets';
250
226
 
251
- **Key exports:** `BreachReportForm`, `BreachRiskAssessment`, `BreachNotificationManager`, `RegulatoryReportGenerator`, `useBreach`, `calculateBreachSeverity`
227
+ <NDPRComplianceDashboard
228
+ input={complianceInput}
229
+ showRecommendations
230
+ maxRecommendations={5}
231
+ />
232
+ ```
252
233
 
253
234
  ---
254
235
 
255
- ### 5. Privacy Policy Generator
236
+ ## Backend Integration
256
237
 
257
- **NDPA Sections 27-28** -- Multi-step wizard producing NDPA-compliant privacy policies with PDF/DOCX export.
238
+ ### CLI scaffolder
258
239
 
259
- ```typescript
260
- import { PolicyGenerator, PolicyPreview, usePrivacyPolicy, generatePolicyText } from '@tantainnovative/ndpr-toolkit/policy';
261
- ```
240
+ Scaffold a complete wiring for your stack in seconds:
262
241
 
263
- ```tsx
264
- <PolicyGenerator
265
- sections={policySections}
266
- variables={policyVariables}
267
- onGenerate={({ content }) => console.log(content)}
268
- />
242
+ ```bash
243
+ npx @tantainnovative/create-ndpr
269
244
  ```
270
245
 
271
- The wizard covers organization info, data collection practices, data sharing, custom sections, and a preview with export.
246
+ Detects Next.js (App Router or Pages Router) or Express, prompts for your ORM (Prisma / Drizzle / none), and generates API routes, schema, and layout files no manual copy-pasting.
272
247
 
273
- **Key exports:** `PolicyGenerator`, `PolicyPreview`, `PolicyExporter`, `usePrivacyPolicy`, `generatePolicyText`
248
+ ### Backend recipes
274
249
 
275
- ---
250
+ `@tantainnovative/ndpr-recipes` is a reference implementation with production-ready patterns:
276
251
 
277
- ### 6. Lawful Basis Tracker
252
+ | Recipe | What you get |
253
+ |--------|-------------|
254
+ | `prisma/schema.prisma` | All 5 NDPA compliance tables |
255
+ | `src/adapters/prisma-consent.ts` | Prisma `StorageAdapter<ConsentSettings>` |
256
+ | `src/adapters/drizzle-consent.ts` | Drizzle `StorageAdapter<ConsentSettings>` |
257
+ | `src/nextjs/app-router/` | Consent, DSR, Breach, ROPA, compliance route handlers |
258
+ | `src/express/` | Full NDPR router with consent, DSR, breach, ROPA routes |
259
+ | `src/nextjs/app-router/middleware.ts` | Next.js consent gate middleware |
278
260
 
279
- **NDPA Section 25** -- Document and manage the lawful basis for every processing activity. Covers all six bases: consent, contract, legal obligation, vital interests, public interest, and legitimate interests.
261
+ Copy the files you need into your project. [Browse the recipes →](https://github.com/tantainnovative/ndpr-toolkit/tree/main/packages/ndpr-recipes)
280
262
 
281
- ```typescript
282
- import { LawfulBasisTracker, useLawfulBasis, validateProcessingActivity, getLawfulBasisDescription } from '@tantainnovative/ndpr-toolkit/lawful-basis';
283
- ```
263
+ ---
284
264
 
285
- ```tsx
286
- const { activities, addActivity, getSummary } = useLawfulBasis();
287
-
288
- addActivity({
289
- name: 'Email marketing',
290
- description: 'Send promotional emails',
291
- lawfulBasis: 'consent',
292
- lawfulBasisJustification: 'Explicit opt-in at signup',
293
- dataCategories: ['email', 'name'],
294
- involvesSensitiveData: false,
295
- dataSubjectCategories: ['customers'],
296
- purposes: ['marketing'],
297
- retentionPeriod: '2 years',
298
- crossBorderTransfer: false,
299
- status: 'active',
300
- });
301
- ```
265
+ ## All 8 Modules
302
266
 
303
- **Key exports:** `LawfulBasisTracker`, `useLawfulBasis`, `validateProcessingActivity`, `getLawfulBasisDescription`, `assessComplianceGaps`, `generateLawfulBasisSummary`
267
+ | Module | Import path | NDPA reference | Key exports |
268
+ |--------|-------------|----------------|-------------|
269
+ | Consent Management | `/consent` | Sections 25–26 | `ConsentBanner`, `ConsentManager`, `Consent.*`, `useConsent` |
270
+ | Data Subject Rights | `/dsr` | Part IV §29–36 | `DSRRequestForm`, `DSRDashboard`, `useDSR` |
271
+ | DPIA | `/dpia` | Sections 38–39 | `DPIAQuestionnaire`, `DPIAReport`, `useDPIA` |
272
+ | Breach Notification | `/breach` | Section 40 | `BreachReportForm`, `BreachRiskAssessment`, `useBreach` |
273
+ | Privacy Policy | `/policy` | Sections 27–28 | `PolicyGenerator`, `PolicyPreview`, `PolicyExporter` |
274
+ | Lawful Basis | `/lawful-basis` | Section 25 | `LawfulBasisTracker`, `useLawfulBasis` |
275
+ | Cross-Border Transfers | `/cross-border` | Part VI §41–45 | `CrossBorderTransferManager`, `useCrossBorderTransfer` |
276
+ | ROPA | `/ropa` | Section 28(2) | `ROPAManager`, `useROPA`, `exportROPAToCSV` |
304
277
 
305
278
  ---
306
279
 
307
- ### 7. Cross-Border Transfer Assessment
308
-
309
- **NDPA Part VI, Sections 41-45** -- Evaluate adequacy decisions, standard contractual clauses, binding corporate rules, and derogations for international data transfers.
280
+ ## Styling & Customization
310
281
 
311
- ```typescript
312
- import { CrossBorderTransferManager, useCrossBorderTransfer, validateTransfer, assessTransferRisk } from '@tantainnovative/ndpr-toolkit/cross-border';
313
- ```
282
+ Every component supports three modes:
314
283
 
284
+ **Default (Tailwind CSS):**
315
285
  ```tsx
316
- const { transfers, addTransfer, getSummary } = useCrossBorderTransfer({
317
- onAdd: (transfer) => logTransfer(transfer),
318
- });
286
+ <ConsentBanner options={options} onSave={handleSave} />
319
287
  ```
320
288
 
321
- **Key exports:** `CrossBorderTransferManager`, `useCrossBorderTransfer`, `validateTransfer`, `getTransferMechanismDescription`, `assessTransferRisk`, `isNDPCApprovalRequired`
322
-
323
- ---
324
-
325
- ### 8. Record of Processing Activities (ROPA)
326
-
327
- **NDPA Section 28(2) & NDPC Regulatory Guidance** -- Maintain comprehensive records of all processing activities for audit readiness and regulatory accountability.
328
-
329
- ```typescript
330
- import { ROPAManager, useROPA, generateROPASummary, exportROPAToCSV } from '@tantainnovative/ndpr-toolkit/ropa';
289
+ **Override specific sections:**
290
+ ```tsx
291
+ <ConsentBanner
292
+ options={options}
293
+ onSave={handleSave}
294
+ classNames={{
295
+ root: "fixed bottom-0 inset-x-0 bg-white shadow-xl p-6",
296
+ acceptButton: "bg-green-600 text-white px-6 py-2 rounded-full",
297
+ }}
298
+ />
331
299
  ```
332
300
 
301
+ **Fully unstyled (BYO CSS — Bootstrap, CSS Modules, vanilla):**
333
302
  ```tsx
334
- const { ropa, addRecord, getSummary } = useROPA({
335
- initialData: { id: 'ropa-1', organizationName: 'Acme Ltd', organizationContact: 'dpo@acme.ng', organizationAddress: 'Lagos, Nigeria', records: [], lastUpdated: Date.now(), version: '1.0' },
336
- });
303
+ <ConsentBanner
304
+ options={options}
305
+ onSave={handleSave}
306
+ unstyled
307
+ classNames={{
308
+ root: "my-consent-banner",
309
+ acceptButton: "btn btn-primary",
310
+ }}
311
+ />
337
312
  ```
338
313
 
339
- **Key exports:** `ROPAManager`, `useROPA`, `validateProcessingRecord`, `generateROPASummary`, `exportROPAToCSV`, `identifyComplianceGaps`
314
+ Each component exports its `ClassNames` TypeScript interface for autocomplete. Full reference in the [docs](https://ndprtoolkit.com.ng/docs/styling).
340
315
 
341
316
  ---
342
317
 
@@ -344,18 +319,20 @@ const { ropa, addRecord, getSummary } = useROPA({
344
319
 
345
320
  | Path | What you get | Dependencies |
346
321
  |------|-------------|--------------|
322
+ | `.` (default) | Everything | All peer deps |
347
323
  | `/core` | Types + utility functions | `tslib` |
348
324
  | `/hooks` | React hooks for all 8 modules | `react` |
349
- | `/consent` | Consent components + hook + utils | `react`, Radix, Tailwind |
350
- | `/dsr` | DSR components + hook + utils | `react`, Radix, Tailwind |
351
- | `/dpia` | DPIA components + hook + utils | `react`, Radix, Tailwind |
352
- | `/breach` | Breach components + hook + utils | `react`, Radix, Tailwind |
353
- | `/policy` | Policy components + hook + utils | `react`, Radix, Tailwind, `jspdf` |
354
- | `/lawful-basis` | Lawful basis component + hook + utils | `react`, Radix, Tailwind |
355
- | `/cross-border` | Cross-border component + hook + utils | `react`, Radix, Tailwind |
356
- | `/ropa` | ROPA component + hook + utils | `react`, Radix, Tailwind |
325
+ | `/presets` | Zero-config preset components | `react`, Radix, Tailwind |
326
+ | `/adapters` | Storage adapters | none |
327
+ | `/consent` | Consent components + `Consent.*` compound API | `react`, Radix, Tailwind |
328
+ | `/dsr` | DSR components + hook | `react`, Radix, Tailwind |
329
+ | `/dpia` | DPIA components + hook | `react`, Radix, Tailwind |
330
+ | `/breach` | Breach components + hook | `react`, Radix, Tailwind |
331
+ | `/policy` | Policy components + hook | `react`, Radix, Tailwind, `jspdf` |
332
+ | `/lawful-basis` | Lawful basis component + hook | `react`, Radix, Tailwind |
333
+ | `/cross-border` | Cross-border component + hook | `react`, Radix, Tailwind |
334
+ | `/ropa` | ROPA component + hook | `react`, Radix, Tailwind |
357
335
  | `/unstyled` | Unstyled consent primitives | `react` |
358
- | `.` (default) | Everything | All peer deps |
359
336
 
360
337
  ---
361
338
 
@@ -367,7 +344,6 @@ The **Nigeria Data Protection Act (NDPA) 2023** replaced the NDPR 2019 and estab
367
344
  |--------|-------------|-------------|
368
345
  | Legal status | NITDA regulation | Act of the National Assembly |
369
346
  | Regulator | NITDA | NDPC (independent commission) |
370
- | Scope | Organizations processing data in Nigeria | Broader territorial + extraterritorial application |
371
347
  | Enforcement | Limited | Independent investigation and penalty powers |
372
348
  | Data subject rights | 6 rights | 8 rights (added information + automated decision-making) |
373
349
  | Cross-border transfers | Basic provisions | Comprehensive framework with adequacy decisions |
@@ -378,26 +354,30 @@ The **Nigeria Data Protection Act (NDPA) 2023** replaced the NDPR 2019 and estab
378
354
 
379
355
  ## TypeScript
380
356
 
381
- The toolkit is written in TypeScript and exports all types:
357
+ Written in TypeScript. All types are exported:
382
358
 
383
359
  ```typescript
384
360
  import type {
385
361
  // Consent
386
- ConsentOption, ConsentSettings, LawfulBasisType,
362
+ ConsentOption, ConsentSettings,
387
363
  // DSR
388
- DSRRequest, DSRType, DSRStatus, RequestType,
364
+ DSRRequest, DSRType, DSRStatus,
389
365
  // DPIA
390
- DPIAQuestion, DPIASection, DPIAResult, DPIARisk,
366
+ DPIAQuestion, DPIASection, DPIAResult,
391
367
  // Breach
392
368
  BreachReport, BreachCategory, RiskAssessment,
393
369
  // Policy
394
- PolicySection, PolicyTemplate, OrganizationInfo, PrivacyPolicy,
370
+ PolicySection, PolicyTemplate, PrivacyPolicy,
395
371
  // Lawful Basis
396
- LawfulBasis, ProcessingActivity, LawfulBasisSummary,
372
+ LawfulBasis, ProcessingActivity,
397
373
  // Cross-Border
398
- CrossBorderTransfer, TransferMechanism, AdequacyStatus,
374
+ CrossBorderTransfer, TransferMechanism,
399
375
  // ROPA
400
- ProcessingRecord, RecordOfProcessingActivities, ROPASummary,
376
+ ProcessingRecord, RecordOfProcessingActivities,
377
+ // Compliance score
378
+ ComplianceInput, ComplianceReport, ComplianceRating,
379
+ // Storage
380
+ StorageAdapter,
401
381
  } from '@tantainnovative/ndpr-toolkit/core';
402
382
  ```
403
383