@datalayer/primer-addons 1.0.18 → 1.0.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/lib/components/appearance/AppearanceControls.d.ts +3 -2
  2. package/lib/components/appearance/AppearanceControls.js +71 -3
  3. package/lib/components/appearance/AppearanceMenu.d.ts +30 -0
  4. package/lib/components/appearance/AppearanceMenu.js +15 -0
  5. package/lib/components/appearance/ColorModeCircle.d.ts +28 -0
  6. package/lib/components/appearance/ColorModeCircle.js +132 -0
  7. package/lib/components/appearance/ThemeCircle.d.ts +21 -0
  8. package/lib/components/appearance/ThemeCircle.js +46 -0
  9. package/lib/components/appearance/ThemePreviewCard.d.ts +12 -0
  10. package/lib/components/appearance/ThemePreviewCard.js +83 -0
  11. package/lib/components/appearance/index.d.ts +4 -0
  12. package/lib/components/appearance/index.js +4 -0
  13. package/lib/components/box/Box.d.ts +2 -1
  14. package/lib/components/closeable-flash/CloseableFlash.js +58 -1
  15. package/lib/components/color/ColorSwatch.d.ts +23 -0
  16. package/lib/components/color/ColorSwatch.js +62 -0
  17. package/lib/components/color/index.d.ts +1 -0
  18. package/lib/components/color/index.js +5 -0
  19. package/lib/components/index.d.ts +6 -0
  20. package/lib/components/index.js +6 -0
  21. package/lib/components/logo/DatalayerLogo.js +49 -1
  22. package/lib/components/side-overlay/SideOverlay.js +1 -1
  23. package/lib/components/sliding-panel/SlidingPanel.d.ts +19 -0
  24. package/lib/components/sliding-panel/SlidingPanel.js +217 -0
  25. package/lib/components/sliding-panel/SlidingPanel.stories.d.ts +16 -0
  26. package/lib/components/sliding-panel/SlidingPanel.stories.js +68 -0
  27. package/lib/theme/colors/datalayerColors.d.ts +12 -0
  28. package/lib/theme/colors/datalayerColors.js +13 -0
  29. package/lib/theme/colors/earthColors.d.ts +12 -0
  30. package/lib/theme/colors/earthColors.js +13 -0
  31. package/lib/theme/colors/index.d.ts +3 -0
  32. package/lib/theme/colors/index.js +9 -0
  33. package/lib/theme/colors/ivoryColors.d.ts +46 -0
  34. package/lib/theme/colors/ivoryColors.js +56 -0
  35. package/lib/theme/colors/lovelyColors.d.ts +12 -0
  36. package/lib/theme/colors/lovelyColors.js +13 -0
  37. package/lib/theme/colors/matrixColors.d.ts +12 -0
  38. package/lib/theme/colors/matrixColors.js +13 -0
  39. package/lib/theme/colors/sandColors.d.ts +45 -0
  40. package/lib/theme/colors/sandColors.js +55 -0
  41. package/lib/theme/colors/spatialColors.d.ts +12 -0
  42. package/lib/theme/colors/spatialColors.js +13 -0
  43. package/lib/theme/colors/sunColors.d.ts +45 -0
  44. package/lib/theme/colors/sunColors.js +55 -0
  45. package/lib/theme/css/createThemeCSSVars.d.ts +25 -1
  46. package/lib/theme/css/createThemeCSSVars.js +56 -3
  47. package/lib/theme/index.d.ts +3 -0
  48. package/lib/theme/index.js +3 -0
  49. package/lib/theme/palettes/ColorPalette.js +121 -1
  50. package/lib/theme/themeRegistry.d.ts +1 -1
  51. package/lib/theme/themeRegistry.js +151 -1
  52. package/lib/theme/themes/datalayerTheme.js +58 -7
  53. package/lib/theme/themes/earthTheme.js +50 -0
  54. package/lib/theme/themes/ivoryTheme.d.ts +1091 -0
  55. package/lib/theme/themes/ivoryTheme.js +257 -0
  56. package/lib/theme/themes/lovelyTheme.js +58 -7
  57. package/lib/theme/themes/matrixTheme.js +57 -8
  58. package/lib/theme/themes/sandTheme.d.ts +1091 -0
  59. package/lib/theme/themes/sandTheme.js +256 -0
  60. package/lib/theme/themes/spatialTheme.js +58 -7
  61. package/lib/theme/themes/sunTheme.d.ts +1091 -0
  62. package/lib/theme/themes/sunTheme.js +257 -0
  63. package/lib/utils/Helper.d.ts +1 -1
  64. package/lib/utils/Portals.d.ts +0 -1
  65. package/lib/utils/Portals.js +0 -1
  66. package/package.json +9 -5
  67. package/lib/App.d.ts +0 -13
  68. package/lib/App.js +0 -25
