@datalayer/primer-addons 1.0.10 → 1.0.12
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/components/appearance/AppearanceControls.d.ts +10 -0
- package/lib/components/appearance/AppearanceControls.js +42 -0
- package/lib/components/appearance/AppearanceControlsWithStore.d.ts +8 -0
- package/lib/components/appearance/AppearanceControlsWithStore.js +21 -0
- package/lib/components/appearance/index.d.ts +2 -0
- package/lib/components/appearance/index.js +6 -0
- package/lib/components/index.d.ts +4 -0
- package/lib/components/index.js +4 -0
- package/lib/components/logo/DatalayerLogo.d.ts +18 -0
- package/lib/components/logo/DatalayerLogo.js +63 -0
- package/lib/components/logo/DatalayerLogoText.d.ts +22 -0
- package/lib/components/logo/DatalayerLogoText.js +29 -0
- package/lib/components/logo/DatalayerText.d.ts +16 -0
- package/lib/components/logo/DatalayerText.js +16 -0
- package/lib/components/logo/index.d.ts +3 -0
- package/lib/components/logo/index.js +3 -0
- package/lib/index.js +0 -1
- package/lib/theme/DatalayerThemeProvider.js +83 -6
- package/lib/theme/Palette.d.ts +8 -4
- package/lib/theme/Palette.js +13 -6
- package/lib/theme/ThemedProvider.d.ts +25 -0
- package/lib/theme/ThemedProvider.js +14 -0
- package/lib/theme/colors/datalayerColors.d.ts +14 -0
- package/lib/theme/colors/datalayerColors.js +17 -0
- package/lib/theme/colors/index.d.ts +1 -0
- package/lib/theme/colors/index.js +1 -0
- package/lib/theme/colors/indicatorColors.d.ts +50 -0
- package/lib/theme/colors/indicatorColors.js +68 -0
- package/lib/theme/colors/lovelyColors.d.ts +14 -0
- package/lib/theme/colors/lovelyColors.js +17 -0
- package/lib/theme/colors/matrixColors.d.ts +14 -0
- package/lib/theme/colors/matrixColors.js +17 -0
- package/lib/theme/colors/spatialColors.d.ts +14 -0
- package/lib/theme/colors/spatialColors.js +17 -0
- package/lib/theme/index.d.ts +2 -0
- package/lib/theme/index.js +2 -0
- package/lib/theme/themeRegistry.d.ts +75 -0
- package/lib/theme/themeRegistry.js +235 -0
- package/lib/theme/themes/createThemeCSSVars.d.ts +14 -1
- package/lib/theme/themes/createThemeCSSVars.js +70 -9
- package/lib/theme/themes/matrixTheme.d.ts +1 -4
- package/lib/theme/themes/matrixTheme.js +3 -7
- package/lib/theme/useThemeStore.d.ts +50 -0
- package/lib/theme/useThemeStore.js +65 -0
- package/lib/utils/Portals.d.ts +19 -0
- package/lib/utils/Portals.js +111 -9
- package/package.json +3 -2
- /package/lib/{_utils/story-helpers.d.ts → story-helpers.d.ts} +0 -0
- /package/lib/{_utils/story-helpers.js → story-helpers.js} +0 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ReactElement } from 'react';
|
|
2
|
+
import { type ColorMode, type ThemeVariant } from '../../theme';
|
|
3
|
+
export interface AppearanceControlsProps {
|
|
4
|
+
colorMode: ColorMode;
|
|
5
|
+
themeVariant: ThemeVariant;
|
|
6
|
+
onColorModeChange: (mode: ColorMode) => void;
|
|
7
|
+
onThemeChange: (theme: ThemeVariant) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare function AppearanceControls({ colorMode, themeVariant, onColorModeChange, onThemeChange, }: AppearanceControlsProps): ReactElement;
|
|
10
|
+
export default AppearanceControls;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { SegmentedControl } from '@primer/react';
|
|
3
|
+
import { MoonIcon, SunIcon, DeviceDesktopIcon, } from '@primer/octicons-react';
|
|
4
|
+
import { Box } from '../box/Box';
|
|
5
|
+
import { themeVariants, themeConfigs, } from '../../theme';
|
|
6
|
+
export function AppearanceControls({ colorMode, themeVariant, onColorModeChange, onThemeChange, }) {
|
|
7
|
+
return (_jsxs(_Fragment, { children: [_jsx(Box, { sx: { px: 2, py: 2, display: 'flex', justifyContent: 'center' }, children: _jsxs(SegmentedControl, { "aria-label": "Color mode", size: "small", onChange: (index) => {
|
|
8
|
+
const modes = ['light', 'dark', 'auto'];
|
|
9
|
+
onColorModeChange(modes[index]);
|
|
10
|
+
}, children: [_jsx(SegmentedControl.IconButton, { selected: colorMode === 'light', icon: SunIcon, "aria-label": "Light" }), _jsx(SegmentedControl.IconButton, { selected: colorMode === 'dark', icon: MoonIcon, "aria-label": "Dark" }), _jsx(SegmentedControl.IconButton, { selected: colorMode === 'auto', icon: DeviceDesktopIcon, "aria-label": "Auto" })] }) }), _jsx(Box, { sx: {
|
|
11
|
+
px: 2,
|
|
12
|
+
pb: 2,
|
|
13
|
+
display: 'flex',
|
|
14
|
+
justifyContent: 'center',
|
|
15
|
+
gap: 2,
|
|
16
|
+
}, children: themeVariants.map((variant) => {
|
|
17
|
+
const cfg = themeConfigs[variant];
|
|
18
|
+
const isSelected = themeVariant === variant;
|
|
19
|
+
return (_jsx(Box, { as: "button", "aria-label": cfg.label, "aria-pressed": isSelected, onClick: () => onThemeChange(variant), sx: {
|
|
20
|
+
width: 24,
|
|
21
|
+
height: 24,
|
|
22
|
+
borderRadius: '50%',
|
|
23
|
+
backgroundColor: cfg.brandColor,
|
|
24
|
+
border: '2px solid',
|
|
25
|
+
borderColor: isSelected ? 'accent.fg' : 'border.default',
|
|
26
|
+
cursor: 'pointer',
|
|
27
|
+
padding: 0,
|
|
28
|
+
outline: 'none',
|
|
29
|
+
transition: 'border-color 0.15s ease',
|
|
30
|
+
boxShadow: isSelected
|
|
31
|
+
? '0 0 0 2px var(--bgColor-accent-muted, rgba(9,105,218,0.3))'
|
|
32
|
+
: 'none',
|
|
33
|
+
'&:hover': {
|
|
34
|
+
borderColor: 'accent.fg',
|
|
35
|
+
},
|
|
36
|
+
'&:focus-visible': {
|
|
37
|
+
boxShadow: '0 0 0 2px var(--bgColor-accent-muted, rgba(9,105,218,0.3))',
|
|
38
|
+
},
|
|
39
|
+
} }, variant));
|
|
40
|
+
}) })] }));
|
|
41
|
+
}
|
|
42
|
+
export default AppearanceControls;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { UseBoundStore, StoreApi } from 'zustand';
|
|
3
|
+
import type { ThemeState } from '../../theme/useThemeStore';
|
|
4
|
+
export interface AppearanceControlsWithStoreProps {
|
|
5
|
+
useStore: UseBoundStore<StoreApi<ThemeState>>;
|
|
6
|
+
}
|
|
7
|
+
export declare const AppearanceControlsWithStore: React.FC<AppearanceControlsWithStoreProps>;
|
|
8
|
+
export default AppearanceControlsWithStore;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { IconButton, SegmentedControl, Tooltip } from '@primer/react';
|
|
3
|
+
import { SunIcon, MoonIcon, DeviceDesktopIcon, CircleIcon, } from '@primer/octicons-react';
|
|
4
|
+
import { Box } from '../box/Box';
|
|
5
|
+
import { themeConfigs, themeVariants } from '../../theme/themeRegistry';
|
|
6
|
+
export const AppearanceControlsWithStore = ({ useStore }) => {
|
|
7
|
+
const { colorMode, theme: themeVariant } = useStore();
|
|
8
|
+
return (_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 3 }, children: [_jsx(Box, { sx: { display: 'flex', alignItems: 'center', gap: 1 }, children: themeVariants.map(variant => {
|
|
9
|
+
const tcfg = themeConfigs[variant];
|
|
10
|
+
const isSelected = themeVariant === variant;
|
|
11
|
+
return (_jsx(Tooltip, { text: tcfg.label, direction: "s", children: _jsx(IconButton, { "aria-label": tcfg.label, "aria-pressed": isSelected, icon: () => _jsx(CircleIcon, { size: 16, fill: tcfg.brandColor }), size: "small", variant: isSelected ? 'default' : 'invisible', onClick: () => useStore.getState().setTheme(variant, false), sx: {
|
|
12
|
+
border: isSelected ? '2px solid' : '1px solid',
|
|
13
|
+
borderColor: isSelected ? 'accent.fg' : 'border.muted',
|
|
14
|
+
borderRadius: '50%',
|
|
15
|
+
} }) }, variant));
|
|
16
|
+
}) }), _jsxs(SegmentedControl, { "aria-label": "Color mode", size: "small", onChange: (index) => {
|
|
17
|
+
const modes = ['light', 'dark', 'auto'];
|
|
18
|
+
useStore.getState().setColorMode(modes[index]);
|
|
19
|
+
}, children: [_jsx(SegmentedControl.IconButton, { selected: colorMode === 'light', icon: SunIcon, "aria-label": "Light" }), _jsx(SegmentedControl.IconButton, { selected: colorMode === 'dark', icon: MoonIcon, "aria-label": "Dark" }), _jsx(SegmentedControl.IconButton, { selected: colorMode === 'auto', icon: DeviceDesktopIcon, "aria-label": "Auto" })] })] }));
|
|
20
|
+
};
|
|
21
|
+
export default AppearanceControlsWithStore;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export * from "./appearance/AppearanceControls";
|
|
2
|
+
export * from "./appearance/AppearanceControlsWithStore";
|
|
1
3
|
export * from "./box/Box";
|
|
2
4
|
export * from "./card/Card";
|
|
3
5
|
export * from "./content-loader/ContentLoader";
|
|
@@ -5,4 +7,6 @@ export * from "./closeable-flash/CloseableFlash";
|
|
|
5
7
|
export * from "./icons/CircleIcon";
|
|
6
8
|
export * from "./overlay/Overlay";
|
|
7
9
|
export * from "./slider/Slider";
|
|
10
|
+
export * from "./logo";
|
|
11
|
+
export * from "./appearance";
|
|
8
12
|
export * from "./toolbar";
|
package/lib/components/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export * from "./appearance/AppearanceControls";
|
|
2
|
+
export * from "./appearance/AppearanceControlsWithStore";
|
|
1
3
|
export * from "./box/Box";
|
|
2
4
|
export * from "./card/Card";
|
|
3
5
|
export * from "./content-loader/ContentLoader";
|
|
@@ -5,4 +7,6 @@ export * from "./closeable-flash/CloseableFlash";
|
|
|
5
7
|
export * from "./icons/CircleIcon";
|
|
6
8
|
export * from "./overlay/Overlay";
|
|
7
9
|
export * from "./slider/Slider";
|
|
10
|
+
export * from "./logo";
|
|
11
|
+
export * from "./appearance";
|
|
8
12
|
export * from "./toolbar";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type SVGProps } from 'react';
|
|
2
|
+
import { type ThemeVariant } from '../../theme';
|
|
3
|
+
export interface LogoColorPair {
|
|
4
|
+
primary: string;
|
|
5
|
+
secondary: string;
|
|
6
|
+
}
|
|
7
|
+
export declare const THEME_LOGO_COLORS: Record<ThemeVariant, {
|
|
8
|
+
light: LogoColorPair;
|
|
9
|
+
dark: LogoColorPair;
|
|
10
|
+
}>;
|
|
11
|
+
export declare function getLogoColors(variant?: ThemeVariant, colorMode?: 'light' | 'dark' | 'auto'): LogoColorPair;
|
|
12
|
+
export interface DatalayerLogoProps extends Omit<SVGProps<SVGSVGElement>, 'ref'> {
|
|
13
|
+
size?: number;
|
|
14
|
+
primaryColor?: string;
|
|
15
|
+
secondaryColor?: string;
|
|
16
|
+
}
|
|
17
|
+
export declare const DatalayerLogo: import("react").ForwardRefExoticComponent<DatalayerLogoProps & import("react").RefAttributes<SVGSVGElement>>;
|
|
18
|
+
export default DatalayerLogo;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
4
|
+
* Distributed under the terms of the Modified BSD License.
|
|
5
|
+
*/
|
|
6
|
+
import { forwardRef } from 'react';
|
|
7
|
+
import { datalayerColors, spatialColors, lovelyColors, matrixColors, } from '../../theme';
|
|
8
|
+
export const THEME_LOGO_COLORS = {
|
|
9
|
+
datalayer: {
|
|
10
|
+
light: {
|
|
11
|
+
primary: datalayerColors.greenBrand,
|
|
12
|
+
secondary: datalayerColors.greenText,
|
|
13
|
+
},
|
|
14
|
+
dark: {
|
|
15
|
+
primary: datalayerColors.greenBright,
|
|
16
|
+
secondary: datalayerColors.greenAccent,
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
spatial: {
|
|
20
|
+
light: {
|
|
21
|
+
primary: spatialColors.indigoBrand,
|
|
22
|
+
secondary: spatialColors.indigoText,
|
|
23
|
+
},
|
|
24
|
+
dark: {
|
|
25
|
+
primary: spatialColors.indigoBright,
|
|
26
|
+
secondary: spatialColors.indigoAccent,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
lovely: {
|
|
30
|
+
light: {
|
|
31
|
+
primary: lovelyColors.roseBrand,
|
|
32
|
+
secondary: lovelyColors.roseText,
|
|
33
|
+
},
|
|
34
|
+
dark: {
|
|
35
|
+
primary: lovelyColors.roseBright,
|
|
36
|
+
secondary: lovelyColors.roseAccent,
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
matrix: {
|
|
40
|
+
light: {
|
|
41
|
+
primary: matrixColors.greenBrand,
|
|
42
|
+
secondary: matrixColors.greenText,
|
|
43
|
+
},
|
|
44
|
+
dark: {
|
|
45
|
+
primary: matrixColors.greenGlow,
|
|
46
|
+
secondary: matrixColors.greenPhosphor,
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
export function getLogoColors(variant = 'datalayer', colorMode = 'light') {
|
|
51
|
+
const mode = colorMode === 'auto' ? 'light' : colorMode;
|
|
52
|
+
return THEME_LOGO_COLORS[variant]?.[mode] ?? THEME_LOGO_COLORS.datalayer.light;
|
|
53
|
+
}
|
|
54
|
+
const BAR_HEIGHT = 25;
|
|
55
|
+
const BARS = [
|
|
56
|
+
{ y: 0, secondaryWidth: 30, primaryWidth: 70 },
|
|
57
|
+
{ y: 37.5, secondaryWidth: 50, primaryWidth: 50 },
|
|
58
|
+
{ y: 75, secondaryWidth: 70, primaryWidth: 30 },
|
|
59
|
+
];
|
|
60
|
+
export const DatalayerLogo = forwardRef(function DatalayerLogo({ size = 16, primaryColor = 'currentColor', secondaryColor = 'currentColor', ...svgProps }, ref) {
|
|
61
|
+
return (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100", width: size, height: size, "aria-hidden": "true", ref: ref, ...svgProps, children: BARS.map(({ y, secondaryWidth, primaryWidth }) => (_jsxs("g", { children: [_jsx("rect", { x: 0, y: y, width: secondaryWidth, height: BAR_HEIGHT, fill: secondaryColor }), _jsx("rect", { x: secondaryWidth, y: y, width: primaryWidth, height: BAR_HEIGHT, fill: primaryColor })] }, y))) }));
|
|
62
|
+
});
|
|
63
|
+
export default DatalayerLogo;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type SVGProps } from 'react';
|
|
2
|
+
import type { ThemeVariant } from '../../theme';
|
|
3
|
+
export interface DatalayerLogoTextProps extends Omit<SVGProps<SVGSVGElement>, 'ref'> {
|
|
4
|
+
size?: number;
|
|
5
|
+
scale?: number;
|
|
6
|
+
colorMode?: 'light' | 'dark' | 'auto';
|
|
7
|
+
variant?: ThemeVariant;
|
|
8
|
+
primaryColor?: string;
|
|
9
|
+
secondaryColor?: string;
|
|
10
|
+
textSizeMultiplier?: number;
|
|
11
|
+
/**
|
|
12
|
+
* When true, render logo mark first then text.
|
|
13
|
+
* When false (default), render text first then logo mark.
|
|
14
|
+
*/
|
|
15
|
+
inverse?: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Datalayer icon + wordmark based on official brand proportions.
|
|
19
|
+
* Uses themed colors by default and allows explicit color overrides.
|
|
20
|
+
*/
|
|
21
|
+
export declare const DatalayerLogoText: import("react").ForwardRefExoticComponent<DatalayerLogoTextProps & import("react").RefAttributes<SVGSVGElement>>;
|
|
22
|
+
export default DatalayerLogoText;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } 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
|
+
import { DatalayerText } from './DatalayerText';
|
|
9
|
+
/**
|
|
10
|
+
* Datalayer icon + wordmark based on official brand proportions.
|
|
11
|
+
* Uses themed colors by default and allows explicit color overrides.
|
|
12
|
+
*/
|
|
13
|
+
export const DatalayerLogoText = forwardRef(function DatalayerLogoText({ size = 25, scale = 1, colorMode = 'light', variant = 'datalayer', primaryColor, secondaryColor,
|
|
14
|
+
// 2.380655 ~= 25 / (0.7 * 15.00187)
|
|
15
|
+
// This makes the wordmark glyph height match the 25-unit icon height.
|
|
16
|
+
textSizeMultiplier = 2.380655, inverse = false, ...svgProps }, ref) {
|
|
17
|
+
const themed = getLogoColors(variant, colorMode);
|
|
18
|
+
const primary = primaryColor ?? themed.primary;
|
|
19
|
+
const secondary = secondaryColor ?? themed.secondary;
|
|
20
|
+
const baseHeight = size;
|
|
21
|
+
const baseWidth = (149.672 / 25) * size;
|
|
22
|
+
const height = baseHeight * scale;
|
|
23
|
+
const width = baseWidth * scale;
|
|
24
|
+
const iconGroup = (_jsxs("g", { transform: "translate(0 0)", children: [_jsx("rect", { x: "0", y: "0", width: "10", height: "6.25", fill: secondary }), _jsx("rect", { x: "10", y: "0", width: "15", height: "6.25", fill: primary }), _jsx("rect", { x: "0", y: "9.375", width: "15", height: "6.25", fill: secondary }), _jsx("rect", { x: "15", y: "9.375", width: "10", height: "6.25", fill: primary }), _jsx("rect", { x: "0", y: "18.75", width: "20", height: "6.25", fill: secondary }), _jsx("rect", { x: "20", y: "18.75", width: "5", height: "6.25", fill: primary })] }));
|
|
25
|
+
const logoFirst = (_jsxs(_Fragment, { children: [iconGroup, _jsx(DatalayerText, { primaryColor: primary, secondaryColor: secondary, sizeMultiplier: textSizeMultiplier, x: 16 })] }));
|
|
26
|
+
const textFirst = (_jsxs(_Fragment, { children: [_jsx(DatalayerText, { primaryColor: primary, secondaryColor: secondary, sizeMultiplier: textSizeMultiplier, x: 0 }), _jsxs("g", { transform: "translate(124.672 0)", children: [_jsx("rect", { x: "0", y: "0", width: "10", height: "6.25", fill: secondary }), _jsx("rect", { x: "10", y: "0", width: "15", height: "6.25", fill: primary }), _jsx("rect", { x: "0", y: "9.375", width: "15", height: "6.25", fill: secondary }), _jsx("rect", { x: "15", y: "9.375", width: "10", height: "6.25", fill: primary }), _jsx("rect", { x: "0", y: "18.75", width: "20", height: "6.25", fill: secondary }), _jsx("rect", { x: "20", y: "18.75", width: "5", height: "6.25", fill: primary })] })] }));
|
|
27
|
+
return (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 149.672 25", width: width, height: height, role: "img", "aria-label": "Datalayer", ref: ref, ...svgProps, children: inverse ? logoFirst : textFirst }));
|
|
28
|
+
});
|
|
29
|
+
export default DatalayerLogoText;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { SVGProps } from 'react';
|
|
2
|
+
export interface DatalayerTextProps extends Omit<SVGProps<SVGGElement>, 'ref'> {
|
|
3
|
+
primaryColor?: string;
|
|
4
|
+
secondaryColor?: string;
|
|
5
|
+
/** Multiplies the base wordmark size. 1.0 keeps current dimensions. */
|
|
6
|
+
sizeMultiplier?: number;
|
|
7
|
+
/** X translation in the parent SVG coordinate system. */
|
|
8
|
+
x?: number;
|
|
9
|
+
/** Y translation in the parent SVG coordinate system. */
|
|
10
|
+
y?: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Official Datalayer wordmark outlines (BebasNeue converted to paths).
|
|
14
|
+
*/
|
|
15
|
+
export declare const DatalayerText: ({ primaryColor, secondaryColor, sizeMultiplier, x, y, ...groupProps }: DatalayerTextProps) => JSX.Element;
|
|
16
|
+
export default DatalayerText;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Official Datalayer wordmark outlines (BebasNeue converted to paths).
|
|
4
|
+
*/
|
|
5
|
+
export const DatalayerText = ({ primaryColor = 'currentColor', secondaryColor = 'currentColor', sizeMultiplier = 1, x = 20, y = -190.15, ...groupProps }) => {
|
|
6
|
+
const baseScale = 0.7;
|
|
7
|
+
const scale = baseScale * sizeMultiplier;
|
|
8
|
+
// Keep the wordmark anchored when scaling so larger multipliers do not
|
|
9
|
+
// move the paths out of the parent SVG viewBox.
|
|
10
|
+
const anchorX = 17.35761;
|
|
11
|
+
const anchorY = 289.499065;
|
|
12
|
+
const translateX = x + anchorX * (baseScale - scale);
|
|
13
|
+
const translateY = y + anchorY * (baseScale - scale);
|
|
14
|
+
return (_jsxs("g", { transform: `matrix(${scale},0,0,${scale},${translateX},${translateY})`, ...groupProps, children: [_jsx("path", { d: "m 17.35761,297 h 3.729038 c 2.357437,0 3.514725,-1.30731 3.514725,-3.70761 v -7.58666 c 0,-2.4003 -1.157288,-3.7076 -3.514725,-3.7076 H 17.35761 Z m 3.686175,-12.85875 c 0.750094,0 1.20015,0.38576 1.20015,1.45733 v 7.80097 c 0,1.07156 -0.450056,1.45733 -1.20015,1.45733 h -1.328737 v -10.71563 z", fill: secondaryColor }), _jsx("path", { d: "M 31.29328,281.99813 H 27.842849 L 25.442549,297 h 2.164556 l 0.407194,-2.72177 h 2.893219 L 31.314711,297 h 2.378869 z m -1.864519,2.65747 h 0.04286 l 1.114425,7.58666 h -2.271713 z", fill: secondaryColor }), _jsx("path", { d: "m 33.2894,284.14125 h 2.464594 V 297 h 2.357438 v -12.85875 h 2.464593 v -2.14312 H 33.2894 Z", fill: secondaryColor }), _jsx("path", { d: "M 46.027265,281.99813 H 42.576834 L 40.176534,297 h 2.164556 l 0.407194,-2.72177 h 2.893219 L 46.048696,297 h 2.378869 z m -1.864519,2.65747 h 0.04286 l 1.114425,7.58666 h -2.271713 z", fill: secondaryColor }), _jsx("path", { d: "m 51.175594,297 h 6.236494 v -2.14312 h -3.879056 v -12.85875 h -2.357438 z", fill: primaryColor }), _jsx("path", { d: "M 63.688095,281.99813 H 60.237664 L 57.837364,297 h 2.164556 l 0.407194,-2.72177 h 2.893219 L 63.709526,297 h 2.378869 z m -1.864519,2.65747 h 0.04286 l 1.114425,7.58666 h -2.271713 z", fill: primaryColor }), _jsx("path", { d: "m 68.326286,297 h 2.357438 v -4.97205 l 2.978944,-10.02982 h -2.250282 l -1.778793,6.83656 h -0.04286 l -1.778794,-6.83656 h -2.464593 l 2.978943,10.02982 z", fill: primaryColor }), _jsx("path", { d: "m 76.973461,284.14125 h 4.071938 v -2.14312 H 74.616024 V 297 h 6.429375 v -2.14312 h -4.071938 v -4.39341 h 3.236119 v -2.14313 h -3.236119 z", fill: primaryColor }), _jsx("path", { d: "m 89.814797,297 c -0.235744,-0.55721 -0.257175,-1.09299 -0.257175,-1.82166 v -2.31457 c 0,-1.56448 -0.385763,-2.67891 -1.564481,-3.17183 v -0.0429 c 1.050131,-0.49292 1.543049,-1.47875 1.543049,-3.0218 v -1.17872 c 0,-2.31458 -1.050131,-3.45043 -3.493293,-3.45043 H 82.485309 V 297 h 2.357438 v -6.10791 h 0.814387 c 1.071563,0 1.54305,0.51435 1.54305,1.90739 v 2.35743 c 0,1.22158 0.08573,1.45733 0.214313,1.84309 z m -3.836194,-12.85875 c 0.835819,0 1.20015,0.47149 1.20015,1.54305 v 1.47876 c 0,1.20015 -0.535781,1.58591 -1.414462,1.58591 h -0.921544 v -4.60772 z", fill: primaryColor })] }));
|
|
15
|
+
};
|
|
16
|
+
export default DatalayerText;
|
package/lib/index.js
CHANGED
|
@@ -3,21 +3,88 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
4
4
|
* Distributed under the terms of the Modified BSD License.
|
|
5
5
|
*/
|
|
6
|
-
import { useEffect } from 'react';
|
|
6
|
+
import { useEffect, useMemo } from 'react';
|
|
7
7
|
import { BaseStyles, ThemeProvider } from '@primer/react';
|
|
8
8
|
import { useSystemColorMode } from './useSystemColorMode';
|
|
9
9
|
import { datalayerTheme, datalayerThemeStyles } from './themes/datalayerTheme';
|
|
10
|
-
import { setupPrimerPortals } from '../utils/Portals';
|
|
10
|
+
import { setupPrimerPortals, syncPortalThemeStyles } from '../utils/Portals';
|
|
11
|
+
/**
|
|
12
|
+
* System sans-serif font stack — shared between `fontFamily` and
|
|
13
|
+
* the Primer `--fontStack-*` CSS custom properties so that
|
|
14
|
+
* components using the CSS `font` shorthand (e.g. `Blankslate`)
|
|
15
|
+
* also pick up the themed typeface.
|
|
16
|
+
*/
|
|
17
|
+
const SYSTEM_FONT = '-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"';
|
|
11
18
|
/**
|
|
12
19
|
* Shared typographic rhythm — clean, spacious feel inspired by
|
|
13
20
|
* modern developer-blog aesthetics (generous line-height, open
|
|
14
21
|
* letter-spacing on headings, crisp body text).
|
|
22
|
+
*
|
|
23
|
+
* Primer components like `Blankslate` use the CSS `font` shorthand
|
|
24
|
+
* through `--text-title-shorthand-*` / `--text-body-shorthand-*`.
|
|
25
|
+
* Those shorthand variables reference `--fontStack-sansSerif` (and
|
|
26
|
+
* `--fontStack-sansSerifDisplay`). If the `@primer/primitives`
|
|
27
|
+
* typography CSS isn't loaded, the shorthand vars are undefined and
|
|
28
|
+
* components fall back to a hardcoded system font stack baked into
|
|
29
|
+
* their CSS. We define the full set here so **every** theme gets
|
|
30
|
+
* correct font inheritance — no primitives CSS import required.
|
|
15
31
|
*/
|
|
16
32
|
const typographyVars = {
|
|
33
|
+
/* ── Font stacks ───────────────────────────────────────────────── */
|
|
34
|
+
'--fontStack-monospace': 'ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace',
|
|
35
|
+
'--fontStack-sansSerif': SYSTEM_FONT,
|
|
36
|
+
'--fontStack-sansSerifDisplay': SYSTEM_FONT,
|
|
37
|
+
'--fontStack-system': SYSTEM_FONT,
|
|
38
|
+
/* ── Base text weights (from @primer/primitives) ───────────────── */
|
|
39
|
+
'--base-text-weight-light': '300',
|
|
40
|
+
'--base-text-weight-normal': '400',
|
|
41
|
+
'--base-text-weight-medium': '500',
|
|
42
|
+
'--base-text-weight-semibold': '600',
|
|
43
|
+
/* ── Body sizing ───────────────────────────────────────────────── */
|
|
44
|
+
'--text-body-size-large': '1rem',
|
|
45
|
+
'--text-body-size-medium': '0.875rem',
|
|
46
|
+
'--text-body-size-small': '0.75rem',
|
|
47
|
+
'--text-body-lineHeight-large': '1.5',
|
|
48
|
+
'--text-body-lineHeight-medium': '1.4285',
|
|
49
|
+
'--text-body-lineHeight-small': '1.6666',
|
|
50
|
+
/* ── Title sizing ──────────────────────────────────────────────── */
|
|
51
|
+
'--text-title-size-large': '2rem',
|
|
52
|
+
'--text-title-size-medium': '1.25rem',
|
|
53
|
+
'--text-title-size-small': '1rem',
|
|
54
|
+
'--text-title-lineHeight-large': '1.5',
|
|
55
|
+
'--text-title-lineHeight-medium': '1.6',
|
|
56
|
+
'--text-title-lineHeight-small': '1.5',
|
|
57
|
+
/* ── Caption / subtitle / display ──────────────────────────────── */
|
|
58
|
+
'--text-caption-size': '0.75rem',
|
|
59
|
+
'--text-caption-lineHeight': '1.3333',
|
|
60
|
+
'--text-subtitle-size': '1.25rem',
|
|
61
|
+
'--text-subtitle-lineHeight': '1.6',
|
|
62
|
+
'--text-display-size': '2.5rem',
|
|
63
|
+
'--text-display-lineHeight': '1.4',
|
|
64
|
+
/* ── Font shorthand tokens ─────────────────────────────────────── *
|
|
65
|
+
* These are the tokens consumed by Primer components (Blankslate,
|
|
66
|
+
* etc.) via `font: var(--text-title-shorthand-medium, <fallback>)`.
|
|
67
|
+
* Defining them here prevents the hard-coded fallback from firing.
|
|
68
|
+
* Each one references `var(--fontStack-sansSerif)` or
|
|
69
|
+
* `SYSTEM_FONT` directly (no nested `var()`) so that the CSS
|
|
70
|
+
* `font` shorthand parses reliably. Themes that override fonts
|
|
71
|
+
* (e.g. Matrix monospace) replace these shorthand tokens via
|
|
72
|
+
* `buildThemeStyles({ fontFamily })` in their `themeStyles`.
|
|
73
|
+
* ─────────────────────────────────────────────────────────────── */
|
|
74
|
+
'--text-body-shorthand-large': `400 1rem/1.5 ${SYSTEM_FONT}`,
|
|
75
|
+
'--text-body-shorthand-medium': `400 0.875rem/1.4285 ${SYSTEM_FONT}`,
|
|
76
|
+
'--text-body-shorthand-small': `400 0.75rem/1.6666 ${SYSTEM_FONT}`,
|
|
77
|
+
'--text-title-shorthand-large': `600 2rem/1.5 ${SYSTEM_FONT}`,
|
|
78
|
+
'--text-title-shorthand-medium': `600 1.25rem/1.6 ${SYSTEM_FONT}`,
|
|
79
|
+
'--text-title-shorthand-small': `600 1rem/1.5 ${SYSTEM_FONT}`,
|
|
80
|
+
'--text-caption-shorthand': `400 0.75rem/1.3333 ${SYSTEM_FONT}`,
|
|
81
|
+
'--text-subtitle-shorthand': `400 1.25rem/1.6 ${SYSTEM_FONT}`,
|
|
82
|
+
'--text-display-shorthand': `500 2.5rem/1.4 ${SYSTEM_FONT}`,
|
|
83
|
+
/* ── Custom overrides ──────────────────────────────────────────── */
|
|
17
84
|
'--text-body-lineHeight': '1.7',
|
|
18
85
|
'--text-title-lineHeight': '1.2',
|
|
19
86
|
'--text-title-letterSpacing': '-0.02em',
|
|
20
|
-
fontFamily:
|
|
87
|
+
fontFamily: SYSTEM_FONT,
|
|
21
88
|
WebkitFontSmoothing: 'antialiased',
|
|
22
89
|
MozOsxFontSmoothing: 'grayscale',
|
|
23
90
|
textRendering: 'optimizeLegibility',
|
|
@@ -31,11 +98,21 @@ export function DatalayerThemeProvider(props) {
|
|
|
31
98
|
const resolvedTheme = theme ?? datalayerTheme;
|
|
32
99
|
const styles = themeStyles ?? datalayerThemeStyles;
|
|
33
100
|
const resolvedStyles = isDark ? styles.dark : styles.light;
|
|
34
|
-
//
|
|
35
|
-
//
|
|
101
|
+
// The full set of styles that <BaseStyles> receives — we also push
|
|
102
|
+
// these to document.body so Primer portal content inherits theme
|
|
103
|
+
// tokens, fonts, and colors.
|
|
104
|
+
const portalStyles = useMemo(() => ({
|
|
105
|
+
...typographyVars,
|
|
106
|
+
...resolvedStyles,
|
|
107
|
+
...baseStyles,
|
|
108
|
+
}), [resolvedStyles, baseStyles]);
|
|
109
|
+
// Keep document.body portal-root attributes AND theme styles in sync
|
|
110
|
+
// so that Primer portals (modals, dialogs, overlays) inherit the
|
|
111
|
+
// correct color mode **and** theme tokens (fonts, colors, CSS vars).
|
|
36
112
|
useEffect(() => {
|
|
37
113
|
setupPrimerPortals(resolvedColorMode === 'night' ? 'dark' : resolvedColorMode === 'day' ? 'light' : resolvedColorMode);
|
|
38
|
-
|
|
114
|
+
syncPortalThemeStyles(portalStyles);
|
|
115
|
+
}, [resolvedColorMode, portalStyles]);
|
|
39
116
|
return (_jsx(ThemeProvider, { colorMode: resolvedColorMode, theme: resolvedTheme, ...rest, children: _jsx(BaseStyles, { style: {
|
|
40
117
|
lineHeight: '1.7',
|
|
41
118
|
transition: 'background-color 0.25s ease, color 0.25s ease',
|
package/lib/theme/Palette.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
export declare const
|
|
3
|
-
|
|
4
|
-
export declare const
|
|
1
|
+
/** @deprecated Use `defaultIndicatorColors.reservation` */
|
|
2
|
+
export declare const RESERVATION_CIRCLE_COLOR: string;
|
|
3
|
+
/** @deprecated Use `defaultIndicatorColors.credits` */
|
|
4
|
+
export declare const CREDITS_CIRCLE_COLOR: string;
|
|
5
|
+
/** @deprecated Use `defaultIndicatorColors.inviteJoined` */
|
|
6
|
+
export declare const JOINED_INVITE_COLOR: string;
|
|
7
|
+
/** @deprecated Use `defaultIndicatorColors.invitePending` */
|
|
8
|
+
export declare const PENDING_INVITE_COLOR: string;
|
package/lib/theme/Palette.js
CHANGED
|
@@ -2,9 +2,16 @@
|
|
|
2
2
|
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
3
3
|
* Distributed under the terms of the Modified BSD License.
|
|
4
4
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
/**
|
|
6
|
+
* @deprecated Use `indicatorColors` / `defaultIndicatorColors` from
|
|
7
|
+
* `@datalayer/primer-addons/lib/theme` instead.
|
|
8
|
+
*/
|
|
9
|
+
import { defaultIndicatorColors } from './colors/indicatorColors';
|
|
10
|
+
/** @deprecated Use `defaultIndicatorColors.reservation` */
|
|
11
|
+
export const RESERVATION_CIRCLE_COLOR = defaultIndicatorColors.reservation;
|
|
12
|
+
/** @deprecated Use `defaultIndicatorColors.credits` */
|
|
13
|
+
export const CREDITS_CIRCLE_COLOR = defaultIndicatorColors.credits;
|
|
14
|
+
/** @deprecated Use `defaultIndicatorColors.inviteJoined` */
|
|
15
|
+
export const JOINED_INVITE_COLOR = defaultIndicatorColors.inviteJoined;
|
|
16
|
+
/** @deprecated Use `defaultIndicatorColors.invitePending` */
|
|
17
|
+
export const PENDING_INVITE_COLOR = defaultIndicatorColors.invitePending;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ThemedProvider – Drop-in theme provider that reads theme / color-mode
|
|
3
|
+
* from a Zustand `ThemeState` store and forwards them to
|
|
4
|
+
* `DatalayerThemeProvider`.
|
|
5
|
+
*
|
|
6
|
+
* Consumers pass the `useStore` hook as a prop, so the provider is
|
|
7
|
+
* completely decoupled from any specific application's store instance.
|
|
8
|
+
*
|
|
9
|
+
* @module theme/ThemedProvider
|
|
10
|
+
*/
|
|
11
|
+
import React from 'react';
|
|
12
|
+
import { type IDatalayerThemeProviderProps } from './DatalayerThemeProvider';
|
|
13
|
+
import type { ThemeState } from './useThemeStore';
|
|
14
|
+
import type { UseBoundStore, StoreApi } from 'zustand';
|
|
15
|
+
export interface ThemedProviderProps extends Omit<IDatalayerThemeProviderProps, 'ref'> {
|
|
16
|
+
/** A Zustand store hook created via `createThemeStore()`. */
|
|
17
|
+
useStore: UseBoundStore<StoreApi<ThemeState>>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Drop-in replacement for `<DatalayerThemeProvider>`.
|
|
21
|
+
* Reads theme / colorMode from the supplied store and forwards them to
|
|
22
|
+
* the real provider. Any explicit props (colorMode, theme, themeStyles)
|
|
23
|
+
* are still respected as overrides.
|
|
24
|
+
*/
|
|
25
|
+
export declare const ThemedProvider: React.FC<React.PropsWithChildren<ThemedProviderProps>>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { DatalayerThemeProvider, } from './DatalayerThemeProvider';
|
|
3
|
+
import { themeConfigs } from './themeRegistry';
|
|
4
|
+
/**
|
|
5
|
+
* Drop-in replacement for `<DatalayerThemeProvider>`.
|
|
6
|
+
* Reads theme / colorMode from the supplied store and forwards them to
|
|
7
|
+
* the real provider. Any explicit props (colorMode, theme, themeStyles)
|
|
8
|
+
* are still respected as overrides.
|
|
9
|
+
*/
|
|
10
|
+
export const ThemedProvider = ({ children, useStore, ...rest }) => {
|
|
11
|
+
const { colorMode, theme: themeVariant } = useStore();
|
|
12
|
+
const cfg = themeConfigs[themeVariant];
|
|
13
|
+
return (_jsx(DatalayerThemeProvider, { colorMode: rest.colorMode ?? colorMode, theme: rest.theme ?? cfg.primerTheme, themeStyles: rest.themeStyles ?? cfg.themeStyles, ...rest, children: children }));
|
|
14
|
+
};
|
|
@@ -12,4 +12,18 @@ export declare const datalayerColors: {
|
|
|
12
12
|
greenTint: string;
|
|
13
13
|
greenBright: string;
|
|
14
14
|
greenHover: string;
|
|
15
|
+
brightGlow: string;
|
|
16
|
+
brightPop: string;
|
|
17
|
+
brightSpark: string;
|
|
18
|
+
brightBlaze: string;
|
|
19
|
+
brightSurge: string;
|
|
20
|
+
brightFlame: string;
|
|
21
|
+
brightGold: string;
|
|
22
|
+
brightLightGlow: string;
|
|
23
|
+
brightLightPop: string;
|
|
24
|
+
brightLightSpark: string;
|
|
25
|
+
brightLightBlaze: string;
|
|
26
|
+
brightLightSurge: string;
|
|
27
|
+
brightLightFlame: string;
|
|
28
|
+
brightLightGold: string;
|
|
15
29
|
};
|
|
@@ -18,4 +18,21 @@ export const datalayerColors = {
|
|
|
18
18
|
greenTint: '#E9F7F1', // Soft background for success / callouts
|
|
19
19
|
greenBright: '#2ECC71', // Highlights and glow on dark backgrounds
|
|
20
20
|
greenHover: '#0E6655', // Primary button hover
|
|
21
|
+
// Bright / vivid colours for SVG illustrations (OpenAI-blog style)
|
|
22
|
+
brightGlow: '#00D68F', // Ultra-vivid emerald — primary glow
|
|
23
|
+
brightPop: '#00E5FF', // Electric cyan — contrasting accent
|
|
24
|
+
brightSpark: '#76FF03', // Lime neon — sparkle / tertiary
|
|
25
|
+
brightBlaze: '#FF1744', // Vivid red — warm accent
|
|
26
|
+
brightSurge: '#2979FF', // Electric blue — cool accent
|
|
27
|
+
// Warm vivid colours — yellow & orange accents for SVG illustrations
|
|
28
|
+
brightFlame: '#FF6D00', // Vivid orange — warm energy accent
|
|
29
|
+
brightGold: '#FFD600', // Vivid yellow — golden highlight
|
|
30
|
+
// Vivid brights for light backgrounds — punchy, saturated, OpenAI-blog vibrancy
|
|
31
|
+
brightLightGlow: '#00BFA5', // Vivid aqua-green
|
|
32
|
+
brightLightPop: '#00B0FF', // Vivid sky blue
|
|
33
|
+
brightLightSpark: '#64DD17', // Vivid chartreuse
|
|
34
|
+
brightLightBlaze: '#FF1744', // Vivid red
|
|
35
|
+
brightLightSurge: '#2979FF', // Electric blue
|
|
36
|
+
brightLightFlame: '#FF6D00', // Vivid orange
|
|
37
|
+
brightLightGold: '#FFAB00', // Vivid amber
|
|
21
38
|
};
|
|
@@ -2,3 +2,4 @@ export { datalayerColors } from './datalayerColors';
|
|
|
2
2
|
export { spatialColors } from './spatialColors';
|
|
3
3
|
export { lovelyColors } from './lovelyColors';
|
|
4
4
|
export { matrixColors } from './matrixColors';
|
|
5
|
+
export { indicatorColors, defaultIndicatorColors, type IndicatorColors, } from './indicatorColors';
|
|
@@ -6,3 +6,4 @@ export { datalayerColors } from './datalayerColors';
|
|
|
6
6
|
export { spatialColors } from './spatialColors';
|
|
7
7
|
export { lovelyColors } from './lovelyColors';
|
|
8
8
|
export { matrixColors } from './matrixColors';
|
|
9
|
+
export { indicatorColors, defaultIndicatorColors, } from './indicatorColors';
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Indicator Color Palette — Semantic status colours for indicators,
|
|
3
|
+
* badges, progress rings, and status dots.
|
|
4
|
+
*
|
|
5
|
+
* Each theme provides its own `IndicatorColors` so consumers pick up
|
|
6
|
+
* the correct tones automatically. The palette contains both
|
|
7
|
+
* **status colours** (success, warning, danger …) and
|
|
8
|
+
* **domain-specific** colours (reservation, credits, invite …).
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { indicatorColors } from '@datalayer/primer-addons/lib/theme';
|
|
13
|
+
* const colors = indicatorColors.datalayer; // or .spatial, .lovely, .matrix
|
|
14
|
+
* <Box sx={{ bg: colors.success }} />
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export interface IndicatorColors {
|
|
18
|
+
/** Neutral / default — nothing notable */
|
|
19
|
+
neutral: string;
|
|
20
|
+
/** Muted — defined but inactive */
|
|
21
|
+
muted: string;
|
|
22
|
+
/** In-progress / loading */
|
|
23
|
+
pending: string;
|
|
24
|
+
/** Warning / attention-needed */
|
|
25
|
+
warning: string;
|
|
26
|
+
/** Error / failure */
|
|
27
|
+
danger: string;
|
|
28
|
+
/** Healthy / success */
|
|
29
|
+
success: string;
|
|
30
|
+
/** Informational / accent */
|
|
31
|
+
info: string;
|
|
32
|
+
/** Reservation indicator (e.g. usage rings) */
|
|
33
|
+
reservation: string;
|
|
34
|
+
/** Credits indicator (e.g. usage rings) */
|
|
35
|
+
credits: string;
|
|
36
|
+
/** Accepted / joined invite */
|
|
37
|
+
inviteJoined: string;
|
|
38
|
+
/** Pending invite */
|
|
39
|
+
invitePending: string;
|
|
40
|
+
}
|
|
41
|
+
export declare const indicatorColors: {
|
|
42
|
+
readonly datalayer: IndicatorColors;
|
|
43
|
+
readonly spatial: IndicatorColors;
|
|
44
|
+
readonly lovely: IndicatorColors;
|
|
45
|
+
readonly matrix: IndicatorColors;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Convenience: default indicator palette (Datalayer theme).
|
|
49
|
+
*/
|
|
50
|
+
export declare const defaultIndicatorColors: IndicatorColors;
|