@nexub/react 7.1.0 → 7.3.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 (34) hide show
  1. package/accessibility.json +1 -1
  2. package/dist/components/Accordion/Accordion.js +1 -1
  3. package/dist/components/AlertDialog/AlertDialog.d.ts +7 -1
  4. package/dist/components/AlertDialog/AlertDialog.js +8 -1
  5. package/dist/components/Avatar/Avatar.js +3 -1
  6. package/dist/components/Breadcrumb/Breadcrumb.js +3 -2
  7. package/dist/components/Card/Card.js +3 -1
  8. package/dist/components/Dialog/Dialog.d.ts +11 -1
  9. package/dist/components/Dialog/Dialog.js +8 -1
  10. package/dist/components/FileUpload/FileUpload.d.ts +8 -1
  11. package/dist/components/FileUpload/FileUpload.js +5 -3
  12. package/dist/components/MediaCard/MediaCard.js +4 -1
  13. package/dist/components/Motion/Collapse.d.ts +5 -4
  14. package/dist/components/Motion/Collapse.js +23 -53
  15. package/dist/components/Motion/motion.types.d.ts +2 -0
  16. package/dist/components/NavigationMenu/NavigationMenu.js +3 -1
  17. package/dist/components/NexubProvider/NexubProvider.d.ts +7 -1
  18. package/dist/components/NexubProvider/NexubProvider.js +3 -1
  19. package/dist/components/PasswordInput/PasswordInput.js +6 -1
  20. package/dist/components/Progress/Progress.js +1 -1
  21. package/dist/components/Tabs/Tabs.js +13 -3
  22. package/dist/components/ThemeProvider/ThemeProvider.js +2 -1
  23. package/dist/hooks/useClassScrollLock.d.ts +13 -0
  24. package/dist/hooks/useClassScrollLock.js +12 -0
  25. package/dist/hooks/useSlidingIndicator.d.ts +1 -1
  26. package/dist/hooks/useSlidingIndicator.js +2 -0
  27. package/dist/index.d.ts +2 -0
  28. package/dist/index.js +3 -0
  29. package/dist/styles.css +1 -1
  30. package/dist/utils/safeHref.d.ts +12 -0
  31. package/dist/utils/safeHref.js +24 -0
  32. package/dist/utils/viewTransition.d.ts +4 -2
  33. package/dist/utils/viewTransition.js +10 -2
  34. package/package.json +11 -6
@@ -0,0 +1,12 @@
1
+ export interface SafeHrefOptions {
2
+ /**
3
+ * `false` (7.x default): block script-capable schemes (`javascript:`,
4
+ * `vbscript:`, `data:`, `file:`), allow everything else.
5
+ * `true` (8.0 default): allow only relative URLs, `#…`, http(s), mailto, tel and sms.
6
+ */
7
+ strict?: boolean;
8
+ }
9
+ /** A link target that can't run script. Returns `undefined` when blocked. */
10
+ export declare function safeHref(url: string | null | undefined, { strict }?: SafeHrefOptions): string | undefined;
11
+ /** An image source: relative, http(s), blob: or a data:image/* URL. */
12
+ export declare function safeSrc(url: string | null | undefined): string | undefined;
@@ -0,0 +1,24 @@
1
+ const SCHEME = /^([a-z][a-z0-9+.-]*):/i;
2
+ const DANGEROUS = /* @__PURE__ */ new Set(["javascript", "vbscript", "data", "file"]);
3
+ const STRICT_HREF = /* @__PURE__ */ new Set(["http", "https", "mailto", "tel", "sms"]);
4
+ function scheme(url) {
5
+ const probe = url.replace(/[\u0000- \u007f]+/g, "");
6
+ return SCHEME.exec(probe)?.[1]?.toLowerCase() ?? null;
7
+ }
8
+ function safeHref(url, { strict = false } = {}) {
9
+ if (!url) return void 0;
10
+ const s = scheme(url);
11
+ if (s === null) return url;
12
+ if (strict) return STRICT_HREF.has(s) ? url : void 0;
13
+ return DANGEROUS.has(s) ? void 0 : url;
14
+ }
15
+ function safeSrc(url) {
16
+ if (!url) return void 0;
17
+ const s = scheme(url);
18
+ if (s === null || s === "http" || s === "https" || s === "blob") return url;
19
+ return s === "data" && /^data:image\//i.test(url.trim()) ? url : void 0;
20
+ }
21
+ export {
22
+ safeHref,
23
+ safeSrc
24
+ };
@@ -1,5 +1,7 @@
1
1
  /**
2
2
  * Run a DOM update as a view transition (styles: @nexub/themes/view-transitions).
3
- * Where the API is missing, or on the server, the update just runs.
3
+ * React state set inside `update` is flushed synchronously, so the browser
4
+ * snapshots the new DOM rather than the stale one. Resolves when the transition
5
+ * has finished (or right after the update where the API is missing / on the server).
4
6
  */
