@datalayer/primer-addons 1.0.15 → 1.0.18

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 (51) hide show
  1. package/lib/App.js +2 -2
  2. package/lib/components/box/Box.d.ts +1 -2
  3. package/lib/components/content-loader/ContentLoader.js +4 -2
  4. package/lib/components/icons/CircleIcon.js +6 -4
  5. package/lib/components/index.d.ts +1 -1
  6. package/lib/components/index.js +1 -1
  7. package/lib/components/logo/AI.d.ts +17 -0
  8. package/lib/components/logo/AI.js +18 -0
  9. package/lib/components/logo/AI2.d.ts +20 -0
  10. package/lib/components/logo/AI2.js +23 -0
  11. package/lib/components/logo/DI.d.ts +19 -0
  12. package/lib/components/logo/DI.js +20 -0
  13. package/lib/components/logo/DatalayerTextAI.d.ts +25 -0
  14. package/lib/components/logo/DatalayerTextAI.js +40 -0
  15. package/lib/components/logo/index.d.ts +4 -0
  16. package/lib/components/logo/index.js +4 -0
  17. package/lib/components/{overlay/Overlay.d.ts → side-overlay/SideOverlay.d.ts} +3 -3
  18. package/lib/components/{overlay/Overlay.js → side-overlay/SideOverlay.js} +16 -16
  19. package/lib/components/side-overlay/SideOverlay.stories.d.ts +16 -0
  20. package/lib/components/{overlay/Overlay.stories.js → side-overlay/SideOverlay.stories.js} +13 -13
  21. package/lib/components/slider/Slider.js +2 -1
  22. package/lib/components/toolbar/FloatingToolbar.js +2 -2
  23. package/lib/theme/DatalayerThemeProvider.d.ts +1 -1
  24. package/lib/theme/colors/index.d.ts +0 -1
  25. package/lib/theme/colors/index.js +0 -1
  26. package/lib/theme/{themes → css}/createThemeCSSVars.js +8 -0
  27. package/lib/theme/index.d.ts +2 -1
  28. package/lib/theme/index.js +2 -1
  29. package/lib/theme/indicators/index.d.ts +1 -0
  30. package/lib/theme/indicators/index.js +5 -0
  31. package/lib/theme/palettes/{SvgPalette.d.ts → ColorPalette.d.ts} +7 -7
  32. package/lib/theme/palettes/{SvgPalette.js → ColorPalette.js} +7 -7
  33. package/lib/theme/palettes/index.d.ts +1 -1
  34. package/lib/theme/palettes/index.js +1 -1
  35. package/lib/theme/themes/datalayerTheme.d.ts +1 -1
  36. package/lib/theme/themes/datalayerTheme.js +1 -1
  37. package/lib/theme/themes/earthTheme.d.ts +1 -1
  38. package/lib/theme/themes/earthTheme.js +1 -1
  39. package/lib/theme/themes/lovelyTheme.d.ts +1 -1
  40. package/lib/theme/themes/lovelyTheme.js +1 -1
  41. package/lib/theme/themes/matrixTheme.d.ts +1 -1
  42. package/lib/theme/themes/matrixTheme.js +1 -1
  43. package/lib/theme/themes/spatialTheme.d.ts +1 -1
  44. package/lib/theme/themes/spatialTheme.js +1 -1
  45. package/lib/theme/useThemeStore.d.ts +5 -3
  46. package/lib/theme/useThemeStore.js +78 -9
  47. package/package.json +6 -4
  48. package/lib/components/overlay/Overlay.stories.d.ts +0 -16
  49. /package/lib/theme/{themes → css}/createThemeCSSVars.d.ts +0 -0
  50. /package/lib/theme/{colors → indicators}/indicatorColors.d.ts +0 -0
  51. /package/lib/theme/{colors → indicators}/indicatorColors.js +0 -0
package/lib/App.js CHANGED
@@ -3,7 +3,7 @@ import { useState, useRef } from "react";
3
3
  import { BaseStyles, Box, Text, NavList, Heading, ThemeProvider, Button, theme, ActionMenu, IconButton, ActionList } from "@primer/react";
4
4
  import { KebabHorizontalIcon } from "@primer/octicons-react";
5
5
  import { DatalayerIcon, LogOutIcon, SettingsIcon } from "@datalayer/icons-react";
6
- import { Slider, Overlay } from ".";
6
+ import { Slider, SideOverlay } from ".";
7
7
  import "@primer/primitives/dist/css/base/typography/typography.css";
8
8
  import "@primer/primitives/dist/css/base/motion/motion.css";
9
9
  import "@primer/primitives/dist/css/functional/themes/light.css";
@@ -20,6 +20,6 @@ const App = () => {
20
20
  const openButtonRef = useRef(null);
21
21
  const closeButtonRef = useRef(null);
22
22
  const headingRef = useRef(null);
23
- return (_jsx(ThemeProvider, { colorMode: "day", theme: theme, children: _jsxs(BaseStyles, { children: [_jsxs(ActionMenu, { children: [_jsx(ActionMenu.Anchor, { children: _jsx(IconButton, { icon: KebabHorizontalIcon, variant: "invisible", "aria-label": "jupyter-runtimes-more" }) }), _jsx(ActionMenu.Overlay, { width: "medium", children: _jsxs(ActionList, { children: [_jsxs(ActionList.Group, { children: [_jsx(ActionList.GroupHeading, { children: "More\u2026" }), _jsxs(ActionList.Item, { onSelect: () => alert('click'), children: [_jsx(ActionList.LeadingVisual, { children: _jsx(SettingsIcon, {}) }), "Settings", _jsx(ActionList.Description, { variant: "block", children: "Configure your personal settings." })] }), _jsxs(ActionList.Item, { onSelect: () => alert('click'), children: [_jsx(ActionList.LeadingVisual, { children: _jsx(DatalayerIcon, {}) }), "About", _jsx(ActionList.Description, { variant: "block", children: "About Runtimes." })] })] }), _jsxs(_Fragment, { children: [_jsx(ActionList.Divider, {}), _jsxs(ActionList.Item, { variant: "danger", onSelect: () => alert('click'), children: [_jsx(ActionList.LeadingVisual, { children: _jsx(LogOutIcon, {}) }), "Logout"] })] })] }) })] }), _jsxs(Box, { bg: "canvas.default", sx: { display: 'flex' }, children: [_jsx(Box, { children: _jsxs(NavList, { children: [_jsx(NavList.Item, { href: "/", "aria-current": "page", children: "Home" }), _jsx(NavList.Item, { href: "/about", children: "About" }), _jsx(NavList.Item, { href: "/contact", children: "Contact" })] }) }), _jsxs(Box, { p: 3, sx: { flexGrow: 1 }, children: [_jsx(Box, { children: _jsx(Text, { children: "Primer React Addons" }) }), _jsx(Box, { children: _jsx(Slider, { id: "slider", name: "slider", min: 1, max: 10, onChange: () => { } }) }), _jsx(Box, { p: 3, bg: "canvas.default", children: _jsxs(Box, { children: [_jsx(Box, { sx: { width: '100%', bg: 'darkgray' }, children: _jsx(Heading, { ref: headingRef, children: "Header" }) }), _jsxs(Box, { children: [_jsx(Button, { ref: openButtonRef, onClick: () => { setIsOpen(!isOpen); }, children: "Open overlay" }), _jsx(Overlay, { isOpen: isOpen, content: _jsxs(Text, { children: ["Look, I am an ", _jsx(Button, { children: "Overlay \uD83D\uDC49" })] }), setIsOpen: setIsOpen, openButtonRef: openButtonRef, closeButtonRef: closeButtonRef, headingRef: headingRef })] })] }) })] })] })] }) }));
23
+ return (_jsx(ThemeProvider, { colorMode: "day", theme: theme, children: _jsxs(BaseStyles, { children: [_jsxs(ActionMenu, { children: [_jsx(ActionMenu.Anchor, { children: _jsx(IconButton, { icon: KebabHorizontalIcon, variant: "invisible", "aria-label": "jupyter-runtimes-more" }) }), _jsx(ActionMenu.Overlay, { width: "medium", children: _jsxs(ActionList, { children: [_jsxs(ActionList.Group, { children: [_jsx(ActionList.GroupHeading, { children: "More\u2026" }), _jsxs(ActionList.Item, { onSelect: () => alert('click'), children: [_jsx(ActionList.LeadingVisual, { children: _jsx(SettingsIcon, {}) }), "Settings", _jsx(ActionList.Description, { variant: "block", children: "Configure your personal settings." })] }), _jsxs(ActionList.Item, { onSelect: () => alert('click'), children: [_jsx(ActionList.LeadingVisual, { children: _jsx(DatalayerIcon, {}) }), "About", _jsx(ActionList.Description, { variant: "block", children: "About Runtimes." })] })] }), _jsxs(_Fragment, { children: [_jsx(ActionList.Divider, {}), _jsxs(ActionList.Item, { variant: "danger", onSelect: () => alert('click'), children: [_jsx(ActionList.LeadingVisual, { children: _jsx(LogOutIcon, {}) }), "Logout"] })] })] }) })] }), _jsxs(Box, { bg: "canvas.default", sx: { display: 'flex' }, children: [_jsx(Box, { children: _jsxs(NavList, { children: [_jsx(NavList.Item, { href: "/", "aria-current": "page", children: "Home" }), _jsx(NavList.Item, { href: "/about", children: "About" }), _jsx(NavList.Item, { href: "/contact", children: "Contact" })] }) }), _jsxs(Box, { p: 3, sx: { flexGrow: 1 }, children: [_jsx(Box, { children: _jsx(Text, { children: "Primer React Addons" }) }), _jsx(Box, { children: _jsx(Slider, { id: "slider", name: "slider", min: 1, max: 10, onChange: () => { } }) }), _jsx(Box, { p: 3, bg: "canvas.default", children: _jsxs(Box, { children: [_jsx(Box, { sx: { width: '100%', bg: 'darkgray' }, children: _jsx(Heading, { ref: headingRef, children: "Header" }) }), _jsxs(Box, { children: [_jsx(Button, { ref: openButtonRef, onClick: () => { setIsOpen(!isOpen); }, children: "Open overlay" }), _jsx(SideOverlay, { isOpen: isOpen, content: _jsxs(Text, { children: ["Look, I am an ", _jsx(Button, { children: "Overlay \uD83D\uDC49" })] }), setIsOpen: setIsOpen, openButtonRef: openButtonRef, closeButtonRef: closeButtonRef, headingRef: headingRef })] })] }) })] })] })] }) }));
24
24
  };
