@datalayer/primer-addons 1.0.8 → 1.0.10

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 (40) hide show
  1. package/lib/components/overlay/Overlay.js +15 -2
  2. package/lib/index.d.ts +1 -0
  3. package/lib/index.js +2 -0
  4. package/lib/theme/DatalayerBrandThemeProvider.d.ts +41 -0
  5. package/lib/theme/DatalayerBrandThemeProvider.js +32 -0
  6. package/lib/theme/DatalayerThemeProvider.d.ts +36 -0
  7. package/lib/theme/DatalayerThemeProvider.js +46 -0
  8. package/lib/theme/Palette.d.ts +4 -0
  9. package/lib/theme/Palette.js +10 -0
  10. package/lib/theme/colors/datalayerColors.d.ts +15 -0
  11. package/lib/theme/colors/datalayerColors.js +21 -0
  12. package/lib/theme/colors/index.d.ts +4 -0
  13. package/lib/theme/colors/index.js +8 -0
  14. package/lib/theme/colors/lovelyColors.d.ts +15 -0
  15. package/lib/theme/colors/lovelyColors.js +21 -0
  16. package/lib/theme/colors/matrixColors.d.ts +20 -0
  17. package/lib/theme/colors/matrixColors.js +26 -0
  18. package/lib/theme/colors/spatialColors.d.ts +15 -0
  19. package/lib/theme/colors/spatialColors.js +21 -0
  20. package/lib/theme/index.d.ts +12 -0
  21. package/lib/theme/index.js +16 -0
  22. package/lib/theme/themeRegistry.d.ts +30 -0
  23. package/lib/theme/themeRegistry.js +53 -0
  24. package/lib/theme/themes/createThemeCSSVars.d.ts +135 -0
  25. package/lib/theme/themes/createThemeCSSVars.js +172 -0
  26. package/lib/theme/themes/datalayerTheme.d.ts +1093 -0
  27. package/lib/theme/themes/datalayerTheme.js +195 -0
  28. package/lib/theme/themes/lovelyTheme.d.ts +1093 -0
  29. package/lib/theme/themes/lovelyTheme.js +190 -0
  30. package/lib/theme/themes/matrixTheme.d.ts +1096 -0
  31. package/lib/theme/themes/matrixTheme.js +202 -0
  32. package/lib/theme/themes/spatialTheme.d.ts +1093 -0
  33. package/lib/theme/themes/spatialTheme.js +190 -0
  34. package/lib/theme/themes-brand/index.d.ts +1 -0
  35. package/lib/theme/themes-brand/index.js +5 -0
  36. package/lib/theme/themes-brand/spatialBrandTheme.d.ts +16 -0
  37. package/lib/theme/themes-brand/spatialBrandTheme.js +157 -0
  38. package/lib/theme/useSystemColorMode.d.ts +9 -0
  39. package/lib/theme/useSystemColorMode.js +26 -0
  40. package/package.json +1 -1
@@ -12,6 +12,19 @@ const PrimerAddonOverlay = (props) => {
12
12
  setTop(headingRef?.current?.getBoundingClientRect().bottom ?? 0);
13
13
  }, [headingRef]);
14
14
  const closeOverlay = () => setIsOpen(false);