@@ -0,0 +1,62 @@
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 { useLayoutEffect, useRef, useState } from "react";
7
+ import { Box, Text } from "@primer/react";
8
+ import { useThemeStore } from "../../theme/useThemeStore";
9
+ /** Convert an `rgb()` / `rgba()` string to a `#rrggbb` hex value. */
10
+ function rgbToHex(rgb) {
11
+ const match = rgb.match(/rgba?\(([^)]+)\)/);
12
+ if (!match) {
13
+ return null;
14
+ }
15
+ const parts = match[1].split(",").map((part) => part.trim());
16
+ if (parts.length < 3) {
17
+ return null;
18
+ }
19
+ const [r, g, b] = parts.map((part) => parseInt(part, 10));
20
+ if ([r, g, b].some((channel) => Number.isNaN(channel))) {
21
+ return null;
22
+ }
23
+ const toHex = (channel) => channel.toString(16).padStart(2, "0");
24
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
25
+ }
26
+ /**
27
+ * Theme-aware color swatch. Renders a block filled with `color`, then reads
28
+ * the resolved value via `getComputedStyle` and displays it as a hex string.
29
+ * The resolved value recomputes whenever the active theme or color mode
30
+ * changes, so swatches backed by CSS custom properties stay in sync.
31
+ */
32
+ export function ColorSwatch({ color, label, showValue = true, height = 54, }) {
33
+ const ref = useRef(null);
34
+ const { theme, colorMode } = useThemeStore();
35
+ const [hex, setHex] = useState(null);
36
+ useLayoutEffect(() => {
37
+ const raf = requestAnimationFrame(() => {
38
+ if (!ref.current) {
39
+ return;
40
+ }
41
+ const rgb = getComputedStyle(ref.current).backgroundColor;
42
+ setHex(rgbToHex(rgb));
43
+ });
44
+ return () => cancelAnimationFrame(raf);
45
+ }, [color, theme, colorMode]);
46
+ return (_jsxs(Box, { sx: {
47
+ display: "grid",
48
+ gridTemplateRows: `${height}px auto`,
49
+ border: "1px solid",
50
+ borderColor: "var(--borderColor-default)",
51
+ borderRadius: 2,
52
+ overflow: "hidden",
53
+ minWidth: 0,
54
+ }, children: [_jsx(Box, { ref: ref, style: { backgroundColor: color } }), _jsxs(Box, { sx: { p: 2, display: "grid", gap: 1 }, children: [_jsx(Text, { sx: {
55
+ fontSize: 0,
56
+ color: "fg.default",
57
+ whiteSpace: "nowrap",
58
+ overflow: "hidden",
59
+ textOverflow: "ellipsis",
60
+ }, title: label ?? color, children: label ?? color }), showValue && hex ? (_jsx(Text, { sx: { fontSize: 0, color: "fg.muted", fontFamily: "mono" }, children: hex })) : null] })] }));
61
+ }
62
+ export default ColorSwatch;
@@ -0,0 +1 @@
1
+ export * from "./ColorSwatch";
@@ -0,0 +1,5 @@
1
+ /*
2
+ * Copyright (c) 2023-2025 Datalayer, Inc.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+ export * from "./ColorSwatch";
@@ -1,11 +1,17 @@
1
1
  export * from "./appearance/AppearanceControls";
2
2
  export * from "./appearance/AppearanceControlsWithStore";
3
+ export * from "./appearance/AppearanceMenu";
4
+ export * from "./appearance/ColorModeCircle";
5
+ export * from "./appearance/ThemePreviewCard";
6
+ export * from "./appearance/ThemeCircle";
3
7
  export * from "./box/Box";
4
8
  export * from "./card/Card";
9
+ export * from "./color";
5
10
  export * from "./content-loader/ContentLoader";
6
11
  export * from "./closeable-flash/CloseableFlash";
7
12
  export * from "./icons/CircleIcon";
8
13
  export * from "./side-overlay/SideOverlay";
14
+ export * from "./sliding-panel/SlidingPanel";
9
15
  export * from "./slider/Slider";
10
16
  export * from "./logo";
11
17
  export * from "./appearance";
@@ -1,11 +1,17 @@
1
1
  export * from "./appearance/AppearanceControls";
2
2
  export * from "./appearance/AppearanceControlsWithStore";
3
+ export * from "./appearance/AppearanceMenu";
4
+ export * from "./appearance/ColorModeCircle";
5
+ export * from "./appearance/ThemePreviewCard";
6
+ export * from "./appearance/ThemeCircle";
3
7
  export * from "./box/Box";
4
8
  export * from "./card/Card";
9
+ export * from "./color";
5
10
  export * from "./content-loader/ContentLoader";
6
11
  export * from "./closeable-flash/CloseableFlash";
7
12
  export * from "./icons/CircleIcon";
8
13
  export * from "./side-overlay/SideOverlay";
14
+ export * from "./sliding-panel/SlidingPanel";
9
15
  export * from "./slider/Slider";
10
16
  export * from "./logo";
11
17
  export * from "./appearance";
@@ -4,7 +4,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
4
  * Distributed under the terms of the Modified BSD License.
5
5
  */