25
25
  export default App;
@@ -1,7 +1,6 @@
1
1
  import { ComponentProps } from 'react';
2
2
  import type { BackgroundProps, BorderProps, ColorProps, FlexboxProps, GridProps, LayoutProps, PositionProps, ShadowProps, SpaceProps, TypographyProps } from 'styled-system';
3
3
  import { type SxProp } from './sx';
4
- type StyledBoxProps = SxProp & SpaceProps & ColorProps & TypographyProps & LayoutProps & FlexboxProps & GridProps & BackgroundProps & BorderProps & PositionProps & ShadowProps;
5
- export declare const Box: import("styled-components").StyledComponent<"div", any, StyledBoxProps, never>;
4
+ export declare const Box: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "sx" | keyof SpaceProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>, string | number | symbol> | keyof ColorProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>, string | number | symbol> | keyof TypographyProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>> | keyof LayoutProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>> | keyof FlexboxProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>> | keyof GridProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>> | keyof BackgroundProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>, import("csstype").Property.Background<import("styled-system").TLengthStyledSystem>> | keyof BorderProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>, import("csstype").Property.Border<import("styled-system").TLengthStyledSystem>> | keyof PositionProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>> | keyof ShadowProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>>> & SxProp & SpaceProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>, string | number | symbol> & ColorProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>, string | number | symbol> & TypographyProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>> & LayoutProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>> & FlexboxProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>> & GridProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>> & BackgroundProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>, import("csstype").Property.Background<import("styled-system").TLengthStyledSystem>> & BorderProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>, import("csstype").Property.Border<import("styled-system").TLengthStyledSystem>> & PositionProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>> & ShadowProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>>, never> & Partial<Pick<import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "sx" | keyof SpaceProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>, string | number | symbol> | keyof ColorProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>, string | number | symbol> | keyof TypographyProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>> | keyof LayoutProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>> | keyof FlexboxProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>> | keyof GridProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>> | keyof BackgroundProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>, import("csstype").Property.Background<import("styled-system").TLengthStyledSystem>> | keyof BorderProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>, import("csstype").Property.Border<import("styled-system").TLengthStyledSystem>> | keyof PositionProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>> | keyof ShadowProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>>> & SxProp & SpaceProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>, string | number | symbol> & ColorProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>, string | number | symbol> & TypographyProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>> & LayoutProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>> & FlexboxProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>> & GridProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>> & BackgroundProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>, import("csstype").Property.Background<import("styled-system").TLengthStyledSystem>> & BorderProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>, import("csstype").Property.Border<import("styled-system").TLengthStyledSystem>> & PositionProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>> & ShadowProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>>, never>>> & string;
6
5
  export type BoxProps = ComponentProps<typeof Box>;
7
6
  export default Box;
@@ -1,8 +1,10 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { Box } from "@primer/react";
2
+ import { Box, useTheme } from "@primer/react";
3
3
  import Skeleton, { SkeletonTheme } from "react-loading-skeleton";
4
4
  import 'react-loading-skeleton/dist/skeleton.css';
5
5
  export const ContentLoader = (props) => {
6
- return (_jsx(Box, { children: _jsx(SkeletonTheme, { children: _jsx(Skeleton, { ...props }) }) }));
6
+ const { colorMode } = useTheme();
7
+ const isDark = colorMode !== 'day';
8
+ return (_jsx(Box, { children: _jsx(SkeletonTheme, { baseColor: isDark ? 'var(--bgColor-muted, #21262d)' : 'var(--bgColor-muted, #ebebeb)', highlightColor: isDark ? 'var(--borderColor-muted, #30363d)' : 'var(--borderColor-muted, #f5f5f5)', children: _jsx(Skeleton, { ...props }) }) }));
7
9
  };
8
10
  export default ContentLoader;
@@ -1,11 +1,13 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useTheme } from '@primer/react';
3
3
  import { CircleCurrentColorIcon } from '@datalayer/icons-react';
4
- const COLORS = {
5
- 'danger': 'danger',
6
- };
7
4
  export const CircleIcon = ({ color = 'white', variant = 'fg', }) => {
8
5
  const { theme } = useTheme();
9
- return (_jsx(CircleCurrentColorIcon, { fill: theme?.colors[COLORS[color]][variant] ?? color ?? 'white' }));
6
+ const colorGroup = theme?.colors?.[color];
7
+ const resolvedColor = colorGroup && typeof colorGroup === 'object'
8
+ ? colorGroup[variant] ??
9
+ colorGroup.fg
10
+ : undefined;
11
+ return (_jsx(CircleCurrentColorIcon, { fill: resolvedColor ?? color ?? 'currentColor', color: resolvedColor ?? color ?? 'currentColor' }));
10
12
  };
11
13
  export default CircleIcon;
@@ -5,7 +5,7 @@ export * from "./card/Card";
5
5
  export * from "./content-loader/ContentLoader";
6
6
  export * from "./closeable-flash/CloseableFlash";
7
7
  export * from "./icons/CircleIcon";
8
- export * from "./overlay/Overlay";
8
+ export * from "./side-overlay/SideOverlay";
9
9
  export * from "./slider/Slider";
10
10
  export * from "./logo";
11
11
  export * from "./appearance";
@@ -5,7 +5,7 @@ export * from "./card/Card";
5
5
  export * from "./content-loader/ContentLoader";
6
6
  export * from "./closeable-flash/CloseableFlash";
7
7
  export * from "./icons/CircleIcon";
8
- export * from "./overlay/Overlay";
8
+ export * from "./side-overlay/SideOverlay";
9
9
  export * from "./slider/Slider";
10
10
  export * from "./logo";
11
11
  export * from "./appearance";
