DSR — Data Subject Request
The <asiri-dsr> Web Component lets your users submit privacy requests (access, erasure, rectification, portability, restriction, objection) directly from your product. It is dependency-free and works in any framework or plain HTML.
Install
npm / bundler
npm install @asiri-ng/elements
# or
pnpm add @asiri-ng/elementsimport '@asiri-ng/elements/dsr';CDN (no build step)
<script
async
src="https://cdn.jsdelivr.net/npm/@asiri-ng/elements@0.1.0/dist/dsr.global.js"
></script>Quick start
Place the element anywhere in your markup:
<asiri-dsr tenant="YOUR_TENANT_SLUG"></asiri-dsr>This renders a button that opens a modal dialog when clicked. The form auto-loads your branding (name, logo, primary colour) from the Asiri portal API.
Variants
variant | Behaviour |
|---|---|
button | (default) A trigger button that opens a modal dialog. |
inline | The form renders directly in the page — no modal. |
floating | A fixed-position launcher button (bottom-right) → modal. |
<!-- Inline form — no modal -->
<asiri-dsr tenant="acme" variant="inline"></asiri-dsr>
<!-- Floating launcher -->
<asiri-dsr tenant="acme" variant="floating" position="bottom-right"></asiri-dsr>All attributes
| Attribute | Required | Default | Description |
|---|---|---|---|
tenant | Yes | — | Your tenant slug. |
api-base | No | https://api.asiri.ng | Override the API base URL (e.g. staging). |
variant | No | button | Layout: button, inline, floating. |
theme | No | light | Colour mode: light, dark, auto (follows OS preference). |
accent | No | #142044 | Brand accent colour (any CSS colour value). |
radius | No | md | Corner radius: sm (6 px), md (10 px), lg (14 px), pill. |
size | No | md | Relative size: sm, md, lg. |
position | No | bottom-right | Floating variant anchor: bottom-left/right, top-left/right. |
label | No | Privacy request | Trigger button text. |
locale | No | browser default | BCP 47 locale tag (reserved for future i18n use). |
turnstile-site-key | No | — | Cloudflare Turnstile site key — enables captcha on the form. |
Request types
The form offers exactly these six request types in the dropdown:
- Access — access my data
- Rectification — correct / rectify my data
- Erasure — erase my data (right to be forgotten)
- Portability — export / portability
- Restriction — restrict processing
- Objection — object to processing
Programmatic mount
import { mountAsiriDsr } from '@asiri-ng/elements/dsr';
mountAsiriDsr({
tenant: 'YOUR_TENANT_SLUG',
variant: 'inline',
theme: 'auto',
target: document.getElementById('dsr-container') ?? undefined,
});Design tokens
Override any token from outside the shadow root:
asiri-dsr {
--asiri-dsr-accent: #7c3aed; /* trigger button + focus rings */
--asiri-dsr-bg: #ffffff; /* panel background */
--asiri-dsr-bg-2: #f8fafc; /* secondary background */
--asiri-dsr-text: #101322; /* primary text */
--asiri-dsr-muted: #647084; /* secondary text */
--asiri-dsr-border: #dfe4ee; /* borders */
--asiri-dsr-shadow: 0 22px 64px rgba(16, 24, 40, 0.14);
--asiri-dsr-danger: #c0392b; /* validation errors */
--asiri-dsr-success: #2f9b63; /* success state */
--asiri-dsr-font: Inter, sans-serif;
--asiri-dsr-radius: 10px; /* corner radius (overridden by `radius` attr) */
}Token precedence: explicit accent / radius attributes beat CSS token overrides, which beat built-in defaults.
Shadow parts
Style individual pieces with ::part():
asiri-dsr::part(trigger) {
/* the launch button */
}
asiri-dsr::part(float-button) {
/* floating launcher button */
}
asiri-dsr::part(dialog) {
/* modal container / inline panel */
}
asiri-dsr::part(backdrop) {
/* semi-transparent overlay */
}
asiri-dsr::part(header) {
/* panel header row */
}
asiri-dsr::part(form) {
/* the <form> element */
}
asiri-dsr::part(field) {
/* each field wrapper */
}
asiri-dsr::part(label) {
/* field labels */
}
asiri-dsr::part(input) {
/* text / email inputs */
}
asiri-dsr::part(select) {
/* dropdowns */
}
asiri-dsr::part(textarea) {
/* details textarea */
}
asiri-dsr::part(submit) {
/* submit button */
}
asiri-dsr::part(cancel) {
/* cancel button */
}
asiri-dsr::part(close) {
/* × close button */
}
asiri-dsr::part(success) {
/* success confirmation view */
}
asiri-dsr::part(error) {
/* error messages */
}Captcha (Cloudflare Turnstile)
When turnstile-site-key is provided the component:
- Lazily injects the Turnstile script from
challenges.cloudflare.com(only once per page). - Renders the Turnstile widget inside the form.
- Includes the resulting token as
captchaTokenin the POST body.
If the attribute is omitted the form submits without a captcha token (suitable for internal tools or when server-side rate limiting is sufficient).
<asiri-dsr tenant="acme" turnstile-site-key="0x4AAAAAAA..."></asiri-dsr>Accessibility
- Modal uses
role="dialog"aria-modal="true"with a labelled title (aria-labelledby). - Focus moves to the first field on open; a focus trap keeps Tab cycling within the dialog.
- Escape and clicking the backdrop both close the modal and restore focus to the trigger.
- Every field has a
<label for>pointing to itsid; required fields carryaria-required="true". - Invalid fields receive
aria-invalid="true"+aria-describedbypointing to the error message. - Email input uses
type="email" inputmode="email"; phone usesinputmode="tel". - All
documentlisteners (Escape, outside-click) are removed indisconnectedCallback— no memory leaks. prefers-color-schemelistener (fortheme="auto") is also removed on disconnect.