5
- export declare function startViewTransition(update: () => void | Promise<void>): void;
7
+ export declare function startViewTransition(update: () => void | Promise<void>): Promise<void>;
@@ -1,7 +1,15 @@
1
+ import { flushSync } from "react-dom";
1
2
  function startViewTransition(update) {
3
+ const run = () => {
4
+ let result = void 0;
5
+ flushSync(() => {
6
+ result = update();
7
+ });
8
+ return result;
9
+ };
2
10
  const doc = typeof document === "undefined" ? void 0 : document;
3
- if (doc?.startViewTransition) doc.startViewTransition(update);
4
- else void update();
11
+ if (doc?.startViewTransition) return doc.startViewTransition(run).finished;
12
+ return Promise.resolve(run());
5
13
  }
6
14
  export {
7
15
  startViewTransition
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexub/react",
3
- "version": "7.1.0",
3
+ "version": "7.3.0",
4
4
  "description": "React component library for Nexub Design System — 90+ accessible, themeable UI components built on Radix UI primitives.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -39,6 +39,10 @@
39
39
  "types": "./dist/utils/cn.d.ts",
40
40
  "default": "./dist/utils/cn.js"
41
41
  },
42
+ "./safeHref": {
43
+ "types": "./dist/utils/safeHref.d.ts",
44
+ "default": "./dist/utils/safeHref.js"
45
+ },
42
46
  "./*": {
43
47
  "types": "./dist/components/*/index.d.ts",
44
48
  "default": "./dist/components/*/index.js"
@@ -79,16 +83,17 @@
79
83
  "clsx": "^2.1.1",
80
84
  "cmdk": "^1.1.1",
81
85
  "date-fns": "^4.4.0",
86
+ "get-nonce": "^1.0.1",
82
87
  "react-day-picker": "^10.0.2",
83
88
  "tailwind-merge": "^3.7.0",
84
- "@nexub/core": "7.1.0",
85
- "@nexub/icons": "7.1.0"
89
+ "@nexub/core": "7.3.0",
90
+ "@nexub/icons": "7.3.0"
86
91
  },
87
92
  "peerDependencies": {
88
93
  "react": ">=19 <20",
89
94
  "react-dom": ">=19 <20",
90
95
  "@tanstack/react-virtual": "^3.14.22",
91
- "@nexub/tokens": "^7.1.0"
96
+ "@nexub/tokens": "^7.3.0"
92
97
  },
93
98
  "peerDependenciesMeta": {
94
99
  "@tanstack/react-virtual": {
@@ -120,8 +125,8 @@
120
125
  "vaul": "1.1.2",
121
126
  "vite": "^8.3.5",
122
127
  "vitest": "^5.0.5",
123
- "@nexub/themes": "7.1.0",
124
- "@nexub/tokens": "7.1.0"
128
+ "@nexub/themes": "7.3.0",
129
+ "@nexub/tokens": "7.3.0"
125
130
  },
126
131
  "scripts": {
127
132
  "build": "rm -rf dist && tsup && tsc -p tsconfig.build.json && rm -f dist/vendor/*.d.ts && node scripts/check-dts.mjs && tailwindcss -i src/styles.css -o dist/styles.css --minify && cp -R ../themes/src/fonts dist/fonts",