@@ -0,0 +1,17 @@
1
+ import { type SVGProps } from 'react';
2
+ import { type ThemeVariant } from '../../theme';
3
+ export interface AIProps extends Omit<SVGProps<SVGSVGElement>, 'ref'> {
4
+ size?: number;
5
+ variant?: ThemeVariant;
6
+ colorMode?: 'light' | 'dark' | 'auto';
7
+ /** Colour of the "I" glyph. */
8
+ primaryColor?: string;
9
+ /** Colour of the "A" glyph. */
10
+ secondaryColor?: string;
11
+ }
12
+ /**
13
+ * AI glyph mark from the official brand source SVG.
14
+ * Defaults to themed logo colors and supports explicit overrides.
15
+ */
16
+ export declare const AI: import("react").ForwardRefExoticComponent<AIProps & import("react").RefAttributes<SVGSVGElement>>;
17
+ export default AI;
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /*
3
+ * Copyright (c) 2023-2026 Datalayer, Inc.
4
+ * Distributed under the terms of the Modified BSD License.
5
+ */
6
+ import { forwardRef } from 'react';
7
+ import { getLogoColors } from './DatalayerLogo';
8
+ /**
9
+ * AI glyph mark from the official brand source SVG.
10
+ * Defaults to themed logo colors and supports explicit overrides.
11
+ */
12
+ export const AI = forwardRef(function AI({ size = 24, variant = 'datalayer', colorMode = 'light', primaryColor, secondaryColor, ...svgProps }, ref) {
13
+ const themed = getLogoColors(variant, colorMode);
14
+ const resolvedPrimary = primaryColor ?? themed.primary;
15
+ const resolvedSecondary = secondaryColor ?? themed.textColor;
16
+ return (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", width: size, height: size, role: "img", "aria-label": "AI", ref: ref, ...svgProps, children: [_jsx("path", { d: "m13.788825 3.932 6.43325 16.136075h3.5279L17.316725 3.932H13.788825Z", fill: resolvedPrimary, strokeWidth: 0.25 }), _jsx("path", { d: "m6.325375 13.682775 2.20125 -5.67065 2.201275 5.67065H6.325375ZM6.68225 3.932 0.25 20.068075h3.596525l1.3155 -3.3886h6.729425l1.315275 3.3886h3.59655L10.371 3.932H6.68225Z", fill: resolvedSecondary, fillRule: "evenodd", clipRule: "evenodd", strokeWidth: 0.25 })] }));
17
+ });
18
+ export default AI;
@@ -0,0 +1,20 @@
1
+ import { type SVGProps } from 'react';
2
+ import { type ThemeVariant } from '../../theme';
3
+ export interface AI2Props extends Omit<SVGProps<SVGSVGElement>, 'ref'> {
4
+ size?: number;
5
+ variant?: ThemeVariant;
6
+ colorMode?: 'light' | 'dark' | 'auto';
7
+ /** Colour of the "I" glyph. */
8
+ primaryColor?: string;
9
+ /** Colour of the "A" glyph. */
10
+ secondaryColor?: string;
11
+ }
12
+ /**
13
+ * Alternate AI glyph mark.
14
+ *
15
+ * A is rendered with an oblique left bar, a right vertical bar,
16
+ * and a horizontal crossbar.
17
+ * I is rendered as a simple vertical bar.
18
+ */
19
+ export declare const AI2: import("react").ForwardRefExoticComponent<AI2Props & import("react").RefAttributes<SVGSVGElement>>;
20
+ export default AI2;
@@ -0,0 +1,23 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /*
3
+ * Copyright (c) 2023-2026 Datalayer, Inc.
4
+ * Distributed under the terms of the Modified BSD License.
5
+ */
6
+ import { forwardRef } from 'react';
7
+ import { getLogoColors } from './DatalayerLogo';
8
+ /**
9
+ * Alternate AI glyph mark.
10
+ *
11
+ * A is rendered with an oblique left bar, a right vertical bar,
12
+ * and a horizontal crossbar.
13
+ * I is rendered as a simple vertical bar.
14
+ */
15
+ export const AI2 = forwardRef(function AI2({ size = 24, variant = 'datalayer', colorMode = 'light', primaryColor, secondaryColor, ...svgProps }, ref) {
16
+ const themed = getLogoColors(variant, colorMode);
17
+ const resolvedPrimary = primaryColor ?? themed.primary;
18
+ const resolvedSecondary = secondaryColor ?? themed.textColor;
19
+ const barWidth = 3.1;
20
+ const leftBarBottomInnerX = -2.2 + barWidth;
21
+ return (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "-2.2 0 26.2 24", width: size, height: size, role: "img", "aria-label": "AI2", ref: ref, ...svgProps, children: [_jsx("path", { d: `M15.35 3.5h${barWidth}V20h-${barWidth}z`, fill: resolvedPrimary }), _jsx("path", { d: `M-2.2 20 9.8 3.5h${barWidth}L${leftBarBottomInnerX} 20H-2.2z`, fill: resolvedSecondary }), _jsx("path", { d: `M10.35 3.5h${barWidth}V20h-${barWidth}z`, fill: resolvedSecondary }), _jsx("path", { d: "M3.5 12.95h9.6v2.75H3.5z", fill: resolvedSecondary })] }));
22
+ });
23
+ export default AI2;
@@ -0,0 +1,19 @@
1
+ import { type SVGProps } from 'react';
2
+ import { type ThemeVariant } from '../../theme';
3
+ export interface DIProps extends Omit<SVGProps<SVGSVGElement>, 'ref'> {
4
+ size?: number;
5
+ variant?: ThemeVariant;
6
+ colorMode?: 'light' | 'dark' | 'auto';
7
+ /** Colour of the "I" glyph. */
8
+ primaryColor?: string;
9
+ /** Colour of the "D" glyph. */
10
+ secondaryColor?: string;
11
+ }
12
+ /**
13
+ * DI glyph mark.
14
+ *
15
+ * Uses the same public API and semantic color mapping as AI:
16
+ * primaryColor styles the "I", secondaryColor styles the "D".
17
+ */
18
+ export declare const DI: import("react").ForwardRefExoticComponent<DIProps & import("react").RefAttributes<SVGSVGElement>>;
19
+ export default DI;
@@ -0,0 +1,20 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /*
3
+ * Copyright (c) 2023-2026 Datalayer, Inc.
4
+ * Distributed under the terms of the Modified BSD License.
5
+ */
6
+ import { forwardRef } from 'react';
7
+ import { getLogoColors } from './DatalayerLogo';
8
+ /**
9
+ * DI glyph mark.
10
+ *
11
+ * Uses the same public API and semantic color mapping as AI:
12
+ * primaryColor styles the "I", secondaryColor styles the "D".
13
+ */
14
+ export const DI = forwardRef(function DI({ size = 24, variant = 'datalayer', colorMode = 'light', primaryColor, secondaryColor, ...svgProps }, ref) {
15
+ const themed = getLogoColors(variant, colorMode);
16
+ const resolvedPrimary = primaryColor ?? themed.primary;
17
+ const resolvedSecondary = secondaryColor ?? themed.textColor;
18
+ return (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", width: size, height: size, role: "img", "aria-label": "DI", ref: ref, ...svgProps, children: [_jsx("path", { d: "M2 3.932H5V20.068075H2ZM3.5 3.932H6.5L12.933 20.068075H9.933ZM2 17.068075H11.4V20.068075H2Z", fill: resolvedSecondary, strokeWidth: 0.25 }), _jsx("path", { d: "m10.788825 3.932 6.43325 16.136075h3.5279L14.316725 3.932H10.788825Z", fill: resolvedPrimary, strokeWidth: 0.25 })] }));
19
+ });
20
+ export default DI;
@@ -0,0 +1,25 @@
1
+ import { type SVGProps } from 'react';
2
+ import { type ThemeVariant } from '../../theme';
3
+ export interface DatalayerTextAIProps extends Omit<SVGProps<SVGSVGElement>, 'ref'> {
4
+ size?: number;
5
+ scale?: number;
6
+ colorMode?: 'light' | 'dark' | 'auto';
7
+ variant?: ThemeVariant;
8
+ /** Colour for the "LAYER" part of the wordmark. */
9
+ primaryColor?: string;
10
+ /** Secondary accent colour used by the AI glyph. */
11
+ secondaryColor?: string;
12
+ /** Colour for the "DATA" part of the wordmark. */
13
+ textColor?: string;
14
+ textSizeMultiplier?: number;
15
+ aiPrimaryColor?: string;
16
+ aiSecondaryColor?: string;
17
+ /** Gap between wordmark and AI glyph in viewBox units. */
18
+ aiGap?: number;
19
+ }
20
+ /**
21
+ * Datalayer wordmark followed by AI glyph on one line.
22
+ * Both elements are aligned to the same 25-unit cap height.
23
+ */
24
+ export declare const DatalayerTextAI: import("react").ForwardRefExoticComponent<DatalayerTextAIProps & import("react").RefAttributes<SVGSVGElement>>;
25
+ export default DatalayerTextAI;
@@ -0,0 +1,40 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /*
3
+ * Copyright (c) 2023-2026 Datalayer, Inc.
4
+ * Distributed under the terms of the Modified BSD License.
5
+ */
6
+ import { forwardRef } from 'react';
7
+ import { AI } from './AI';
8
+ import { DatalayerText } from './DatalayerText';
9
+ import { getLogoColors } from './DatalayerLogo';
10
+ const TEXT_LEFT_TRIM = 12;
11
+ const TEXT_END_X = 136.672 - TEXT_LEFT_TRIM;
12
+ const AI_SIZE = 24;
13
+ const AI_VISIBLE_TOP = 3.932;
14
+ const AI_VISIBLE_LEFT = 0.25;
15
+ const AI_VISIBLE_HEIGHT = 16.136075;
16
+ const AI_SCALE_TO_TEXT_HEIGHT = 25 / AI_VISIBLE_HEIGHT;
17
+ const AI_RENDER_SIZE = AI_SIZE * AI_SCALE_TO_TEXT_HEIGHT;
18
+ const AI_X_TRIM = AI_VISIBLE_LEFT * AI_SCALE_TO_TEXT_HEIGHT;
19
+ const AI_Y_TRIM = AI_VISIBLE_TOP * AI_SCALE_TO_TEXT_HEIGHT;
20
+ /**
21
+ * Datalayer wordmark followed by AI glyph on one line.
22
+ * Both elements are aligned to the same 25-unit cap height.
23
+ */
24
+ export const DatalayerTextAI = forwardRef(function DatalayerTextAI({ size = 25, scale = 1, colorMode = 'light', variant = 'datalayer', primaryColor, secondaryColor, textColor,
25
+ // 2.380655 ~= 25 / (0.7 * 15.00187)
26
+ textSizeMultiplier = 2.380655, aiPrimaryColor, aiSecondaryColor, aiGap = 6, ...svgProps }, ref) {
27
+ const themed = getLogoColors(variant, colorMode);
28
+ const layerColor = primaryColor ?? themed.primary;
29
+ const accentColor = secondaryColor ?? themed.secondary;
30
+ const dataTextColor = textColor ?? themed.textColor;
31
+ const resolvedAiPrimary = aiPrimaryColor ?? layerColor;
32
+ const resolvedAiSecondary = aiSecondaryColor ?? accentColor;
33
+ const viewBoxWidth = TEXT_END_X + aiGap + AI_RENDER_SIZE - AI_X_TRIM;
34
+ const baseHeight = size;
35
+ const baseWidth = (viewBoxWidth / 25) * size;
36
+ const height = baseHeight * scale;
37
+ const width = baseWidth * scale;
38
+ return (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: `0 0 ${viewBoxWidth} 25`, width: width, height: height, role: "img", "aria-label": "Datalayer AI", ref: ref, ...svgProps, children: [_jsx(DatalayerText, { primaryColor: layerColor, secondaryColor: dataTextColor, sizeMultiplier: textSizeMultiplier, x: -TEXT_LEFT_TRIM }), _jsx(AI, { size: AI_RENDER_SIZE, x: TEXT_END_X + aiGap - AI_X_TRIM, y: -AI_Y_TRIM, variant: variant, colorMode: colorMode, primaryColor: resolvedAiPrimary, secondaryColor: resolvedAiSecondary })] }));
39
+ });
40
+ export default DatalayerTextAI;
@@ -1,3 +1,7 @@
1
+ export * from './AI';
2
+ export * from './AI2';
3
+ export * from './DI';
1
4
  export * from './DatalayerLogo';
