@datalayer/core 0.0.24 → 0.0.25

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.
@@ -297,7 +297,10 @@ export declare const useCache: ({ loginRoute }?: CacheProps) => {
297
297
  token: string;
298
298
  }, unknown>;
299
299
  useOAuth2AuthorizationURL: () => import("@tanstack/react-query").UseMutationResult<string, Error, Record<string, string>, unknown>;
300
- useOAuth2AuthorizationLinkURL: () => import("@tanstack/react-query").UseMutationResult<string, Error, Record<string, string>, unknown>;
300
+ useOAuth2AuthorizationLinkURL: () => import("@tanstack/react-query").UseMutationResult<{
301
+ success: boolean;
302
+ autorization_url: string;
303
+ }, Error, Record<string, string>, unknown>;
301
304
  useGetGitHubProfile: () => import("@tanstack/react-query").UseMutationResult<any, Error, string, unknown>;
302
305
  useGetLinkedinProfile: () => import("@tanstack/react-query").UseMutationResult<any, Error, string, unknown>;
303
306
  usePostLinkedinShare: () => import("@tanstack/react-query").UseMutationResult<any, Error, {
@@ -655,7 +658,9 @@ export declare const useCache: ({ loginRoute }?: CacheProps) => {
655
658
  useUpdateDatasource: () => import("@tanstack/react-query").UseMutationResult<any, Error, IDatasource, unknown>;
656
659
  useSecret: (secretId: string, options?: {
657
660
  enabled?: boolean;
658
- refetchOnMount?: boolean;
661
+ refetchOnMount?: boolean | "always";
662
+ staleTime?: number;
663
+ gcTime?: number;
659
664
  }) => import("@tanstack/react-query").UseQueryResult<ISecret | null | undefined, Error>;
660
665
  useSecrets: () => import("@tanstack/react-query").UseQueryResult<any, Error>;
661
666
  useCreateSecret: () => import("@tanstack/react-query").UseMutationResult<any, Error, Omit<ISecret, "id">, unknown>;
@@ -1834,6 +1834,10 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1834
1834
  /**
1835
1835
  * Get all secrets
1836
1836
  */
1837
+ // TODO: Previously this hook pre-populated individual secret caches with setQueryData,
1838
+ // but this prevented useSecret from fetching fresh data (e.g., the value field).
1839
+ // Consider re-adding cache pre-population if the list endpoint returns full secret data,
1840
+ // or use a different query key pattern for partial vs full secret data.
1837
1841
  const useSecrets = () => {
1838
1842
  return useQuery({
1839
1843
  queryKey: queryKeys.secrets.all(),
@@ -1844,13 +1848,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1844
1848
  });
1845
1849
  if (resp.success && resp.secrets) {
1846
1850
  const secrets = resp.secrets
1847
- .map((s) => {
1848
- const secret = toSecret(s);
1849
- if (secret) {
1850
- queryClient.setQueryData(queryKeys.secrets.detail(secret.id), secret);
1851
- }
1852
- return secret;
1853
- })
1851
+ .map((s) => toSecret(s))
1854
1852
  .filter(Boolean);
1855
1853
  return secrets;
1856
1854
  }
@@ -2208,6 +2206,8 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2208
2206
  ...DEFAULT_QUERY_OPTIONS,
2209
2207
  enabled: options?.enabled ?? !!secretId,
2210
2208
  refetchOnMount: options?.refetchOnMount ?? DEFAULT_QUERY_OPTIONS.refetchOnMount,
2209
+ staleTime: options?.staleTime ?? DEFAULT_QUERY_OPTIONS.staleTime,
2210
+ gcTime: options?.gcTime ?? DEFAULT_QUERY_OPTIONS.gcTime,
2211
2211
  });
2212
2212
  };
