@datalayer/primer-addons 1.0.17 → 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.
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,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;
@@ -1,4 +1,6 @@
1
1
  export * from './AI';
2
+ export * from './AI2';
3
+ export * from './DI';
2
4
  export * from './DatalayerLogo';
3
5
  export * from './DatalayerLogoText';
4
6
  export * from './DatalayerText';
@@ -1,4 +1,6 @@
1
1
  export * from './AI';
2
+ export * from './AI2';
3
+ export * from './DI';
2
4
  export * from './DatalayerLogo';
3
5
  export * from './DatalayerLogoText';
4
6
  export * from './DatalayerText';
@@ -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',
@@ -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,
@@ -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.17",
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;