@datalayer/primer-addons 1.0.19 → 1.0.21

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.
@@ -1,9 +1,9 @@
1
- import { type SVGProps } from 'react';
2
- import { type ThemeVariant } from '../../theme';
3
- export interface DatalayerTextAIProps extends Omit<SVGProps<SVGSVGElement>, 'ref'> {
1
+ import { type SVGProps } from "react";
2
+ import { type ThemeVariant } from "../../theme";
3
+ export interface DatalayerTextAIProps extends Omit<SVGProps<SVGSVGElement>, "ref"> {
4
4
  size?: number;
5
5
  scale?: number;
6
- colorMode?: 'light' | 'dark' | 'auto';
6
+ colorMode?: "light" | "dark" | "auto";
7
7
  variant?: ThemeVariant;
8
8
  /** Colour for the "LAYER" part of the wordmark. */
9
9
  primaryColor?: string;
@@ -3,10 +3,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  * Copyright (c) 2023-2026 Datalayer, Inc.
4
4
  * Distributed under the terms of the Modified BSD License.
5
5
  */
6
- import { forwardRef } from 'react';
7
- import { AI } from './AI';
8
- import { DatalayerText } from './DatalayerText';
9
- import { getLogoColors } from './DatalayerLogo';
6
+ import { forwardRef } from "react";
7
+ import { DatalayerText } from "./DatalayerText";
8
+ import { getLogoColors } from "./DatalayerLogo";
10
9
  const TEXT_LEFT_TRIM = 12;
11
10
  const TEXT_END_X = 136.672 - TEXT_LEFT_TRIM;
12
11
  const AI_SIZE = 24;
@@ -15,13 +14,14 @@ const AI_VISIBLE_LEFT = 0.25;
15
14
  const AI_VISIBLE_HEIGHT = 16.136075;
16
15
  const AI_SCALE_TO_TEXT_HEIGHT = 25 / AI_VISIBLE_HEIGHT;
17
16
  const AI_RENDER_SIZE = AI_SIZE * AI_SCALE_TO_TEXT_HEIGHT;
17
+ const AI_RENDER_SCALE = AI_RENDER_SIZE / AI_SIZE;
18
18
  const AI_X_TRIM = AI_VISIBLE_LEFT * AI_SCALE_TO_TEXT_HEIGHT;
19
19
  const AI_Y_TRIM = AI_VISIBLE_TOP * AI_SCALE_TO_TEXT_HEIGHT;
20
20
  /**
21
21
  * Datalayer wordmark followed by AI glyph on one line.
22
22
  * Both elements are aligned to the same 25-unit cap height.
23
23
  */
24
- export const DatalayerTextAI = forwardRef(function DatalayerTextAI({ size = 25, scale = 1, colorMode = 'light', variant = 'datalayer', primaryColor, secondaryColor, textColor,
24
+ export const DatalayerTextAI = forwardRef(function DatalayerTextAI({ size = 25, scale = 1, colorMode = "light", variant = "datalayer", primaryColor, secondaryColor, textColor,
25
25
  // 2.380655 ~= 25 / (0.7 * 15.00187)
26
26
  textSizeMultiplier = 2.380655, aiPrimaryColor, aiSecondaryColor, aiGap = 6, ...svgProps }, ref) {
27
27
  const themed = getLogoColors(variant, colorMode);
@@ -35,6 +35,6 @@ textSizeMultiplier = 2.380655, aiPrimaryColor, aiSecondaryColor, aiGap = 6, ...s
35
35
  const baseWidth = (viewBoxWidth / 25) * size;
36
36
  const height = baseHeight * scale;
37
37
  const width = baseWidth * scale;
38
- return (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: `0 0 ${viewBoxWidth} 25`, width: width, height: height, role: "img", "aria-label": "Datalayer AI", ref: ref, ...svgProps, children: [_jsx(DatalayerText, { primaryColor: layerColor, secondaryColor: dataTextColor, sizeMultiplier: textSizeMultiplier, x: -TEXT_LEFT_TRIM }), _jsx(AI, { size: AI_RENDER_SIZE, x: TEXT_END_X + aiGap - AI_X_TRIM, y: -AI_Y_TRIM, variant: variant, colorMode: colorMode, primaryColor: resolvedAiPrimary, secondaryColor: resolvedAiSecondary })] }));
38
+ return (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: `0 0 ${viewBoxWidth} 25`, width: width, height: height, role: "img", "aria-label": "Datalayer AI", ref: ref, ...svgProps, children: [_jsx(DatalayerText, { primaryColor: layerColor, secondaryColor: dataTextColor, sizeMultiplier: textSizeMultiplier, x: -TEXT_LEFT_TRIM }), _jsxs("g", { transform: `translate(${TEXT_END_X + aiGap - AI_X_TRIM} ${-AI_Y_TRIM}) scale(${AI_RENDER_SCALE})`, children: [_jsx("path", { d: "m13.788825 3.932 6.43325 16.136075h3.5279L17.316725 3.932H13.788825Z", fill: resolvedAiPrimary, strokeWidth: 0.25 }), _jsx("path", { d: "m6.325375 13.682775 2.20125 -5.67065 2.201275 5.67065H6.325375ZM6.68225 3.932 0.25 20.068075h3.596525l1.3155 -3.3886h6.729425l1.315275 3.3886h3.59655L10.371 3.932H6.68225Z", fill: resolvedAiSecondary, fillRule: "evenodd", clipRule: "evenodd", strokeWidth: 0.25 })] })] }));
39
39
  });
40
40
  export default DatalayerTextAI;
@@ -1,7 +1,5 @@
1
- export * from './AI';
2
- export * from './AI2';
3
- export * from './DI';
4
- export * from './DatalayerLogo';
5
- export * from './DatalayerLogoText';
6
- export * from './DatalayerText';
7
- export * from './DatalayerTextAI';
1
+ export * from "./DI";
2
+ export * from "./DatalayerLogo";
3
+ export * from "./DatalayerLogoText";
4
+ export * from "./DatalayerText";
5
+ export * from "./DatalayerTextAI";
@@ -1,7 +1,5 @@
1
- export * from './AI';
2
- export * from './AI2';
3
- export * from './DI';
4
- export * from './DatalayerLogo';
5
- export * from './DatalayerLogoText';
6
- export * from './DatalayerText';
7
- export * from './DatalayerTextAI';
1
+ export * from "./DI";
2
+ export * from "./DatalayerLogo";
3
+ export * from "./DatalayerLogoText";
4
+ export * from "./DatalayerText";
5
+ export * from "./DatalayerTextAI";
@@ -1,3 +1,3 @@
1
1
  import type { ToolbarProps } from './types';
2
- export declare function Toolbar({ items, extraItems, className, disabled, ariaLabel, }: ToolbarProps): import("react/jsx-runtime").JSX.Element;
2
+ export declare function Toolbar({ items, extraItems, className, disabled, ariaLabel, overflow, }: ToolbarProps): import("react/jsx-runtime").JSX.Element;
3
3
  export default Toolbar;
Binary file
@@ -6,16 +6,19 @@ import { jsx as _jsx } from "react/jsx-runtime";
6
6
  /**
7
7
  * ToolbarButton - A single button in a Toolbar.
8
8
  *
9
- * Renders a native <button> with a direct Octicon icon.
10
- * Avoids Primer's IconButton and Tooltip components to prevent invariant
11
- * violations in Primer v37 (Tooltip requires a native interactive child,
12
- * and IconButton's internal Tooltip conflicts with external wrappers).
13
- *
14
- * Uses the native HTML `title` attribute for tooltip behaviour.
9
+ * Renders a native <button> with a direct Octicon icon, wrapped in Primer's
10
+ * Tooltip when the item carries a title. The v37 Tooltip demands a native
11
+ * interactive child — the reason IconButton is avoided — and a plain
12
+ * <button> is exactly that. A disabled item therefore wears `aria-disabled`
13
+ * rather than the `disabled` attribute: a truly disabled button is not
14
+ * interactive, which both silences its tooltip and breaks the invariant —
15
+ * and the tooltip of a disabled action is precisely where the why-disabled
16
+ * explanation lives.
15
17
  *
16
18
  * @module components/toolbar/ToolbarButton
17
19
  */
18
20
  import { isValidElement } from 'react';
21
+ import { Tooltip } from '@primer/react';
19
22
  export function ToolbarButton({ item, size = 'medium' }) {
20
23
  const { ariaLabel, title, icon, label, isActive, onClick, disabled } = item;
21
24
  // Resolve icon → React element.
@@ -38,7 +41,7 @@ export function ToolbarButton({ item, size = 'medium' }) {
38
41
  iconElement = _jsx("span", { style: { fontSize: 12, fontWeight: 600, lineHeight: 1 }, children: label });
39
42
  }
40
43
  const btnSize = size === 'small' ? 28 : 32;
41
- return (_jsx("button", { type: "button", "aria-label": ariaLabel, title: title, onMouseDown: (e) => e.preventDefault(), onClick: onClick, disabled: disabled, style: {
44
+ const button = (_jsx("button", { type: "button", "aria-label": ariaLabel, "aria-disabled": disabled || undefined, onMouseDown: (e) => e.preventDefault(), onClick: disabled ? undefined : onClick, style: {
42
45
  display: 'inline-flex',
43
46
  alignItems: 'center',
44
47
  justifyContent: 'center',
@@ -66,5 +69,7 @@ export function ToolbarButton({ item, size = 'medium' }) {
66
69
  ? 'var(--fgColor-accent, #0969da)'
67
70
  : 'var(--fgColor-muted, #656d76)';
68
71
  }, children: iconElement }));
72
+ // No title: nothing to say, no wrapper to say it with.
73
+ return title ? (_jsx(Tooltip, { text: title, direction: "s", children: button })) : (button);
69
74
  }
70
75
  export default ToolbarButton;
@@ -11,6 +11,7 @@ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
11
11
  * @module components/toolbar/ToolbarRenderer
12
12
  */
13
13
  import { Fragment } from 'react';
14
+ import { Box } from '../box/Box';
14
15
  import { ToolbarButton } from './ToolbarButton';
15
16
  import { ToolbarDropdown } from './ToolbarDropdown';
16
17
  import { ToolbarDivider } from './ToolbarDivider';
@@ -30,6 +31,8 @@ export function ToolbarRenderer({ items, disabled, size = 'medium' }) {
30
31
  return (_jsx(Fragment, { children: _jsx(ToolbarDropdown, { item: { ...item, disabled: itemDisabled }, size: size }) }, item.key));
31
32
  case 'divider':
32
33
  return (_jsx(Fragment, { children: _jsx(ToolbarDivider, {}) }, item.key));
34
+ case 'spacer':
35
+ return (_jsx(Box, { sx: { flex: '1 1 auto', minWidth: 8 } }, item.key));
33
36
  case 'custom':
34
37
  return _jsx(Fragment, { children: item.render() }, item.key);
35
38
  default:
@@ -3,7 +3,7 @@ import type { IconProps } from '@primer/octicons-react';
3
3
  /**
4
4
  * Toolbar item types that can be registered in a toolbar.
5
5
  */
6
- export type ToolbarItemType = 'button' | 'dropdown' | 'divider' | 'custom';
6
+ export type ToolbarItemType = 'button' | 'dropdown' | 'divider' | 'spacer' | 'custom';
7
7
  /**
8
8
  * Base toolbar item definition.
9
9
  */
@@ -88,6 +88,15 @@ export interface ToolbarDropdownItem extends ToolbarItemBase {
88
88
  export interface ToolbarDividerItem extends ToolbarItemBase {
89
89
  type: 'divider';
90
90
  }
91
+ /**
92
+ * Toolbar spacer item definition.
93
+ *
94
+ * Takes the free space of the toolbar, so the items ordered after it sit on
95
+ * the trailing edge — e.g. a status indicator kept away from the actions.
96
+ */
97
+ export interface ToolbarSpacerItem extends ToolbarItemBase {
98
+ type: 'spacer';
99
+ }
91
100
  /**
92
101
  * Toolbar custom item definition.
93
102
  */
@@ -99,7 +108,7 @@ export interface ToolbarCustomItem extends ToolbarItemBase {
99
108
  /**
100
109
  * Union of all toolbar item types.
101
110
  */
102
- export type ToolbarItem = ToolbarButtonItem | ToolbarDropdownItem | ToolbarDividerItem | ToolbarCustomItem;
111
+ export type ToolbarItem = ToolbarButtonItem | ToolbarDropdownItem | ToolbarDividerItem | ToolbarSpacerItem | ToolbarCustomItem;
103
112
  /**
104
113
  * Props for the extensible Toolbar component.
105
114
  */
@@ -114,6 +123,13 @@ export interface ToolbarProps {
114
123
  extraItems?: ToolbarItem[];
115
124
  /** Aria label for the toolbar */
116
125
  ariaLabel?: string;
126
+ /**
127
+ * Keep the toolbar to one line, moving what does not fit into a menu.
128
+ *
129
+ * On by default. Turned off, the items are all laid on the line and it is
130
+ * up to the host to leave room for them.
131
+ */
132
+ overflow?: boolean;
117
133
  }
118
134
  /**
119
135
  * Props for the extensible FloatingToolbar component.
@@ -1,4 +1,12 @@
1
1
  import { type CSSProperties } from 'react';
2
+ /**
3
+ * Id of the element Primer portals render under.
4
+ *
5
+ * Exported because a host may need to mark that element as its own — the
6
+ * JupyterLab theming of jupyter-react adds `jp-ThemedContainer` to it, so
7
+ * the rules JupyterLab scopes to that class reach portaled content too.
8
+ */
9
+ export declare const PRIMER_PORTAL_ROOT_ID = "__primerPortalRoot__";
2
10
  type Colormode = 'light' | 'dark' | 'auto';
3
11
  /**
4
12
  * Ensure we define a root for Primer portal root.
@@ -11,6 +19,13 @@ type Colormode = 'light' | 'dark' | 'auto';
11
19
  * @see https://github.com/primer/react/blob/030fe020b48b7f12c2994c6614e5d4191fe764ee/src/Portal/Portal.tsx#L33
12
20
  */
13
21
  export declare const setupPrimerPortals: (colormode?: Colormode) => void;
22
+ /**
23
+ * The element Primer portals render under, when it has been set up.
24
+ *
25
+ * `setupPrimerPortals` creates it; before that call there is none, and this
26
+ * answers `null` rather than inventing one.
27
+ */
28
+ export declare const getPrimerPortalRoot: () => HTMLElement | null;
14
29
  /**
15
30
  * Sync a set of CSS properties (including CSS custom properties) to
16
31
  * `document.body` so that Primer portal content — which is a DOM child
@@ -3,7 +3,14 @@
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
5
  import { registerPortalRoot } from '@primer/react';
6
- const PRIMER_PORTAL_ROOT_ID = '__primerPortalRoot__';
6
+ /**
7
+ * Id of the element Primer portals render under.
8
+ *
9
+ * Exported because a host may need to mark that element as its own — the
10
+ * JupyterLab theming of jupyter-react adds `jp-ThemedContainer` to it, so
11
+ * the rules JupyterLab scopes to that class reach portaled content too.
12
+ */
13
+ export const PRIMER_PORTAL_ROOT_ID = '__primerPortalRoot__';
7
14
  /**
8
15
  * Key used on `document.body` to track the CSS-property names we
9
16
  * previously applied so we can remove stale entries on theme switch.
@@ -81,11 +88,38 @@ export const setupPrimerPortals = (colormode) => {
81
88
  portalRoot.dataset['colorMode'] = resolved;
82
89
  portalRoot.dataset['lightTheme'] = lightTheme;
83
90
  portalRoot.dataset['darkTheme'] = darkTheme;
84
- // High z-index so overlays render above positioned UI (e.g. chat z-index 1001).
85
- portalRoot.style.position = 'relative';
91
+ /*
92
+ * Pinned to the origin of the document, never left in the flow of the body.
93
+ *
94
+ * Primer positions an anchored overlay — a menu, a dropdown — with
95
+ * `position: absolute` and coordinates taken from the VIEWPORT rectangle
96
+ * of its anchor. Those coordinates are only right when the containing
97
+ * block of the overlay starts at the origin of the document, which is why
98
+ * Primer's own default portal root is `absolute` at `0, 0`.
99
+ *
100
+ * Left `relative`, this root instead sits wherever the flow of the body
101
+ * ends and becomes the containing block of everything portaled into it:
102
+ * in an application whose markup is a full-height element — a React page
103
+ * hosting JupyterLab — that is the bottom of the screen, and every menu
104
+ * opened at the top of the page was drawn a screen further down, off the
105
+ * bottom edge. Which reads, to whoever clicked, as a menu that refuses to
106
+ * open. The high z-index is kept: it needs a positioned element, and
107
+ * `absolute` is one.
108
+ */
109
+ portalRoot.style.position = 'absolute';
110
+ portalRoot.style.top = '0';
111
+ portalRoot.style.left = '0';
112
+ portalRoot.style.width = '100%';
86
113
  portalRoot.style.zIndex = '9999';
87
114
  registerPortalRoot(portalRoot);
88
115
  };
116
+ /**
117
+ * The element Primer portals render under, when it has been set up.
118
+ *
119
+ * `setupPrimerPortals` creates it; before that call there is none, and this
120
+ * answers `null` rather than inventing one.
121
+ */
122
+ export const getPrimerPortalRoot = () => document.getElementById(PRIMER_PORTAL_ROOT_ID);
89
123
  /* ─── camelCase → kebab-case ─────────────────────────────────────────── */
90
124
  const camelToKebab = (s) => s.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
91
125
  /**
@@ -102,33 +136,54 @@ const camelToKebab = (s) => s.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
102
136
  * portals stay in sync whenever theme or color-mode changes.
103
137
  */
104
138
  export function syncPortalThemeStyles(styles) {
105
- const body = document.body;
106
- // 1. Remove properties set by the previous invocation.
107
- const prev = body[PORTAL_THEME_KEYS];
108
- if (prev) {
109
- for (const key of prev) {
110
- body.style.removeProperty(key);
111
- }
112
- }
113
- // 2. Apply the new properties.
114
- const tracked = [];
115
- for (const [key, value] of Object.entries(styles)) {
116
- if (value == null)
117
- continue;
118
- const strVal = String(value);
119
- if (key.startsWith('--')) {
120
- // CSS custom property — must use setProperty
121
- body.style.setProperty(key, strVal);
122
- tracked.push(key);
139
+ /*
140
+ * On the portal root as well as on the body, and that is the point.
141
+ *
142
+ * The body was enough for what portals INHERIT — a font, a line height —
143
+ * and never enough for the colours. The portal root carries Primer's own
144
+ * theme markers (`data-color-mode`, `data-light-theme`), and Primer's
145
+ * stylesheet declares `--bgColor-*`, `--fgColor-*` and the rest ON any
146
+ * element carrying them. A declaration on the element always beats a value
147
+ * inherited from an ancestor, so Primer's default palette won on the portal
148
+ * root and everything drawn inside it — the buttons of a dialog, the
149
+ * background of a menu — came out in the default theme while the same
150
+ * components in the page wore the chosen one.
151
+ *
152
+ * Written inline on that element, the theme wins in turn: an inline style
153
+ * outranks any selector in a stylesheet.
154
+ */
155
+ const targets = [
156
+ document.body,
157
+ document.getElementById(PRIMER_PORTAL_ROOT_ID)
158
+ ].filter(Boolean);
159
+ for (const target of targets) {
160
+ // 1. Remove properties set by the previous invocation.
161
+ const prev = target[PORTAL_THEME_KEYS];
162
+ if (prev) {
163
+ for (const key of prev) {
164
+ target.style.removeProperty(key);
165
+ }
123
166
  }
124
- else {
125
- // Standard CSS property (camelCase → kebab-case)
126
- const kebab = camelToKebab(key);
127
- body.style.setProperty(kebab, strVal);
128
- tracked.push(kebab);
167
+ // 2. Apply the new properties.
168
+ const tracked = [];
169
+ for (const [key, value] of Object.entries(styles)) {
170
+ if (value == null)
171
+ continue;
172
+ const strVal = String(value);
173
+ if (key.startsWith('--')) {
174
+ // CSS custom property — must use setProperty
175
+ target.style.setProperty(key, strVal);
176
+ tracked.push(key);
177
+ }
178
+ else {
179
+ // Standard CSS property (camelCase → kebab-case)
180
+ const kebab = camelToKebab(key);
181
+ target.style.setProperty(kebab, strVal);
182
+ tracked.push(kebab);
183
+ }
129
184
  }
185
+ // 3. Stash the list for the next cleanup.
186
+ target[PORTAL_THEME_KEYS] = tracked;
130
187
  }
131
- // 3. Stash the list for the next cleanup.
132
- body[PORTAL_THEME_KEYS] = tracked;
133
188
  }
134
189
  export default setupPrimerPortals;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datalayer/primer-addons",
3
- "version": "1.0.19",
3
+ "version": "1.0.21",
4
4
  "license": "BSD-3-Clause",
5
5
  "scripts": {
6
6
  "build": "npm run build:lib",
@@ -1,17 +0,0 @@
1
- import { type SVGProps } from 'react';
2
- import { type ThemeVariant } from '../../theme';
3
- export interface AIProps extends Omit<SVGProps<SVGSVGElement>, 'ref'> {
4
- size?: number;
5
- variant?: ThemeVariant;
6
- colorMode?: 'light' | 'dark' | 'auto';
7
- /** Colour of the "I" glyph. */
8
- primaryColor?: string;
9
- /** Colour of the "A" glyph. */
10
- secondaryColor?: string;
11
- }
12
- /**
13
- * AI glyph mark from the official brand source SVG.
14
- * Defaults to themed logo colors and supports explicit overrides.
15
- */
16
- export declare const AI: import("react").ForwardRefExoticComponent<AIProps & import("react").RefAttributes<SVGSVGElement>>;
17
- export default AI;
@@ -1,18 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- /*
3
- * Copyright (c) 2023-2026 Datalayer, Inc.
4
- * Distributed under the terms of the Modified BSD License.
5
- */
6
- import { forwardRef } from 'react';
7
- import { getLogoColors } from './DatalayerLogo';
8
- /**
9
- * AI glyph mark from the official brand source SVG.
10
- * Defaults to themed logo colors and supports explicit overrides.
11
- */
12
- export const AI = forwardRef(function AI({ size = 24, variant = 'datalayer', colorMode = 'light', primaryColor, secondaryColor, ...svgProps }, ref) {
13
- const themed = getLogoColors(variant, colorMode);
14
- const resolvedPrimary = primaryColor ?? themed.primary;
15
- const resolvedSecondary = secondaryColor ?? themed.textColor;
16
- return (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", width: size, height: size, role: "img", "aria-label": "AI", ref: ref, ...svgProps, children: [_jsx("path", { d: "m13.788825 3.932 6.43325 16.136075h3.5279L17.316725 3.932H13.788825Z", fill: resolvedPrimary, strokeWidth: 0.25 }), _jsx("path", { d: "m6.325375 13.682775 2.20125 -5.67065 2.201275 5.67065H6.325375ZM6.68225 3.932 0.25 20.068075h3.596525l1.3155 -3.3886h6.729425l1.315275 3.3886h3.59655L10.371 3.932H6.68225Z", fill: resolvedSecondary, fillRule: "evenodd", clipRule: "evenodd", strokeWidth: 0.25 })] }));
17
- });
18
- export default AI;
@@ -1,20 +0,0 @@
1
- import { type SVGProps } from 'react';
2
- import { type ThemeVariant } from '../../theme';
3
- export interface AI2Props extends Omit<SVGProps<SVGSVGElement>, 'ref'> {
4
- size?: number;
5
- variant?: ThemeVariant;
6
- colorMode?: 'light' | 'dark' | 'auto';
7
- /** Colour of the "I" glyph. */
8
- primaryColor?: string;
9
- /** Colour of the "A" glyph. */
10
- secondaryColor?: string;
11
- }
12
- /**
13
- * Alternate AI glyph mark.
14
- *
15
- * A is rendered with an oblique left bar, a right vertical bar,
16
- * and a horizontal crossbar.
17
- * I is rendered as a simple vertical bar.
18
- */
19
- export declare const AI2: import("react").ForwardRefExoticComponent<AI2Props & import("react").RefAttributes<SVGSVGElement>>;
20
- export default AI2;
@@ -1,23 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- /*
3
- * Copyright (c) 2023-2026 Datalayer, Inc.
4
- * Distributed under the terms of the Modified BSD License.
5
- */
6
- import { forwardRef } from 'react';
7
- import { getLogoColors } from './DatalayerLogo';
8
- /**
9
- * Alternate AI glyph mark.
10
- *
11
- * A is rendered with an oblique left bar, a right vertical bar,
12
- * and a horizontal crossbar.
13
- * I is rendered as a simple vertical bar.
14
- */
15
- export const AI2 = forwardRef(function AI2({ size = 24, variant = 'datalayer', colorMode = 'light', primaryColor, secondaryColor, ...svgProps }, ref) {
16
- const themed = getLogoColors(variant, colorMode);
17
- const resolvedPrimary = primaryColor ?? themed.primary;
18
- const resolvedSecondary = secondaryColor ?? themed.textColor;
19
- const barWidth = 3.1;
20
- const leftBarBottomInnerX = -2.2 + barWidth;
21
- return (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "-2.2 0 26.2 24", width: size, height: size, role: "img", "aria-label": "AI2", ref: ref, ...svgProps, children: [_jsx("path", { d: `M15.35 3.5h${barWidth}V20h-${barWidth}z`, fill: resolvedPrimary }), _jsx("path", { d: `M-2.2 20 9.8 3.5h${barWidth}L${leftBarBottomInnerX} 20H-2.2z`, fill: resolvedSecondary }), _jsx("path", { d: `M10.35 3.5h${barWidth}V20h-${barWidth}z`, fill: resolvedSecondary }), _jsx("path", { d: "M3.5 12.95h9.6v2.75H3.5z", fill: resolvedSecondary })] }));
22
- });
23
- export default AI2;