npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@truconsent/consent-notice

v0.0.41

Published

React consent-notice components (in-page & modal)

Readme

@truconsent/consent-notice

React components for embedding truConsent consent banners and the Data Principal Rights Center into any web application.

Current version: 0.0.41


Changelog

0.0.41

  • Fixed Reject All incorrectly triggering the H-Case "Consent Required" warning popup whenever any mandatory purpose was configured (the common case) — rejectAll() built a synthetic all-declined purposes array and ran it through the same mandatory-decline intercept savePreferences/"I Consent" uses, which always found the mandatory purpose "declined" in that array and blocked the action. Reject All is a deliberate, explicit decline of everything (mandatory included); it no longer runs through the intercept at all
  • Fixed HCaseWarningPopup (the "Consent Required" popup) rendering with fixed white background, black title, and grey message text regardless of the notice's configured theme — now falls back to the same --banner-bg/--banner-text/--banner-text-muted/--banner-button-color/--banner-button-text-color/--banner-hover-bg CSS variables the rest of the modal already uses, so it always matches the configured background/text/button colors. Admin-configured h_case_* color overrides still take priority when set
  • Fixed the same popup's proceed button silently using the modal's Background Color as its own background whenever h_case_proceed_button_color wasn't explicitly configured — the fallback chain read primaryColor (which resolves to Background Color, not Button Color, despite the prop's name) before ever reaching the Button Color CSS variable; reordered so Button Color wins
  • Fixed the Tabbed Notice's Next/Ok button always using white text regardless of the configured Button Text Color — the button's background correctly read Button Color, but its text color was hardcoded via CSS (.tru-btn-primary { color: #fff; }) and never read buttonTextColor, unlike every other action button

0.0.40

  • Rights Center: nominee verification before a submitted/updated nominee is treated as active — OTP (via the backend's /nominee/{id}/send-otp + /verify-otp, MSG91) with DigiLocker shown as a disabled "Coming Soon" option. A nominee stays in a "Not verified yet" state with a Verify Now action until OTP verification succeeds
  • Fixed the nominee verify modal not rendering (hooks declaration-order bug), only appearing while the Grievance tab was active (should be visible regardless of active tab), and losing the widget's --banner-* theme variables when rendered via a document.body portal — now renders inline so it inherits the scoped theme
  • Resized the modal (560px → 460px max-width) and stopped leaking internal request paths/HTTP status codes in error messages

0.0.39

  • Increased the General Notice header's logo (ModernBannerHeader.jsx) from h-7 (28px) to h-10 (40px) — too small to clearly identify the brand at the previous size, per user report on the "Consent by Mars Money" banner. Kept w-auto so non-square logos aren't distorted

0.0.38

  • Fixed I Consent staying enabled (and clickable) even when the user switched a Necessary/mandatory purpose's toggle off. Necessary toggles stay interactive by design — the user can still switch one off — but doing so must disable the "I Consent" action itself; only Reject All / Only Necessary remain available at that point, matching the existing H-Case warning popup's own definition of "mandatory purpose declined"

0.0.37

  • Fixed I Consent being disabled whenever every optional purpose was declined, requiring at least one optional acceptance on top of the normal scroll-gating — Reject All and Only Necessary never had this extra requirement. Optional purposes are the user's free choice to accept or decline; Only Necessary already exists as the dedicated "decline everything optional" action, so gating I Consent on an optional acceptance just made it redundant with Only Necessary and confusingly disabled in the all-declined state
  • Fixed the Tabbed Notice's Informational/Consent tab Next/Ok button using Background Color (primaryColor) for its own background — every other action button already used the configured Button Color; this one alone used the modal's background color instead, giving it no real background in most themes
  • Fixed the Tabbed Notice's Consent tab purpose groups rendering in Necessary → Optional → Profile Based order — now Necessary → Profile Based → Optional, matching the configured display priority

0.0.36

  • Changed the Tabbed Notice's active tab label and underline to use Primary Text Color (--banner-text) instead of Button Color — this partially reverses 0.0.32's change (Button Color was picked there to fix a different case where the tab was invisible against a matching background). Button Color is chosen for contrast against a button's own background, not the banner's background, so a light banner paired with a bright accent Button Color (e.g. lime green on white) read as low-contrast for body text. Primary Text Color is guaranteed legible against the banner's own background by definition. This exact change is now the reference truKIT-react-native and truKIT-flutter-sdk mirror

0.0.35

  • Fixed the General Notice's purpose-card toggle switch rendering the wrong track/thumb colors (a fixed dark "success" green track, --banner-bg thumb) whenever the Cookie Banner's CSS was also loaded on the same page. Both widgets' toggles used the same generic .switch/.track/.thumb class names, but TruCookieConsent's Cookie Banner styling (.switch input:checked+.track, specificity 0,3,1) is more specific than the General Notice's own rule (input:checked+.track, 0,2,1) and silently won regardless of which widget was actually on screen — any site loading both consent-modal.css and banner-styles.css together (the normal case) was affected. Renamed the General Notice's toggle classes to .tru-switch/.tru-track/.tru-thumb across ModernPurposeCard.jsx, CompactListUI.jsx, SplitPaneUI.jsx, and InlineSingleRowUI.jsx to remove the collision entirely
  • Fixed the Tabbed Notice's tab buttons showing the browser's raw default focus ring (a solid blue rounded outline in Chrome/Edge, unrelated to the widget's theme) on click/focus, which looked like a stray highlight box obscuring the tab label — replaced with a theme-colored :focus-visible outline

0.0.34

  • Fixed TruConsentModal's styleVars never setting --banner-border/--banner-hover-bg at all — every purpose card border and the header/footer wrapper background fell through to variables.css's fixed light-theme preset (#e5e7eb) regardless of configuration, showing as a bright near-white border on any dark-configured banner. Both now derive from the configured Primary Text Color, matching the pattern already used in TruCookieConsent.jsx
  • Fixed the "Necessary" badge never appearing on a mandatory purpose card in BannerUI.jsx (never passed showNecessaryTag at all) and only appearing for the narrower isDynamic && isMandatory condition in TabbedBannerUI.jsx — any genuinely mandatory but non-dynamic purpose showed no indication at all that it was required. Both (and PreferencesModalUI.jsx, which had the same gap) now show the badge for every mandatory purpose, matching truKIT-react-native/truKIT-flutter-sdk's existing isMandatory-only condition

0.0.33

  • Fixed the purpose-toggle switch's thumb (.thumb in the Notice, .rc-slider:before in the Rights Center, .tp-thumb in the Cookie Consent Manage Preferences panel) using the configured Primary Text Color instead of the Primary Button Text Color — the thumb sits on a colored track, not on the card's own background, so it needs to read against the button's text/background pairing, not the body text color. Also fixed .tp-thumb's unchecked (off) state still hardcoding #fff — its checked state already read the CSS var correctly, but the base rule never did, so the two states could visibly disagree
  • This exact corrected behavior (thumb = Primary Button Text Color, same whether on or off) is now the reference truKIT-react-native and truKIT-flutter-sdk mirror

0.0.32

  • Fixed TruConsentModal's card/close-button border (--banner-border) and TruCookieConsent's cookie banner + Manage Preferences panel border (--banner-border/--tp-border) never being derived from the configured theme — both fell through to a hardcoded light-theme gray that looked like a stray white border on a dark card; now derived from the configured secondary/body text color (matching RightCenter.jsx's existing hexToRgba(secondaryText, 0.45) pattern), also fixing --banner-hover-bg the same way
  • Fixed the tabbed Notice's active tab label always using the neutral text color instead of the configured Button Color — text and underline now both use the accent color together
  • Fixed the cookie consent Manage Preferences panel (#tp-modal) hardcoding a fixed system-font stack, ignoring the configured Font Type entirely
  • Fixed the Manage Preferences "Strictly Necessary" category card's left accent border hardcoding a fixed green (#10b981) instead of the configured Button Color, unlike every other (non-essential) category card, which already correctly used it
  • Fixed the Manage Preferences category toggle's thumb (inner circle) hardcoding white regardless of state — the track already correctly used the configured Button Color when on, but the thumb never reflected the configured Button Text Color
  • Added the missing side_panel General Notice template — selecting "Side Panel" in the admin's Templates picker previously silently rendered as Center Modal, since no component was ever registered for that key (the CSS positioning for the drawer-from-the-right-edge layout already existed and just needed a component to fill it)
  • Fixed the purpose-toggle switch (.thumb/.track in the Notice, .rc-slider/.rc-slider:before in the Rights Center) never actually using the configured Button Color for the "on" track or the configured Primary Text Color for the thumb — both were hardcoded (a fixed "success" green token for the Notice's on-track, literal white/hardcoded gray for the Rights Center's thumb/off-track) regardless of what's configured. The thumb is now the same color (Primary Text Color) whether on or off — only the track's color changes to signal state — and this exact behavior is now the reference truKIT-react-native and truKIT-flutter-sdk mirror

0.0.31

  • Fixed --banner-bg reading nonexistent backgroundColor/cardBackground fields (0.0.30 checked for fields that don't exist anywhere in the API response) — it now reads settings.primaryColor, the actual field the admin dashboard's "Background Color" setting maps to, so the configured background color renders instead of always falling through to the hardcoded white default

0.0.30

  • Fixed TruConsentModal not reading dashboard theme colors when the API returns a theme object instead of bannerSettings/banner_settings (added a bridging mapper so colors from the real API response are no longer silently dropped to JS defaults)
  • Fixed --banner-bg never being set from the configured background color, so BannerUI and other general_consent templates always rendered the CSS default background regardless of dashboard configuration

Install

npm install @truconsent/consent-notice

Components

<ConsentModal /> — Consent Banner

Renders the truConsent consent notice (banner/modal) for a given collection point.

import { ConsentModal } from '@truconsent/consent-notice';
import '@truconsent/consent-notice/dist/consent-modal.css';

<ConsentModal
  userId="user-uuid"
  apiKey={import.meta.env.VITE_TRU_CONSENT_API_KEY}
  organizationId={import.meta.env.VITE_TRU_CONSENT_ORGANIZATION_ID}
  apiUrl={import.meta.env.VITE_TRU_CONSENT_API_URL}
  assetId={import.meta.env.VITE_TRU_CONSENT_ASSET_ID}
  bannerId={import.meta.env.VITE_TRU_CONSENT_BANNER_ID}
/>

<RightCenter /> — Data Principal Rights Center

Pre-built UI for DPDPA data subject rights — consent management, data access/deletion requests, grievances, nominees, and DPO info.

Single asset

import { RightCenter } from '@truconsent/consent-notice';
import '@truconsent/consent-notice/dist/consent-modal.css';

<RightCenter
  userId="user-uuid"
  apiKey={import.meta.env.VITE_TRU_CONSENT_API_KEY}
  organizationId={import.meta.env.VITE_TRU_CONSENT_ORGANIZATION_ID}
  apiUrl={import.meta.env.VITE_TRU_CONSENT_API_URL}
  assetId={import.meta.env.VITE_TRU_CONSENT_ASSET_ID}
/>

Multiple assets via groupId

Use groupId to load consents from all assets in a group into one unified view:

<RightCenter
  userId="user-uuid"
  apiKey={import.meta.env.VITE_TRU_CONSENT_API_KEY}
  organizationId={import.meta.env.VITE_TRU_CONSENT_ORGANIZATION_ID}
  apiUrl={import.meta.env.VITE_TRU_CONSENT_API_URL}
  groupId={import.meta.env.VITE_TRU_CONSENT_GROUP_ID}
/>

Props

| Prop | Type | Required | Description | |---|---|---|---| | userId | string | ✅ | Authenticated user ID — must match the ID used when consent was recorded | | apiKey | string | ✅ | Consent-scope API key from the platform dashboard | | organizationId | string | ✅ | Org ID sent as X-Org-Id on every request | | apiUrl | string | ✅ | SDK base URL e.g. https://trukit-dev.truconsent.io | | assetId | string | one of | Asset UUID. Use for a single-asset setup | | groupId | string | one of | Asset group UUID. Loads consents across all assets in the group. Takes precedence over assetId | | authToken | string | — | Bearer token for JWT-authenticated tenants |

Pass at least one of assetId or groupId. When both are provided, groupId wins.

Consent card behaviour

  • Legitimate Interest purposes → Legitimate Interest badge (green) + Shown: Yes/No — no toggle
  • Mandatory purposes → Necessary badge (red) + Consented: Yes/No — no toggle
  • Optional purposes → no badge + Consented: Yes/No + toggle to withdraw/grant consent
  • Shown timestamp is sourced exclusively from the server consent log (shown_at) set when the banner was displayed to the user

Environment variables

VITE_TRU_CONSENT_API_KEY=your_api_key
VITE_TRU_CONSENT_ORGANIZATION_ID=your_org_id
VITE_TRU_CONSENT_API_URL=https://trukit-dev.truconsent.io
VITE_TRU_CONSENT_ASSET_ID=your_asset_uuid
VITE_TRU_CONSENT_GROUP_ID=your_group_uuid    # optional — for multi-asset Rights Center
VITE_TRU_CONSENT_BANNER_ID=your_banner_uuid  # for ConsentModal

Development

# Install dependencies
npm install

# Build the package
npm run build

# Run tests
npm test

Build outputs to dist/. CSS files are copied from src/styles/ directly.


Changelog

0.0.29

  • Fixed: Primary Text Color / Secondary Text Color had no visible effect on the Notice modal (<TruConsentModal />), across every template (Center Modal, Tabbed Banner, Notice Only). ModernBannerHeader.jsx/ModernPurposeCard.jsx/SplitPaneUI.jsx/etc. all read color: var(--banner-text) / var(--banner-text-muted) with no fallback default — but TruConsentModal.jsx's own root styleVars, and BannerUI.jsx's, TabbedBannerUI.jsx's, and NoticeOnlyBanner.jsx's own template-level styleVars, never actually set those two CSS variables anywhere, even though primaryTextColor/secondaryTextColor were already being fetched correctly from the API. With nothing in the cascade ever defining them, elements using them (tab labels, purpose titles/descriptions, category badges) fell back to the browser's own initial value instead of the configured color — this is what caused labels like the "Consent" tab and "OPTIONAL" badge to render unreadable against the modal's actual background. All four files now set --banner-text: primaryTextColor / --banner-text-muted: secondaryTextColor (falling back to #111827/#6b7280) alongside the primary/secondary color variables they already set.
  • Fixed: the active "Consent"/"Cookies" tab in the Tabbed Banner template (TabbedBannerUI.jsx) rendered its label and underline in var(--banner-primary-color), which for the Notice API is the Notice's Background Color field — on any asset with a light/near-white background color, the active tab's own text and underline were nearly invisible against the same-toned modal. consent-modal.css's .tru-tab-button[data-active] underline now uses var(--banner-button-color, var(--banner-primary-color)) (the actual accent color) as the active-state indicator, while the tab's text color stays var(--banner-text) — the same primary text color used by every other heading/label in the modal (e.g. the "Consent by [Organization Name]" title) — since an active tab is a label, not a button, and shouldn't switch to the button's accent color.

0.0.28

  • Fixed: on the Cookie Banner specifically, Button Text Color, Font Type, and Font Size never had any effect no matter what was set in Global Settings — apps/api/backend's /api/v1/internal/sdk/cookie-consent endpoint's theme response never included button_text_color/font_type/font_size at all (unlike the Notice and Rights Center endpoints, which already merged these from the same appearance_global_settings row). Background color and the accept/reject button background colors worked because those fields were already wired — only the three now-added fields were missing.
  • Fixed the widget side to match: TruCookieConsent.jsx never set --font-size as a CSS variable at all for the Cookie Banner (so the existing calc(var(--font-size, 16px) * ratio) rules always silently fell back to the 16px default), hardcoded its font-family stack ignoring Font Type, and hardcoded the primary/accept button's text color to white regardless of the Button Text Color setting (both the summary bar's Accept button and the preferences modal's Save Preferences button).

0.0.27

  • Fixed: the appearance "Font Size" setting had no effect anywhere in <RightCenter /> — --font-size was never even set as a CSS variable, so all 62 font-size rules in RightCenter.css were hardcoded pixel values. Every rule now scales off calc(var(--font-size, 16px) * ratio), preserving the existing visual hierarchy while responding to the setting.
  • Fixed the same gap in the Cookie Banner (banner-styles.css, TruCookieConsent.jsx) and Notice modal (consent-modal.css, TruConsentModal.jsx): only the outermost container picked up font-size via var(--font-size, inherit), but every button, button-label, and secondary/description text rule used a rem (root-relative) unit that ignored it entirely — converted to the same calc(var(--font-size, 16px) * ratio) pattern. Decorative icon glyphs and fixed micro-badges were left as-is deliberately.
  • Backend fix (not a widget change, but required for this to actually take effect): apps/api/backend's /rights-center/settings/global endpoint had a response-construction path — the common "asset already has settings saved" case — that never merged in the asset's real appearance row at all, silently falling back to the response schema's hardcoded defaults for every color and font field, not just font_size.
  • Redesigned the Non-SSO phone/OTP modal: combined the country code into a single fixed "+91" prefix on the mobile number field (no longer a separate editable input), added a close button, a "we'll text a 6-digit code" helper line, and a verification-trust footer note.
  • Redesigned the Non-SSO OTP verification screen: replaced the single free-text OTP field with a 6-box segmented digit input (auto-advance on type, backspace-to-previous, paste support), added a "Code sent to +91 xxxxxxxxxx Change" line (Change returns to the phone step), and combined the previously stacked "Back" button and resend control into one footer row.
  • Fixed: the modal's close (×) button did nothing on either the phone or OTP step — there was no dismiss state at all. Both close buttons now actually hide the modal and restore page scroll.
  • Fixed: the "Change"/"Resend" links rendered in a fixed violet/purple color instead of the widget's configured button/primary theme color — they now use the same var(--banner-primary-color) as every other themed control.
  • Fixed a variable-ordering bug where the modal's dismissed-state check ran before the state itself was declared, silently no-opping the close button regardless of theme/build target.
  • Fixed: the Non-SSO "Consents You Have Given" list was showing mandatory ("Necessary") purposes even when their recorded value was "declined" — mandatory purposes have no opt-in concept (DPDPA doesn't require consent for them) and their default/untouched value could get bundled into any real log for that collection point, making it look like the data principal had "given" a consent they never actually acted on. The list now only includes purposes with a genuine affirmative record (accepted for optional purposes, actually-shown for Legitimate Interest); mandatory purposes with a real log are now shown separately under a new "Mandatory Processing (No Consent Required)" section.
  • Fixed: a purpose could be silently dropped from the Non-SSO "Consents You Have Given" list even when it had a real "shown" disclosure record — this happened whenever a purpose's current is_legitimate flag disagreed with its own purpose_type (a real data inconsistency: purpose_type='legitimate_optional' but is_legitimate=false), which made the widget treat it as an "optional" purpose and check consented === 'accepted' instead of the "shown" signal that Legitimate Interest disclosures actually record. The list (and the individual consent card's Shown/Consented badge) now checks the recorded "shown" status directly instead of trusting only the (possibly stale) is_legitimate flag.
  • Fixed: the Non-SSO modal is position: fixed, but the host page's body remained scrollable behind it — the modal now locks document.body scroll while open and restores it on close/resolution.
  • Added line-height to the modal's hint/description text, which previously used the browser default and could look oddly spaced when it wrapped to two lines.

0.0.26

  • Non-SSO (mobile + OTP) access for <RightCenter />: when an asset's access_mode is non_sso and no userId prop is supplied, the widget renders a phone-entry + OTP-verification modal (with resend + cooldown) instead of the tab UI, resolving a data_principal_id once verified
  • Non-SSO consent view is read-only and scoped to purposes with an actual recorded decision for that phone number only — no toggle/save capability, no full-purpose-catalog exposure (distinct from the SSO give/withdraw experience)
  • When access_mode is sso (default) and no userId is supplied, renders an explanatory "please log in" message instead of a silently broken tab UI
  • Fixed: consent save grouped purposes by asset instead of by collection point, so toggling a purpose from any collection point other than the first-seen one for that asset silently sent zero save requests despite showing "Changes Saved"

0.0.25

  • groupId prop on <RightCenter /> — load consents across all assets in an asset group
  • Consent card 4-column layout: name / badge / expiry period / toggle — pixel-aligned across all rows
  • Badge logic: Legitimate Interest (green outlined), Necessary (red solid), no badge for optional
  • Shown/Consented split: LI purposes show Shown: Yes/No only; non-LI show Consented: Yes/No only
  • shown_at timestamp sourced only from server consent logs (banner-display event); generic timestamp fallbacks removed
  • Banner shown → all LI purposes in that banner automatically marked as shown_to_principal = true

0.0.24

  • Rights Center UI alignment and layout improvements

0.0.23

  • Initial Rights Center (<RightCenter />) release

License

MIT