15
+ /**
16
+ * Don't close the overlay when the click outside lands on a portaled
17
+ * Dialog (role="dialog"). Primer Dialogs render in a portal at
18
+ * document.body, so they are "outside" the Overlay DOM tree and would
19
+ * otherwise trigger an unwanted close.
20
+ */
21
+ const handleClickOutside = (e) => {
22
+ if (e.target instanceof HTMLElement &&
23
+ e.target.closest('[role="dialog"]')) {
24
+ return;
25
+ }
26
+ closeOverlay();
27
+ };
15
28
  const overlayContent = (_jsx(ThemeProvider, { theme: theme, colorMode: colorMode, children: _jsx(BaseStyles, { children: _jsxs(Box, { sx: {
16
29
  /* We need to remove the padding */
17
30
  height: `calc(100vh - ${top}px - 8px)`,
@@ -28,9 +41,9 @@ const PrimerAddonOverlay = (props) => {
28
41
  return (closeButtonRef && openButtonRef ?
29
42
  _jsx(_Fragment, { children: isOpen ?
30
43
  direction === 'left' ?
31
- _jsx(Box, { sx: { zIndex }, children: _jsx(PrimerOverlay, { initialFocusRef: closeButtonRef, returnFocusRef: openButtonRef, ignoreClickRefs: [openButtonRef], onEscape: closeOverlay, onClickOutside: closeOverlay, width: "auto", anchorSide: "inside-right", left: 0, position: "fixed", top: top, children: overlayContent }) })
44
+ _jsx(Box, { sx: { zIndex }, children: _jsx(PrimerOverlay, { initialFocusRef: closeButtonRef, returnFocusRef: openButtonRef, ignoreClickRefs: [openButtonRef], onEscape: closeOverlay, onClickOutside: handleClickOutside, width: "auto", anchorSide: "inside-right", left: 0, position: "fixed", top: top, children: overlayContent }) })
32
45
  :
33
- _jsx(Box, { sx: { zIndex }, children: _jsx(PrimerOverlay, { initialFocusRef: closeButtonRef, returnFocusRef: openButtonRef, ignoreClickRefs: [openButtonRef], onEscape: closeOverlay, onClickOutside: closeOverlay, width: "auto", anchorSide: 'inside-left', right: 0, position: "fixed", top: top, children: overlayContent }) })
46
+ _jsx(Box, { sx: { zIndex }, children: _jsx(PrimerOverlay, { initialFocusRef: closeButtonRef, returnFocusRef: openButtonRef, ignoreClickRefs: [openButtonRef], onEscape: closeOverlay, onClickOutside: handleClickOutside, width: "auto", anchorSide: 'inside-left', right: 0, position: "fixed", top: top, children: overlayContent }) })
34
47
  : _jsx(_Fragment, {}) })
35
48
  :
36
49
  _jsx(_Fragment, {}));
package/lib/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from "./components";
2
2
  export * from "./utils";
3
+ export * from './theme';
package/lib/index.js CHANGED
@@ -1,2 +1,4 @@
1
1
  export * from "./components";
2
2
  export * from "./utils";
3
+ // Export Theme.
4
+ export * from './theme';
@@ -0,0 +1,41 @@
1
+ import { type CSSProperties, type ReactNode } from 'react';
2
+ import type { BrandTheme } from './themes-brand/spatialBrandTheme';
3
+ export type ColorMode = 'light' | 'dark' | 'auto';
4
+ export interface IDatalayerBrandThemeProviderProps {
5
+ /**
6
+ * Color mode to use.
7
+ * - `'light'` / `'dark'` — explicit override
8
+ * - `'auto'` — follow the operating system preference (prefers-color-scheme)
9
+ */
10
+ colorMode?: ColorMode;
11
+ /**
12
+ * A brand theme object with per-mode CSS variable overrides.
13
+ * Each key (`light` / `dark`) is a `CSSProperties` map whose entries
14
+ * are `--brand-color-*` / `--brand-button-*` custom properties.
15
+ *
16
+ * When omitted, the default Primer Brand tokens are used unchanged.
17
+ */
18
+ brandTheme?: BrandTheme;
19
+ /**
20
+ * Additional inline styles merged on top of the resolved brand theme.
21
+ */
22
+ style?: CSSProperties;
23
+ children: ReactNode;
24
+ }
25
+ /**
26
+ * Theme provider for Primer Brand (`@primer/react-brand`) components.
27
+ *
28
+ * Works by passing CSS custom-property overrides as inline `style` to
29
+ * `ThemeProvider`, which scopes them to its DOM subtree — exactly how
30
+ * the VS Code extension re-skins Primer via CSS variables.
31
+ *
32
+ * ```tsx
33
+ * import { DatalayerBrandThemeProvider } from '@datalayer/core/lib/theme';
34
+ * import { spatialBrandTheme } from '@datalayer/core/lib/theme/themes-brand/spatialBrandTheme';
35
+ *
36
+ * <DatalayerBrandThemeProvider colorMode="dark" brandTheme={spatialBrandTheme}>
37
+ * <Hero>…</Hero>
38
+ * </DatalayerBrandThemeProvider>
39
+ * ```
40
+ */
41
+ export declare function DatalayerBrandThemeProvider({ colorMode, brandTheme, style, children, }: IDatalayerBrandThemeProviderProps): JSX.Element;
@@ -0,0 +1,32 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { ThemeProvider as PrimerBrandThemeProvider } from '@primer/react-brand';
3
+ import { useSystemColorMode } from './useSystemColorMode';
4
+ /**
5
+ * Theme provider for Primer Brand (`@primer/react-brand`) components.
6
+ *
7
+ * Works by passing CSS custom-property overrides as inline `style` to
8
+ * `ThemeProvider`, which scopes them to its DOM subtree — exactly how
9
+ * the VS Code extension re-skins Primer via CSS variables.
10
+ *
11
+ * ```tsx
12
+ * import { DatalayerBrandThemeProvider } from '@datalayer/core/lib/theme';
13
+ * import { spatialBrandTheme } from '@datalayer/core/lib/theme/themes-brand/spatialBrandTheme';
14
+ *
15
+ * <DatalayerBrandThemeProvider colorMode="dark" brandTheme={spatialBrandTheme}>
16
+ * <Hero>…</Hero>
17
+ * </DatalayerBrandThemeProvider>
18
+ * ```
19
+ */
20
+ export function DatalayerBrandThemeProvider({ colorMode = 'light', brandTheme, style, children, }) {
21
+ const systemMode = useSystemColorMode();
22
+ const resolved = colorMode === 'auto' ? systemMode : colorMode;
23
+ const themeOverrides = brandTheme
24
+ ? resolved === 'dark'
25
+ ? brandTheme.dark
26
+ : brandTheme.light
27
+ : undefined;
28
+ return (_jsx(PrimerBrandThemeProvider, { colorMode: resolved, style: {
29
+ ...themeOverrides,
30
+ ...style,
31
+ }, children: children }));
32
+ }
@@ -0,0 +1,36 @@
1
+ import { type CSSProperties } from 'react';
2
+ import { ThemeProviderProps } from '@primer/react';
3
+ export interface IDatalayerThemeProviderProps extends Omit<ThemeProviderProps, 'theme' | 'colorMode'> {
4
+ /**
5
+ * Color mode to use.
6
+ * - `'light'` / `'dark'` — explicit override
7
+ * - `'auto'` — follow the operating system preference (prefers-color-scheme)
8
+ * - Primer's `'day'` / `'night'` are still accepted.
9
+ */
10
+ colorMode?: 'light' | 'dark' | 'auto' | 'day' | 'night';
11
+ /**
12
+ * Additional base styles merged on top of theme defaults.
13
+ */
14
+ baseStyles?: CSSProperties;
15
+ /**
16
+ * Optional Primer theme object. Defaults to the built-in datalayerTheme
17
+ * (which is the unmodified default Primer theme — all theming is done
18
+ * via CSS custom-property overrides in `themeStyles`).
19
+ */
20
+ theme?: Record<string, any>;
21
+ /**
22
+ * Per-mode CSS-property overrides (background, foreground, and all
23
+ * Primer functional-token CSS custom properties).
24
+ *
25
+ * When provided, these replace the built-in datalayer styles entirely.
26
+ * The `baseStyles` prop is still merged on top.
27
+ *
28
+ * Use the `buildThemeStyles` helper from `./themes/createThemeCSSVars`
29
+ * to generate comprehensive overrides from a `ThemeColorDefs` pair.
30
+ */
31
+ themeStyles?: {
32
+ light: CSSProperties;
33
+ dark: CSSProperties;
34
+ };
35
+ }
36
+ export declare function DatalayerThemeProvider(props: React.PropsWithChildren<IDatalayerThemeProviderProps>): JSX.Element;
@@ -0,0 +1,46 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /*
3
+ * Copyright (c) 2023-2025 Datalayer, Inc.
4
+ * Distributed under the terms of the Modified BSD License.
5
+ */
6
+ import { useEffect } from 'react';
7
+ import { BaseStyles, ThemeProvider } from '@primer/react';
8
+ import { useSystemColorMode } from './useSystemColorMode';
9
+ import { datalayerTheme, datalayerThemeStyles } from './themes/datalayerTheme';
10
+ import { setupPrimerPortals } from '../utils/Portals';
11
+ /**
12
+ * Shared typographic rhythm — clean, spacious feel inspired by
13
+ * modern developer-blog aesthetics (generous line-height, open
14
+ * letter-spacing on headings, crisp body text).
15
+ */
16
+ const typographyVars = {
17
+ '--text-body-lineHeight': '1.7',
18
+ '--text-title-lineHeight': '1.2',
19
+ '--text-title-letterSpacing': '-0.02em',
20
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"',
21
+ WebkitFontSmoothing: 'antialiased',
22
+ MozOsxFontSmoothing: 'grayscale',
23
+ textRendering: 'optimizeLegibility',
24
+ };
25
+ export function DatalayerThemeProvider(props) {
26
+ const { children, colorMode, baseStyles, theme, themeStyles, ...rest } = props;
27
+ // Resolve 'auto' → actual system preference ('light' or 'dark').
28
+ const systemMode = useSystemColorMode();
29
+ const resolvedColorMode = colorMode === 'auto' ? systemMode : (colorMode ?? 'light');
30
+ const isDark = resolvedColorMode === 'dark' || resolvedColorMode === 'night';
31
+ const resolvedTheme = theme ?? datalayerTheme;
32
+ const styles = themeStyles ?? datalayerThemeStyles;
33
+ const resolvedStyles = isDark ? styles.dark : styles.light;
34
+ // Keep document.body portal-root attributes in sync so that Primer
35
+ // portals (modals, dialogs, overlays) inherit the correct color mode.
36
+ useEffect(() => {
37
+ setupPrimerPortals(resolvedColorMode === 'night' ? 'dark' : resolvedColorMode === 'day' ? 'light' : resolvedColorMode);
38
+ }, [resolvedColorMode]);
39
+ return (_jsx(ThemeProvider, { colorMode: resolvedColorMode, theme: resolvedTheme, ...rest, children: _jsx(BaseStyles, { style: {
40
+ lineHeight: '1.7',
41
+ transition: 'background-color 0.25s ease, color 0.25s ease',
42
+ ...typographyVars,
43
+ ...resolvedStyles,
44
+ ...baseStyles,
45
+ }, children: children }) }));
46
+ }
@@ -0,0 +1,4 @@
1
+ export declare const RESERVATION_CIRCLE_COLOR = "#656D76";
2
+ export declare const CREDITS_CIRCLE_COLOR = "#16A085";
3
+ export declare const JOINED_INVITE_COLOR = "#0366d6";
4
+ export declare const PENDING_INVITE_COLOR = "#cfd3d7";
@@ -0,0 +1,10 @@
1
+ /*
2
+ * Copyright (c) 2023-2025 Datalayer, Inc.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+ // export const RESERVATION_CIRCLE_COLOR_VAR = '--data-yellow-color';
6
+ export const RESERVATION_CIRCLE_COLOR = '#656D76';
7
+ // export const CREDITS_CIRCLE_COLOR_VAR = '--data-blue-color';
8
+ export const CREDITS_CIRCLE_COLOR = '#16A085';
9
+ export const JOINED_INVITE_COLOR = '#0366d6';
10
+ export const PENDING_INVITE_COLOR = '#cfd3d7';
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Datalayer Accessible Color System
3
+ * Based on Datalayer's brand manual - WCAG AA/AAA compliant
4
+ */
5
+ export declare const datalayerColors: {
6
+ black: string;
7
+ gray: string;
8
+ white: string;
9
+ greenBrand: string;
10
+ greenAccent: string;
11
+ greenText: string;
12
+ greenTint: string;
13
+ greenBright: string;
14
+ greenHover: string;
15
+ };
@@ -0,0 +1,21 @@
1
+ /*
2
+ * Copyright (c) 2023-2025 Datalayer, Inc.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+ /**
6
+ * Datalayer Accessible Color System
7
+ * Based on Datalayer's brand manual - WCAG AA/AAA compliant
8
+ */
9
+ export const datalayerColors = {
10
+ // Core Neutrals
11
+ black: '#000000', // Primary text - AAA on white
12
+ gray: '#59595C', // Secondary text - AA on white
13
+ white: '#FFFFFF', // Background
14
+ // Greens (Brand & Accessibility)
15
+ greenBrand: '#16A085', // Brand accent, icons, dividers, headings
16
+ greenAccent: '#1ABC9C', // Icons, charts, highlights on dark surfaces
17
+ greenText: '#117A65', // Accessible green for text & buttons (AA+ on white)
18
+ greenTint: '#E9F7F1', // Soft background for success / callouts
19
+ greenBright: '#2ECC71', // Highlights and glow on dark backgrounds
20
+ greenHover: '#0E6655', // Primary button hover
21
+ };
@@ -0,0 +1,4 @@
1
+ export { datalayerColors } from './datalayerColors';
2
+ export { spatialColors } from './spatialColors';
3
+ export { lovelyColors } from './lovelyColors';
4
+ export { matrixColors } from './matrixColors';
@@ -0,0 +1,8 @@
1
+ /*
2
+ * Copyright (c) 2023-2025 Datalayer, Inc.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+ export { datalayerColors } from './datalayerColors';
6
+ export { spatialColors } from './spatialColors';
7
+ export { lovelyColors } from './lovelyColors';
8
+ export { matrixColors } from './matrixColors';
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Lovely Color System – Warm & Pink-Inspired
3
+ * Rose, magenta, blush — designed for light-first usage.
4
+ */
5
+ export declare const lovelyColors: {
6
+ black: string;
7
+ gray: string;
8
+ white: string;
9
+ roseBrand: string;
10
+ roseAccent: string;
11
+ roseText: string;
12
+ roseTint: string;
13
+ roseBright: string;
14
+ roseHover: string;
15
+ };
@@ -0,0 +1,21 @@
1
+ /*
2
+ * Copyright (c) 2023-2025 Datalayer, Inc.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+ /**
6
+ * Lovely Color System – Warm & Pink-Inspired
7
+ * Rose, magenta, blush — designed for light-first usage.
8
+ */
9
+ export const lovelyColors = {
10
+ // Core Neutrals
11
+ black: '#1A0A14', // Deep plum — primary dark background
12
+ gray: '#9D7A8F', // Mauve gray — secondary text
13
+ white: '#FFF5F7', // Rose white — primary light background
14
+ // Rose / Pink palette
15
+ roseBrand: '#DB2777', // Core brand — headings, icons, dividers
16
+ roseAccent: '#EC4899', // Charts, highlights on dark surfaces
17
+ roseText: '#9D174D', // Accessible text & buttons on light (AA+)
18
+ roseTint: '#FDF2F8', // Soft background for callouts
19
+ roseBright: '#F472B6', // Highlights & glow on dark
20
+ roseHover: '#831843', // Primary button hover
21
+ };
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Matrix Color System – Terminal & Phosphor-Green
3
+ *
4
+ * Inspired by the iconic green-on-black aesthetic of The Matrix.
5
+ * Dark-first, CRT feel. Uses Datalayer brand greens for accessible text
6
+ * and introduces phosphor-green accents for the signature glow.
7
+ */
8
+ export declare const matrixColors: {
9
+ black: string;
10
+ gray: string;
11
+ white: string;
12
+ greenBrand: string;
13
+ greenAccent: string;
14
+ greenText: string;
15
+ greenTint: string;
16
+ greenPhosphor: string;
17
+ greenGlow: string;
18
+ greenHover: string;
19
+ greenTerminal: string;
20
+ };
@@ -0,0 +1,26 @@
1
+ /*
2
+ * Copyright (c) 2023-2025 Datalayer, Inc.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+ /**
6
+ * Matrix Color System – Terminal & Phosphor-Green
7
+ *
8
+ * Inspired by the iconic green-on-black aesthetic of The Matrix.
9
+ * Dark-first, CRT feel. Uses Datalayer brand greens for accessible text
10
+ * and introduces phosphor-green accents for the signature glow.
11
+ */
12
+ export const matrixColors = {
13
+ // Core Neutrals — CRT / terminal aesthetic
14
+ black: '#0D0208', // Matrix void — near-black with faint warm undertone
15
+ gray: '#4A7856', // Dim terminal gray-green — secondary text
16
+ white: '#F0FFF0', // Honeydew — light bg with subtle green cast (CRT paper)
17
+ // Green palette — Datalayer brand greens + Matrix phosphor highlights
18
+ greenBrand: '#16A085', // Datalayer brand — headings, icons, dividers
19
+ greenAccent: '#1ABC9C', // Datalayer accent — icons, charts on dark surfaces
20
+ greenText: '#117A65', // Datalayer text — accessible buttons & text on light (AA+)
21
+ greenTint: '#E8F5E9', // Matrix-tinted soft background for callouts
22
+ greenPhosphor: '#00FF41', // Iconic Matrix falling-code green — dark mode highlights
23
+ greenGlow: '#39FF14', // Neon phosphor glow — brightest accent on dark
24
+ greenHover: '#0E6655', // Datalayer hover — primary button hover
25
+ greenTerminal: '#003B00', // Deep terminal — dark mode subtle/canvas
26
+ };
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Spatial Color System – Cosmic & Space-Inspired
3
+ * Deep blues, indigo, nebula purples — designed for dark-first usage.
4
+ */
5
+ export declare const spatialColors: {
6
+ black: string;
7
+ gray: string;
8
+ white: string;
9
+ indigoBrand: string;
10
+ indigoAccent: string;
11
+ indigoText: string;
12
+ indigoTint: string;
13
+ indigoBright: string;
14
+ indigoHover: string;
15
+ };
@@ -0,0 +1,21 @@
1
+ /*
2
+ * Copyright (c) 2023-2025 Datalayer, Inc.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+ /**
6
+ * Spatial Color System – Cosmic & Space-Inspired
7
+ * Deep blues, indigo, nebula purples — designed for dark-first usage.
8
+ */
9
+ export const spatialColors = {
10
+ // Core Neutrals
11
+ black: '#0B1120', // Deep space — primary dark background
12
+ gray: '#8892B0', // Nebula gray — secondary text
13
+ white: '#F8FAFF', // Star white — primary light background
14
+ // Indigo / Cosmic palette
15
+ indigoBrand: '#4F46E5', // Core brand — headings, icons, dividers
16
+ indigoAccent: '#6366F1', // Charts, highlights on dark surfaces
17
+ indigoText: '#3730A3', // Accessible text & buttons on light (AA+)
18
+ indigoTint: '#EEF2FF', // Soft background for callouts
19
+ indigoBright: '#818CF8', // Highlights & glow on dark
20
+ indigoHover: '#312E81', // Primary button hover
21
+ };
@@ -0,0 +1,12 @@
1
+ export * from './colors';
2
+ export * from './themes/createThemeCSSVars';
3
+ export * from './themes/datalayerTheme';
4
+ export * from './DatalayerThemeProvider';
5
+ export * from './DatalayerBrandThemeProvider';
6
+ export * from './themes/spatialTheme';
7
+ export * from './themes/lovelyTheme';
8
+ export * from './themes/matrixTheme';
9
+ export * from './themes-brand/spatialBrandTheme';
10
+ export * from './themeRegistry';
11
+ export * from './Palette';
12
+ export * from './useSystemColorMode';
@@ -0,0 +1,16 @@
1
+ /*
2
+ * Copyright (c) 2023-2025 Datalayer, Inc.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+ export * from './colors';
6
+ export * from './themes/createThemeCSSVars';
7
+ export * from './themes/datalayerTheme';
8
+ export * from './DatalayerThemeProvider';
9
+ export * from './DatalayerBrandThemeProvider';
10
+ export * from './themes/spatialTheme';
11
+ export * from './themes/lovelyTheme';
12
+ export * from './themes/matrixTheme';
13
+ export * from './themes-brand/spatialBrandTheme';
14
+ export * from './themeRegistry';
15
+ export * from './Palette';
16
+ export * from './useSystemColorMode';
@@ -0,0 +1,30 @@
1
+ import { type CSSProperties } from 'react';
2
+ import { type ColorMode } from './DatalayerBrandThemeProvider';
3
+ /** Available theme variants. */
4
+ export type ThemeVariant = 'datalayer' | 'spatial' | 'lovely' | 'matrix';
5
+ /**
6
+ * Complete configuration for a theme, including the Primer theme object,
7
+ * display metadata, and CSS custom property overrides per color mode.
8
+ */
9
+ export interface ThemeConfig {
10
+ /** Human-readable name for UI display. */
11
+ label: string;
12
+ /** Short description of the theme. */
13
+ description: string;
14
+ /** Brand color for the theme — used for colored swatch buttons. */
15
+ brandColor: string;
16
+ /** Recommended default color mode for this theme. */
17
+ defaultColorMode: ColorMode;
18
+ /** Primer theme object passed to `<ThemeProvider theme={…}>`. */
19
+ primerTheme: Record<string, any>;
20
+ /** Per-mode CSS-property overrides for `<DatalayerThemeProvider themeStyles={…}>`. */
21
+ themeStyles: {
22
+ light: CSSProperties;
23
+ dark: CSSProperties;
24
+ };
25
+ }
26
+ export declare const themeConfigs: Record<ThemeVariant, ThemeConfig>;
27
+ /** All available theme variants in display order. */
28
+ export declare const themeVariants: ThemeVariant[];
29
+ /** Look up a theme config by variant name. */
30
+ export declare function getThemeConfig(variant: ThemeVariant): ThemeConfig;
@@ -0,0 +1,53 @@
1
+ /*
2
+ * Copyright (c) 2023-2025 Datalayer, Inc.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+ import { datalayerTheme, datalayerThemeStyles } from './themes/datalayerTheme';
6
+ import { spatialTheme, spatialThemeStyles } from './themes/spatialTheme';
7
+ import { lovelyTheme, lovelyThemeStyles } from './themes/lovelyTheme';
8
+ import { matrixTheme, matrixThemeStyles } from './themes/matrixTheme';
9
+ import { datalayerColors } from './colors/datalayerColors';
10
+ import { spatialColors } from './colors/spatialColors';
11
+ import { lovelyColors } from './colors/lovelyColors';
12
+ import { matrixColors } from './colors/matrixColors';
13
+ /* ─── Registry ────────────────────────────────────────────────────────── */
14
+ export const themeConfigs = {
15
+ datalayer: {
16
+ label: 'Datalayer',
17
+ description: 'Default green palette — the classic Datalayer look.',
18
+ brandColor: datalayerColors.greenBrand,
19
+ defaultColorMode: 'auto',
20
+ primerTheme: datalayerTheme,
21
+ themeStyles: datalayerThemeStyles,
22
+ },
23
+ spatial: {
24
+ label: 'Spatial',
25
+ description: 'Cosmic indigo & deep blues — inspired by space.',
26
+ brandColor: spatialColors.indigoBrand,
27
+ defaultColorMode: 'auto',
28
+ primerTheme: spatialTheme,
29
+ themeStyles: spatialThemeStyles,
30
+ },
31
+ lovely: {
32
+ label: 'Lovely',
33
+ description: 'Warm rose & magenta — soft and inviting.',
34
+ brandColor: lovelyColors.roseBrand,
35
+ defaultColorMode: 'auto',
36
+ primerTheme: lovelyTheme,
37
+ themeStyles: lovelyThemeStyles,
38
+ },
39
+ matrix: {
40
+ label: 'Matrix',
41
+ description: 'Phosphor green on black — CRT terminal aesthetic.',
42
+ brandColor: matrixColors.greenPhosphor,
43
+ defaultColorMode: 'dark',
44
+ primerTheme: matrixTheme,
45
+ themeStyles: matrixThemeStyles,
46
+ },
47
+ };
48
+ /** All available theme variants in display order. */
49
+ export const themeVariants = ['datalayer', 'spatial', 'lovely', 'matrix'];
50
+ /** Look up a theme config by variant name. */
51
+ export function getThemeConfig(variant) {
52
+ return themeConfigs[variant];
53
+ }
@@ -0,0 +1,135 @@
1
+ import { type CSSProperties } from 'react';
2
+ /**
3
+ * Structured colour definitions that mirror the *old* Primer
4
+ * `colorSchemes.*.colors` shape. Each theme file provides one of
5
+ * these for light mode and one for dark mode.
6
+ *
7
+ * The {@link colorDefsToCSS} helper converts them into a flat
8
+ * `CSSProperties` bag of Primer CSS custom-property overrides so
9
+ * the `<DatalayerThemeProvider>` can apply them via
10
+ * `<BaseStyles style={…}>`.
11
+ */
12
+ export interface ThemeColorDefs {
13
+ canvas: {
14
+ default: string;
15
+ subtle?: string;
16
+ };
17
+ fg: {
18
+ default: string;
19
+ muted: string;
20
+ onEmphasis: string;
21
+ };
22
+ accent: {
23
+ fg: string;
24
+ emphasis: string;
25
+ muted: string;
26
+ subtle?: string;
27
+ };
28
+ success: {
29
+ fg: string;
30
+ emphasis: string;
31
+ muted: string;
32
+ subtle?: string;
33
+ };
34
+ border?: {
35
+ default: string;
36
+ muted: string;
37
+ };
38
+ btn: {
39
+ text: string;
40
+ bg: string;
41
+ border: string;
42
+ hoverBg: string;
43
+ hoverBorder: string;
44
+ activeBg: string;
45
+ activeBorder: string;
46
+ selectedBg: string;
47
+ counterBg: string;
48
+ primary: {
49
+ text: string;
50
+ bg: string;
51
+ border: string;
52
+ hoverBg: string;
53
+ hoverBorder: string;
54
+ selectedBg: string;
55
+ disabledText: string;
56
+ disabledBg: string;
57
+ disabledBorder: string;
58
+ icon: string;
59
+ counterBg: string;
60
+ };
61
+ outline: {
62
+ text: string;
63
+ hoverText: string;
64
+ hoverBg: string;
65
+ hoverBorder: string;
66
+ hoverCounterBg: string;
67
+ selectedText: string;
68
+ selectedBg: string;
69
+ selectedBorder: string;
70
+ disabledText: string;
71
+ disabledBg: string;
72
+ disabledCounterBg: string;
73
+ counterBg: string;
74
+ counterFg: string;
75
+ hoverCounterFg: string;
76
+ disabledCounterFg: string;
77
+ };
78
+ danger: {
79
+ text: string;
80
+ hoverText: string;
81
+ hoverBg: string;
82
+ hoverBorder: string;
83
+ hoverCounterBg: string;
84
+ selectedText: string;
85
+ selectedBg: string;
86
+ selectedBorder: string;
87
+ disabledText: string;
88
+ disabledBg: string;
89
+ disabledCounterBg: string;
90
+ counterBg: string;
91
+ counterFg: string;
92
+ hoverCounterFg: string;
93
+ disabledCounterFg: string;
94
+ icon: string;
95
+ };
96
+ };
97
+ }
98
+ /**
99
+ * Convert a structured `ThemeColorDefs` object into a flat
100
+ * `CSSProperties` bag of Primer React CSS custom-property overrides.
101
+ *
102
+ * These variables are the *functional tokens* consumed by Primer
103
+ * React components (sourced from `@primer/primitives`). Setting
104
+ * them on a parent element is enough to retheme every Primer
105
+ * component in the sub-tree.
106
+ *
107
+ * ### Variable families covered
108
+ *
109
+ * | Family | Example variable |
110
+ * |------------------|----------------------------------------|
111
+ * | Background | `--bgColor-default` |
112
+ * | Foreground | `--fgColor-default` |
113
+ * | Border | `--borderColor-default` |
114
+ * | Link | `--fgColor-link` |
115
+ * | Accent / Success | `--bgColor-accent-emphasis` |
116
+ * | Default button | `--button-default-bgColor-rest` |
117
+ * | Primary button | `--button-primary-bgColor-rest` |
118
+ * | Outline button | `--button-outline-fgColor-rest` |
119
+ * | Danger button | `--button-danger-bgColor-hover` |
120
+ * | Button counters | `--buttonCounter-primary-bgColor-rest` |
121
+ * | Legacy aliases | `--color-btn-primary-bg` |
122
+ * | Brand (custom) | `--brand-color-canvas-default` |
123
+ */
124
+ export declare function colorDefsToCSS(defs: ThemeColorDefs): CSSProperties;
125
+ /** Light + dark CSS-property pairs for the `themeStyles` prop. */
126
+ export interface ThemeStyles {
127
+ light: CSSProperties;
128
+ dark: CSSProperties;
129
+ }
130
+ /**
131
+ * Build a complete `ThemeStyles` object from light / dark
132
+ * `ThemeColorDefs`. The result is ready to pass straight to
133
+ * `<DatalayerThemeProvider themeStyles={…}>`.
134
+ */
135
+ export declare function buildThemeStyles(light: ThemeColorDefs, dark: ThemeColorDefs): ThemeStyles;