@datalayer/primer-addons 1.0.9 → 1.0.11

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.
@@ -5,6 +5,11 @@
5
5
  import { registerPortalRoot } from '@primer/react';
6
6
  import '@primer/react-brand/lib/css/main.css';
7
7
  const PRIMER_PORTAL_ROOT_ID = '__primerPortalRoot__';
8
+ /**
9
+ * Key used on `document.body` to track the CSS-property names we
10
+ * previously applied so we can remove stale entries on theme switch.
11
+ */
12
+ const PORTAL_THEME_KEYS = '__primerPortalThemeKeys__';
8
13
  /**
9
14
  * Resolve 'auto' colormode to the actual OS preference.
10
15
  */
@@ -30,4 +35,49 @@ export const setupPrimerPortals = (colormode = 'light') => {
30
35
  body.id = PRIMER_PORTAL_ROOT_ID;
31
36
  registerPortalRoot(body);
32
37
  };
38
+ /* ─── camelCase → kebab-case ─────────────────────────────────────────── */
39
+ const camelToKebab = (s) => s.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
40
+ /**
41
+ * Sync a set of CSS properties (including CSS custom properties) to
42
+ * `document.body` so that Primer portal content — which is a DOM child
43
+ * of `<body>`, not of the React-tree `<BaseStyles>` element — inherits
44
+ * the same theme tokens and cascade properties (font, color, background)
45
+ * as the rest of the application.
46
+ *
47
+ * This function is **idempotent**: calling it again replaces the
48
+ * properties from the previous call and removes any stale ones.
49
+ *
50
+ * Typical usage: call from `DatalayerThemeProvider`'s `useEffect` so
51
+ * portals stay in sync whenever theme or color-mode changes.
52
+ */
53
+ export function syncPortalThemeStyles(styles) {
54
+ const body = document.body;
55
+ // 1. Remove properties set by the previous invocation.
56
+ const prev = body[PORTAL_THEME_KEYS];
57
+ if (prev) {
58
+ for (const key of prev) {
59
+ body.style.removeProperty(key);
60
+ }
61
+ }
62
+ // 2. Apply the new properties.
63
+ const tracked = [];
64
+ for (const [key, value] of Object.entries(styles)) {
65
+ if (value == null)
66
+ continue;
67
+ const strVal = String(value);
68
+ if (key.startsWith('--')) {
69
+ // CSS custom property — must use setProperty
70
+ body.style.setProperty(key, strVal);
71
+ tracked.push(key);
72
+ }
73
+ else {
74
+ // Standard CSS property (camelCase → kebab-case)
75
+ const kebab = camelToKebab(key);
76
+ body.style.setProperty(kebab, strVal);
77
+ tracked.push(kebab);
78
+ }
79
+ }
80
+ // 3. Stash the list for the next cleanup.
81
+ body[PORTAL_THEME_KEYS] = tracked;
82
+ }
33
83
  export default setupPrimerPortals;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datalayer/primer-addons",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "license": "BSD-3-Clause",
5
5
  "scripts": {
6
6
  "build": "tsc && vite build",
@@ -33,7 +33,8 @@
33
33
  "react": "^18.3.1 || ^19.0.0",
34
34
  "react-dom": "^18.3.1 || ^19.0.0",
35
35
  "react-loading-skeleton": "^3.5.0",
36
- "styled-components": "^5.3.10"
36
+ "styled-components": "^5.3.10",
37
+ "zustand": "^5.0.0"
37
38
  },
38
39
  "devDependencies": {
39
40
  "@storybook/addon-docs": "^9.0.15",