6
6
  import { forwardRef, useId } from 'react';
7
- import { datalayerColors, spatialColors, lovelyColors, matrixColors, earthColors, } from '../../theme';
7
+ import { datalayerColors, spatialColors, lovelyColors, matrixColors, earthColors, sandColors, ivoryColors, sunColors, } from '../../theme';
8
8
  /**
9
9
  * Gradient pattern derived from the original brand logo SVG:
10
10
  * - Left bars: accent → brand (bright → mid)
@@ -93,6 +93,54 @@ export const THEME_LOGO_COLORS = {
93
93
  secondaryGradient: [earthColors.oceanHover, earthColors.oceanAccent],
94
94
  },
95
95
  },
96
+ sand: {
97
+ light: {
98
+ primary: sandColors.sandBrand,
99
+ secondary: sandColors.sandText,
100
+ textColor: sandColors.gray,
101
+ primaryGradient: [sandColors.sandAccent, sandColors.sandBrand],
102
+ secondaryGradient: [sandColors.sandHover, sandColors.sandText],
103
+ },
104
+ dark: {
105
+ primary: sandColors.sandBright,
106
+ secondary: sandColors.sandAccent,
107
+ textColor: sandColors.gray,
108
+ primaryGradient: [sandColors.sandBright, sandColors.sandBrand],
109
+ secondaryGradient: [sandColors.sandHover, sandColors.sandAccent],
110
+ },
111
+ },
112
+ ivory: {
113
+ light: {
114
+ primary: ivoryColors.ivoryBrand,
115
+ secondary: ivoryColors.ivoryText,
116
+ textColor: ivoryColors.gray,
117
+ primaryGradient: [ivoryColors.ivoryAccent, ivoryColors.ivoryBrand],
118
+ secondaryGradient: [ivoryColors.ivoryHover, ivoryColors.ivoryText],
119
+ },
120
+ dark: {
121
+ primary: ivoryColors.ivoryBright,
122
+ secondary: ivoryColors.ivoryAccent,
123
+ textColor: ivoryColors.gray,
124
+ primaryGradient: [ivoryColors.ivoryBright, ivoryColors.ivoryBrand],
125
+ secondaryGradient: [ivoryColors.ivoryHover, ivoryColors.ivoryAccent],
126
+ },
127
+ },
128
+ sun: {
129
+ light: {
130
+ primary: sunColors.sunBrand,
131
+ secondary: sunColors.sunText,
132
+ textColor: sunColors.gray,
133
+ primaryGradient: [sunColors.sunAccent, sunColors.sunBrand],
134
+ secondaryGradient: [sunColors.sunHover, sunColors.sunText],
135
+ },
136
+ dark: {
137
+ primary: sunColors.sunBright,
138
+ secondary: sunColors.sunAccent,
139
+ textColor: sunColors.gray,
140
+ primaryGradient: [sunColors.sunBright, sunColors.sunBrand],
141
+ secondaryGradient: [sunColors.sunHover, sunColors.sunAccent],
142
+ },
143
+ },
96
144
  };
97
145
  export function getLogoColors(variant = 'datalayer', colorMode = 'light') {
98
146
  const mode = colorMode === 'auto' ? 'light' : colorMode;
@@ -37,7 +37,7 @@ const PrimerAddonOverlay = (props) => {
37
37
  display: 'flex',
38
38
  justifyContent: 'right',
39
39
  width: '100%'
40
- }, children: _jsx(IconButton, { variant: 'invisible', ref: closeButtonRef, onClick: closeOverlay, icon: XIcon, "aria-labelledby": "close" }) }), content] }) }));
40
+ }, children: _jsx(IconButton, { variant: 'invisible', ref: closeButtonRef, onClick: closeOverlay, icon: XIcon, "aria-label": "Close" }) }), content] }) }));
41
41
  return (closeButtonRef && openButtonRef ?
42
42
  _jsx(_Fragment, { children: isOpen ?
43
43
  direction === 'left' ?
@@ -0,0 +1,19 @@
1
+ import { type ReactNode } from 'react';
2
+ export type SlidingPanelPosition = 'north' | 'south' | 'west' | 'east';
3
+ export type SlidingPanelVariant = 'default' | 'info' | 'success' | 'warning' | 'error' | 'danger';
4
+ export interface SlidingPanelProps {
5
+ isOpen: boolean;
6
+ message: ReactNode;
7
+ details?: ReactNode;
8
+ onDismiss?: () => void;
9
+ position?: SlidingPanelPosition;
10
+ variant?: SlidingPanelVariant;
11
+ durationMs?: number;
12
+ transitionMs?: number;
13
+ zIndex?: number;
14
+ offset?: number;
15
+ panelSize?: number | string;
16
+ fullWidth?: boolean;
17
+ }
18
+ export declare const SlidingPanel: ({ isOpen, message, details, onDismiss, position, variant, durationMs, transitionMs, zIndex, offset, panelSize, fullWidth, }: SlidingPanelProps) => import("react/jsx-runtime").JSX.Element | null;
19
+ export default SlidingPanel;
@@ -0,0 +1,217 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useMemo, useState } from 'react';
3
+ import { IconButton } from '@primer/react';
4
+ import { XIcon } from '@primer/octicons-react';
5
+ import { Box } from '../box/Box';
6
+ const variantStyles = {
7
+ default: {
8
+ bg: 'var(--bgColor-default, #ffffff)',
9
+ border: 'var(--borderColor-default, #d0d7de)',
10
+ fg: 'var(--fgColor-default, #1f2328)',
11
+ },
12
+ info: {
13
+ bg: 'var(--bgColor-accent-muted, #ddf4ff)',
14
+ border: 'var(--borderColor-accent-emphasis, #218bff)',
15
+ fg: 'var(--fgColor-default, #1f2328)',
16
+ },
17
+ success: {
18
+ bg: 'var(--bgColor-success-muted, #dafbe1)',
19
+ border: 'var(--borderColor-success-emphasis, #1a7f37)',
20
+ fg: 'var(--fgColor-success, #1a7f37)',
21
+ },
22
+ warning: {
23
+ bg: 'var(--bgColor-attention-muted, #fff8c5)',
24
+ border: 'var(--borderColor-attention-emphasis, #9a6700)',
25
+ fg: 'var(--fgColor-attention, #9a6700)',
26
+ },
27
+ error: {
28
+ bg: 'var(--bgColor-danger-muted, #ffebe9)',
29
+ border: 'var(--borderColor-danger-emphasis, #cf222e)',
30
+ fg: 'var(--fgColor-danger, #cf222e)',
31
+ },
32
+ danger: {
33
+ bg: 'var(--bgColor-danger-muted, #ffebe9)',
34
+ border: 'var(--borderColor-danger-emphasis, #cf222e)',
35
+ fg: 'var(--fgColor-danger, #cf222e)',
36
+ },
37
+ };
38
+ const closeButtonStyles = {
39
+ default: {
40
+ fg: 'var(--fgColor-default, #1f2328)',
41
+ hoverBg: 'rgba(31, 35, 40, 0.10)',
42
+ },
43
+ info: {
44
+ fg: 'var(--fgColor-accent, #0969da)',
45
+ hoverBg: 'rgba(9, 105, 218, 0.14)',
46
+ },
47
+ success: {
48
+ fg: 'var(--fgColor-success, #1a7f37)',
49
+ hoverBg: 'rgba(26, 127, 55, 0.14)',
50
+ },
51
+ warning: {
52
+ fg: 'var(--fgColor-attention, #9a6700)',
53
+ hoverBg: 'rgba(154, 103, 0, 0.16)',
54
+ },
55
+ error: {
56
+ fg: 'var(--fgColor-danger, #cf222e)',
57
+ hoverBg: 'rgba(207, 34, 46, 0.14)',
58
+ },
59
+ danger: {
60
+ fg: 'var(--fgColor-danger, #cf222e)',
61
+ hoverBg: 'rgba(207, 34, 46, 0.14)',
62
+ },
63
+ };
64
+ const closedTransforms = {
65
+ north: 'translateY(-100%)',
66
+ south: 'translateY(100%)',
67
+ west: 'translateX(-100%)',
68
+ east: 'translateX(100%)',
69
+ };
70
+ const edgeBorderStyles = {
71
+ north: {
72
+ borderTop: '0',
73
+ borderRight: '0',
74
+ borderBottom: '1px solid',
75
+ borderLeft: '0',
76
+ },
77
+ south: {
78
+ borderTop: '1px solid',
79
+ borderRight: '0',
80
+ borderBottom: '0',
81
+ borderLeft: '0',
82
+ },
83
+ west: {
84
+ borderTop: '0',
85
+ borderRight: '1px solid',
86
+ borderBottom: '0',
87
+ borderLeft: '0',
88
+ },
89
+ east: {
90
+ borderTop: '0',
91
+ borderRight: '0',
92
+ borderBottom: '0',
93
+ borderLeft: '1px solid',
94
+ },
95
+ };
96
+ export const SlidingPanel = ({ isOpen, message, details, onDismiss, position = 'north', variant = 'default', durationMs, transitionMs = 260, zIndex = 200, offset = 0, panelSize = 360, fullWidth = true, }) => {
97
+ const [isMounted, setIsMounted] = useState(isOpen);
98
+ const [isVisible, setIsVisible] = useState(isOpen);
99
+ useEffect(() => {
100
+ if (isOpen) {
101
+ setIsMounted(true);
102
+ const showTimer = window.setTimeout(() => setIsVisible(true), 10);
103
+ return () => window.clearTimeout(showTimer);
104
+ }
105
+ setIsVisible(false);
106
+ const hideTimer = window.setTimeout(() => setIsMounted(false), transitionMs);
107
+ return () => window.clearTimeout(hideTimer);
108
+ }, [isOpen, transitionMs]);
109
+ useEffect(() => {
110
+ if (!isOpen || !onDismiss) {
111
+ return;
112
+ }
113
+ if (durationMs === undefined || durationMs <= 0) {
114
+ return;
115
+ }
116
+ const timer = window.setTimeout(() => {
117
+ onDismiss();
118
+ }, durationMs);
119
+ return () => {
120
+ window.clearTimeout(timer);
121
+ };
122
+ }, [isOpen, durationMs, onDismiss]);
123
+ const anchorStyles = useMemo(() => {
124
+ if (position === 'north') {
125
+ return {
126
+ top: offset,
127
+ left: 0,
128
+ right: 0,
129
+ justifyContent: 'center',
130
+ alignItems: 'flex-start',
131
+ };
132
+ }
133
+ if (position === 'south') {
134
+ return {
135
+ bottom: offset,
136
+ left: 0,
137
+ right: 0,
138
+ justifyContent: 'center',
139
+ alignItems: 'flex-end',
140
+ };
141
+ }
142
+ if (position === 'west') {
143
+ return {
144
+ left: offset,
145
+ top: 0,
146
+ bottom: 0,
147
+ justifyContent: 'flex-start',
148
+ alignItems: 'stretch',
149
+ };
150
+ }
151
+ return {
152
+ right: offset,
153
+ top: 0,
154
+ bottom: 0,
155
+ justifyContent: 'flex-end',
156
+ alignItems: 'stretch',
157
+ };
158
+ }, [position, offset]);
159
+ if (!isMounted) {
160
+ return null;
161
+ }
162
+ const style = variantStyles[variant];
163
+ const closeStyle = closeButtonStyles[variant];
164
+ const horizontal = position === 'north' || position === 'south';
165
+ const edgeBorder = edgeBorderStyles[position];
166
+ return (_jsx(Box, { sx: {
167
+ position: 'fixed',
168
+ zIndex,
169
+ display: 'flex',
170
+ pointerEvents: 'none',
171
+ ...anchorStyles,
172
+ }, children: _jsxs(Box, { role: variant === 'error' || variant === 'danger' ? 'alert' : 'status', "aria-live": variant === 'error' || variant === 'danger' ? 'assertive' : 'polite', onClick: onDismiss, sx: {
173
+ pointerEvents: 'auto',
174
+ position: 'relative',
175
+ display: 'flex',
176
+ alignItems: 'center',
177
+ justifyContent: 'flex-start',
178
+ cursor: onDismiss ? 'pointer' : 'default',
179
+ width: horizontal
180
+ ? fullWidth
181
+ ? '100vw'
182
+ : 'min(960px, 96vw)'
183
+ : panelSize,
184
+ maxWidth: horizontal ? '100vw' : undefined,
185
+ height: horizontal ? undefined : '100vh',
186
+ maxHeight: horizontal ? undefined : '100vh',
187
+ borderColor: style.border,
188
+ borderTop: edgeBorder.borderTop,
189
+ borderRight: edgeBorder.borderRight,
190
+ borderBottom: edgeBorder.borderBottom,
191
+ borderLeft: edgeBorder.borderLeft,
192
+ backgroundColor: style.bg,
193
+ color: style.fg,
194
+ textAlign: 'left',
195
+ px: 4,
196
+ py: horizontal ? 3 : 4,
197
+ boxShadow: 'shadow.large',
198
+ transform: isVisible ? 'translate(0, 0)' : closedTransforms[position],
199
+ opacity: isVisible ? 1 : 0,
200
+ transition: `transform ${transitionMs}ms ease, opacity ${transitionMs}ms ease`,
201
+ overflow: 'auto',
202
+ }, children: [onDismiss ? (_jsx(Box, { sx: {
203
+ position: 'absolute',
204
+ top: 2,
205
+ right: 3,
206
+ }, children: _jsx(IconButton, { variant: "invisible", icon: XIcon, "aria-label": "Close panel", onClick: event => {
207
+ event.stopPropagation();
208
+ onDismiss();
209
+ }, sx: {
210
+ color: closeStyle.fg,
211
+ borderRadius: 2,
212
+ '&:hover': {
213
+ backgroundColor: closeStyle.hoverBg,
214
+ },
215
+ } }) })) : null, _jsxs(Box, { sx: { width: 'min(980px, 100%)', display: 'grid', gap: 1, pr: onDismiss ? 6 : 0 }, children: [_jsx(Box, { sx: { fontSize: 3, fontWeight: 500, lineHeight: 1.4 }, children: message }), details ? (_jsx(Box, { sx: { fontSize: 1, fontWeight: 400, lineHeight: 1.4, color: 'fg.muted' }, children: details })) : null] })] }) }));
216
+ };
217
+ export default SlidingPanel;
@@ -0,0 +1,16 @@
1
+ import type { StoryObj } from '@storybook/react';
2
+ import { type SlidingPanelProps } from './SlidingPanel';
3
+ declare const meta: {
4
+ title: string;
5
+ component: ({ isOpen, message, details, onDismiss, position, variant, durationMs, transitionMs, zIndex, offset, panelSize, fullWidth, }: SlidingPanelProps) => import("react/jsx-runtime").JSX.Element | null;
6
+ tags: string[];
7
+ parameters: {
8
+ layout: string;
9
+ };
10
+ };
11
+ export default meta;
12
+ type Story = StoryObj<typeof meta>;
13
+ export declare const NorthInfo: Story;
14
+ export declare const SouthWarning: Story;
15
+ export declare const EastSuccess: Story;
16
+ export declare const WestError: Story;
@@ -0,0 +1,68 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useRef, useState } from 'react';
3
+ import { Box, Button, Heading } from '@primer/react';
4
+ import { SlidingPanel } from './SlidingPanel';
5
+ const meta = {
6
+ title: 'Components/SlidingPanel',
7
+ component: SlidingPanel,
8
+ tags: ['autodocs'],
9
+ parameters: {
10
+ layout: 'fullscreen',
11
+ },
12
+ };
13
+ export default meta;
14
+ const Demo = (props) => {
15
+ const [isOpen, setIsOpen] = useState(false);
16
+ const openButtonRef = useRef(null);
17
+ return (_jsxs(Box, { sx: { p: 4, minHeight: '100vh', bg: 'canvas.default' }, children: [_jsx(Heading, { as: "h2", sx: { fontSize: 3, mb: 3 }, children: "Sliding Panel Demo" }), _jsx(Button, { ref: openButtonRef, onClick: () => setIsOpen(true), children: "Open panel" }), _jsx(SlidingPanel, { ...props, isOpen: isOpen, onDismiss: () => setIsOpen(false) }), isOpen ? (_jsx(Box, { sx: { mt: 3 }, children: _jsx(Button, { size: "small", onClick: () => setIsOpen(false), children: "Close" }) })) : null] }));
18
+ };
19
+ export const NorthInfo = {
20
+ args: {
21
+ isOpen: false,
22
+ message: 'Sliding panel message',
23
+ details: 'Additional details appear below the message in normal font.',
24
+ position: 'north',
25
+ variant: 'info',
26
+ durationMs: 4500,
27
+ fullWidth: true,
28
+ },
29
+ render: args => _jsx(Demo, { ...args }),
30
+ };
31
+ export const SouthWarning = {
32
+ args: {
33
+ isOpen: false,
34
+ message: 'Sliding panel message',
35
+ details: 'Additional details appear below the message in normal font.',
36
+ position: 'south',
37
+ variant: 'warning',
38
+ durationMs: 0,
39
+ fullWidth: true,
40
+ },
41
+ render: args => _jsx(Demo, { ...args }),
42
+ };
43
+ export const EastSuccess = {
44
+ args: {
45
+ isOpen: false,
46
+ message: 'Sliding panel message',
47
+ details: 'Additional details appear below the message in normal font.',
48
+ position: 'east',
49
+ variant: 'success',
50
+ durationMs: 0,
51
+ panelSize: 360,
52
+ fullWidth: false,
53
+ },
54
+ render: args => _jsx(Demo, { ...args }),
55
+ };
56
+ export const WestError = {
57
+ args: {
58
+ isOpen: false,
59
+ message: 'Sliding panel message',
60
+ details: 'Additional details appear below the message in normal font.',
61
+ position: 'west',
62
+ variant: 'error',
63
+ durationMs: 0,
64
+ panelSize: 360,
65
+ fullWidth: false,
66
+ },
67
+ render: args => _jsx(Demo, { ...args }),
68
+ };
@@ -12,6 +12,18 @@ export declare const datalayerColors: {
12
12
  greenTint: string;
13
13
  greenBright: string;
14
14
  greenHover: string;
15
+ attentionBrand: string;
16
+ attentionAccent: string;
17
+ attentionTint: string;
18
+ dangerBrand: string;
19
+ dangerAccent: string;
20
+ dangerTint: string;
21
+ severeBrand: string;
22
+ severeAccent: string;
23
+ severeTint: string;
24
+ doneBrand: string;
25
+ doneAccent: string;
26
+ doneTint: string;
15
27
  brightGlow: string;
16
28
  brightPop: string;
17
29
  brightSpark: string;
@@ -18,6 +18,19 @@ 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
+ // Semantic roles
22
+ attentionBrand: '#B08800',
23
+ attentionAccent: '#D4A72C',
24
+ attentionTint: '#FFF8C5',
25
+ dangerBrand: '#D1242F',
26
+ dangerAccent: '#FF6A69',
27
+ dangerTint: '#FFE5E5',
28
+ severeBrand: '#BC4C00',
29
+ severeAccent: '#F0883E',
30
+ severeTint: '#FFF1E5',
31
+ doneBrand: '#0969DA',
32
+ doneAccent: '#54AEFF',
33
+ doneTint: '#DDF4FF',
21
34
  // Bright / vivid colours for SVG illustrations (OpenAI-blog style)
22
35
  brightGlow: '#00D68F', // Ultra-vivid emerald — primary glow
23
36
  brightPop: '#00E5FF', // Electric cyan — contrasting accent
@@ -22,6 +22,18 @@ export declare const earthColors: {
22
22
  earthWarm: string;
23
23
  earthSand: string;
24
24
  earthClay: string;
25
+ attentionBrand: string;
26
+ attentionAccent: string;
27
+ attentionTint: string;
28
+ dangerBrand: string;
29
+ dangerAccent: string;
30
+ dangerTint: string;
31
+ severeBrand: string;
32
+ severeAccent: string;
33
+ severeTint: string;
34
+ doneBrand: string;
35
+ doneAccent: string;
36
+ doneTint: string;
25
37
  brightGlow: string;
26
38
  brightPop: string;
27
39
  brightSpark: string;
@@ -31,6 +31,19 @@ export const earthColors = {
31
31
  earthWarm: '#92400E', // Red earth / laterite
32
32
  earthSand: '#D97706', // Sandstone / amber
33
33
  earthClay: '#B45309', // Terracotta
34
+ // Semantic roles
35
+ attentionBrand: '#CA8A04',
36
+ attentionAccent: '#EAB308',
37
+ attentionTint: '#FEF9C3',
38
+ dangerBrand: '#B42318',
39
+ dangerAccent: '#EF4444',
40
+ dangerTint: '#FEE4E2',
41
+ severeBrand: '#B45309',
42
+ severeAccent: '#F59E0B',
43
+ severeTint: '#FFF1DA',
44
+ doneBrand: '#1D4ED8',
45
+ doneAccent: '#3B82F6',
46
+ doneTint: '#DBEAFE',
34
47
  // Bright / vivid colours for SVG illustrations
35
48
  brightGlow: '#0EA5E9', // Vivid ocean blue — primary glow (sea)
36
49
  brightPop: '#22C55E', // Vivid green — contrasting accent (vegetation)
@@ -3,6 +3,9 @@ export { spatialColors } from './spatialColors';
3
3
  export { lovelyColors } from './lovelyColors';
4
4
  export { matrixColors } from './matrixColors';
5
5
  export { earthColors } from './earthColors';
6
+ export { sandColors } from './sandColors';
7
+ export { ivoryColors } from './ivoryColors';
8
+ export { sunColors } from './sunColors';
6
9
  import type { ThemeVariant } from '../themeRegistry';
7
10
  /**
8
11
  * Themed color palettes — maps each `ThemeVariant` to its corresponding
@@ -7,11 +7,17 @@ export { spatialColors } from './spatialColors';
7
7
  export { lovelyColors } from './lovelyColors';
8
8
  export { matrixColors } from './matrixColors';
9
9
  export { earthColors } from './earthColors';
10
+ export { sandColors } from './sandColors';
11
+ export { ivoryColors } from './ivoryColors';
12
+ export { sunColors } from './sunColors';
10
13
  import { datalayerColors } from './datalayerColors';
11
14
  import { spatialColors } from './spatialColors';
12
15
  import { lovelyColors } from './lovelyColors';
13
16
  import { matrixColors } from './matrixColors';
14
17
  import { earthColors } from './earthColors';
18
+ import { sandColors } from './sandColors';
19
+ import { ivoryColors } from './ivoryColors';
20
+ import { sunColors } from './sunColors';
15
21
  /**
16
22
  * Themed color palettes — maps each `ThemeVariant` to its corresponding
17
23
  * color object so consumers can pick the right palette at runtime.
@@ -28,4 +34,7 @@ export const themedColors = {
28
34
  lovely: lovelyColors,
29
35
  matrix: matrixColors,
30
36
  earth: earthColors,
37
+ sand: sandColors,
38
+ ivory: ivoryColors,
39
+ sun: sunColors,
31
40
  };
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Ivory Color System – Soft, warm off-white neutrals.
3
+ *
4
+ * Anchored on the light-ivory base #E6D2B5 (R:230 G:210 B:181): a calm,
5
+ * refined, and welcoming palette paired with a deep warm taupe for
6
+ * accessible text. Gentle and editorial, with a hospitable, paper-like
7
+ * warmth. WCAG AA/AAA for text & buttons.
8
+ */
9
+ export declare const ivoryColors: {
10
+ black: string;
11
+ gray: string;
12
+ white: string;
13
+ ivoryBase: string;
14
+ ivoryBrand: string;
15
+ ivoryAccent: string;
16
+ ivoryText: string;
17
+ ivoryTint: string;
18
+ ivoryBright: string;
19
+ ivoryHover: string;
20
+ attentionBrand: string;
21
+ attentionAccent: string;
22
+ attentionTint: string;
23
+ dangerBrand: string;
24
+ dangerAccent: string;
25
+ dangerTint: string;
26
+ severeBrand: string;
27
+ severeAccent: string;
28
+ severeTint: string;
29
+ doneBrand: string;
30
+ doneAccent: string;
31
+ doneTint: string;
32
+ brightGlow: string;
33
+ brightPop: string;
34
+ brightSpark: string;
35
+ brightBlaze: string;
36
+ brightSurge: string;
37
+ brightFlame: string;
38
+ brightGold: string;
39
+ brightLightGlow: string;
40
+ brightLightPop: string;
41
+ brightLightSpark: string;
42
+ brightLightBlaze: string;
43
+ brightLightSurge: string;
44
+ brightLightFlame: string;
45
+ brightLightGold: string;
46
+ };