2
5
  export * from './DatalayerLogoText';
3
6
  export * from './DatalayerText';
7
+ export * from './DatalayerTextAI';
@@ -1,3 +1,7 @@
1
+ export * from './AI';
2
+ export * from './AI2';
3
+ export * from './DI';
1
4
  export * from './DatalayerLogo';
2
5
  export * from './DatalayerLogoText';
3
6
  export * from './DatalayerText';
7
+ export * from './DatalayerTextAI';
@@ -1,4 +1,4 @@
1
- export interface OverlayProps {
1
+ export interface SideOverlayProps {
2
2
  closeButtonRef?: React.RefObject<HTMLButtonElement>;
3
3
  content: JSX.Element;
4
4
  direction?: 'left' | 'right';
@@ -9,5 +9,5 @@ export interface OverlayProps {
9
9
  width?: number | string;
10
10
  zIndex?: number;
11
11
  }
12
- export declare const Overlay: ({ width, direction, zIndex, ...rest }: OverlayProps) => import("react/jsx-runtime").JSX.Element;
13
- export default Overlay;
12
+ export declare const SideOverlay: ({ width, direction, zIndex, ...rest }: SideOverlayProps) => import("react/jsx-runtime").JSX.Element;
13
+ export default SideOverlay;
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useEffect, useState } from 'react';
3
- import { IconButton, Overlay as PrimerOverlay, BaseStyles, ThemeProvider, useTheme } from "@primer/react";
3
+ import { IconButton, Overlay as PrimerOverlay, ThemeProvider, useTheme } from "@primer/react";
4
4
  import { XIcon } from "@primer/octicons-react";
5
5
  import { Box } from '../box/Box';
6
6
  const PrimerAddonOverlay = (props) => {
@@ -25,19 +25,19 @@ const PrimerAddonOverlay = (props) => {
25
25
  }
26
26
  closeOverlay();
27
27
  };
28
- const overlayContent = (_jsx(ThemeProvider, { theme: theme, colorMode: colorMode, children: _jsx(BaseStyles, { children: _jsxs(Box, { sx: {
29
- /* We need to remove the padding */
30
- height: `calc(100vh - ${top}px - 8px)`,
31
- width,
32
- display: 'flex',
33
- flexDirection: 'column',
34
- alignItems: 'center',
35
- padding: '4px'
36
- }, children: [_jsx(Box, { sx: {
37
- display: 'flex',
38
- justifyContent: 'right',
39
- width: '100%'
40
- }, children: _jsx(IconButton, { variant: 'invisible', ref: closeButtonRef, onClick: closeOverlay, icon: XIcon, "aria-labelledby": "close" }) }), content] }) }) }));
28
+ const overlayContent = (_jsx(ThemeProvider, { theme: theme, colorMode: colorMode, children: _jsxs(Box, { sx: {
29
+ /* We need to remove the padding */
30
+ height: `calc(100vh - ${top}px - 8px)`,
31
+ width,
32
+ display: 'flex',
33
+ flexDirection: 'column',
34
+ alignItems: 'center',
35
+ padding: '4px'
36
+ }, children: [_jsx(Box, { sx: {
37
+ display: 'flex',
38
+ justifyContent: 'right',
39
+ width: '100%'
40
+ }, children: _jsx(IconButton, { variant: 'invisible', ref: closeButtonRef, onClick: closeOverlay, icon: XIcon, "aria-labelledby": "close" }) }), content] }) }));
41
41
  return (closeButtonRef && openButtonRef ?
42
42
  _jsx(_Fragment, { children: isOpen ?
43
43
  direction === 'left' ?
@@ -48,7 +48,7 @@ const PrimerAddonOverlay = (props) => {
48
48
  :
49
49
  _jsx(_Fragment, {}));
50
50
  };
51
- export const Overlay = ({ width = '500px', direction = 'left', zIndex = 100, ...rest }) => {
51
+ export const SideOverlay = ({ width = '500px', direction = 'left', zIndex = 100, ...rest }) => {
52
52
  return (_jsx(PrimerAddonOverlay, { width: width, direction: direction, zIndex: zIndex, ...rest }));
53
53
  };
54
- export default Overlay;
54
+ export default SideOverlay;
@@ -0,0 +1,16 @@
1
+ import type { StoryObj } from '@storybook/react';
2
+ import { SideOverlayProps } from '../..';
3
+ declare const meta: {
4
+ title: string;
5
+ component: ({ width, direction, zIndex, ...rest }: SideOverlayProps) => import("react/jsx-runtime").JSX.Element;
6
+ tags: string[];
7
+ parameters: {
8
+ layout: string;
9
+ };
10
+ };
11
+ export default meta;
12
+ type Story = StoryObj<typeof meta>;
13
+ export declare const SideOverlayDayLeft: Story;
14
+ export declare const SideOverlayDayRight: Story;
15
+ export declare const SideOverlayNightLeft: Story;
16
+ export declare const SideOverlayNightRight: Story;
@@ -1,10 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useState, useRef } from "react";
3
3
  import { Heading, Text, Box, Button } from "@primer/react";
4
- import { Overlay } from '../..';
4
+ import { SideOverlay } from '../..';
5
5
  const meta = {
6
- title: 'Components/Overlay',
7
- component: Overlay,
6
+ title: 'Components/SideOverlay',
7
+ component: SideOverlay,
8
8
  // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/react/writing-docs/autodocs
9
9
  tags: ['autodocs'],
10
10
  parameters: {
@@ -13,42 +13,42 @@ const meta = {
13
13
  },
14
14
  };
15
15
  export default meta;
16
- const ThemedOverlay = (props) => {
16
+ const ThemedSideOverlay = (props) => {
17
17
  const [isOpen, setIsOpen] = useState(false);
18
18
  const openButtonRef = useRef(null);
19
19
  const closeButtonRef = useRef(null);
20
20
  const headingRef = useRef(null);
21
- return (_jsx(Box, { p: 3, bg: "canvas.default", children: _jsxs(Box, { children: [_jsx(Box, { sx: { width: '100%', bg: 'darkgray' }, children: _jsx(Heading, { ref: headingRef, children: "Header" }) }), _jsxs(Box, { children: [_jsx(Button, { ref: openButtonRef, onClick: () => { setIsOpen(!isOpen); }, children: "Open overlay" }), _jsx(Overlay, { ...props, isOpen: isOpen, setIsOpen: setIsOpen, openButtonRef: openButtonRef, closeButtonRef: closeButtonRef })] })] }) }));
21
+ return (_jsx(Box, { p: 3, bg: "canvas.default", children: _jsxs(Box, { children: [_jsx(Box, { sx: { width: '100%', bg: 'darkgray' }, children: _jsx(Heading, { ref: headingRef, children: "Header" }) }), _jsxs(Box, { children: [_jsx(Button, { ref: openButtonRef, onClick: () => { setIsOpen(!isOpen); }, children: "Open overlay" }), _jsx(SideOverlay, { ...props, isOpen: isOpen, setIsOpen: setIsOpen, openButtonRef: openButtonRef, closeButtonRef: closeButtonRef })] })] }) }));
22
22
  };
23
- export const OverlayDayLeft = {
23
+ export const SideOverlayDayLeft = {
24
24
  args: {
25
25
  content: _jsx(Text, { children: "\uD83D\uDC48 Look, left aligned, no heading." }),
26
26
  direction: "left",
27
27
  width: '500px',
28
28
  },
29
- render: (args) => _jsx(ThemedOverlay, { ...args, colorMode: "day" })
29
+ render: (args) => _jsx(ThemedSideOverlay, { ...args, colorMode: "day" })
30
30
  };
31
- export const OverlayDayRight = {
31
+ export const SideOverlayDayRight = {
32
32
  args: {
33
33
  content: _jsx(Text, { children: "Look, right aligned, on heading \uD83D\uDC49" }),
34
34
  direction: "right",
35
35
  width: '500px',
36
36
  },
37
- render: (args) => _jsx(ThemedOverlay, { ...args, colorMode: "day" })
37
+ render: (args) => _jsx(ThemedSideOverlay, { ...args, colorMode: "day" })
38
38
  };
39
- export const OverlayNightLeft = {
39
+ export const SideOverlayNightLeft = {
40
40
  args: {
41
41
  content: _jsx(Text, { children: "\uD83D\uDC48 Look, left aligned, no heading." }),
42
42
  direction: "left",
43
43
  width: '300px',
44
44
  },
45
- render: (args) => _jsx(ThemedOverlay, { ...args, colorMode: "night" })
45
+ render: (args) => _jsx(ThemedSideOverlay, { ...args, colorMode: "night" })
46
46
  };
47
- export const OverlayNightRight = {
47
+ export const SideOverlayNightRight = {
48
48
  args: {
49
49
  content: _jsx(Text, { children: "Look, right aligned, on heading \uD83D\uDC49" }),
50
50
  direction: "right",
51
51
  width: '300px',
52
52
  },
53
- render: (args) => _jsx(ThemedOverlay, { ...args, colorMode: "night" })
53
+ render: (args) => _jsx(ThemedSideOverlay, { ...args, colorMode: "night" })
54
54
  };
@@ -17,7 +17,8 @@ export const Slider = ({ name = "slider", id = "slider", min = 0, max = 10, valu
17
17
  const sliderStyle = {
18
18
  width,
19
19
  ...(orientation === "vertical" ? { transform: "rotate(-90deg)" } : {}),
20
- colorScheme: colorMode == 'day' ? 'light' : 'dark'
20
+ colorScheme: colorMode == 'day' ? 'light' : 'dark',
21
+ accentColor: 'var(--fgColor-accent)',
21
22
  };
22
23
  return (_jsxs(Box, { display: "flex", alignItems: "center", children: [_jsx("input", { type: "range", id: id, name: name, min: min, max: max, value: sliderVal, step: step ?? "any", list: "slider-markers", style: sliderStyle, onChange: handleSliderChange, disabled: disabled }), markers && step && (_jsx("datalist", { id: "slider-markers", children: Array.from({ length: Math.floor((max - min) / step) + 1 }, (_, i) => min + i * step).map((e) => (
23
24
  // TODO: Supply markers as array and show them here
@@ -114,9 +114,9 @@ export function FloatingToolbar({ items, extraItems, anchorElement, isVisible, c
114
114
  gap: '2px',
115
115
  px: 1,
116
116
  py: '4px',
117
- bg: 'canvas.overlay',
117
+ bg: 'var(--overlay-bgColor, var(--bgColor-default))',
118
118
  border: '1px solid',
119
- borderColor: 'border.default',
119
+ borderColor: 'var(--borderColor-muted, transparent)',
120
120
  borderRadius: 2,
121
121
  boxShadow: 'shadow.large',
122
122
  position: 'absolute',
@@ -25,7 +25,7 @@ export interface IDatalayerThemeProviderProps extends Omit<ThemeProviderProps, '
25
25
  * When provided, these replace the built-in datalayer styles entirely.
26
26
  * The `baseStyles` prop is still merged on top.
27
27
  *
28
- * Use the `buildThemeStyles` helper from `./themes/createThemeCSSVars`
28
+ * Use the `buildThemeStyles` helper from `./css/createThemeCSSVars`
29
29
  * to generate comprehensive overrides from a `ThemeColorDefs` pair.
30
30
  */
31
31
  themeStyles?: {
@@ -3,7 +3,6 @@ export { spatialColors } from './spatialColors';
3
3
  export { lovelyColors } from './lovelyColors';
4
4
  export { matrixColors } from './matrixColors';
5
5
  export { earthColors } from './earthColors';
6
- export { indicatorColors, defaultIndicatorColors, type IndicatorColors, } from './indicatorColors';
7
6
  import type { ThemeVariant } from '../themeRegistry';
8
7
  /**
9
8
  * Themed color palettes — maps each `ThemeVariant` to its corresponding
@@ -7,7 +7,6 @@ export { spatialColors } from './spatialColors';
7
7
  export { lovelyColors } from './lovelyColors';
8
8
  export { matrixColors } from './matrixColors';
9
9
  export { earthColors } from './earthColors';
10
- export { indicatorColors, defaultIndicatorColors, } from './indicatorColors';
11
10
  import { datalayerColors } from './datalayerColors';
12
11
  import { spatialColors } from './spatialColors';
13
12
  import { lovelyColors } from './lovelyColors';
@@ -43,6 +43,13 @@ export function colorDefsToCSS(defs) {
43
43
  '--bgColor-default': defs.canvas.default,
44
44
  '--bgColor-inset': defs.canvas.default,
45
45
  ...optional,
46
+ /* ── Overlay (portaled surfaces: menus, dialogs, popovers) ────
47
+ * Primer's <Overlay> paints its surface with `var(--overlay-bgColor)`,
48
+ * which normally ships in @primer/primitives. Apps using this theme do
49
+ * NOT load primitives CSS, so define the overlay tokens here to avoid
50
+ * transparent overlay panels. */
51
+ '--overlay-bgColor': defs.canvas.default,
52
+ '--overlay-backdrop-bgColor': 'rgba(0, 0, 0, 0.5)',
46
53
  /* ── Foreground / Text ───────────────────────────────────────── */
47
54
  '--fgColor-default': defs.fg.default,
48
55
  '--fgColor-muted': defs.fg.muted,
@@ -174,6 +181,7 @@ export function colorDefsToCSS(defs) {
174
181
  /* ── Datalayer brand tokens (consumed by custom components) ─── */
175
182
  '--brand-color-canvas-default': defs.canvas.default,
176
183
  '--brand-color-text-default': defs.fg.default,
184
+ '--datalayer-icon-fg': defs.accent.fg,
177
185
  };
178
186
  }
179
187
  /**
@@ -1,5 +1,6 @@
1
1
  export * from './colors';
2
- export * from './themes/createThemeCSSVars';
2
+ export * from './indicators';
3
+ export * from './css/createThemeCSSVars';
3
4
  export * from './themes/datalayerTheme';
4
5
  export * from './DatalayerThemeProvider';
5
6
  export * from './DatalayerBrandThemeProvider';
@@ -3,7 +3,8 @@
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
5
  export * from './colors';
6
- export * from './themes/createThemeCSSVars';
6
+ export * from './indicators';
7
+ export * from './css/createThemeCSSVars';
7
8
  export * from './themes/datalayerTheme';
8
9
  export * from './DatalayerThemeProvider';
9
10
  export * from './DatalayerBrandThemeProvider';
@@ -0,0 +1 @@
1
+ export { indicatorColors, defaultIndicatorColors, type IndicatorColors, } from './indicatorColors';
@@ -0,0 +1,5 @@
1
+ /*
2
+ * Copyright (c) 2023-2025 Datalayer, Inc.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+ export { indicatorColors, defaultIndicatorColors, } from './indicatorColors';
@@ -1,5 +1,5 @@
1
1
  import { type ThemeVariant } from '../themeRegistry';
2
- export interface SvgPalette {
2
+ export interface ColorPalette {
3
3
  bg: string;
4
4
  bgPanel: string;
5
5
  bgAlt: string;
@@ -17,15 +17,15 @@ export interface SvgPalette {
17
17
  textMuted: string;
18
18
  isLight: boolean;
19
19
  }
20
- export declare function getSvgPalette(theme?: ThemeVariant, colorMode?: 'light' | 'dark' | 'auto'): SvgPalette;
21
- export declare function useSvgPalette(): SvgPalette;
22
- /** @deprecated Use `useSvgPalette` instead. */
23
- export declare const useBlogSvgPalette: typeof useSvgPalette;
20
+ export declare function getColorPalette(theme?: ThemeVariant, colorMode?: 'light' | 'dark' | 'auto'): ColorPalette;
21
+ export declare function useColorPalette(): ColorPalette;
22
+ /** @deprecated Use `useColorPalette` instead. */
23
+ export declare const useBlogColorPalette: typeof useColorPalette;
24
24
  export declare const LightBoostFilter: () => import("react/jsx-runtime").JSX.Element;
25
25
  export declare const SharedDefs: ({ p }: {
26
- p: SvgPalette;
26
+ p: ColorPalette;
27
27
  }) => import("react/jsx-runtime").JSX.Element;
28
- export declare const svgLightFilter: (p: SvgPalette) => "url(#svgLightBoost)" | undefined;
28
+ export declare const svgLightFilter: (p: ColorPalette) => "url(#svgLightBoost)" | undefined;
29
29
  export declare const BgGrid: ({ w, h }: {
30
30
  w?: number;
31
31
  h?: number;
@@ -5,8 +5,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
5
5
  * Datalayer License
6
6
  */
7
7
  /**
8
- * Shared SVG palette types, theme-aware colour resolution, and reusable
9
- * gradient / grid definitions consumed by SVG illustrations.
8
+ * Shared palette types, theme-aware colour resolution, and reusable
9
+ * gradient / grid definitions.
10
10
  */
11
11
  import { datalayerColors, spatialColors, lovelyColors, matrixColors, earthColors, } from '../colors';
12
12
  import { getBrightPalette, } from '../themeRegistry';
@@ -213,7 +213,7 @@ const palettes = {
213
213
  },
214
214
  },
215
215
  };
216
- export function getSvgPalette(theme = 'datalayer', colorMode = 'auto') {
216
+ export function getColorPalette(theme = 'datalayer', colorMode = 'auto') {
217
217
  const mode = colorMode === 'auto'
218
218
  ? typeof window !== 'undefined' &&
219
219
  window.matchMedia('(prefers-color-scheme: dark)').matches
@@ -222,12 +222,12 @@ export function getSvgPalette(theme = 'datalayer', colorMode = 'auto') {
222
222
  : colorMode;
223
223
  return palettes[theme]?.[mode] ?? palettes.datalayer.dark;
224
224
  }
225
- export function useSvgPalette() {
225
+ export function useColorPalette() {
226
226
  const { colorMode, theme } = useThemeStore();
227
- return getSvgPalette(theme, colorMode);
227
+ return getColorPalette(theme, colorMode);
228
228
  }
229
- /** @deprecated Use `useSvgPalette` instead. */
230
- export const useBlogSvgPalette = useSvgPalette;
229
+ /** @deprecated Use `useColorPalette` instead. */
230
+ export const useBlogColorPalette = useColorPalette;
231
231
  export const LightBoostFilter = () => (_jsx("filter", { id: "svgLightBoost", colorInterpolationFilters: "sRGB", children: _jsx("feComponentTransfer", { children: _jsx("feFuncA", { type: "gamma", exponent: "0.45", amplitude: "1", offset: "0" }) }) }));
232
232
  export const SharedDefs = ({ p }) => (_jsxs("defs", { children: [_jsx(LightBoostFilter, {}), _jsxs("linearGradient", { id: "fadeGreen", x1: "0", y1: "0", x2: "1", y2: "1", children: [_jsx("stop", { offset: "0%", stopColor: p.primary, stopOpacity: "0.7" }), _jsx("stop", { offset: "100%", stopColor: p.secondary, stopOpacity: "0" })] }), _jsxs("linearGradient", { id: "fadeGreenH", x1: "0", y1: "0", x2: "1", y2: "0", children: [_jsx("stop", { offset: "0%", stopColor: p.primary, stopOpacity: "0.5" }), _jsx("stop", { offset: "50%", stopColor: p.secondary, stopOpacity: "0.25" }), _jsx("stop", { offset: "100%", stopColor: p.secondary, stopOpacity: "0" })] }), _jsxs("linearGradient", { id: "fadeBright", x1: "0", y1: "0", x2: "0", y2: "1", children: [_jsx("stop", { offset: "0%", stopColor: p.accent, stopOpacity: "0.4" }), _jsx("stop", { offset: "100%", stopColor: p.accent, stopOpacity: "0" })] }), _jsxs("linearGradient", { id: "fadeVivid", x1: "0", y1: "0", x2: "1", y2: "1", children: [_jsx("stop", { offset: "0%", stopColor: p.glow, stopOpacity: "0.8" }), _jsx("stop", { offset: "50%", stopColor: p.pop, stopOpacity: "0.5" }), _jsx("stop", { offset: "100%", stopColor: p.spark, stopOpacity: "0" })] }), _jsxs("linearGradient", { id: "fadeVividH", x1: "0", y1: "0", x2: "1", y2: "0", children: [_jsx("stop", { offset: "0%", stopColor: p.glow, stopOpacity: "0.6" }), _jsx("stop", { offset: "100%", stopColor: p.pop, stopOpacity: "0.15" })] }), _jsxs("radialGradient", { id: "glowGreen", children: [_jsx("stop", { offset: "0%", stopColor: p.primary, stopOpacity: "0.6" }), _jsx("stop", { offset: "100%", stopColor: p.primary, stopOpacity: "0" })] }), _jsxs("radialGradient", { id: "glowBright", children: [_jsx("stop", { offset: "0%", stopColor: p.accent, stopOpacity: "0.45" }), _jsx("stop", { offset: "100%", stopColor: p.accent, stopOpacity: "0" })] }), _jsxs("radialGradient", { id: "glowVivid", children: [_jsx("stop", { offset: "0%", stopColor: p.glow, stopOpacity: "0.7" }), _jsx("stop", { offset: "60%", stopColor: p.glow, stopOpacity: "0.2" }), _jsx("stop", { offset: "100%", stopColor: p.glow, stopOpacity: "0" })] }), _jsxs("radialGradient", { id: "glowPop", children: [_jsx("stop", { offset: "0%", stopColor: p.pop, stopOpacity: "0.65" }), _jsx("stop", { offset: "60%", stopColor: p.pop, stopOpacity: "0.15" }), _jsx("stop", { offset: "100%", stopColor: p.pop, stopOpacity: "0" })] }), _jsxs("radialGradient", { id: "glowSpark", children: [_jsx("stop", { offset: "0%", stopColor: p.spark, stopOpacity: "0.6" }), _jsx("stop", { offset: "60%", stopColor: p.spark, stopOpacity: "0.15" }), _jsx("stop", { offset: "100%", stopColor: p.spark, stopOpacity: "0" })] }), _jsxs("radialGradient", { id: "glowBlaze", children: [_jsx("stop", { offset: "0%", stopColor: p.blaze, stopOpacity: "0.7" }), _jsx("stop", { offset: "55%", stopColor: p.blaze, stopOpacity: "0.2" }), _jsx("stop", { offset: "100%", stopColor: p.blaze, stopOpacity: "0" })] }), _jsxs("radialGradient", { id: "glowSurge", children: [_jsx("stop", { offset: "0%", stopColor: p.surge, stopOpacity: "0.7" }), _jsx("stop", { offset: "55%", stopColor: p.surge, stopOpacity: "0.2" }), _jsx("stop", { offset: "100%", stopColor: p.surge, stopOpacity: "0" })] }), _jsxs("radialGradient", { id: "glowFlame", children: [_jsx("stop", { offset: "0%", stopColor: p.flame, stopOpacity: "0.7" }), _jsx("stop", { offset: "55%", stopColor: p.flame, stopOpacity: "0.2" }), _jsx("stop", { offset: "100%", stopColor: p.flame, stopOpacity: "0" })] }), _jsxs("radialGradient", { id: "glowGold", children: [_jsx("stop", { offset: "0%", stopColor: p.gold, stopOpacity: "0.7" }), _jsx("stop", { offset: "55%", stopColor: p.gold, stopOpacity: "0.2" }), _jsx("stop", { offset: "100%", stopColor: p.gold, stopOpacity: "0" })] }), _jsxs("linearGradient", { id: "fadeBlazeToSurge", x1: "0", y1: "0", x2: "1", y2: "0", children: [_jsx("stop", { offset: "0%", stopColor: p.blaze, stopOpacity: "0.7" }), _jsx("stop", { offset: "50%", stopColor: p.spark, stopOpacity: "0.3" }), _jsx("stop", { offset: "100%", stopColor: p.surge, stopOpacity: "0.7" })] }), _jsx("pattern", { id: "gridDots", width: "24", height: "24", patternUnits: "userSpaceOnUse", children: _jsx("circle", { cx: "1", cy: "1", r: "0.7", fill: p.primary, opacity: "0.06" }) })] }));
233
233
  export const svgLightFilter = (p) => p.isLight ? 'url(#svgLightBoost)' : undefined;
@@ -1 +1 @@
1
- export * from './SvgPalette';
1
+ export * from './ColorPalette';
@@ -3,4 +3,4 @@
3
3
  *
4
4
  * Datalayer License
5
5
  */
6
- export * from './SvgPalette';
6
+ export * from './ColorPalette';
@@ -1087,5 +1087,5 @@ export declare const datalayerTheme: {
1087
1087
  }>;
1088
1088
  };
1089
1089
  /** Comprehensive Primer CSS-variable overrides for light & dark mode. */
1090
- export declare const datalayerThemeStyles: import("./createThemeCSSVars").ThemeStyles;
1090
+ export declare const datalayerThemeStyles: import("../css/createThemeCSSVars").ThemeStyles;
1091
1091
  export default datalayerTheme;
@@ -11,7 +11,7 @@
11
11
  */
12
12
  import { theme as primerTheme } from '@primer/react';
13
13
  import { datalayerColors } from '../colors';
14
- import { buildThemeStyles } from './createThemeCSSVars';
14
+ import { buildThemeStyles } from '../css/createThemeCSSVars';
15
15
  /* ── Light-mode colour definitions ───────────────────────────────────── */
16
16
  const datalayerLight = {
17
17
  canvas: {
@@ -1087,5 +1087,5 @@ export declare const earthTheme: {
1087
1087
  }>;
1088
1088
  };
1089
1089
  /** Comprehensive Primer CSS-variable overrides for light & dark mode. */
1090
- export declare const earthThemeStyles: import("./createThemeCSSVars").ThemeStyles;
1090
+ export declare const earthThemeStyles: import("../css/createThemeCSSVars").ThemeStyles;
1091
1091
  export default earthTheme;
@@ -11,7 +11,7 @@
11
11
  */
12
12
  import { theme as primerTheme } from '@primer/react';
13
13
  import { earthColors } from '../colors/earthColors';
14
- import { buildThemeStyles } from './createThemeCSSVars';
14
+ import { buildThemeStyles } from '../css/createThemeCSSVars';
15
15
  /* ── Light-mode colour definitions ───────────────────────────────────── */
16
16
  const earthLight = {
17
17
  canvas: {
@@ -1087,5 +1087,5 @@ export declare const lovelyTheme: {
1087
1087
  }>;
1088
1088
  };
1089
1089
  /** Comprehensive Primer CSS-variable overrides for light & dark mode. */
1090
- export declare const lovelyThemeStyles: import("./createThemeCSSVars").ThemeStyles;
1090
+ export declare const lovelyThemeStyles: import("../css/createThemeCSSVars").ThemeStyles;
1091
1091
  export default lovelyTheme;
@@ -10,7 +10,7 @@
10
10
  */
11
11
  import { theme as primerTheme } from '@primer/react';
12
12
  import { lovelyColors } from '../colors';
13
- import { buildThemeStyles } from './createThemeCSSVars';
13
+ import { buildThemeStyles } from '../css/createThemeCSSVars';
14
14
  /* ── Light-mode colour definitions ───────────────────────────────────── */
15
15
  const lovelyLight = {
16
16
  canvas: {
@@ -1087,5 +1087,5 @@ export declare const matrixTheme: {
1087
1087
  }>;
1088
1088
  };
1089
1089
  /** Comprehensive Primer CSS-variable overrides for light & dark mode. */
1090
- export declare const matrixThemeStyles: import("./createThemeCSSVars").ThemeStyles;
1090
+ export declare const matrixThemeStyles: import("../css/createThemeCSSVars").ThemeStyles;
1091
1091
  export default matrixTheme;
@@ -10,7 +10,7 @@
10
10
  */
11
11
  import { theme as primerTheme } from '@primer/react';
12
12
  import { matrixColors } from '../colors';
13
- import { buildThemeStyles } from './createThemeCSSVars';
13
+ import { buildThemeStyles } from '../css/createThemeCSSVars';
14
14
  /* ── Light-mode colour definitions ───────────────────────────────────── */
15
15
  const matrixLight = {
16
16
  canvas: {
@@ -1087,5 +1087,5 @@ export declare const spatialTheme: {
1087
1087
  }>;
1088
1088
  };
1089
1089
  /** Comprehensive Primer CSS-variable overrides for light & dark mode. */
1090
- export declare const spatialThemeStyles: import("./createThemeCSSVars").ThemeStyles;
1090
+ export declare const spatialThemeStyles: import("../css/createThemeCSSVars").ThemeStyles;
1091
1091
  export default spatialTheme;
@@ -10,7 +10,7 @@
10
10
  */
11
11
  import { theme as primerTheme } from '@primer/react';
12
12
  import { spatialColors } from '../colors';
13
- import { buildThemeStyles } from './createThemeCSSVars';
13
+ import { buildThemeStyles } from '../css/createThemeCSSVars';
14
14
  /* ── Light-mode colour definitions ───────────────────────────────────── */
15
15
  const spatialLight = {
16
16
  canvas: {
@@ -22,11 +22,13 @@
22
22
  import { type StoreApi, type UseBoundStore } from 'zustand';
23
23
  import type { ThemeVariant } from './themeRegistry';
24
24
  import type { ColorMode } from './DatalayerBrandThemeProvider';
25
- /** Per-variant theme + colorMode preferences. */
26
- export type VariantDefaults = Record<string, {
25
+ export type VariantPreference = {
27
26
  theme: ThemeVariant;
28
27
  colorMode: ColorMode;
29
- }>;
28
+ version?: number;
29
+ };
30
+ /** Per-variant theme + colorMode preferences. */
31
+ export type VariantDefaults = Record<string, VariantPreference>;
30
32
  export interface ThemeState {
31
33
  /** Current color mode (light, dark, or auto = follow OS). */
32
34
  colorMode: ColorMode;
@@ -26,6 +26,33 @@
26
26
  import { create } from 'zustand';
27
27
  import { persist, createJSONStorage } from 'zustand/middleware';
28
28
  import { themeConfigs } from './themeRegistry';
29
+ const VARIANT_SCHEMA_VERSION = 1;
30
+ function normalizeVariantPreference(pref) {
31
+ return {
32
+ theme: pref.theme,
33
+ colorMode: pref.colorMode,
34
+ version: typeof pref.version === 'number' ? pref.version : VARIANT_SCHEMA_VERSION,
35
+ };
36
+ }
37
+ function normalizeVariants(variants) {
38
+ if (!variants) {
39
+ return {};
40
+ }
41
+ const normalized = {};
42
+ for (const [key, pref] of Object.entries(variants)) {
43
+ if (!pref || typeof pref !== 'object' || !('theme' in pref) || !('colorMode' in pref)) {
44
+ continue;
45
+ }
46
+ normalized[key] = normalizeVariantPreference(pref);
47
+ }
48
+ return normalized;
49
+ }
50
+ function hasMissingVariantVersion(variants) {
51
+ if (!variants || Object.keys(variants).length === 0) {
52
+ return false;
53
+ }
54
+ return Object.values(variants).some(pref => typeof pref?.version !== 'number');
55
+ }
29
56
  /* ── Helpers ─────────────────────────────────────────────────────── */
30
57
  const colorModeCycle = {
31
58
  light: 'dark',
@@ -49,7 +76,7 @@ export function createThemeStore(storageKey, defaults) {
49
76
  theme: defaults?.theme ?? 'matrix',
50
77
  /* ── variant state ──────────────────────────────────── */
51
78
  activeVariant: null,
52
- variants: defaults?.variants ?? {},
79
+ variants: normalizeVariants(defaults?.variants),
53
80
  /* ── actions ────────────────────────────────────────── */
54
81
  toggleColorMode: () => set(state => {
55
82
  const next = colorModeCycle[state.colorMode];
@@ -58,7 +85,11 @@ export function createThemeStore(storageKey, defaults) {
58
85
  colorMode: next,
59
86
  variants: {
60
87
  ...state.variants,
61
- [state.activeVariant]: { ...state.variants[state.activeVariant], colorMode: next },
88
+ [state.activeVariant]: {
89
+ ...state.variants[state.activeVariant],
90
+ colorMode: next,
91
+ version: VARIANT_SCHEMA_VERSION,
92
+ },
62
93
  },
63
94
  };
64
95
  }
@@ -70,7 +101,11 @@ export function createThemeStore(storageKey, defaults) {
70
101
  colorMode: mode,
71
102
  variants: {
72
103
  ...state.variants,
73
- [state.activeVariant]: { ...state.variants[state.activeVariant], colorMode: mode },
104
+ [state.activeVariant]: {
105
+ ...state.variants[state.activeVariant],
106
+ colorMode: mode,
107
+ version: VARIANT_SCHEMA_VERSION,
108
+ },
74
109
  },
75
110
  };
76
111
  }
@@ -86,7 +121,11 @@ export function createThemeStore(storageKey, defaults) {
86
121
  colorMode: nextColorMode,
87
122
  variants: {
88
123
  ...state.variants,
89
- [state.activeVariant]: { theme, colorMode: nextColorMode },
124
+ [state.activeVariant]: {
125
+ theme,
126
+ colorMode: nextColorMode,
127
+ version: VARIANT_SCHEMA_VERSION,
128
+ },
90
129
  },
91
130
  };
92
131
  }
@@ -96,7 +135,13 @@ export function createThemeStore(storageKey, defaults) {
96
135
  const merged = { ...state.variants };
97
136
  for (const [key, val] of Object.entries(defs)) {
98
137
  if (!merged[key]) {
99
- merged[key] = val;
138
+ merged[key] = normalizeVariantPreference(val);
139
+ }
140
+ else {
141
+ merged[key] = normalizeVariantPreference({
142
+ ...merged[key],
143
+ version: merged[key].version ?? VARIANT_SCHEMA_VERSION,
144
+ });
100
145
  }
101
146
  }
102
147
  return { variants: merged };
@@ -114,7 +159,7 @@ export function createThemeStore(storageKey, defaults) {
114
159
  }),
115
160
  }), {
116
161
  name: storageKey,
117
- version: 2,
162
+ version: 3,
118
163
  storage: createJSONStorage(() => localStorage),
119
164
  partialize: state => ({
120
165
  colorMode: state.colorMode,
@@ -127,7 +172,31 @@ export function createThemeStore(storageKey, defaults) {
127
172
  * value the persisted state is discarded and the store starts fresh
128
173
  * from code-defined defaults.
129
174
  */
130
- migrate: () => ({}),
175
+ migrate: persisted => {
176
+ const p = (persisted ?? {});
177
+ const legacyVariants = p.variants;
178
+ const missingVariantVersion = hasMissingVariantVersion(legacyVariants);
179
+ const variants = normalizeVariants(legacyVariants);
180
+ // Legacy snapshots without per-variant versions are upgraded to v1.
181
+ // Anonymous defaults are forced to matrix/dark during this upgrade.
182
+ if (missingVariantVersion) {
183
+ variants['agent-anonymous'] = {
184
+ theme: 'matrix',
185
+ colorMode: 'dark',
186
+ version: VARIANT_SCHEMA_VERSION,
187
+ };
188
+ }
189
+ return {
190
+ ...p,
191
+ variants,
192
+ ...(missingVariantVersion
193
+ ? {
194
+ theme: p.activeVariant === 'agent-anonymous' ? 'matrix' : p.theme,
195
+ colorMode: p.activeVariant === 'agent-anonymous' ? 'dark' : p.colorMode,
196
+ }
197
+ : {}),
198
+ };
199
+ },
131
200
  /**
132
201
  * Deep-merge variants during hydration so that:
133
202
  * - Code-defined variants (from defaults or registerVariants) are
@@ -139,11 +208,11 @@ export function createThemeStore(storageKey, defaults) {
139
208
  const p = (persisted ?? {});
140
209
  // Build merged variants: start from code-defined, then overlay
141
210
  // any persisted variant whose prefs differ (user customisations).
142
- const mergedVariants = { ...current.variants };
211
+ const mergedVariants = normalizeVariants(current.variants);
143
212
  if (p.variants) {
144
213
  for (const [key, val] of Object.entries(p.variants)) {
145
214
  if (val && typeof val === 'object' && 'theme' in val) {
146
- mergedVariants[key] = val;
215
+ mergedVariants[key] = normalizeVariantPreference(val);
147
216
  }
148
217
  }
149
218
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datalayer/primer-addons",
3
- "version": "1.0.15",
3
+ "version": "1.0.18",
4
4
  "license": "BSD-3-Clause",
5
5
  "scripts": {
6
6
  "build": "tsc && vite build",
@@ -8,6 +8,8 @@
8
8
  "build:lib": "npm run clean:lib&& tsc -b",
9
9
  "clean:lib": "rimraf lib tsconfig.tsbuildinfo",
10
10
  "dev": "vite",
11
+ "gallery": "npm --prefix examples/gallery run dev",
12
+ "gallery:build": "npm --prefix examples/gallery run build",
11
13
  "lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
12
14
  "preview": "vite preview",
13
15
  "start": "vite",
@@ -27,9 +29,9 @@
27
29
  "homepage": "https://primer-addons.datalayer.tech",
28
30
  "dependencies": {
29
31
  "@datalayer/icons-react": "^1.0.0",
30
- "@primer/octicons-react": "^19.15.1",
31
- "@primer/primitives": "^10.5.0",
32
- "@primer/react": "^37.19.0",
32
+ "@primer/octicons-react": "^19.29.1",
33
+ "@primer/primitives": "^10.7.0",
34
+ "@primer/react": "^37.31.0",
33
35
  "react": "^18.3.1 || ^19.0.0",
34
36
  "react-dom": "^18.3.1 || ^19.0.0",
35
37
  "react-loading-skeleton": "^3.5.0",
@@ -1,16 +0,0 @@
1
- import type { StoryObj } from '@storybook/react';
2
- import { OverlayProps } from '../..';
3
- declare const meta: {
4
- title: string;
5
- component: ({ width, direction, zIndex, ...rest }: OverlayProps) => import("react/jsx-runtime").JSX.Element;
6
- tags: string[];
7
- parameters: {
8
- layout: string;
9
- };
10
- };
11
- export default meta;
12
- type Story = StoryObj<typeof meta>;
13
- export declare const OverlayDayLeft: Story;
14
- export declare const OverlayDayRight: Story;
15
- export declare const OverlayNightLeft: Story;
16
- export declare const OverlayNightRight: Story;