@datalayer/primer-addons 1.0.11 → 1.0.13
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.d.ts +1 -0
- package/lib/App.js +1 -0
- 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/{theme/ThemeSwitcher.js → components/appearance/AppearanceControlsWithStore.js} +5 -3
- 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 +39 -0
- package/lib/components/logo/DatalayerLogo.js +116 -0
- package/lib/components/logo/DatalayerLogoText.d.ts +30 -0
- package/lib/components/logo/DatalayerLogoText.js +30 -0
- package/lib/components/logo/DatalayerText.d.ts +22 -0
- package/lib/components/logo/DatalayerText.js +21 -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/colors/datalayerColors.js +1 -1
- package/lib/theme/colors/earthColors.d.ts +39 -0
- package/lib/theme/colors/earthColors.js +51 -0
- package/lib/theme/colors/index.d.ts +14 -0
- package/lib/theme/colors/index.js +24 -0
- package/lib/theme/colors/indicatorColors.d.ts +50 -0
- package/lib/theme/colors/indicatorColors.js +68 -0
- package/lib/theme/index.d.ts +1 -2
- package/lib/theme/index.js +1 -2
- package/lib/theme/themeRegistry.d.ts +1 -1
- package/lib/theme/themeRegistry.js +51 -1
- package/lib/theme/themes/datalayerTheme.d.ts +0 -2
- package/lib/theme/themes/datalayerTheme.js +0 -2
- package/lib/theme/themes/earthTheme.d.ts +1091 -0
- package/lib/theme/themes/earthTheme.js +193 -0
- package/lib/theme/themes/lovelyTheme.d.ts +0 -2
- package/lib/theme/themes/lovelyTheme.js +0 -2
- package/lib/theme/themes/matrixTheme.d.ts +0 -2
- package/lib/theme/themes/matrixTheme.js +0 -2
- package/lib/theme/themes/spatialTheme.d.ts +0 -2
- package/lib/theme/themes/spatialTheme.js +0 -2
- package/lib/theme/useThemeStore.d.ts +0 -1
- package/lib/utils/Portals.d.ts +4 -0
- package/lib/utils/Portals.js +61 -9
- package/package.json +1 -1
- package/lib/_utils/story-helpers.d.ts +0 -31
- package/lib/_utils/story-helpers.js +0 -105
- package/lib/theme/Palette.d.ts +0 -4
- package/lib/theme/Palette.js +0 -10
- package/lib/theme/ThemeSwitcher.d.ts +0 -17
package/lib/App.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import "@primer/primitives/dist/css/base/typography/typography.css";
|
|
2
|
+
import "@primer/primitives/dist/css/base/motion/motion.css";
|
|
2
3
|
import "@primer/primitives/dist/css/functional/themes/light.css";
|
|
3
4
|
import "@primer/primitives/dist/css/functional/size/border.css";
|
|
4
5
|
import "@primer/primitives/dist/css/functional/size/breakpoints.css";
|
package/lib/App.js
CHANGED
|
@@ -5,6 +5,7 @@ import { KebabHorizontalIcon } from "@primer/octicons-react";
|
|
|
5
5
|
import { DatalayerIcon, LogOutIcon, SettingsIcon } from "@datalayer/icons-react";
|
|
6
6
|
import { Slider, Overlay } from ".";
|
|
7
7
|
import "@primer/primitives/dist/css/base/typography/typography.css";
|
|
8
|
+
import "@primer/primitives/dist/css/base/motion/motion.css";
|
|
8
9
|
import "@primer/primitives/dist/css/functional/themes/light.css";
|
|
9
10
|
import "@primer/primitives/dist/css/functional/size/border.css";
|
|
10
11
|
import "@primer/primitives/dist/css/functional/size/breakpoints.css";
|
|
@@ -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, Tooltip } 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(Tooltip, { text: cfg.label, direction: "s", children: _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;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { IconButton, SegmentedControl, Tooltip } from '@primer/react';
|
|
3
3
|
import { SunIcon, MoonIcon, DeviceDesktopIcon, CircleIcon, } from '@primer/octicons-react';
|
|
4
|
-
import {
|
|
5
|
-
|
|
4
|
+
import { Box } from '../box/Box';
|
|
5
|
+
import { themeConfigs, themeVariants } from '../../theme/themeRegistry';
|
|
6
|
+
export const AppearanceControlsWithStore = ({ useStore }) => {
|
|
6
7
|
const { colorMode, theme: themeVariant } = useStore();
|
|
7
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 => {
|
|
8
9
|
const tcfg = themeConfigs[variant];
|
|
@@ -17,3 +18,4 @@ export const ThemeSwitcher = ({ useStore }) => {
|
|
|
17
18
|
useStore.getState().setColorMode(modes[index]);
|
|
18
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" })] })] }));
|
|
19
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,39 @@
|
|
|
1
|
+
import { type SVGProps } from 'react';
|
|
2
|
+
import { type ThemeVariant } from '../../theme';
|
|
3
|
+
export interface LogoColorPair {
|
|
4
|
+
primary: string;
|
|
5
|
+
secondary: string;
|
|
6
|
+
/** Colour for the "DATA" part of the wordmark (gray in the original brand logo). */
|
|
7
|
+
textColor: string;
|
|
8
|
+
/** Gradient [start, end] for primary (left) bars. */
|
|
9
|
+
primaryGradient: [start: string, end: string];
|
|
10
|
+
/** Gradient [start, end] for secondary (right) bars. */
|
|
11
|
+
secondaryGradient: [start: string, end: string];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Gradient pattern derived from the original brand logo SVG:
|
|
15
|
+
* - Left bars: accent → brand (bright → mid)
|
|
16
|
+
* - Right bars: hover → text (dark → mid)
|
|
17
|
+
*
|
|
18
|
+
* This mapping is consistent across all four themes.
|
|
19
|
+
*/
|
|
20
|
+
export declare const THEME_LOGO_COLORS: Record<ThemeVariant, {
|
|
21
|
+
light: LogoColorPair;
|
|
22
|
+
dark: LogoColorPair;
|
|
23
|
+
}>;
|
|
24
|
+
export declare function getLogoColors(variant?: ThemeVariant, colorMode?: 'light' | 'dark' | 'auto'): LogoColorPair;
|
|
25
|
+
export interface DatalayerLogoProps extends Omit<SVGProps<SVGSVGElement>, 'ref'> {
|
|
26
|
+
size?: number;
|
|
27
|
+
variant?: ThemeVariant;
|
|
28
|
+
colorMode?: 'light' | 'dark' | 'auto';
|
|
29
|
+
primaryColor?: string;
|
|
30
|
+
secondaryColor?: string;
|
|
31
|
+
/** Explicit gradient [start, end] for primary (left) bars. */
|
|
32
|
+
primaryGradient?: [start: string, end: string];
|
|
33
|
+
/** Explicit gradient [start, end] for secondary (right) bars. */
|
|
34
|
+
secondaryGradient?: [start: string, end: string];
|
|
35
|
+
/** Enable horizontal gradients matching the original brand logo. Default `true`. */
|
|
36
|
+
gradient?: boolean;
|
|
37
|
+
}
|
|
38
|
+
export declare const DatalayerLogo: import("react").ForwardRefExoticComponent<DatalayerLogoProps & import("react").RefAttributes<SVGSVGElement>>;
|
|
39
|
+
export default DatalayerLogo;
|
|
@@ -0,0 +1,116 @@
|
|
|
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, useId } from 'react';
|
|
7
|
+
import { datalayerColors, spatialColors, lovelyColors, matrixColors, earthColors, } from '../../theme';
|
|
8
|
+
/**
|
|
9
|
+
* Gradient pattern derived from the original brand logo SVG:
|
|
10
|
+
* - Left bars: accent → brand (bright → mid)
|
|
11
|
+
* - Right bars: hover → text (dark → mid)
|
|
12
|
+
*
|
|
13
|
+
* This mapping is consistent across all four themes.
|
|
14
|
+
*/
|
|
15
|
+
export const THEME_LOGO_COLORS = {
|
|
16
|
+
datalayer: {
|
|
17
|
+
light: {
|
|
18
|
+
primary: datalayerColors.greenAccent,
|
|
19
|
+
secondary: datalayerColors.greenText,
|
|
20
|
+
textColor: datalayerColors.gray,
|
|
21
|
+
primaryGradient: [datalayerColors.greenAccent, datalayerColors.greenBrand],
|
|
22
|
+
secondaryGradient: [datalayerColors.greenHover, datalayerColors.greenBrand],
|
|
23
|
+
},
|
|
24
|
+
dark: {
|
|
25
|
+
primary: datalayerColors.greenBright,
|
|
26
|
+
secondary: datalayerColors.greenAccent,
|
|
27
|
+
textColor: datalayerColors.gray,
|
|
28
|
+
primaryGradient: [datalayerColors.greenAccent, datalayerColors.greenBrand],
|
|
29
|
+
secondaryGradient: [datalayerColors.greenHover, datalayerColors.greenText],
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
spatial: {
|
|
33
|
+
light: {
|
|
34
|
+
primary: spatialColors.indigoBrand,
|
|
35
|
+
secondary: spatialColors.indigoText,
|
|
36
|
+
textColor: spatialColors.gray,
|
|
37
|
+
primaryGradient: [spatialColors.indigoBright, spatialColors.indigoBrand],
|
|
38
|
+
secondaryGradient: [spatialColors.indigoHover, spatialColors.indigoAccent],
|
|
39
|
+
},
|
|
40
|
+
dark: {
|
|
41
|
+
primary: spatialColors.indigoBright,
|
|
42
|
+
secondary: spatialColors.indigoAccent,
|
|
43
|
+
textColor: spatialColors.gray,
|
|
44
|
+
primaryGradient: [spatialColors.indigoBright, spatialColors.indigoBrand],
|
|
45
|
+
secondaryGradient: [spatialColors.indigoHover, spatialColors.indigoAccent],
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
lovely: {
|
|
49
|
+
light: {
|
|
50
|
+
primary: lovelyColors.roseBrand,
|
|
51
|
+
secondary: lovelyColors.roseText,
|
|
52
|
+
textColor: lovelyColors.gray,
|
|
53
|
+
primaryGradient: [lovelyColors.roseBright, lovelyColors.roseBrand],
|
|
54
|
+
secondaryGradient: [lovelyColors.roseHover, lovelyColors.roseAccent],
|
|
55
|
+
},
|
|
56
|
+
dark: {
|
|
57
|
+
primary: lovelyColors.roseBright,
|
|
58
|
+
secondary: lovelyColors.roseAccent,
|
|
59
|
+
textColor: lovelyColors.gray,
|
|
60
|
+
primaryGradient: [lovelyColors.roseBright, lovelyColors.roseBrand],
|
|
61
|
+
secondaryGradient: [lovelyColors.roseHover, lovelyColors.roseAccent],
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
matrix: {
|
|
65
|
+
light: {
|
|
66
|
+
primary: matrixColors.greenBrand,
|
|
67
|
+
secondary: matrixColors.greenText,
|
|
68
|
+
textColor: matrixColors.gray,
|
|
69
|
+
primaryGradient: [matrixColors.greenGlow, matrixColors.greenBrand],
|
|
70
|
+
secondaryGradient: [matrixColors.greenHover, matrixColors.greenAccent],
|
|
71
|
+
},
|
|
72
|
+
dark: {
|
|
73
|
+
primary: matrixColors.greenGlow,
|
|
74
|
+
secondary: matrixColors.greenPhosphor,
|
|
75
|
+
textColor: matrixColors.gray,
|
|
76
|
+
primaryGradient: [matrixColors.greenGlow, matrixColors.greenBrand],
|
|
77
|
+
secondaryGradient: [matrixColors.greenHover, matrixColors.greenAccent],
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
earth: {
|
|
81
|
+
light: {
|
|
82
|
+
primary: earthColors.oceanBrand,
|
|
83
|
+
secondary: earthColors.oceanText,
|
|
84
|
+
textColor: earthColors.gray,
|
|
85
|
+
primaryGradient: [earthColors.oceanAccent, earthColors.oceanBrand],
|
|
86
|
+
secondaryGradient: [earthColors.oceanHover, earthColors.oceanText],
|
|
87
|
+
},
|
|
88
|
+
dark: {
|
|
89
|
+
primary: earthColors.oceanBright,
|
|
90
|
+
secondary: earthColors.oceanAccent,
|
|
91
|
+
textColor: earthColors.gray,
|
|
92
|
+
primaryGradient: [earthColors.oceanBright, earthColors.oceanBrand],
|
|
93
|
+
secondaryGradient: [earthColors.oceanHover, earthColors.oceanAccent],
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
export function getLogoColors(variant = 'datalayer', colorMode = 'light') {
|
|
98
|
+
const mode = colorMode === 'auto' ? 'light' : colorMode;
|
|
99
|
+
return THEME_LOGO_COLORS[variant]?.[mode] ?? THEME_LOGO_COLORS.datalayer.light;
|
|
100
|
+
}
|
|
101
|
+
const BAR_HEIGHT = 25;
|
|
102
|
+
const BARS = [
|
|
103
|
+
{ y: 0, secondaryWidth: 30, primaryWidth: 70 },
|
|
104
|
+
{ y: 37.5, secondaryWidth: 50, primaryWidth: 50 },
|
|
105
|
+
{ y: 75, secondaryWidth: 70, primaryWidth: 30 },
|
|
106
|
+
];
|
|
107
|
+
export const DatalayerLogo = forwardRef(function DatalayerLogo({ size = 16, variant = 'datalayer', colorMode = 'light', primaryColor, secondaryColor, primaryGradient, secondaryGradient, gradient = true, ...svgProps }, ref) {
|
|
108
|
+
const themed = getLogoColors(variant, colorMode);
|
|
109
|
+
const resolvedPrimary = primaryColor ?? themed.primary;
|
|
110
|
+
const resolvedSecondary = secondaryColor ?? themed.secondary;
|
|
111
|
+
const uid = useId().replace(/:/g, '');
|
|
112
|
+
const [primaryStart, primaryEnd] = primaryGradient ?? themed.primaryGradient;
|
|
113
|
+
const [secondaryStart, secondaryEnd] = secondaryGradient ?? themed.secondaryGradient;
|
|
114
|
+
return (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 100 100", width: size, height: size, "aria-hidden": "true", ref: ref, ...svgProps, children: [gradient && (_jsxs("defs", { children: [_jsxs("linearGradient", { id: `${uid}-p`, x1: "0", y1: "0", x2: "1", y2: "0", children: [_jsx("stop", { offset: "0", stopColor: primaryStart }), _jsx("stop", { offset: "1", stopColor: primaryEnd })] }), _jsxs("linearGradient", { id: `${uid}-s`, x1: "0", y1: "0", x2: "1", y2: "0", children: [_jsx("stop", { offset: "0", stopColor: secondaryStart }), _jsx("stop", { offset: "1", stopColor: secondaryEnd })] })] })), BARS.map(({ y, secondaryWidth, primaryWidth }) => (_jsxs("g", { children: [_jsx("rect", { x: 0, y: y, width: secondaryWidth, height: BAR_HEIGHT, fill: gradient ? `url(#${uid}-p)` : resolvedPrimary }), _jsx("rect", { x: secondaryWidth, y: y, width: primaryWidth, height: BAR_HEIGHT, fill: gradient ? `url(#${uid}-s)` : resolvedSecondary })] }, y)))] }));
|
|
115
|
+
});
|
|
116
|
+
export default DatalayerLogo;
|
|
@@ -0,0 +1,30 @@
|
|
|
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
|
+
/** Explicit gradient [start, end] for primary (left) bars. */
|
|
11
|
+
primaryGradient?: [start: string, end: string];
|
|
12
|
+
/** Explicit gradient [start, end] for secondary (right) bars. */
|
|
13
|
+
secondaryGradient?: [start: string, end: string];
|
|
14
|
+
/** Enable horizontal gradients matching the original brand logo. Default `true`. */
|
|
15
|
+
gradient?: boolean;
|
|
16
|
+
/** Colour for the "DATA" part of the wordmark (defaults to theme gray). */
|
|
17
|
+
textColor?: string;
|
|
18
|
+
textSizeMultiplier?: number;
|
|
19
|
+
/**
|
|
20
|
+
* When true, render logo mark first then text.
|
|
21
|
+
* When false (default), render text first then logo mark.
|
|
22
|
+
*/
|
|
23
|
+
inverse?: boolean;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Datalayer icon + wordmark based on official brand proportions.
|
|
27
|
+
* Uses themed colors by default and allows explicit color overrides.
|
|
28
|
+
*/
|
|
29
|
+
export declare const DatalayerLogoText: import("react").ForwardRefExoticComponent<DatalayerLogoTextProps & import("react").RefAttributes<SVGSVGElement>>;
|
|
30
|
+
export default DatalayerLogoText;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, 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 { DatalayerLogo, 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, primaryGradient, secondaryGradient, gradient = true, textColor,
|
|
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
|
+
// "DATA" part of the wordmark defaults to the themed gray.
|
|
21
|
+
const dataTextColor = textColor ?? themed.textColor;
|
|
22
|
+
const baseHeight = size;
|
|
23
|
+
const baseWidth = (161.672 / 25) * size;
|
|
24
|
+
const height = baseHeight * scale;
|
|
25
|
+
const width = baseWidth * scale;
|
|
26
|
+
const logoFirst = (_jsxs(_Fragment, { children: [_jsx(DatalayerLogo, { size: 25, x: 0, y: 0, variant: variant, colorMode: colorMode, primaryColor: primary, secondaryColor: secondary, primaryGradient: primaryGradient, secondaryGradient: secondaryGradient, gradient: gradient }), _jsx(DatalayerText, { primaryColor: primary, secondaryColor: dataTextColor, sizeMultiplier: textSizeMultiplier, x: 16 })] }));
|
|
27
|
+
const textFirst = (_jsxs(_Fragment, { children: [_jsx(DatalayerText, { primaryColor: primary, secondaryColor: dataTextColor, sizeMultiplier: textSizeMultiplier, x: 0 }), _jsx(DatalayerLogo, { size: 25, x: 136.672, y: 0, variant: variant, colorMode: colorMode, primaryColor: primary, secondaryColor: secondary, primaryGradient: primaryGradient, secondaryGradient: secondaryGradient, gradient: gradient })] }));
|
|
28
|
+
return (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 161.672 25", width: width, height: height, role: "img", "aria-label": "Datalayer", ref: ref, ...svgProps, children: inverse ? logoFirst : textFirst }));
|
|
29
|
+
});
|
|
30
|
+
export default DatalayerLogoText;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { SVGProps } from 'react';
|
|
2
|
+
export interface DatalayerTextProps extends Omit<SVGProps<SVGGElement>, 'ref'> {
|
|
3
|
+
/** Colour for the "LAYER" part of the wordmark. */
|
|
4
|
+
primaryColor?: string;
|
|
5
|
+
/** Colour for the "DATA" part of the wordmark (gray in the original brand logo). */
|
|
6
|
+
secondaryColor?: string;
|
|
7
|
+
/** Multiplies the base wordmark size. 1.0 keeps current dimensions. */
|
|
8
|
+
sizeMultiplier?: number;
|
|
9
|
+
/** X translation in the parent SVG coordinate system. */
|
|
10
|
+
x?: number;
|
|
11
|
+
/** Y translation in the parent SVG coordinate system. */
|
|
12
|
+
y?: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Official Datalayer wordmark outlines (BebasNeue converted to paths).
|
|
16
|
+
*
|
|
17
|
+
* Colour mapping matches the original brand logo SVG:
|
|
18
|
+
* - "DATA" = secondaryColor (gray in the original)
|
|
19
|
+
* - "LAYER" = primaryColor (green accent in the original)
|
|
20
|
+
*/
|
|
21
|
+
export declare const DatalayerText: ({ primaryColor, secondaryColor, sizeMultiplier, x, y, ...groupProps }: DatalayerTextProps) => JSX.Element;
|
|
22
|
+
export default DatalayerText;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { datalayerColors } from '../../theme';
|
|
3
|
+
/**
|
|
4
|
+
* Official Datalayer wordmark outlines (BebasNeue converted to paths).
|
|
5
|
+
*
|
|
6
|
+
* Colour mapping matches the original brand logo SVG:
|
|
7
|
+
* - "DATA" = secondaryColor (gray in the original)
|
|
8
|
+
* - "LAYER" = primaryColor (green accent in the original)
|
|
9
|
+
*/
|
|
10
|
+
export const DatalayerText = ({ primaryColor = datalayerColors.greenAccent, secondaryColor = datalayerColors.gray, sizeMultiplier = 1, x = 20, y = -190.15, ...groupProps }) => {
|
|
11
|
+
const baseScale = 0.7;
|
|
12
|
+
const scale = baseScale * sizeMultiplier;
|
|
13
|
+
// Keep the wordmark anchored when scaling so larger multipliers do not
|
|
14
|
+
// move the paths out of the parent SVG viewBox.
|
|
15
|
+
const anchorX = 17.35761;
|
|
16
|
+
const anchorY = 289.499065;
|
|
17
|
+
const translateX = x + anchorX * (baseScale - scale);
|
|
18
|
+
const translateY = y + anchorY * (baseScale - scale);
|
|
19
|
+
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 })] }));
|
|
20
|
+
};
|
|
21
|
+
export default DatalayerText;
|
package/lib/index.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
export const datalayerColors = {
|
|
10
10
|
// Core Neutrals
|
|
11
11
|
black: '#000000', // Primary text - AAA on white
|
|
12
|
-
gray: '#
|
|
12
|
+
gray: '#595A5C', // Secondary text - AA on white (matches original brand SVG)
|
|
13
13
|
white: '#FFFFFF', // Background
|
|
14
14
|
// Greens (Brand & Accessibility)
|
|
15
15
|
greenBrand: '#16A085', // Brand accent, icons, dividers, headings
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Earth Color System – The Blue Planet
|
|
3
|
+
* Ocean blues (sea), forest greens (plants), golden yellows (sun)
|
|
4
|
+
* WCAG AA/AAA compliant
|
|
5
|
+
*/
|
|
6
|
+
export declare const earthColors: {
|
|
7
|
+
black: string;
|
|
8
|
+
gray: string;
|
|
9
|
+
white: string;
|
|
10
|
+
oceanBrand: string;
|
|
11
|
+
oceanAccent: string;
|
|
12
|
+
oceanText: string;
|
|
13
|
+
oceanTint: string;
|
|
14
|
+
oceanBright: string;
|
|
15
|
+
oceanHover: string;
|
|
16
|
+
forestBrand: string;
|
|
17
|
+
forestAccent: string;
|
|
18
|
+
forestTint: string;
|
|
19
|
+
sunBrand: string;
|
|
20
|
+
sunAccent: string;
|
|
21
|
+
sunTint: string;
|
|
22
|
+
earthWarm: string;
|
|
23
|
+
earthSand: string;
|
|
24
|
+
earthClay: string;
|
|
25
|
+
brightGlow: string;
|
|
26
|
+
brightPop: string;
|
|
27
|
+
brightSpark: string;
|
|
28
|
+
brightBlaze: string;
|
|
29
|
+
brightSurge: string;
|
|
30
|
+
brightFlame: string;
|
|
31
|
+
brightGold: string;
|
|
32
|
+
brightLightGlow: string;
|
|
33
|
+
brightLightPop: string;
|
|
34
|
+
brightLightSpark: string;
|
|
35
|
+
brightLightBlaze: string;
|
|
36
|
+
brightLightSurge: string;
|
|
37
|
+
brightLightFlame: string;
|
|
38
|
+
brightLightGold: string;
|
|
39
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Earth Color System – The Blue Planet
|
|
7
|
+
* Ocean blues (sea), forest greens (plants), golden yellows (sun)
|
|
8
|
+
* WCAG AA/AAA compliant
|
|
9
|
+
*/
|
|
10
|
+
export const earthColors = {
|
|
11
|
+
// Core Neutrals
|
|
12
|
+
black: '#0A1628', // Deep ocean night — primary dark background
|
|
13
|
+
gray: '#5B6B7A', // Slate — secondary text
|
|
14
|
+
white: '#F7FAFC', // Morning sky — primary light background
|
|
15
|
+
// Ocean Blue palette (Brand) — the blue planet
|
|
16
|
+
oceanBrand: '#0369A1', // Deep ocean — headings, icons, dividers
|
|
17
|
+
oceanAccent: '#0EA5E9', // Bright sky blue — charts, highlights on dark surfaces
|
|
18
|
+
oceanText: '#075985', // Accessible ocean blue for text & buttons (AA+ on white)
|
|
19
|
+
oceanTint: '#E0F2FE', // Pale sky — soft background for callouts
|
|
20
|
+
oceanBright: '#38BDF8', // Vivid sky blue — highlights on dark backgrounds
|
|
21
|
+
oceanHover: '#0C4A6E', // Abyss navy — primary button hover
|
|
22
|
+
// Forest / Canopy (Secondary — green like plants)
|
|
23
|
+
forestBrand: '#15803D', // Dense canopy green
|
|
24
|
+
forestAccent: '#22C55E', // Sunlit leaf green
|
|
25
|
+
forestTint: '#DCFCE7', // Morning dew
|
|
26
|
+
// Sun / Warmth (Tertiary — yellow like sun)
|
|
27
|
+
sunBrand: '#CA8A04', // Deep golden sun
|
|
28
|
+
sunAccent: '#EAB308', // Vivid sunflower
|
|
29
|
+
sunTint: '#FEF9C3', // Pale sunshine
|
|
30
|
+
// Earth / Soil tones
|
|
31
|
+
earthWarm: '#92400E', // Red earth / laterite
|
|
32
|
+
earthSand: '#D97706', // Sandstone / amber
|
|
33
|
+
earthClay: '#B45309', // Terracotta
|
|
34
|
+
// Bright / vivid colours for SVG illustrations
|
|
35
|
+
brightGlow: '#0EA5E9', // Vivid ocean blue — primary glow (sea)
|
|
36
|
+
brightPop: '#22C55E', // Vivid green — contrasting accent (vegetation)
|
|
37
|
+
brightSpark: '#EAB308', // Vivid gold — sparkle (sunlight)
|
|
38
|
+
brightBlaze: '#EF4444', // Vivid red — warm accent (wildfire / alerts)
|
|
39
|
+
brightSurge: '#3B82F6', // Deep blue — cool accent (deep water)
|
|
40
|
+
// Warm vivid colours — earth & sun accents
|
|
41
|
+
brightFlame: '#F59E0B', // Amber gold — warm energy (solar)
|
|
42
|
+
brightGold: '#FACC15', // Bright sunflower — golden highlight
|
|
43
|
+
// Vivid brights for light backgrounds
|
|
44
|
+
brightLightGlow: '#0284C7', // Deep ocean blue
|
|
45
|
+
brightLightPop: '#16A34A', // Vivid forest green
|
|
46
|
+
brightLightSpark: '#CA8A04', // Deep golden sun
|
|
47
|
+
brightLightBlaze: '#DC2626', // Deep red
|
|
48
|
+
brightLightSurge: '#2563EB', // Deep ocean blue
|
|
49
|
+
brightLightFlame: '#D97706', // Deep amber
|
|
50
|
+
brightLightGold: '#A16207', // Deep gold
|
|
51
|
+
};
|
|
@@ -2,3 +2,17 @@ export { datalayerColors } from './datalayerColors';
|
|
|
2
2
|
export { spatialColors } from './spatialColors';
|
|
3
3
|
export { lovelyColors } from './lovelyColors';
|
|
4
4
|
export { matrixColors } from './matrixColors';
|
|
5
|
+
export { earthColors } from './earthColors';
|
|
6
|
+
export { indicatorColors, defaultIndicatorColors, type IndicatorColors, } from './indicatorColors';
|
|
7
|
+
import type { ThemeVariant } from '../themeRegistry';
|
|
8
|
+
/**
|
|
9
|
+
* Themed color palettes — maps each `ThemeVariant` to its corresponding
|
|
10
|
+
* color object so consumers can pick the right palette at runtime.
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { themedColors } from '@datalayer/primer-addons/lib/theme';
|
|
15
|
+
* const colors = themedColors[themeVariant]; // Record<string, string>
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare const themedColors: Record<ThemeVariant, Record<string, string>>;
|
|
@@ -6,3 +6,27 @@ export { datalayerColors } from './datalayerColors';
|
|
|
6
6
|
export { spatialColors } from './spatialColors';
|
|
7
7
|
export { lovelyColors } from './lovelyColors';
|
|
8
8
|
export { matrixColors } from './matrixColors';
|
|
9
|
+
export { earthColors } from './earthColors';
|
|
10
|
+
export { indicatorColors, defaultIndicatorColors, } from './indicatorColors';
|
|
11
|
+
import { datalayerColors } from './datalayerColors';
|
|
12
|
+
import { spatialColors } from './spatialColors';
|
|
13
|
+
import { lovelyColors } from './lovelyColors';
|
|
14
|
+
import { matrixColors } from './matrixColors';
|
|
15
|
+
import { earthColors } from './earthColors';
|
|
16
|
+
/**
|
|
17
|
+
* Themed color palettes — maps each `ThemeVariant` to its corresponding
|
|
18
|
+
* color object so consumers can pick the right palette at runtime.
|
|
19
|
+
*
|
|
20
|
+
* Usage:
|
|
21
|
+
* ```ts
|
|
22
|
+
* import { themedColors } from '@datalayer/primer-addons/lib/theme';
|
|
23
|
+
* const colors = themedColors[themeVariant]; // Record<string, string>
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export const themedColors = {
|
|
27
|
+
datalayer: datalayerColors,
|
|
28
|
+
spatial: spatialColors,
|
|
29
|
+
lovely: lovelyColors,
|
|
30
|
+
matrix: matrixColors,
|
|
31
|
+
earth: earthColors,
|
|
32
|
+
};
|
|
@@ -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;
|