2213
2213
  /**
@@ -4485,7 +4485,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4485
4485
  const resp = await requestDatalayer({
4486
4486
  url: `${configuration.iamRunUrl}/api/iam/v1/oauth2/authz/url/link?${queryString}`,
4487
4487
  });
4488
- return resp.autorization_url;
4488
+ return resp;
4489
4489
  },
4490
4490
  });
4491
4491
  };
@@ -4835,7 +4835,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4835
4835
  method: 'POST',
4836
4836
  body: {
4837
4837
  request_method: 'GET',
4838
- request_url: 'https://api.linkedin.com/v2/me',
4838
+ request_url: 'https://api.linkedin.com/v2/userinfo',
4839
4839
  request_token: accessToken,
4840
4840
  },
4841
4841
  });
@@ -2,5 +2,5 @@
2
2
  * Main navigation hook that provides a universal navigate function
3
3
  * Works with React Router, Next.js, or native browser navigation
4
4
  */
5
- export declare const useNavigate: () => (location: string, optionsOrEvent?: any, resetPortals?: boolean, extraOptions?: any) => void;
5
+ export declare const useNavigate: () => (location: string | number, optionsOrEvent?: any, resetPortals?: boolean, extraOptions?: any) => void;
6
6
  export default useNavigate;
@@ -36,7 +36,12 @@ export const useNavigate = () => {
36
36
  if (isReactRouter && rrNavigate) {
37
37
  // eslint-disable-next-line react-hooks/rules-of-hooks
38
38
  return useCallback((to, options) => {
39
- // For React Router, just pass through directly without side effects
39
+ // Scroll to top when navigating (except for history navigation)
40
+ if (typeof to === 'string') {
41
+ window.scrollTo(0, 0);
42
+ document.body.scrollTop = 0;
43
+ }
44
+ // For React Router, pass through directly
40
45
  return rrNavigate(to, options);
41
46
  }, [rrNavigate]);
42
47
  }
@@ -45,6 +50,11 @@ export const useNavigate = () => {
45
50
  // Wrap with our custom behavior for native navigation
46
51
  // eslint-disable-next-line react-hooks/rules-of-hooks
47
52
  const navigate = useCallback((location, optionsOrEvent, resetPortals = true, extraOptions) => {
53
+ // Handle number for history navigation (e.g., -1 to go back)
54
+ if (typeof location === 'number') {
55
+ window.history.go(location);
56
+ return;
57
+ }
48
58
  // Handle different call signatures for native navigation
49
59
  let options = undefined;
50
60
  let event = undefined;
@@ -1,4 +1,19 @@
1
- declare const datalayerTheme: {
1
+ /**
2
+ * Datalayer Accessible Color System
3
+ * Based on Datalayer's brand manual - WCAG AA/AAA compliant
4
+ */
5
+ export declare const datalayerColors: {
6
+ black: string;
7
+ gray: string;
8
+ white: string;
9
+ greenBrand: string;
10
+ greenAccent: string;
11
+ greenText: string;
12
+ greenTint: string;
13
+ greenBright: string;
14
+ greenHover: string;
15
+ };
16
+ export declare const datalayerTheme: {
2
17
  animation: {
3
18
  easeOutCubic: string;
4
19
  };
@@ -34,4 +49,4 @@ declare const datalayerTheme: {
34
49
  dark: {};
35
50
  };
36
51
  };
37
- export { datalayerTheme };
52
+ export default datalayerTheme;
@@ -5,58 +5,224 @@
5
5
  import { theme as primerTheme } from '@primer/react';
6
6
  import cloneDeep from 'lodash/cloneDeep.js';
7
7
  import merge from 'lodash/merge.js';
8
+ /**
9
+ * Datalayer Accessible Color System
10
+ * Based on Datalayer's brand manual - WCAG AA/AAA compliant
11
+ */
12
+ export const datalayerColors = {
13
+ // Core Neutrals
14
+ black: '#000000', // Primary text - AAA on white
15
+ gray: '#59595C', // Secondary text - AA on white
16
+ white: '#FFFFFF', // Background
17
+ // Greens (Brand & Accessibility)
18
+ greenBrand: '#16A085', // Brand accent, icons, dividers, headings
19
+ greenAccent: '#1ABC9C', // Icons, charts, highlights on dark surfaces
20
+ greenText: '#117A65', // Accessible green for text & buttons (AA+ on white)
21
+ greenTint: '#E9F7F1', // Soft background for success / callouts
22
+ greenBright: '#2ECC71', // Highlights and glow on dark backgrounds
23
+ greenHover: '#0E6655', // Primary button hover
24
+ };
8
25
  /**
9
26
  * Datalayer Theme for Primer React.
27
+ *
28
+ * Uses accessible color palette from Datalayer's brand manual.
10
29
  */
11
30
  const datalayerThemeDefs = {
12
31
  colorSchemes: {
13
32
  light: {
14
33
  colors: {
34
+ // Canvas colors
35
+ canvas: {
36
+ default: datalayerColors.white,
37
+ // subtle: datalayerColors.greenTint,
38
+ },
39
+ // Foreground colors
40
+ fg: {
41
+ default: datalayerColors.black,
42
+ muted: datalayerColors.gray,
43
+ onEmphasis: datalayerColors.white,
44
+ },
45
+ // Accent colors (brand green)
46
+ accent: {
47
+ fg: datalayerColors.greenText,
48
+ emphasis: datalayerColors.greenBrand,
49
+ muted: datalayerColors.greenAccent,
50
+ // subtle: datalayerColors.greenTint,
51
+ },
52
+ // Success colors (green)
53
+ success: {
54
+ fg: datalayerColors.greenText,
55
+ emphasis: datalayerColors.greenBrand,
56
+ muted: datalayerColors.greenAccent,
57
+ // subtle: datalayerColors.greenTint,
58
+ },
59
+ // Button colors
15
60
  btn: {
16
- // text: 'var(--jp-ui-font-color1, rgba(0, 0, 0, 0.87))',
17
- // bg: 'var(--jp-layout-color1, white)',
18
- // border: 'var(--jp-border-color1, #bdbdbd)',
19
- // hoverBg: 'var(--jp-layout-color2, #eee)',
20
- // hoverBorder: 'var(--jp-border-color1, #bdbdbd)',
21
- // activeBg: 'var(--jp-layout-color3, #bdbdbd)',
22
- // activeBorder: 'var(--jp-border-color1, #bdbdbd)',
23
- // selectedBg: 'var(--jp-layout-color0, white)',
24
- // counterBg: 'var(--jp-layout-color4, #757575)',
61
+ text: datalayerColors.black,
62
+ bg: datalayerColors.white,
63
+ border: datalayerColors.gray,
64
+ hoverBg: datalayerColors.greenTint,
65
+ hoverBorder: datalayerColors.gray,
66
+ activeBg: datalayerColors.greenTint,
67
+ activeBorder: datalayerColors.gray,
68
+ selectedBg: datalayerColors.white,
69
+ counterBg: datalayerColors.gray,
25
70
  primary: {
26
- // text: 'var(--jp-ui-inverse-font-color1, rgba(255, 255, 255, 1))',
27
- bg: 'var(--dla-color-green-dark)',
28
- // border: 'var(--dla-color-green-light)',
29
- hoverBg: 'var(--dla-color-grey)',
30
- // hoverBorder: 'var(--dla-color-green-light)',
31
- selectedBg: 'var(--dla-color-black)',
32
- // disabledText: 'var(--jp-ui-inverse-font-color2, rgba(255, 255, 255, 0.7))',
33
- // disabledBg: 'var(--jp-brand-color3, #c8e6c9)',
34
- // disabledBorder: 'var(--jp-border-color1, #bdbdbd)',
35
- // icon: 'var(--jp-ui-inverse-font-color2, rgba(255, 255, 255, 0.7))',
36
- // counterBg: 'var(--jp-inverse-layout-color3, #616161)',
71
+ text: datalayerColors.white,
72
+ bg: datalayerColors.greenText,
73
+ border: datalayerColors.greenText,
74
+ hoverBg: datalayerColors.greenHover,
75
+ hoverBorder: datalayerColors.greenHover,
76
+ selectedBg: datalayerColors.greenHover,
77
+ disabledText: 'rgba(255, 255, 255, 0.7)',
78
+ disabledBg: datalayerColors.gray,
79
+ disabledBorder: datalayerColors.gray,
80
+ icon: datalayerColors.white,
81
+ counterBg: 'rgba(0, 0, 0, 0.2)',
82
+ },
83
+ outline: {
84
+ text: datalayerColors.greenText,
85
+ hoverText: datalayerColors.white,
86
+ hoverBg: datalayerColors.greenText,
87
+ hoverBorder: datalayerColors.greenText,
88
+ hoverCounterBg: 'rgba(255, 255, 255, 0.2)',
89
+ selectedText: datalayerColors.white,
90
+ selectedBg: datalayerColors.greenHover,
91
+ selectedBorder: datalayerColors.greenHover,
92
+ disabledText: datalayerColors.gray,
93
+ disabledBg: datalayerColors.greenTint,
94
+ disabledCounterBg: 'rgba(0, 0, 0, 0.05)',
95
+ counterBg: 'rgba(0, 0, 0, 0.05)',
96
+ counterFg: datalayerColors.greenText,
97
+ hoverCounterFg: datalayerColors.white,
98
+ disabledCounterFg: datalayerColors.gray,
99
+ },
100
+ danger: {
101
+ text: '#d32f2f',
102
+ hoverText: datalayerColors.white,
103
+ hoverBg: '#d32f2f',
104
+ hoverBorder: '#d32f2f',
105
+ hoverCounterBg: 'rgba(255, 255, 255, 0.2)',
106
+ selectedText: datalayerColors.white,
107
+ selectedBg: '#b71c1c',
108
+ selectedBorder: '#b71c1c',
109
+ disabledText: 'rgba(211, 47, 47, 0.5)',
110
+ disabledBg: datalayerColors.greenTint,
111
+ disabledCounterBg: 'rgba(211, 47, 47, 0.05)',
112
+ counterBg: 'rgba(211, 47, 47, 0.1)',
113
+ counterFg: '#d32f2f',
114
+ hoverCounterFg: datalayerColors.white,
115
+ disabledCounterFg: 'rgba(211, 47, 47, 0.5)',
116
+ icon: '#d32f2f',
37
117
  },
38
118
  },
39
119
  },
40
120
  shadows: {},
41
121
  },
42
122
  dark: {
43
- colors: {},
123
+ colors: {
124
+ // Canvas colors
125
+ canvas: {
126
+ default: datalayerColors.black,
127
+ subtle: '#0d1117',
128
+ },
129
+ // Foreground colors
130
+ fg: {
131
+ default: datalayerColors.white,
132
+ muted: '#8b949e',
133
+ onEmphasis: datalayerColors.white,
134
+ },
135
+ // Accent colors (bright greens for dark mode)
136
+ accent: {
137
+ fg: datalayerColors.greenAccent,
138
+ emphasis: datalayerColors.greenBright,
139
+ muted: datalayerColors.greenBrand,
140
+ subtle: '#1f352d',
141
+ },
142
+ // Success colors
143
+ success: {
144
+ fg: datalayerColors.greenAccent,
145
+ emphasis: datalayerColors.greenBright,
146
+ muted: datalayerColors.greenBrand,
147
+ subtle: '#1f352d',
148
+ },
149
+ // Button colors for dark mode
150
+ btn: {
151
+ text: '#c9d1d9',
152
+ bg: '#21262d',
153
+ border: 'rgba(240, 246, 252, 0.1)',
154
+ hoverBg: '#30363d',
155
+ hoverBorder: '#8b949e',
156
+ activeBg: 'hsla(212, 12%, 18%, 1)',
157
+ activeBorder: '#6e7681',
158
+ selectedBg: '#161b22',
159
+ counterBg: '#30363d',
160
+ primary: {
161
+ text: datalayerColors.white,
162
+ bg: datalayerColors.greenAccent,
163
+ border: 'rgba(240, 246, 252, 0.1)',
164
+ hoverBg: datalayerColors.greenBright,
165
+ hoverBorder: 'rgba(240, 246, 252, 0.1)',
166
+ selectedBg: datalayerColors.greenBright,
167
+ disabledText: 'rgba(255, 255, 255, 0.5)',
168
+ disabledBg: 'rgba(22, 160, 133, 0.6)',
169
+ disabledBorder: 'rgba(240, 246, 252, 0.1)',
170
+ icon: datalayerColors.white,
171
+ counterBg: 'rgba(0, 0, 0, 0.2)',
172
+ },
173
+ outline: {
174
+ text: datalayerColors.greenAccent,
175
+ hoverText: datalayerColors.white,
176
+ hoverBg: datalayerColors.greenAccent,
177
+ hoverBorder: datalayerColors.greenAccent,
178
+ hoverCounterBg: 'rgba(255, 255, 255, 0.2)',
179
+ selectedText: datalayerColors.white,
180
+ selectedBg: datalayerColors.greenBright,
181
+ selectedBorder: datalayerColors.greenBright,
182
+ disabledText: 'rgba(26, 188, 156, 0.5)',
183
+ disabledBg: 'rgba(26, 188, 156, 0.1)',
184
+ disabledCounterBg: 'rgba(26, 188, 156, 0.05)',
185
+ counterBg: 'rgba(26, 188, 156, 0.1)',
186
+ counterFg: datalayerColors.greenAccent,
187
+ hoverCounterFg: datalayerColors.white,
188
+ disabledCounterFg: 'rgba(26, 188, 156, 0.5)',
189
+ },
190
+ danger: {
191
+ text: '#f85149',
192
+ hoverText: datalayerColors.white,
193
+ hoverBg: '#da3633',
194
+ hoverBorder: '#f85149',
195
+ hoverCounterBg: 'rgba(255, 255, 255, 0.2)',
196
+ selectedText: datalayerColors.white,
197
+ selectedBg: '#b62324',
198
+ selectedBorder: '#ff7b72',
199
+ disabledText: 'rgba(248, 81, 73, 0.5)',
200
+ disabledBg: 'rgba(248, 81, 73, 0.1)',
201
+ disabledCounterBg: 'rgba(248, 81, 73, 0.05)',
202
+ counterBg: 'rgba(248, 81, 73, 0.1)',
203
+ counterFg: '#f85149',
204
+ hoverCounterFg: datalayerColors.white,
205
+ disabledCounterFg: 'rgba(248, 81, 73, 0.5)',
206
+ icon: '#f85149',
207
+ },
208
+ },
209
+ },
44
210
  shadows: {},
45
211
  },
46
212
  },
47
213
  };
48
214
  const { colorSchemes: primerSchemes, ...primerOthers } = cloneDeep(primerTheme);
49
- const { colorSchemes: jupyterSchemes, ...datalayerOthers } = datalayerThemeDefs;
50
- // Merge with the light theme to ensure all variables are defined (although the style may be ugly).
51
- const datalayerTheme = merge(primerOthers, datalayerOthers, {
215
+ const { colorSchemes: datalayerSchemes, ...datalayerOthers } = datalayerThemeDefs;
216
+ // Merge with the light theme to ensure all variables are defined.
217
+ export const datalayerTheme = merge(primerOthers, datalayerOthers, {
52
218
  colorSchemes: { light: {}, dark: {} },
53
219
  });
54
220
  datalayerTheme.colorSchemes.light = {
55
- colors: merge(primerSchemes.light.colors, jupyterSchemes.light.colors),
56
- shadows: merge(primerSchemes.light.shadows, jupyterSchemes.light.shadows),
221
+ colors: merge(primerSchemes.light.colors, datalayerSchemes.light.colors),
222
+ shadows: merge(primerSchemes.light.shadows, datalayerSchemes.light.shadows),
57
223
  };
58
224
  datalayerTheme.colorSchemes.dark = {
59
- colors: merge(primerSchemes.dark.colors, jupyterSchemes.dark.colors),
60
- shadows: merge(primerSchemes.dark.shadows, jupyterSchemes.dark.shadows),
225
+ colors: merge(primerSchemes.dark.colors, datalayerSchemes.dark.colors),
226
+ shadows: merge(primerSchemes.dark.shadows, datalayerSchemes.dark.shadows),
61
227
  };
62
- export { datalayerTheme };
228
+ export default datalayerTheme;
@@ -1,6 +1,6 @@
1
1
  import { type CSSProperties } from 'react';
2
2
  import { ThemeProviderProps } from '@primer/react';
3
- export interface IDatalayerThemeProviderProps extends ThemeProviderProps {
3
+ export interface IDatalayerThemeProviderProps extends Omit<ThemeProviderProps, 'theme'> {
4
4
  /**
5
5
  * Base styles.
6
6
  */
@@ -1,11 +1,46 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { BaseStyles, ThemeProvider } from '@primer/react';
3
+ import { datalayerTheme, datalayerColors } from './DatalayerTheme';
4
+ const baseStyleLight = {
5
+ backgroundColor: datalayerColors.white,
6
+ color: datalayerColors.black,
7
+ fontSize: 'var(--text-body-size-medium)',
8
+ };
9
+ const baseStyleDark = {
10
+ backgroundColor: datalayerColors.black,
11
+ color: datalayerColors.white,
12
+ fontSize: 'var(--text-body-size-medium)',
13
+ };
14
+ const primaryButtonVarsLight = {
15
+ '--button-primary-bgColor-rest': datalayerColors.greenText,
16
+ '--button-primary-bgColor-hover': datalayerColors.greenHover,
17
+ '--button-primary-bgColor-active': datalayerColors.greenHover,
18
+ '--button-primary-fgColor-rest': datalayerColors.white,
19
+ '--button-primary-borderColor-rest': datalayerColors.greenText,
20
+ '--button-primary-borderColor-hover': datalayerColors.greenHover,
21
+ '--color-btn-primary-bg': datalayerColors.greenText,
22
+ '--color-btn-primary-hover-bg': datalayerColors.greenHover,
23
+ };
24
+ const primaryButtonVarsDark = {
25
+ '--button-primary-bgColor-rest': datalayerColors.greenAccent,
26
+ '--button-primary-bgColor-hover': datalayerColors.greenBright,
27
+ '--button-primary-bgColor-active': datalayerColors.greenBright,
28
+ '--button-primary-fgColor-rest': datalayerColors.white,
29
+ '--button-primary-borderColor-rest': datalayerColors.greenAccent,
30
+ '--button-primary-borderColor-hover': datalayerColors.greenBright,
31
+ '--color-btn-primary-bg': datalayerColors.greenAccent,
32
+ '--color-btn-primary-hover-bg': datalayerColors.greenBright,
33
+ };
3
34
  export function DatalayerThemeProvider(props) {
4
35
  const { children, colorMode, baseStyles, ...rest } = props;
5
- return (_jsx(ThemeProvider, { colorMode: colorMode, ...rest, children: _jsx(BaseStyles, { style: {
6
- backgroundColor: 'var(--bgColor-default)',
7
- color: 'var(--fgColor-default)',
8
- fontSize: 'var(--text-body-size-medium)',
36
+ const isDark = colorMode === 'dark' || colorMode === 'night';
37
+ const baseStyleDefaults = isDark ? baseStyleDark : baseStyleLight;
38
+ const primaryButtonVars = isDark
39
+ ? primaryButtonVarsDark
40
+ : primaryButtonVarsLight;
41
+ return (_jsx(ThemeProvider, { colorMode: colorMode, theme: datalayerTheme, ...rest, children: _jsx(BaseStyles, { style: {
42
+ ...baseStyleDefaults,
43
+ ...primaryButtonVars,
9
44
  ...baseStyles,
10
45
  }, children: children }) }));
11
46
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datalayer/core",
3
- "version": "0.0.24",
3
+ "version": "0.0.25",
4
4
  "type": "module",
5
5
  "workspaces": [
6
6
  ".",
@@ -103,7 +103,7 @@
103
103
  },
104
104
  "dependencies": {
105
105
  "@datalayer/icons-react": "^1.0.6",
106
- "@datalayer/jupyter-lexical": "^1.0.8",
106
+ "@datalayer/jupyter-lexical": "^1.0.9",
107
107
  "@datalayer/jupyter-react": "^2.0.2",
108
108
  "@datalayer/primer-addons": "^1.0.4",
109
109
  "@datalayer/primer-rjsf": "^1.0.1",
@@ -125,7 +125,7 @@
125
125
  "@lumino/disposable": "^2.1.5",
126
126
  "@lumino/polling": "^2.1.5",
127
127
  "@lumino/signaling": "^2.1.5",
128
- "@lumino/widgets": "^2.7.2",
128
+ "@lumino/widgets": "^2.7.3",
129
129
  "@primer/behaviors": "^1.8.4",
130
130
  "@primer/brand-primitives": "^0.51.0",
131
131
  "@primer/css": "^21.5.1",