@govnepal/ui 0.2.1 → 0.4.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 (134) hide show
  1. package/dist/Accordion.d.ts +17 -0
  2. package/dist/Accordion.d.ts.map +1 -0
  3. package/dist/Accordion.js +19 -0
  4. package/dist/Accordion.js.map +1 -0
  5. package/dist/AddressBlock.d.ts +28 -0
  6. package/dist/AddressBlock.d.ts.map +1 -0
  7. package/dist/AddressBlock.js +10 -0
  8. package/dist/AddressBlock.js.map +1 -0
  9. package/dist/AmountInput.d.ts +18 -0
  10. package/dist/AmountInput.d.ts.map +1 -0
  11. package/dist/AmountInput.js +7 -0
  12. package/dist/AmountInput.js.map +1 -0
  13. package/dist/BackLink.d.ts +7 -0
  14. package/dist/BackLink.d.ts.map +1 -0
  15. package/dist/BackLink.js +14 -0
  16. package/dist/BackLink.js.map +1 -0
  17. package/dist/Breadcrumb.d.ts +16 -0
  18. package/dist/Breadcrumb.d.ts.map +1 -0
  19. package/dist/Breadcrumb.js +9 -0
  20. package/dist/Breadcrumb.js.map +1 -0
  21. package/dist/Card.d.ts +16 -0
  22. package/dist/Card.d.ts.map +1 -0
  23. package/dist/Card.js +7 -0
  24. package/dist/Card.js.map +1 -0
  25. package/dist/CharacterCount.d.ts +7 -0
  26. package/dist/CharacterCount.d.ts.map +1 -0
  27. package/dist/CharacterCount.js +26 -0
  28. package/dist/CharacterCount.js.map +1 -0
  29. package/dist/ConfirmationDialog.d.ts +24 -0
  30. package/dist/ConfirmationDialog.d.ts.map +1 -0
  31. package/dist/ConfirmationDialog.js +13 -0
  32. package/dist/ConfirmationDialog.js.map +1 -0
  33. package/dist/CookieBanner.d.ts +18 -0
  34. package/dist/CookieBanner.d.ts.map +1 -0
  35. package/dist/CookieBanner.js +9 -0
  36. package/dist/CookieBanner.js.map +1 -0
  37. package/dist/EmptyState.d.ts +13 -0
  38. package/dist/EmptyState.d.ts.map +1 -0
  39. package/dist/EmptyState.js +11 -0
  40. package/dist/EmptyState.js.map +1 -0
  41. package/dist/FileUpload.d.ts +19 -0
  42. package/dist/FileUpload.d.ts.map +1 -0
  43. package/dist/FileUpload.js +18 -0
  44. package/dist/FileUpload.js.map +1 -0
  45. package/dist/Footer.d.ts +22 -0
  46. package/dist/Footer.d.ts.map +1 -0
  47. package/dist/Footer.js +7 -0
  48. package/dist/Footer.js.map +1 -0
  49. package/dist/IconButton.d.ts +15 -0
  50. package/dist/IconButton.d.ts.map +1 -0
  51. package/dist/IconButton.js +6 -0
  52. package/dist/IconButton.js.map +1 -0
  53. package/dist/LoadingState.d.ts +17 -0
  54. package/dist/LoadingState.d.ts.map +1 -0
  55. package/dist/LoadingState.js +20 -0
  56. package/dist/LoadingState.js.map +1 -0
  57. package/dist/MaskedValue.d.ts +21 -0
  58. package/dist/MaskedValue.d.ts.map +1 -0
  59. package/dist/MaskedValue.js +18 -0
  60. package/dist/MaskedValue.js.map +1 -0
  61. package/dist/Modal.d.ts +18 -0
  62. package/dist/Modal.d.ts.map +1 -0
  63. package/dist/Modal.js +68 -0
  64. package/dist/Modal.js.map +1 -0
  65. package/dist/OfflineBanner.d.ts +11 -0
  66. package/dist/OfflineBanner.d.ts.map +1 -0
  67. package/dist/OfflineBanner.js +11 -0
  68. package/dist/OfflineBanner.js.map +1 -0
  69. package/dist/OtpInput.d.ts +21 -0
  70. package/dist/OtpInput.d.ts.map +1 -0
  71. package/dist/OtpInput.js +11 -0
  72. package/dist/OtpInput.js.map +1 -0
  73. package/dist/Pagination.d.ts +11 -0
  74. package/dist/Pagination.d.ts.map +1 -0
  75. package/dist/Pagination.js +26 -0
  76. package/dist/Pagination.js.map +1 -0
  77. package/dist/PasswordInput.d.ts +18 -0
  78. package/dist/PasswordInput.d.ts.map +1 -0
  79. package/dist/PasswordInput.js +18 -0
  80. package/dist/PasswordInput.js.map +1 -0
  81. package/dist/ProgressBar.d.ts +8 -0
  82. package/dist/ProgressBar.d.ts.map +1 -0
  83. package/dist/ProgressBar.js +18 -0
  84. package/dist/ProgressBar.js.map +1 -0
  85. package/dist/QrCode.d.ts +22 -0
  86. package/dist/QrCode.d.ts.map +1 -0
  87. package/dist/QrCode.js +6 -0
  88. package/dist/QrCode.js.map +1 -0
  89. package/dist/SearchBox.d.ts +16 -0
  90. package/dist/SearchBox.d.ts.map +1 -0
  91. package/dist/SearchBox.js +16 -0
  92. package/dist/SearchBox.js.map +1 -0
  93. package/dist/SessionTimeoutWarning.d.ts +17 -0
  94. package/dist/SessionTimeoutWarning.d.ts.map +1 -0
  95. package/dist/SessionTimeoutWarning.js +17 -0
  96. package/dist/SessionTimeoutWarning.js.map +1 -0
  97. package/dist/SkipLink.d.ts +6 -0
  98. package/dist/SkipLink.d.ts.map +1 -0
  99. package/dist/SkipLink.js +14 -0
  100. package/dist/SkipLink.js.map +1 -0
  101. package/dist/SummaryList.d.ts +18 -0
  102. package/dist/SummaryList.d.ts.map +1 -0
  103. package/dist/SummaryList.js +6 -0
  104. package/dist/SummaryList.js.map +1 -0
  105. package/dist/Table.d.ts +22 -0
  106. package/dist/Table.d.ts.map +1 -0
  107. package/dist/Table.js +6 -0
  108. package/dist/Table.js.map +1 -0
  109. package/dist/Tabs.d.ts +20 -0
  110. package/dist/Tabs.d.ts.map +1 -0
  111. package/dist/Tabs.js +38 -0
  112. package/dist/Tabs.js.map +1 -0
  113. package/dist/Tag.d.ts +11 -0
  114. package/dist/Tag.d.ts.map +1 -0
  115. package/dist/Tag.js +11 -0
  116. package/dist/Tag.js.map +1 -0
  117. package/dist/Textarea.d.ts +15 -0
  118. package/dist/Textarea.d.ts.map +1 -0
  119. package/dist/Textarea.js +13 -0
  120. package/dist/Textarea.js.map +1 -0
  121. package/dist/Toast.d.ts +11 -0
  122. package/dist/Toast.d.ts.map +1 -0
  123. package/dist/Toast.js +31 -0
  124. package/dist/Toast.js.map +1 -0
  125. package/dist/Toggle.d.ts +22 -0
  126. package/dist/Toggle.d.ts.map +1 -0
  127. package/dist/Toggle.js +9 -0
  128. package/dist/Toggle.js.map +1 -0
  129. package/dist/generated/statusTaxonomy.js +1 -1
  130. package/dist/index.d.ts +32 -0
  131. package/dist/index.d.ts.map +1 -1
  132. package/dist/index.js +38 -0
  133. package/dist/index.js.map +1 -1
  134. package/package.json +2 -2
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Masked value (components/masked-value.md) — a sensitive identifier masked by default, revealed
3
+ * only by an explicit, permission-gated, audited action (§9.1). The reveal control is present only
4
+ * when `canReveal` is true (the role check happens in the app), and `onReveal` records the audit
5
+ * event. The masked state is announced as masked, not read digit by digit.
6
+ */
7
+ interface MaskedValueProps {
8
+ value: string;
9
+ /** How many trailing characters to show, e.g. 4 → ••••2345. */
10
+ visibleChars?: number;
11
+ /** Whether the current user's role permits revealing (§9.1). */
12
+ canReveal?: boolean;
13
+ /** Called when revealed — record the audit event (who/when). */
14
+ onReveal?: () => void;
15
+ /** What is revealed, for the control's accessible name, e.g. "citizenship number". */
16
+ name: string;
17
+ className?: string;
18
+ }
19
+ export declare function MaskedValue({ value, visibleChars, canReveal, onReveal, name, className }: MaskedValueProps): import("react").JSX.Element;
20
+ export {};
21
+ //# sourceMappingURL=MaskedValue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MaskedValue.d.ts","sourceRoot":"","sources":["../src/MaskedValue.tsx"],"names":[],"mappings":"AAMA;;;;;GAKG;AACH,UAAU,gBAAgB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gEAAgE;IAChE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,sFAAsF;IACtF,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,YAAgB,EAAE,SAAiB,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,gBAAgB,+BA0BtH"}
@@ -0,0 +1,18 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useState } from "react";
4
+ import { cx } from "./cx.js";
5
+ import { useTheme } from "./ThemeProvider.js";
6
+ export function MaskedValue({ value, visibleChars = 4, canReveal = false, onReveal, name, className }) {
7
+ const { language } = useTheme();
8
+ const [revealed, setRevealed] = useState(false);
9
+ const masked = "••••" + value.slice(-visibleChars);
10
+ const show = language === "ne" ? `${name} देखाउनुहोस्` : `Show ${name}`;
11
+ const hide = language === "ne" ? `${name} लुकाउनुहोस्` : `Hide ${name}`;
12
+ return (_jsxs("span", { className: cx("gov-masked", className), children: [_jsx("span", { "aria-label": revealed ? undefined : `${name}, masked`, children: revealed ? value : masked }), canReveal && (_jsx("button", { type: "button", className: "gov-icon-button", "aria-label": revealed ? hide : show, "aria-pressed": revealed, onClick: () => {
13
+ if (!revealed)
14
+ onReveal?.();
15
+ setRevealed((r) => !r);
16
+ }, children: _jsx("span", { "aria-hidden": "true", children: revealed ? "🙈" : "👁" }) }))] }));
17
+ }
18
+ //# sourceMappingURL=MaskedValue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MaskedValue.js","sourceRoot":"","sources":["../src/MaskedValue.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAqB9C,MAAM,UAAU,WAAW,CAAC,EAAE,KAAK,EAAE,YAAY,GAAG,CAAC,EAAE,SAAS,GAAG,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAoB;IACrH,MAAM,EAAE,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAAC;IAChC,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC;IACnD,MAAM,IAAI,GAAG,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,cAAc,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC;IACxE,MAAM,IAAI,GAAG,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,cAAc,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC;IAExE,OAAO,CACL,gBAAM,SAAS,EAAE,EAAE,CAAC,YAAY,EAAE,SAAS,CAAC,aAC1C,6BAAkB,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,UAAU,YAAG,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,GAAQ,EAC7F,SAAS,IAAI,CACZ,iBACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAC,iBAAiB,gBACf,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,kBACpB,QAAQ,EACtB,OAAO,EAAE,GAAG,EAAE;oBACZ,IAAI,CAAC,QAAQ;wBAAE,QAAQ,EAAE,EAAE,CAAC;oBAC5B,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;gBACzB,CAAC,YAED,8BAAkB,MAAM,YAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAQ,GACjD,CACV,IACI,CACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { type ReactNode } from "react";
2
+ interface ModalProps {
3
+ open: boolean;
4
+ onClose: () => void;
5
+ title: ReactNode;
6
+ children: ReactNode;
7
+ /** The action row (buttons). */
8
+ actions?: ReactNode;
9
+ /** alertdialog for a decision that must be read (ConfirmationDialog sets this). */
10
+ role?: "dialog" | "alertdialog";
11
+ /** A destructive confirmation does not dismiss on scrim click or (optionally) Escape. */
12
+ dismissOnScrim?: boolean;
13
+ dismissOnEscape?: boolean;
14
+ className?: string;
15
+ }
16
+ export declare function Modal({ open, onClose, title, children, actions, role, dismissOnScrim, dismissOnEscape, className, }: ModalProps): import("react").JSX.Element | null;
17
+ export {};
18
+ //# sourceMappingURL=Modal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Modal.d.ts","sourceRoot":"","sources":["../src/Modal.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA4B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAiBjE,UAAU,UAAU;IAClB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,SAAS,CAAC;IACpB,gCAAgC;IAChC,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,mFAAmF;IACnF,IAAI,CAAC,EAAE,QAAQ,GAAG,aAAa,CAAC;IAChC,yFAAyF;IACzF,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,KAAK,CAAC,EACpB,IAAI,EACJ,OAAO,EACP,KAAK,EACL,QAAQ,EACR,OAAO,EACP,IAAe,EACf,cAAqB,EACrB,eAAsB,EACtB,SAAS,GACV,EAAE,UAAU,sCAwEZ"}
package/dist/Modal.js ADDED
@@ -0,0 +1,68 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useId, useRef } from "react";
4
+ import { cx } from "./cx.js";
5
+ /**
6
+ * Modal (components/modal.md) — focus the user on one short self-contained task without leaving the
7
+ * page. The whole value is the focus contract, which is easy to ship wrong:
8
+ * - on open, focus moves into the dialog;
9
+ * - while open, focus is TRAPPED inside it (Tab cycles within);
10
+ * - on close, focus returns to the element that opened it;
11
+ * - Escape closes a plain modal; the background is inert (aria-hidden handled by the app root).
12
+ *
13
+ * role="dialog" + aria-modal + an accessible name from the title. A destructive confirmation uses
14
+ * ConfirmationDialog, which layers alertdialog semantics on top of this.
15
+ */
16
+ const FOCUSABLE = 'a[href],button:not([disabled]),textarea:not([disabled]),input:not([disabled]),select:not([disabled]),[tabindex]:not([tabindex="-1"])';
17
+ export function Modal({ open, onClose, title, children, actions, role = "dialog", dismissOnScrim = true, dismissOnEscape = true, className, }) {
18
+ const titleId = useId();
19
+ const dialogRef = useRef(null);
20
+ const returnFocusRef = useRef(null);
21
+ useEffect(() => {
22
+ if (!open)
23
+ return;
24
+ // Remember what to return focus to, then move focus into the dialog.
25
+ returnFocusRef.current = document.activeElement ?? null;
26
+ const dialog = dialogRef.current;
27
+ const first = dialog?.querySelector(FOCUSABLE);
28
+ (first ?? dialog)?.focus();
29
+ const onKeyDown = (event) => {
30
+ if (event.key === "Escape" && dismissOnEscape) {
31
+ event.preventDefault();
32
+ onClose();
33
+ return;
34
+ }
35
+ if (event.key !== "Tab" || !dialog)
36
+ return;
37
+ // Trap focus within the dialog.
38
+ const focusable = Array.from(dialog.querySelectorAll(FOCUSABLE)).filter((el) => el.offsetParent !== null || el === document.activeElement);
39
+ if (focusable.length === 0) {
40
+ event.preventDefault();
41
+ return;
42
+ }
43
+ const firstEl = focusable[0];
44
+ const lastEl = focusable[focusable.length - 1];
45
+ if (event.shiftKey && document.activeElement === firstEl) {
46
+ event.preventDefault();
47
+ lastEl.focus();
48
+ }
49
+ else if (!event.shiftKey && document.activeElement === lastEl) {
50
+ event.preventDefault();
51
+ firstEl.focus();
52
+ }
53
+ };
54
+ document.addEventListener("keydown", onKeyDown);
55
+ return () => {
56
+ document.removeEventListener("keydown", onKeyDown);
57
+ // Restore focus to the trigger on close.
58
+ returnFocusRef.current?.focus?.();
59
+ };
60
+ }, [open, onClose, dismissOnEscape]);
61
+ if (!open)
62
+ return null;
63
+ return (_jsx("div", { className: "gov-modal__scrim", onClick: (e) => {
64
+ if (dismissOnScrim && e.target === e.currentTarget)
65
+ onClose();
66
+ }, children: _jsxs("div", { ref: dialogRef, role: role, "aria-modal": "true", "aria-labelledby": titleId, tabIndex: -1, className: cx("gov-modal", className), children: [_jsx("h2", { className: "gov-modal__title", id: titleId, children: title }), _jsx("div", { children: children }), actions && _jsx("div", { className: "gov-modal__actions", children: actions })] }) }));
67
+ }
68
+ //# sourceMappingURL=Modal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Modal.js","sourceRoot":"","sources":["../src/Modal.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { ReactNode } from "react";
2
+ /**
3
+ * Offline banner (components/offline-banner.md) — the connection is lost; state what still works and
4
+ * how retry behaves (§8.1.2). Announced politely on appear; never colour alone — the sentence
5
+ * carries the meaning (§4.1). Driven by real connectivity detection in the app; never a dead end.
6
+ */
7
+ export declare function OfflineBanner({ children, className }: {
8
+ children: ReactNode;
9
+ className?: string;
10
+ }): import("react").JSX.Element;
11
+ //# sourceMappingURL=OfflineBanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OfflineBanner.d.ts","sourceRoot":"","sources":["../src/OfflineBanner.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BASjG"}
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cx } from "./cx.js";
3
+ /**
4
+ * Offline banner (components/offline-banner.md) — the connection is lost; state what still works and
5
+ * how retry behaves (§8.1.2). Announced politely on appear; never colour alone — the sentence
6
+ * carries the meaning (§4.1). Driven by real connectivity detection in the app; never a dead end.
7
+ */
8
+ export function OfflineBanner({ children, className }) {
9
+ return (_jsxs("div", { className: cx("gov-offline-banner", className), role: "status", "aria-live": "polite", children: [_jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", "aria-hidden": "true", fill: "currentColor", children: _jsx("path", { d: "M12 2a10 10 0 100 20 10 10 0 000-20zm-1 5h2v6h-2V7zm0 8h2v2h-2v-2z" }) }), _jsx("span", { children: children })] }));
10
+ }
11
+ //# sourceMappingURL=OfflineBanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OfflineBanner.js","sourceRoot":"","sources":["../src/OfflineBanner.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAE7B;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,EAAE,QAAQ,EAAE,SAAS,EAA+C;IAChG,OAAO,CACL,eAAK,SAAS,EAAE,EAAE,CAAC,oBAAoB,EAAE,SAAS,CAAC,EAAE,IAAI,EAAC,QAAQ,eAAW,QAAQ,aACnF,cAAK,KAAK,EAAC,IAAI,EAAC,MAAM,EAAC,IAAI,EAAC,OAAO,EAAC,WAAW,iBAAa,MAAM,EAAC,IAAI,EAAC,cAAc,YACpF,eAAM,CAAC,EAAC,oEAAoE,GAAG,GAC3E,EACN,yBAAO,QAAQ,GAAQ,IACnB,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { type ReactNode } from "react";
2
+ /**
3
+ * One-time-code input (components/otp-input.md) — enter a short SMS code. A single accessible field
4
+ * with autocomplete="one-time-code" and inputmode="numeric" so the OS offers autofill and pasting
5
+ * the whole code fills it. The resend control is disabled with a countdown; never allow instant
6
+ * infinite resend. A non-SMS fallback path is the app's responsibility (§8.1.6, citizens abroad).
7
+ */
8
+ interface OtpInputProps {
9
+ label: ReactNode;
10
+ id?: string;
11
+ length?: number;
12
+ error?: ReactNode;
13
+ value?: string;
14
+ onChange?: (code: string) => void;
15
+ /** Seconds until resend is allowed; the control is disabled until 0. */
16
+ resendIn?: number;
17
+ onResend?: () => void;
18
+ }
19
+ export declare function OtpInput({ label, id, length, error, value, onChange, resendIn, onResend }: OtpInputProps): import("react").JSX.Element;
20
+ export {};
21
+ //# sourceMappingURL=OtpInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OtpInput.d.ts","sourceRoot":"","sources":["../src/OtpInput.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAS,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAG9C;;;;;GAKG;AACH,UAAU,aAAa;IACrB,KAAK,EAAE,SAAS,CAAC;IACjB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,MAAU,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAY,EAAE,QAAQ,EAAE,EAAE,aAAa,+BA0BhH"}
@@ -0,0 +1,11 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useId } from "react";
4
+ import { cx } from "./cx.js";
5
+ export function OtpInput({ label, id, length = 6, error, value, onChange, resendIn = 0, onResend }) {
6
+ const generatedId = useId();
7
+ const fieldId = id ?? generatedId;
8
+ const errorId = error ? `${fieldId}-error` : undefined;
9
+ return (_jsxs("div", { className: cx("gov-field", error ? "gov-field--error" : undefined), children: [_jsx("label", { className: "gov-field__label", htmlFor: fieldId, children: label }), _jsx("input", { id: fieldId, className: "gov-input gov-input--masked", style: { inlineSize: `${length + 4}ch` }, inputMode: "numeric", autoComplete: "one-time-code", maxLength: length, value: value, "aria-invalid": error ? true : undefined, "aria-describedby": errorId, onChange: (e) => onChange?.(e.target.value.replace(/[^\d]/g, "").slice(0, length)) }), _jsxs("button", { type: "button", className: "gov-link", disabled: resendIn > 0, onClick: onResend, style: { background: "none", border: 0, padding: 0, cursor: resendIn > 0 ? "not-allowed" : "pointer" }, children: ["Resend code", resendIn > 0 ? ` (available in ${resendIn}s)` : ""] }), error && _jsx("span", { className: "gov-field__error", id: errorId, children: error })] }));
10
+ }
11
+ //# sourceMappingURL=OtpInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OtpInput.js","sourceRoot":"","sources":["../src/OtpInput.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,KAAK,EAAkB,MAAM,OAAO,CAAC;AAC9C,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAoB7B,MAAM,UAAU,QAAQ,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,GAAG,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,GAAG,CAAC,EAAE,QAAQ,EAAiB;IAC/G,MAAM,WAAW,GAAG,KAAK,EAAE,CAAC;IAC5B,MAAM,OAAO,GAAG,EAAE,IAAI,WAAW,CAAC;IAClC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;IAEvD,OAAO,CACL,eAAK,SAAS,EAAE,EAAE,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,SAAS,CAAC,aACrE,gBAAO,SAAS,EAAC,kBAAkB,EAAC,OAAO,EAAE,OAAO,YAAG,KAAK,GAAS,EACrE,gBACE,EAAE,EAAE,OAAO,EACX,SAAS,EAAC,6BAA6B,EACvC,KAAK,EAAE,EAAE,UAAU,EAAE,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,EACxC,SAAS,EAAC,SAAS,EACnB,YAAY,EAAC,eAAe,EAC5B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,KAAK,kBACE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,sBACpB,OAAO,EACzB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAClF,EACF,kBAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,UAAU,EAAC,QAAQ,EAAE,QAAQ,GAAG,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,EAAE,4BAC9K,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,kBAAkB,QAAQ,IAAI,CAAC,CAAC,CAAC,EAAE,IACvD,EACR,KAAK,IAAI,eAAM,SAAS,EAAC,kBAAkB,EAAC,EAAE,EAAE,OAAO,YAAG,KAAK,GAAQ,IACpE,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ interface PaginationProps {
2
+ page: number;
3
+ totalPages: number;
4
+ /** Build the href for a page; omit for a button-driven handler via onNavigate. */
5
+ hrefFor?: (page: number) => string;
6
+ onNavigate?: (page: number) => void;
7
+ className?: string;
8
+ }
9
+ export declare function Pagination({ page, totalPages, hrefFor, onNavigate, className }: PaginationProps): import("react").JSX.Element;
10
+ export {};
11
+ //# sourceMappingURL=Pagination.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Pagination.d.ts","sourceRoot":"","sources":["../src/Pagination.tsx"],"names":[],"mappings":"AAcA,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,kFAAkF;IAClF,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACnC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,eAAe,+BAsC/F"}
@@ -0,0 +1,26 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { cx } from "./cx.js";
4
+ import { useTheme } from "./ThemeProvider.js";
5
+ /**
6
+ * Pagination (components/pagination.md) — move through a long list one page at a time, with the
7
+ * position visible ("Page X of Y"). nav[aria-label=Pagination]; the current page is aria-current;
8
+ * Previous/Next are disabled at the ends. Numerals follow the active language (§3.1).
9
+ */
10
+ const NE_DIGITS = ["०", "१", "२", "३", "४", "५", "६", "७", "८", "९"];
11
+ const toNe = (n) => String(n).split("").map((d) => NE_DIGITS[Number(d)] ?? d).join("");
12
+ export function Pagination({ page, totalPages, hrefFor, onNavigate, className }) {
13
+ const { language } = useTheme();
14
+ const num = (n) => (language === "ne" ? toNe(n) : String(n));
15
+ const prevLabel = language === "ne" ? "अघिल्लो" : "Previous";
16
+ const nextLabel = language === "ne" ? "अर्को" : "Next";
17
+ const position = language === "ne" ? `पृष्ठ ${num(page)} / ${num(totalPages)}` : `Page ${num(page)} of ${num(totalPages)}`;
18
+ const control = (target, label, disabled) => {
19
+ if (disabled) {
20
+ return (_jsx("span", { className: "gov-pagination__link", "aria-disabled": "true", children: label }));
21
+ }
22
+ return hrefFor ? (_jsx("a", { className: "gov-pagination__link", href: hrefFor(target), "aria-label": label, children: label })) : (_jsx("button", { type: "button", className: "gov-pagination__link", onClick: () => onNavigate?.(target), "aria-label": label, children: label }));
23
+ };
24
+ return (_jsx("nav", { "aria-label": "Pagination", className: className, children: _jsxs("ul", { className: "gov-pagination", children: [_jsx("li", { children: control(page - 1, prevLabel, page <= 1) }), _jsx("li", { "aria-current": "page", style: { padding: "0 var(--gov-space-3)" }, children: position }), _jsx("li", { children: control(page + 1, nextLabel, page >= totalPages) })] }) }));
25
+ }
26
+ //# sourceMappingURL=Pagination.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Pagination.js","sourceRoot":"","sources":["../src/Pagination.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAGb,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C;;;;GAIG;AACH,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AACrE,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAW/F,MAAM,UAAU,UAAU,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAmB;IAC9F,MAAM,EAAE,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAAC;IAChC,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACrE,MAAM,SAAS,GAAG,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC;IAC7D,MAAM,SAAS,GAAG,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;IACvD,MAAM,QAAQ,GACZ,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;IAE5G,MAAM,OAAO,GAAG,CAAC,MAAc,EAAE,KAAa,EAAE,QAAiB,EAAa,EAAE;QAC9E,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,CACL,eAAM,SAAS,EAAC,sBAAsB,mBAAe,MAAM,YACxD,KAAK,GACD,CACR,CAAC;QACJ,CAAC;QACD,OAAO,OAAO,CAAC,CAAC,CAAC,CACf,YAAG,SAAS,EAAC,sBAAsB,EAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,gBAAc,KAAK,YACzE,KAAK,GACJ,CACL,CAAC,CAAC,CAAC,CACF,iBAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,sBAAsB,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE,CAAC,MAAM,CAAC,gBAAc,KAAK,YAC1G,KAAK,GACC,CACV,CAAC;IACJ,CAAC,CAAC;IAEF,OAAO,CACL,4BAAgB,YAAY,EAAC,SAAS,EAAE,SAAS,YAC/C,cAAI,SAAS,EAAC,gBAAgB,aAC5B,uBAAK,OAAO,CAAC,IAAI,GAAG,CAAC,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,CAAC,GAAM,EAClD,6BAAiB,MAAM,EAAC,KAAK,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAE,YAC/D,QAAQ,GACN,EACL,uBAAK,OAAO,CAAC,IAAI,GAAG,CAAC,EAAE,SAAS,EAAE,IAAI,IAAI,UAAU,CAAC,GAAM,IACxD,GACD,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { type InputHTMLAttributes, type ReactNode } from "react";
2
+ /**
3
+ * Password input (components/password-input.md) — a password field with a show/hide toggle and NO
4
+ * paste-blocking (blocking paste breaks password managers and harms security, §4.1). The toggle is a
5
+ * real button whose accessible name reflects state (aria-pressed). Requirements are described up
6
+ * front via aria-describedby, never sprung as a post-submit gotcha.
7
+ */
8
+ interface PasswordInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "id" | "type"> {
9
+ label: ReactNode;
10
+ id?: string;
11
+ hint?: ReactNode;
12
+ error?: ReactNode;
13
+ /** current-password (sign-in) or new-password (create account) for manager integration. */
14
+ autoComplete?: "current-password" | "new-password";
15
+ }
16
+ export declare function PasswordInput({ label, id, hint, error, autoComplete, className, ...rest }: PasswordInputProps): import("react").JSX.Element;
17
+ export {};
18
+ //# sourceMappingURL=PasswordInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PasswordInput.d.ts","sourceRoot":"","sources":["../src/PasswordInput.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAmB,KAAK,mBAAmB,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIlF;;;;;GAKG;AACH,UAAU,kBAAmB,SAAQ,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;IAC7F,KAAK,EAAE,SAAS,CAAC;IACjB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,2FAA2F;IAC3F,YAAY,CAAC,EAAE,kBAAkB,GAAG,cAAc,CAAC;CACpD;AAED,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,YAAiC,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,kBAAkB,+BAqClI"}
@@ -0,0 +1,18 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useId, useState } from "react";
4
+ import { cx } from "./cx.js";
5
+ import { useTheme } from "./ThemeProvider.js";
6
+ export function PasswordInput({ label, id, hint, error, autoComplete = "current-password", className, ...rest }) {
7
+ const { language } = useTheme();
8
+ const generatedId = useId();
9
+ const fieldId = id ?? generatedId;
10
+ const hintId = hint ? `${fieldId}-hint` : undefined;
11
+ const errorId = error ? `${fieldId}-error` : undefined;
12
+ const describedBy = [hintId, errorId].filter(Boolean).join(" ") || undefined;
13
+ const [shown, setShown] = useState(false);
14
+ const show = language === "ne" ? "पासवर्ड देखाउनुहोस्" : "Show password";
15
+ const hide = language === "ne" ? "पासवर्ड लुकाउनुहोस्" : "Hide password";
16
+ return (_jsxs("div", { className: cx("gov-field", error ? "gov-field--error" : undefined), children: [_jsx("label", { className: "gov-field__label", htmlFor: fieldId, children: label }), hint && _jsx("span", { className: "gov-field__hint", id: hintId, children: hint }), _jsxs("span", { className: "gov-password", children: [_jsx("input", { id: fieldId, type: shown ? "text" : "password", className: cx("gov-input", className), autoComplete: autoComplete, "aria-describedby": describedBy, "aria-invalid": error ? true : undefined, ...rest }), _jsx("button", { type: "button", className: "gov-password__toggle", "aria-pressed": shown, "aria-label": shown ? hide : show, onClick: () => setShown((s) => !s), children: shown ? (language === "ne" ? "लुकाउनुहोस्" : "Hide") : (language === "ne" ? "देखाउनुहोस्" : "Show") })] }), error && (_jsxs("span", { className: "gov-field__error", id: errorId, children: [_jsx("svg", { className: "gov-field__error-icon", viewBox: "0 0 24 24", "aria-hidden": "true", fill: "currentColor", children: _jsx("path", { d: "M12 2a10 10 0 100 20 10 10 0 000-20zm-1 5h2v6h-2V7zm0 8h2v2h-2v-2z" }) }), error] }))] }));
17
+ }
18
+ //# sourceMappingURL=PasswordInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PasswordInput.js","sourceRoot":"","sources":["../src/PasswordInput.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,KAAK,EAAE,QAAQ,EAA4C,MAAM,OAAO,CAAC;AAClF,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAiB9C,MAAM,UAAU,aAAa,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,GAAG,kBAAkB,EAAE,SAAS,EAAE,GAAG,IAAI,EAAsB;IACjI,MAAM,EAAE,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAAC;IAChC,MAAM,WAAW,GAAG,KAAK,EAAE,CAAC;IAC5B,MAAM,OAAO,GAAG,EAAE,IAAI,WAAW,CAAC;IAClC,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IACpD,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;IACvD,MAAM,WAAW,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC;IAC7E,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,eAAe,CAAC;IACzE,MAAM,IAAI,GAAG,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,eAAe,CAAC;IAEzE,OAAO,CACL,eAAK,SAAS,EAAE,EAAE,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,SAAS,CAAC,aACrE,gBAAO,SAAS,EAAC,kBAAkB,EAAC,OAAO,EAAE,OAAO,YAAG,KAAK,GAAS,EACpE,IAAI,IAAI,eAAM,SAAS,EAAC,iBAAiB,EAAC,EAAE,EAAE,MAAM,YAAG,IAAI,GAAQ,EACpE,gBAAM,SAAS,EAAC,cAAc,aAC5B,gBACE,EAAE,EAAE,OAAO,EACX,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,EACjC,SAAS,EAAE,EAAE,CAAC,WAAW,EAAE,SAAS,CAAC,EACrC,YAAY,EAAE,YAAY,sBACR,WAAW,kBACf,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,KAClC,IAAI,GACR,EACF,iBAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,sBAAsB,kBAAe,KAAK,gBAAc,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,YAC5I,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,GAC7F,IACJ,EACN,KAAK,IAAI,CACR,gBAAM,SAAS,EAAC,kBAAkB,EAAC,EAAE,EAAE,OAAO,aAC5C,cAAK,SAAS,EAAC,uBAAuB,EAAC,OAAO,EAAC,WAAW,iBAAa,MAAM,EAAC,IAAI,EAAC,cAAc,YAAC,eAAM,CAAC,EAAC,oEAAoE,GAAG,GAAM,EACtL,KAAK,IACD,CACR,IACG,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { ReactNode } from "react";
2
+ export declare function ProgressBar({ value, max, label, className }: {
3
+ value: number;
4
+ max?: number;
5
+ label: ReactNode;
6
+ className?: string;
7
+ }): ReactNode;
8
+ //# sourceMappingURL=ProgressBar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProgressBar.d.ts","sourceRoot":"","sources":["../src/ProgressBar.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAYvC,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,GAAS,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAqBpJ"}
@@ -0,0 +1,18 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { cx } from "./cx.js";
4
+ import { useTheme } from "./ThemeProvider.js";
5
+ /**
6
+ * Progress bar (components/progress-bar.md) — determinate progress with a text percentage for a
7
+ * known-length operation (an upload). role="progressbar" with the aria-value attributes; the number
8
+ * is shown as text as well as the bar (never conveyed by the bar alone, §4.1). Forward-only fill.
9
+ */
10
+ const NE_DIGITS = ["०", "१", "२", "३", "४", "५", "६", "७", "८", "९"];
11
+ const toNe = (n) => String(n).split("").map((d) => NE_DIGITS[Number(d)] ?? d).join("");
12
+ export function ProgressBar({ value, max = 100, label, className }) {
13
+ const { language } = useTheme();
14
+ const pct = Math.round((value / max) * 100);
15
+ const pctText = language === "ne" ? `${toNe(pct)}%` : `${pct}%`;
16
+ return (_jsxs("div", { className: cx("gov-progress", className), children: [_jsx("div", { className: "gov-progress__track", role: "progressbar", "aria-valuenow": value, "aria-valuemin": 0, "aria-valuemax": max, "aria-label": typeof label === "string" ? label : undefined, children: _jsx("div", { className: "gov-progress__fill", style: { inlineSize: `${pct}%` } }) }), _jsxs("span", { className: "gov-progress__label", children: [label, " \u2014 ", pctText] })] }));
17
+ }
18
+ //# sourceMappingURL=ProgressBar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProgressBar.js","sourceRoot":"","sources":["../src/ProgressBar.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAGb,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C;;;;GAIG;AACH,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AACrE,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAE/F,MAAM,UAAU,WAAW,CAAC,EAAE,KAAK,EAAE,GAAG,GAAG,GAAG,EAAE,KAAK,EAAE,SAAS,EAAyE;IACvI,MAAM,EAAE,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAAC;IAChC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC;IAChE,OAAO,CACL,eAAK,SAAS,EAAE,EAAE,CAAC,cAAc,EAAE,SAAS,CAAC,aAC3C,cACE,SAAS,EAAC,qBAAqB,EAC/B,IAAI,EAAC,aAAa,mBACH,KAAK,mBACL,CAAC,mBACD,GAAG,gBACN,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,YAEzD,cAAK,SAAS,EAAC,oBAAoB,EAAC,KAAK,EAAE,EAAE,UAAU,EAAE,GAAG,GAAG,GAAG,EAAE,GAAI,GACpE,EACN,gBAAM,SAAS,EAAC,qBAAqB,aAClC,KAAK,cAAK,OAAO,IACb,IACH,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * QR code (components/qr-code.md) — a verification QR paired with the human-readable reference number
3
+ * beneath it, so a document is verifiable without a scanner (§9.1). The QR encodes a verification URL
4
+ * or reference only — never sensitive data (§5.6). The image is generated by the app/build (this
5
+ * component takes the produced image src) and its alt text says what scanning does, never "QR code".
6
+ *
7
+ * A build-time generator produces the QR image from the verification URL; this component renders it
8
+ * with the reference below. No client-side QR library is bundled.
9
+ */
10
+ interface QrCodeProps {
11
+ /** The generated QR image (data URI or URL). Encodes the verification URL/reference only. */
12
+ src: string;
13
+ /** The same reference in human-readable form, shown beneath and used in the alt text. */
14
+ reference: string;
15
+ /** What scanning does, e.g. "Scan to verify this certificate". */
16
+ alt: string;
17
+ size?: number;
18
+ className?: string;
19
+ }
20
+ export declare function QrCode({ src, reference, alt, size, className }: QrCodeProps): import("react").JSX.Element;
21
+ export {};
22
+ //# sourceMappingURL=QrCode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QrCode.d.ts","sourceRoot":"","sources":["../src/QrCode.tsx"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,UAAU,WAAW;IACnB,6FAA6F;IAC7F,GAAG,EAAE,MAAM,CAAC;IACZ,yFAAyF;IACzF,SAAS,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,MAAM,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,IAAU,EAAE,SAAS,EAAE,EAAE,WAAW,+BAOjF"}
package/dist/QrCode.js ADDED
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cx } from "./cx.js";
3
+ export function QrCode({ src, reference, alt, size = 120, className }) {
4
+ return (_jsxs("span", { className: cx("gov-qr", className), style: { display: "inline-flex", flexDirection: "column", alignItems: "center", gap: "var(--gov-space-2)" }, children: [_jsx("img", { src: src, alt: alt, width: size, height: size, style: { background: "#FFFFFF", padding: "var(--gov-space-2)" } }), _jsx("code", { className: "gov-reference gov-text-small", children: reference })] }));
5
+ }
6
+ //# sourceMappingURL=QrCode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QrCode.js","sourceRoot":"","sources":["../src/QrCode.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAsB7B,MAAM,UAAU,MAAM,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAe;IAChF,OAAO,CACL,gBAAM,SAAS,EAAE,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,oBAAoB,EAAE,aACnJ,cAAK,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,oBAAoB,EAAE,GAAI,EACvH,eAAM,SAAS,EAAC,8BAA8B,YAAE,SAAS,GAAQ,IAC5D,CACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { type FormHTMLAttributes, type ReactNode } from "react";
2
+ /**
3
+ * Search box (components/search-box.md) — a labelled query field in a role="search" landmark. The
4
+ * label is real (a placeholder is not a label, §7.1); submitting is a real form submit so Enter
5
+ * works. The clear control (when present) is a labelled icon button.
6
+ */
7
+ interface SearchBoxProps extends Omit<FormHTMLAttributes<HTMLFormElement>, "onSubmit"> {
8
+ label: ReactNode;
9
+ name?: string;
10
+ defaultValue?: string;
11
+ onSubmit?: (query: string) => void;
12
+ buttonLabel?: ReactNode;
13
+ }
14
+ export declare function SearchBox({ label, name, defaultValue, onSubmit, buttonLabel, className, ...rest }: SearchBoxProps): import("react").JSX.Element;
15
+ export {};
16
+ //# sourceMappingURL=SearchBox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SearchBox.d.ts","sourceRoot":"","sources":["../src/SearchBox.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAS,KAAK,kBAAkB,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvE;;;;GAIG;AACH,UAAU,cAAe,SAAQ,IAAI,CAAC,kBAAkB,CAAC,eAAe,CAAC,EAAE,UAAU,CAAC;IACpF,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,WAAW,CAAC,EAAE,SAAS,CAAC;CACzB;AAED,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,IAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,cAAc,+BAuBvH"}
@@ -0,0 +1,16 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useId } from "react";
4
+ import { cx } from "./cx.js";
5
+ import { useTheme } from "./ThemeProvider.js";
6
+ export function SearchBox({ label, name = "q", defaultValue, onSubmit, buttonLabel, className, ...rest }) {
7
+ const { language } = useTheme();
8
+ const fieldId = useId();
9
+ const submit = buttonLabel ?? (language === "ne" ? "खोज्नुहोस्" : "Search");
10
+ return (_jsxs("form", { role: "search", className: cx("gov-search-field", className), onSubmit: (e) => {
11
+ e.preventDefault();
12
+ const value = new FormData(e.currentTarget).get(name);
13
+ onSubmit?.(typeof value === "string" ? value : "");
14
+ }, ...rest, children: [_jsx("label", { className: "gov-field__label", htmlFor: fieldId, children: label }), _jsxs("span", { className: "gov-search", children: [_jsx("input", { id: fieldId, name: name, type: "search", className: "gov-input", defaultValue: defaultValue }), _jsx("button", { type: "submit", className: "gov-button gov-button--primary", children: submit })] })] }));
15
+ }
16
+ //# sourceMappingURL=SearchBox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SearchBox.js","sourceRoot":"","sources":["../src/SearchBox.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,KAAK,EAA2C,MAAM,OAAO,CAAC;AACvE,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAe9C,MAAM,UAAU,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,GAAG,GAAG,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,IAAI,EAAkB;IACtH,MAAM,EAAE,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAAC;IAChC,MAAM,OAAO,GAAG,KAAK,EAAE,CAAC;IACxB,MAAM,MAAM,GAAG,WAAW,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAE5E,OAAO,CACL,gBACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAE,EAAE,CAAC,kBAAkB,EAAE,SAAS,CAAC,EAC5C,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE;YACd,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACtD,QAAQ,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACrD,CAAC,KACG,IAAI,aAER,gBAAO,SAAS,EAAC,kBAAkB,EAAC,OAAO,EAAE,OAAO,YAAG,KAAK,GAAS,EACrE,gBAAM,SAAS,EAAC,YAAY,aAC1B,gBAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,WAAW,EAAC,YAAY,EAAE,YAAY,GAAI,EAClG,iBAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,gCAAgC,YAAE,MAAM,GAAU,IAC7E,IACF,CACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Session timeout warning (components/session-timeout-warning.md) — warn before an idle session ends,
3
+ * letting the user stay signed in without losing entered data (§9.1). Built on Modal as an
4
+ * alertdialog so it is announced; focus lands on "Stay signed in". The countdown is passed in and
5
+ * should be announced on a coarse interval by the app, not every second (which floods a screen
6
+ * reader). Entered data survives re-authentication (the app owns persistence).
7
+ */
8
+ interface SessionTimeoutWarningProps {
9
+ open: boolean;
10
+ /** Seconds remaining, shown in the message. */
11
+ secondsLeft: number;
12
+ onStay: () => void;
13
+ onSignOut: () => void;
14
+ }
15
+ export declare function SessionTimeoutWarning({ open, secondsLeft, onStay, onSignOut }: SessionTimeoutWarningProps): import("react").JSX.Element;
16
+ export {};
17
+ //# sourceMappingURL=SessionTimeoutWarning.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SessionTimeoutWarning.d.ts","sourceRoot":"","sources":["../src/SessionTimeoutWarning.tsx"],"names":[],"mappings":"AAOA;;;;;;GAMG;AACH,UAAU,0BAA0B;IAClC,IAAI,EAAE,OAAO,CAAC;IACd,+CAA+C;IAC/C,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,wBAAgB,qBAAqB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,0BAA0B,+BA6BzG"}
@@ -0,0 +1,17 @@
1
+ "use client";
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Modal } from "./Modal.js";
4
+ import { Button } from "./Button.js";
5
+ import { useTheme } from "./ThemeProvider.js";
6
+ export function SessionTimeoutWarning({ open, secondsLeft, onStay, onSignOut }) {
7
+ const { language } = useTheme();
8
+ const minutes = Math.ceil(secondsLeft / 60);
9
+ const message = language === "ne"
10
+ ? `तपाईंको सत्र लगभग ${minutes} मिनेटमा सकिन्छ। साइन इन रहनुहुन्छ?`
11
+ : `Your session will end in about ${minutes} minute${minutes === 1 ? "" : "s"}. Stay signed in?`;
12
+ const stay = language === "ne" ? "साइन इन रहनुहोस्" : "Stay signed in";
13
+ const out = language === "ne" ? "अहिले साइन आउट गर्नुहोस्" : "Sign out now";
14
+ const title = language === "ne" ? "सत्र सकिन लाग्यो" : "Your session is about to end";
15
+ return (_jsx(Modal, { open: open, onClose: onStay, role: "alertdialog", title: title, dismissOnScrim: false, actions: _jsxs(_Fragment, { children: [_jsx(Button, { type: "button", onClick: onStay, children: stay }), _jsx(Button, { variant: "secondary", type: "button", onClick: onSignOut, children: out })] }), children: message }));
16
+ }
17
+ //# sourceMappingURL=SessionTimeoutWarning.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SessionTimeoutWarning.js","sourceRoot":"","sources":["../src/SessionTimeoutWarning.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAGb,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAiB9C,MAAM,UAAU,qBAAqB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAA8B;IACxG,MAAM,EAAE,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAAC;IAChC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC;IAC5C,MAAM,OAAO,GACX,QAAQ,KAAK,IAAI;QACf,CAAC,CAAC,qBAAqB,OAAO,qCAAqC;QACnE,CAAC,CAAC,kCAAkC,OAAO,UAAU,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,mBAAmB,CAAC;IACrG,MAAM,IAAI,GAAG,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,gBAAgB,CAAC;IACvE,MAAM,GAAG,GAAG,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,cAAc,CAAC;IAC5E,MAAM,KAAK,GAAG,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,8BAA8B,CAAC;IAEtF,OAAO,CACL,KAAC,KAAK,IACJ,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,MAAM,EACf,IAAI,EAAC,aAAa,EAClB,KAAK,EAAE,KAAK,EACZ,cAAc,EAAE,KAAK,EACrB,OAAO,EACL,8BAEE,KAAC,MAAM,IAAC,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,MAAM,YAAG,IAAI,GAAU,EACtD,KAAC,MAAM,IAAC,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,SAAS,YAAG,GAAG,GAAU,IAC3E,YAGJ,OAAO,GACF,CACT,CAAC;AACJ,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { ReactNode } from "react";
2
+ export declare function SkipLink({ targetId, children }: {
3
+ targetId?: string;
4
+ children?: ReactNode;
5
+ }): import("react").JSX.Element;
6
+ //# sourceMappingURL=SkipLink.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SkipLink.d.ts","sourceRoot":"","sources":["../src/SkipLink.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAWvC,wBAAgB,QAAQ,CAAC,EAAE,QAAiB,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,+BAOpG"}
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useTheme } from "./ThemeProvider.js";
3
+ /**
4
+ * Skip link (components/skip-link.md) — the first focusable element on the page, jumping keyboard
5
+ * users past the header to the main content. Visually hidden until focused (never display:none,
6
+ * which would drop it from the tab order). The Header renders one automatically; this standalone
7
+ * export is for pages that compose their own chrome.
8
+ */
9
+ const LABEL = { ne: "मुख्य सामग्रीमा जानुहोस्", en: "Skip to main content" };
10
+ export function SkipLink({ targetId = "main", children }) {
11
+ const { language } = useTheme();
12
+ return (_jsx("a", { className: "gov-skip-link", href: `#${targetId}`, children: children ?? LABEL[language] }));
13
+ }
14
+ //# sourceMappingURL=SkipLink.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SkipLink.js","sourceRoot":"","sources":["../src/SkipLink.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C;;;;;GAKG;AACH,MAAM,KAAK,GAAG,EAAE,EAAE,EAAE,0BAA0B,EAAE,EAAE,EAAE,sBAAsB,EAAW,CAAC;AAEtF,MAAM,UAAU,QAAQ,CAAC,EAAE,QAAQ,GAAG,MAAM,EAAE,QAAQ,EAA+C;IACnG,MAAM,EAAE,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAAC;IAChC,OAAO,CACL,YAAG,SAAS,EAAC,eAAe,EAAC,IAAI,EAAE,IAAI,QAAQ,EAAE,YAC9C,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC,GAC1B,CACL,CAAC;AACJ,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { ReactNode } from "react";
2
+ /**
3
+ * Summary list (components/summary-list.md) — the "check your answers" rows before submit: each the
4
+ * question, the citizen's answer, and a "Change" link back to the step that set it (§7.4). Rendered
5
+ * as a description list so the question/answer relationship is announced; each change link names
6
+ * what it changes, never a bare repeated "Change".
7
+ */
8
+ export interface SummaryRow {
9
+ key: ReactNode;
10
+ value: ReactNode;
11
+ /** The change link. Its accessible name should include what it changes. */
12
+ action?: ReactNode;
13
+ }
14
+ export declare function SummaryList({ rows, className }: {
15
+ rows: SummaryRow[];
16
+ className?: string;
17
+ }): import("react").JSX.Element;
18
+ //# sourceMappingURL=SummaryList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SummaryList.d.ts","sourceRoot":"","sources":["../src/SummaryList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,SAAS,CAAC;IACf,KAAK,EAAE,SAAS,CAAC;IACjB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAED,wBAAgB,WAAW,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE;IAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAY1F"}
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cx } from "./cx.js";
3
+ export function SummaryList({ rows, className }) {
4
+ return (_jsx("dl", { className: cx("gov-summary-list", className), children: rows.map((row, i) => (_jsxs("div", { className: "gov-summary-list__row", children: [_jsx("dt", { className: "gov-summary-list__key", children: row.key }), _jsx("dd", { className: "gov-summary-list__value", children: row.value }), row.action && _jsx("dd", { className: "gov-summary-list__action", children: row.action })] }, i))) }));
5
+ }
6
+ //# sourceMappingURL=SummaryList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SummaryList.js","sourceRoot":"","sources":["../src/SummaryList.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAe7B,MAAM,UAAU,WAAW,CAAC,EAAE,IAAI,EAAE,SAAS,EAA8C;IACzF,OAAO,CACL,aAAI,SAAS,EAAE,EAAE,CAAC,kBAAkB,EAAE,SAAS,CAAC,YAC7C,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CACpB,eAAK,SAAS,EAAC,uBAAuB,aACpC,aAAI,SAAS,EAAC,uBAAuB,YAAE,GAAG,CAAC,GAAG,GAAM,EACpD,aAAI,SAAS,EAAC,yBAAyB,YAAE,GAAG,CAAC,KAAK,GAAM,EACvD,GAAG,CAAC,MAAM,IAAI,aAAI,SAAS,EAAC,0BAA0B,YAAE,GAAG,CAAC,MAAM,GAAM,KAH/B,CAAC,CAIvC,CACP,CAAC,GACC,CACN,CAAC;AACJ,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { ReactNode } from "react";
2
+ /**
3
+ * Table (components/table.md) — semantic rows/columns for comparison. A real <table> with
4
+ * <th scope> so each cell's row/column is announced; never a grid of divs. Numeric columns are
5
+ * right-aligned. On mobile, prefer cards when a table becomes unreadable (§7.3) — that is the
6
+ * consumer's layout choice, not something this component forces.
7
+ */
8
+ export interface Column<T> {
9
+ key: string;
10
+ header: ReactNode;
11
+ render: (row: T) => ReactNode;
12
+ numeric?: boolean;
13
+ }
14
+ export declare function Table<T>({ caption, columns, rows, sticky, getRowKey, className }: {
15
+ caption?: ReactNode;
16
+ columns: Column<T>[];
17
+ rows: T[];
18
+ sticky?: boolean;
19
+ getRowKey: (row: T, index: number) => string | number;
20
+ className?: string;
21
+ }): import("react").JSX.Element;
22
+ //# sourceMappingURL=Table.d.ts.map