@atlaskit/editor-toolbar 0.3.8 → 0.5.0

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 (37) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/cjs/index.js +14 -0
  3. package/dist/cjs/ui/ColorPalette/Color.compiled.css +1 -2
  4. package/dist/cjs/ui/ColorPalette/Color.js +3 -2
  5. package/dist/cjs/ui/ColorPalette/index.js +239 -5
  6. package/dist/cjs/ui/ColorPalette/utils.js +40 -1
  7. package/dist/cjs/ui/ToolbarDropdownItem.js +9 -2
  8. package/dist/cjs/ui/ToolbarDropdownMenu.compiled.css +2 -1
  9. package/dist/cjs/ui/ToolbarDropdownMenu.js +4 -2
  10. package/dist/cjs/ui/icons/LoomIcon.js +13 -0
  11. package/dist/es2019/index.js +2 -0
  12. package/dist/es2019/ui/ColorPalette/Color.compiled.css +1 -2
  13. package/dist/es2019/ui/ColorPalette/Color.js +3 -2
  14. package/dist/es2019/ui/ColorPalette/index.js +240 -5
  15. package/dist/es2019/ui/ColorPalette/utils.js +36 -1
  16. package/dist/es2019/ui/ToolbarDropdownItem.js +23 -14
  17. package/dist/es2019/ui/ToolbarDropdownMenu.compiled.css +2 -1
  18. package/dist/es2019/ui/ToolbarDropdownMenu.js +4 -2
  19. package/dist/es2019/ui/icons/LoomIcon.js +2 -0
  20. package/dist/esm/index.js +2 -0
  21. package/dist/esm/ui/ColorPalette/Color.compiled.css +1 -2
  22. package/dist/esm/ui/ColorPalette/Color.js +3 -2
  23. package/dist/esm/ui/ColorPalette/index.js +242 -8
  24. package/dist/esm/ui/ColorPalette/utils.js +38 -1
  25. package/dist/esm/ui/ToolbarDropdownItem.js +9 -2
  26. package/dist/esm/ui/ToolbarDropdownMenu.compiled.css +2 -1
  27. package/dist/esm/ui/ToolbarDropdownMenu.js +4 -2
  28. package/dist/esm/ui/icons/LoomIcon.js +2 -0
  29. package/dist/types/index.d.ts +2 -0
  30. package/dist/types/ui/ColorPalette/utils.d.ts +20 -0
  31. package/dist/types/ui/ToolbarDropdownItem.d.ts +4 -1
  32. package/dist/types/ui/icons/LoomIcon.d.ts +1 -0
  33. package/dist/types-ts4.5/index.d.ts +2 -0
  34. package/dist/types-ts4.5/ui/ColorPalette/utils.d.ts +20 -0
  35. package/dist/types-ts4.5/ui/ToolbarDropdownItem.d.ts +4 -1
  36. package/dist/types-ts4.5/ui/icons/LoomIcon.d.ts +1 -0
  37. package/package.json +6 -8
@@ -1,14 +1,15 @@
1
1
  /* index.tsx generated by @compiled/babel-plugin v0.36.1 */
2
2
  import "./index.compiled.css";
3
3
  import { ax, ix } from "@compiled/react/runtime";
4
- import React, { useMemo } from 'react';
4
+ import React, { useMemo, useCallback, useRef, useEffect } from 'react';
5
5
  import chromatism from 'chromatism';
6
6
  import { useIntl } from 'react-intl-next';
7
- import { Box } from '@atlaskit/primitives/compiled';
7
+ import { Box, Grid, Inline } from '@atlaskit/primitives/compiled';
8
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
8
9
  import { useThemeObserver } from '@atlaskit/tokens';
9
10
  import { Color } from './Color';
10
11
  import getColorMessage from './getColorMessage';
11
- import { DEFAULT_COLOR_PICKER_COLUMNS, getColorsPerRowFromPalette, getTokenCSSVariableValue } from './utils';
12
+ import { DEFAULT_COLOR_PICKER_COLUMNS, getColorsPerRowFromPalette, getSelectedRowAndColumnFromPalette, getTokenCSSVariableValue } from './utils';
12
13
  var styles = {
13
14
  paletteWrapper: "_1e0c1txw"
14
15
  };
@@ -19,7 +20,7 @@ var styles = {
19
20
  *
20
21
  * @param color color string, supports HEX, RGB, RGBA etc.
21
22
  * @param useIconToken boolean, describes if a token should be used for the icon color
22
- * @return Highest contrast color in pool
23
+ * @returns Highest contrast color in pool
23
24
  */
24
25
  function getCheckMarkColor(color, useIconToken) {
25
26
  var tokenVal = getTokenCSSVariableValue(color);
@@ -66,15 +67,203 @@ var ColorPalette = function ColorPalette(_ref) {
66
67
  var _useThemeObserver = useThemeObserver(),
67
68
  tokenTheme = _useThemeObserver.colorMode;
68
69
  var useIconToken = !!hexToPaletteColor;
70
+
71
+ // Refs for keyboard navigation
72
+ var paletteRef = useRef(null);
73
+ var currentFocusRef = useRef({
74
+ row: 0,
75
+ col: 0
76
+ });
69
77
  var colorsPerRow = useMemo(function () {
70
78
  return getColorsPerRowFromPalette(palette, cols);
71
79
  }, [palette, cols]);
72
- return /*#__PURE__*/React.createElement(React.Fragment, null, colorsPerRow.map(function (row) {
73
- return /*#__PURE__*/React.createElement(Box, {
74
- xcss: styles.paletteWrapper,
80
+
81
+ // Get initial focus position based on selected color
82
+ var _useMemo = useMemo(function () {
83
+ return getSelectedRowAndColumnFromPalette(palette, selectedColor, cols);
84
+ }, [palette, selectedColor, cols]),
85
+ selectedRowIndex = _useMemo.selectedRowIndex,
86
+ selectedColumnIndex = _useMemo.selectedColumnIndex;
87
+
88
+ // Focus management utility
89
+ var focusColorAt = useCallback(function (row, col) {
90
+ var _rowElement$children$, _rowElement$children$2;
91
+ if (!paletteRef.current) {
92
+ return;
93
+ }
94
+ var rowElement = paletteRef.current.children[row];
95
+ if (!(rowElement instanceof HTMLElement)) {
96
+ return;
97
+ }
98
+ var colorButtonCandidate = (_rowElement$children$ = rowElement.children[col]) === null || _rowElement$children$ === void 0 || (_rowElement$children$2 = _rowElement$children$.querySelector) === null || _rowElement$children$2 === void 0 ? void 0 : _rowElement$children$2.call(_rowElement$children$, 'button');
99
+ var colorButton = colorButtonCandidate instanceof HTMLButtonElement ? colorButtonCandidate : null;
100
+ if (colorButton) {
101
+ colorButton.focus();
102
+ currentFocusRef.current = {
103
+ row: row,
104
+ col: col
105
+ };
106
+ }
107
+ }, []);
108
+
109
+ // Initialize focus position and handle autofocus
110
+ useEffect(function () {
111
+ if (!expValEquals('platform_editor_toolbar_aifc_patch_1', 'isEnabled', true)) {
112
+ return;
113
+ }
114
+ if (selectedRowIndex >= 0 && selectedColumnIndex >= 0) {
115
+ currentFocusRef.current = {
116
+ row: selectedRowIndex,
117
+ col: selectedColumnIndex
118
+ };
119
+ } else {
120
+ currentFocusRef.current = {
121
+ row: 0,
122
+ col: 0
123
+ };
124
+ }
125
+ }, [selectedRowIndex, selectedColumnIndex]);
126
+
127
+ // Keyboard navigation handler
128
+ var handleKeyDown = useCallback(function (value, label, event) {
129
+ var _colorsPerRow$row;
130
+ var _currentFocusRef$curr = currentFocusRef.current,
131
+ row = _currentFocusRef$curr.row,
132
+ col = _currentFocusRef$curr.col;
133
+ var maxRow = colorsPerRow.length - 1;
134
+ var maxCol = ((_colorsPerRow$row = colorsPerRow[row]) === null || _colorsPerRow$row === void 0 ? void 0 : _colorsPerRow$row.length) - 1 || 0;
135
+ switch (event.key) {
136
+ case 'ArrowRight':
137
+ {
138
+ event.preventDefault();
139
+ if (col < maxCol) {
140
+ focusColorAt(row, col + 1);
141
+ } else if (row < maxRow) {
142
+ // Move to first color of next row
143
+ focusColorAt(row + 1, 0);
144
+ } else {
145
+ // Wrap to first color of first row
146
+ focusColorAt(0, 0);
147
+ }
148
+ break;
149
+ }
150
+ case 'ArrowLeft':
151
+ {
152
+ event.preventDefault();
153
+ if (col > 0) {
154
+ focusColorAt(row, col - 1);
155
+ } else if (row > 0) {
156
+ var _colorsPerRow;
157
+ // Move to last color of previous row
158
+ var prevRowMaxCol = ((_colorsPerRow = colorsPerRow[row - 1]) === null || _colorsPerRow === void 0 ? void 0 : _colorsPerRow.length) - 1 || 0;
159
+ focusColorAt(row - 1, prevRowMaxCol);
160
+ } else {
161
+ var _colorsPerRow$maxRow;
162
+ // Wrap to last color of last row
163
+ var lastRowMaxCol = ((_colorsPerRow$maxRow = colorsPerRow[maxRow]) === null || _colorsPerRow$maxRow === void 0 ? void 0 : _colorsPerRow$maxRow.length) - 1 || 0;
164
+ focusColorAt(maxRow, lastRowMaxCol);
165
+ }
166
+ break;
167
+ }
168
+ case 'ArrowDown':
169
+ {
170
+ event.preventDefault();
171
+ if (row < maxRow) {
172
+ var _colorsPerRow2;
173
+ // Move to same column in next row, or last available column
174
+ var nextRowMaxCol = ((_colorsPerRow2 = colorsPerRow[row + 1]) === null || _colorsPerRow2 === void 0 ? void 0 : _colorsPerRow2.length) - 1 || 0;
175
+ var targetCol = Math.min(col, nextRowMaxCol);
176
+ focusColorAt(row + 1, targetCol);
177
+ } else {
178
+ var _colorsPerRow$;
179
+ // Wrap to same column in first row
180
+ var firstRowMaxCol = ((_colorsPerRow$ = colorsPerRow[0]) === null || _colorsPerRow$ === void 0 ? void 0 : _colorsPerRow$.length) - 1 || 0;
181
+ var _targetCol = Math.min(col, firstRowMaxCol);
182
+ focusColorAt(0, _targetCol);
183
+ }
184
+ break;
185
+ }
186
+ case 'ArrowUp':
187
+ {
188
+ event.preventDefault();
189
+ if (row > 0) {
190
+ var _colorsPerRow3;
191
+ // Move to same column in previous row, or last available column
192
+ var _prevRowMaxCol = ((_colorsPerRow3 = colorsPerRow[row - 1]) === null || _colorsPerRow3 === void 0 ? void 0 : _colorsPerRow3.length) - 1 || 0;
193
+ var _targetCol2 = Math.min(col, _prevRowMaxCol);
194
+ focusColorAt(row - 1, _targetCol2);
195
+ } else {
196
+ var _colorsPerRow$maxRow2;
197
+ // Wrap to same column in last row
198
+ var _lastRowMaxCol = ((_colorsPerRow$maxRow2 = colorsPerRow[maxRow]) === null || _colorsPerRow$maxRow2 === void 0 ? void 0 : _colorsPerRow$maxRow2.length) - 1 || 0;
199
+ var _targetCol3 = Math.min(col, _lastRowMaxCol);
200
+ focusColorAt(maxRow, _targetCol3);
201
+ }
202
+ break;
203
+ }
204
+ case 'Home':
205
+ {
206
+ event.preventDefault();
207
+ focusColorAt(row, 0);
208
+ break;
209
+ }
210
+ case 'End':
211
+ {
212
+ event.preventDefault();
213
+ focusColorAt(row, maxCol);
214
+ break;
215
+ }
216
+ case 'PageUp':
217
+ {
218
+ event.preventDefault();
219
+ focusColorAt(0, col);
220
+ break;
221
+ }
222
+ case 'PageDown':
223
+ {
224
+ var _colorsPerRow$maxRow3;
225
+ event.preventDefault();
226
+ var _lastRowMaxCol2 = ((_colorsPerRow$maxRow3 = colorsPerRow[maxRow]) === null || _colorsPerRow$maxRow3 === void 0 ? void 0 : _colorsPerRow$maxRow3.length) - 1 || 0;
227
+ var _targetCol4 = Math.min(col, _lastRowMaxCol2);
228
+ focusColorAt(maxRow, _targetCol4);
229
+ break;
230
+ }
231
+ case 'Tab':
232
+ {
233
+ // Allow Tab to move to next focusable element (don't prevent default)
234
+ // This will allow Tab to move between color palettes
235
+ if (onKeyDown) {
236
+ onKeyDown(value, label, event);
237
+ }
238
+ break;
239
+ }
240
+ case 'Enter':
241
+ case ' ':
242
+ {
243
+ event.preventDefault();
244
+ onClick(value, label);
245
+ break;
246
+ }
247
+ default:
248
+ {
249
+ // Pass through to custom onKeyDown handler if provided
250
+ if (onKeyDown) {
251
+ onKeyDown(value, label, event);
252
+ }
253
+ break;
254
+ }
255
+ }
256
+ }, [colorsPerRow, focusColorAt, onClick, onKeyDown]);
257
+ return expValEquals('platform_editor_toolbar_aifc_patch_1', 'isEnabled', true) ? /*#__PURE__*/React.createElement(Grid, {
258
+ gap: "space.050",
259
+ ref: paletteRef,
260
+ role: "group"
261
+ }, colorsPerRow.map(function (row, rowIndex) {
262
+ return /*#__PURE__*/React.createElement(Inline, {
263
+ rowSpace: "space.050",
75
264
  key: "row-first-color-".concat(row[0].value),
76
265
  role: "radiogroup"
77
- }, row.map(function (_ref2) {
266
+ }, row.map(function (_ref2, colIndex) {
78
267
  var value = _ref2.value,
79
268
  label = _ref2.label,
80
269
  border = _ref2.border,
@@ -82,6 +271,51 @@ var ColorPalette = function ColorPalette(_ref) {
82
271
  decorator = _ref2.decorator;
83
272
  var tooltipMessage = message;
84
273
 
274
+ // Override with theme-specific tooltip messages if provided
275
+ if (paletteColorTooltipMessages) {
276
+ if (tokenTheme === 'dark') {
277
+ tooltipMessage = getColorMessage(paletteColorTooltipMessages.dark, value.toUpperCase());
278
+ }
279
+ if (tokenTheme === 'light') {
280
+ tooltipMessage = getColorMessage(paletteColorTooltipMessages.light, value.toUpperCase());
281
+ }
282
+ }
283
+
284
+ // Determine if this color should be focusable
285
+ var isSelectedColor = value === selectedColor;
286
+ var isFirstColor = rowIndex === 0 && colIndex === 0;
287
+
288
+ // Only the selected color or first color should be focusable via Tab
289
+ // This allows Tab to move between color palettes
290
+ var shouldBeFocusable = isSelectedColor || !selectedColor && isFirstColor;
291
+ return /*#__PURE__*/React.createElement(Color, {
292
+ key: value,
293
+ value: value,
294
+ borderColor: border,
295
+ label: tooltipMessage ? formatMessage(tooltipMessage) : label,
296
+ onClick: onClick,
297
+ onKeyDown: handleKeyDown,
298
+ isSelected: isSelectedColor,
299
+ checkMarkColor: getCheckMarkColor(value, useIconToken),
300
+ hexToPaletteColor: hexToPaletteColor,
301
+ decorator: decorator,
302
+ tabIndex: shouldBeFocusable ? 0 : -1,
303
+ autoFocus: isSelectedColor && rowIndex === selectedRowIndex && colIndex === selectedColumnIndex
304
+ });
305
+ }));
306
+ })) : /*#__PURE__*/React.createElement(React.Fragment, null, colorsPerRow.map(function (row) {
307
+ return /*#__PURE__*/React.createElement(Box, {
308
+ xcss: styles.paletteWrapper,
309
+ key: "row-first-color-".concat(row[0].value),
310
+ role: "radiogroup"
311
+ }, row.map(function (_ref3) {
312
+ var value = _ref3.value,
313
+ label = _ref3.label,
314
+ border = _ref3.border,
315
+ message = _ref3.message,
316
+ decorator = _ref3.decorator;
317
+ var tooltipMessage = message;
318
+
85
319
  // Override with theme-specific tooltip messages if provided
86
320
  if (paletteColorTooltipMessages) {
87
321
  if (tokenTheme === 'dark') {
@@ -1,3 +1,4 @@
1
+ import chromatism from 'chromatism';
1
2
  /**
2
3
  * Default number of columns in the color picker
3
4
  */
@@ -81,4 +82,40 @@ export var getTokenCSSVariableValue = function getTokenCSSVariableValue(variable
81
82
  return value || fallback;
82
83
  }
83
84
  return '';
84
- };
85
+ };
86
+
87
+ /**
88
+ * Get the best contrasting background color for a given text color
89
+ * Ensures WCAG AA compliance for accessibility
90
+ *
91
+ * @param textColor - The text color to find a contrasting background for (supports HEX, RGB, RGBA etc.)
92
+ * @param useTokens - Whether to return design tokens instead of raw hex values
93
+ * @returns The best contrasting background color (hex value or design token)
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * // Get contrasting color for white text
98
+ * const bgForWhite = getContrastingBackgroundColor('#FFFFFF', false);
99
+ * // Returns: '#42526E' (dark gray)
100
+ *
101
+ * // Get contrasting color for black text with design tokens
102
+ * const bgForBlack = getContrastingBackgroundColor('#000000', true);
103
+ * // Returns: token('elevation.surface', '#FFFFFF')
104
+ * ```
105
+ */
106
+ export function getContrastingBackgroundColor(textColor) {
107
+ var candidates = ['#FFFFFF',
108
+ // white - surface
109
+ '#172B4D' // dark blue-gray - text color
110
+ ];
111
+
112
+ // Extract actual color value if it's a CSS variable
113
+ var tokenVal = getTokenCSSVariableValue(textColor);
114
+ var colorValue = !!tokenVal ? tokenVal : textColor;
115
+
116
+ // Find the color with the highest contrast ratio
117
+ var bestContrast = candidates.sort(function (a, b) {
118
+ return chromatism.difference(b, colorValue) - chromatism.difference(a, colorValue);
119
+ })[0];
120
+ return bestContrast;
121
+ }
@@ -5,6 +5,7 @@ import React, { forwardRef } from 'react';
5
5
  import { cx } from '@atlaskit/css';
6
6
  import { DropdownItem } from '@atlaskit/dropdown-menu';
7
7
  import { Pressable } from '@atlaskit/primitives/compiled';
8
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
8
9
  var styles = {
9
10
  toolbarDropdownItem: "_18zrpxbi _1rjcu2gc _1e0c1txw _kqswh2mm _bfhksm61 _1bsb1osq _1tke14no _1ul9163w _1basglpi _1ah31i6y",
10
11
  enabled: "_irr3166n _1di61dty",
@@ -43,7 +44,10 @@ export var ToolbarDropdownItem = function ToolbarDropdownItem(_ref2) {
43
44
  hasNestedDropdownMenu = _ref2.hasNestedDropdownMenu,
44
45
  triggerRef = _ref2.triggerRef,
45
46
  testId = _ref2.testId,
46
- ariaKeyshortcuts = _ref2.ariaKeyshortcuts;
47
+ ariaKeyshortcuts = _ref2.ariaKeyshortcuts,
48
+ href = _ref2.href,
49
+ target = _ref2.target,
50
+ rel = _ref2.rel;
47
51
  return /*#__PURE__*/React.createElement(DropdownItem, {
48
52
  onClick: onClick,
49
53
  elemBefore: elemBefore,
@@ -54,7 +58,10 @@ export var ToolbarDropdownItem = function ToolbarDropdownItem(_ref2) {
54
58
  "aria-pressed": isSelected,
55
59
  "aria-keyshortcuts": ariaKeyshortcuts,
56
60
  ref: triggerRef,
57
- component: CustomDropdownMenuItemButton,
61
+ href: href,
62
+ target: target,
63
+ rel: rel,
64
+ component: href && expValEquals('platform_editor_toolbar_migrate_loom', 'isEnabled', true) ? undefined : CustomDropdownMenuItemButton,
58
65
  testId: testId
59
66
  }, children);
60
67
  };
@@ -1 +1,2 @@
1
- ._1mou1b66{margin-block:var(--ds-space-050,4px)}
1
+
2
+ ._1mou1b66{margin-block:var(--ds-space-050,4px)}._18l8n7od [data-section]:first-of-type{border-block-start:unset}
@@ -3,11 +3,13 @@ import "./ToolbarDropdownMenu.compiled.css";
3
3
  import { ax, ix } from "@compiled/react/runtime";
4
4
  import React, { useCallback } from 'react';
5
5
  import DropdownMenu from '@atlaskit/dropdown-menu';
6
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
6
7
  import { useToolbarUI } from '../hooks/ui-context';
7
8
  import { ToolbarButton } from './ToolbarButton';
8
9
  import { ToolbarDropdownMenuProvider, useToolbarDropdownMenu } from './ToolbarDropdownMenuContext';
9
10
  var styles = {
10
- sectionMargin: "_1mou1b66"
11
+ sectionMargin: "_1mou1b66",
12
+ firstSectionSeparator: "_18l8n7od"
11
13
  };
12
14
  var ToolbarDropdownMenuContent = function ToolbarDropdownMenuContent(_ref) {
13
15
  var iconBefore = _ref.iconBefore,
@@ -72,6 +74,6 @@ export var ToolbarDropdownMenu = function ToolbarDropdownMenu(_ref2) {
72
74
  testId: testId,
73
75
  label: label
74
76
  }, /*#__PURE__*/React.createElement("div", {
75
- className: ax([hasSectionMargin && styles.sectionMargin])
77
+ className: ax([hasSectionMargin && styles.sectionMargin, expValEquals('platform_editor_toolbar_migrate_loom', 'isEnabled', true) && styles.firstSectionSeparator])
76
78
  }, children)));
77
79
  };
@@ -0,0 +1,2 @@
1
+ /* eslint-disable @atlaskit/editor/no-re-export */
2
+ export { default as LoomIcon } from '@atlaskit/icon/core/video';
@@ -64,6 +64,8 @@ export { TaskIcon } from './ui/icons/TaskIcon';
64
64
  export { UndoIcon } from './ui/icons/UndoIcon';
65
65
  export { RedoIcon } from './ui/icons/RedoIcon';
66
66
  export { HistoryIcon } from './ui/icons/HistoryIcon';
67
+ export { LoomIcon } from './ui/icons/LoomIcon';
67
68
  export { default as ColorPalette } from './ui/ColorPalette';
69
+ export { getContrastingBackgroundColor } from './ui/ColorPalette/utils';
68
70
  export type { IconComponent } from './types';
69
71
  export { useToolbarUI, ToolbarUIProvider, type ToolbarUIContextType } from './hooks/ui-context';
@@ -38,3 +38,23 @@ export declare function getSelectedRowAndColumnFromPalette(palette: PaletteColor
38
38
  * @returns The resolved color value or empty string if not found
39
39
  */
40
40
  export declare const getTokenCSSVariableValue: (variableExpression: string) => string;
41
+ /**
42
+ * Get the best contrasting background color for a given text color
43
+ * Ensures WCAG AA compliance for accessibility
44
+ *
45
+ * @param textColor - The text color to find a contrasting background for (supports HEX, RGB, RGBA etc.)
46
+ * @param useTokens - Whether to return design tokens instead of raw hex values
47
+ * @returns The best contrasting background color (hex value or design token)
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * // Get contrasting color for white text
52
+ * const bgForWhite = getContrastingBackgroundColor('#FFFFFF', false);
53
+ * // Returns: '#42526E' (dark gray)
54
+ *
55
+ * // Get contrasting color for black text with design tokens
56
+ * const bgForBlack = getContrastingBackgroundColor('#000000', true);
57
+ * // Returns: token('elevation.surface', '#FFFFFF')
58
+ * ```
59
+ */
60
+ export declare function getContrastingBackgroundColor(textColor: string): string;
@@ -13,12 +13,15 @@ type ToolbarDropdownItemProps = {
13
13
  elemAfter?: ReactNode;
14
14
  elemBefore?: ReactNode;
15
15
  hasNestedDropdownMenu?: boolean;
16
+ href?: string;
16
17
  isDisabled?: boolean;
17
18
  isSelected?: boolean;
18
19
  onClick?: (e: React.MouseEvent | React.KeyboardEvent) => void;
20
+ rel?: string;
21
+ target?: string;
19
22
  testId?: string;
20
23
  textStyle?: TextStyle;
21
24
  triggerRef?: Ref<HTMLButtonElement>;
22
25
  };
23
- export declare const ToolbarDropdownItem: ({ onClick, elemBefore, elemAfter, isSelected, children, isDisabled, hasNestedDropdownMenu, triggerRef, testId, ariaKeyshortcuts, }: ToolbarDropdownItemProps) => React.JSX.Element;
26
+ export declare const ToolbarDropdownItem: ({ onClick, elemBefore, elemAfter, isSelected, children, isDisabled, hasNestedDropdownMenu, triggerRef, testId, ariaKeyshortcuts, href, target, rel, }: ToolbarDropdownItemProps) => React.JSX.Element;
24
27
  export {};
@@ -0,0 +1 @@
1
+ export { default as LoomIcon } from '@atlaskit/icon/core/video';
@@ -64,6 +64,8 @@ export { TaskIcon } from './ui/icons/TaskIcon';
64
64
  export { UndoIcon } from './ui/icons/UndoIcon';
65
65
  export { RedoIcon } from './ui/icons/RedoIcon';
66
66
  export { HistoryIcon } from './ui/icons/HistoryIcon';
67
+ export { LoomIcon } from './ui/icons/LoomIcon';
67
68
  export { default as ColorPalette } from './ui/ColorPalette';
69
+ export { getContrastingBackgroundColor } from './ui/ColorPalette/utils';
68
70
  export type { IconComponent } from './types';
69
71
  export { useToolbarUI, ToolbarUIProvider, type ToolbarUIContextType } from './hooks/ui-context';
@@ -38,3 +38,23 @@ export declare function getSelectedRowAndColumnFromPalette(palette: PaletteColor
38
38
  * @returns The resolved color value or empty string if not found
39
39
  */
40
40
  export declare const getTokenCSSVariableValue: (variableExpression: string) => string;
41
+ /**
42
+ * Get the best contrasting background color for a given text color
43
+ * Ensures WCAG AA compliance for accessibility
44
+ *
45
+ * @param textColor - The text color to find a contrasting background for (supports HEX, RGB, RGBA etc.)
46
+ * @param useTokens - Whether to return design tokens instead of raw hex values
47
+ * @returns The best contrasting background color (hex value or design token)
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * // Get contrasting color for white text
52
+ * const bgForWhite = getContrastingBackgroundColor('#FFFFFF', false);
53
+ * // Returns: '#42526E' (dark gray)
54
+ *
55
+ * // Get contrasting color for black text with design tokens
56
+ * const bgForBlack = getContrastingBackgroundColor('#000000', true);
57
+ * // Returns: token('elevation.surface', '#FFFFFF')
58
+ * ```
59
+ */
60
+ export declare function getContrastingBackgroundColor(textColor: string): string;
@@ -13,12 +13,15 @@ type ToolbarDropdownItemProps = {
13
13
  elemAfter?: ReactNode;
14
14
  elemBefore?: ReactNode;
15
15
  hasNestedDropdownMenu?: boolean;
16
+ href?: string;
16
17
  isDisabled?: boolean;
17
18
  isSelected?: boolean;
18
19
  onClick?: (e: React.MouseEvent | React.KeyboardEvent) => void;
20
+ rel?: string;
21
+ target?: string;
19
22
  testId?: string;
20
23
  textStyle?: TextStyle;
21
24
  triggerRef?: Ref<HTMLButtonElement>;
22
25
  };
23
- export declare const ToolbarDropdownItem: ({ onClick, elemBefore, elemAfter, isSelected, children, isDisabled, hasNestedDropdownMenu, triggerRef, testId, ariaKeyshortcuts, }: ToolbarDropdownItemProps) => React.JSX.Element;
26
+ export declare const ToolbarDropdownItem: ({ onClick, elemBefore, elemAfter, isSelected, children, isDisabled, hasNestedDropdownMenu, triggerRef, testId, ariaKeyshortcuts, href, target, rel, }: ToolbarDropdownItemProps) => React.JSX.Element;
24
27
  export {};
@@ -0,0 +1 @@
1
+ export { default as LoomIcon } from '@atlaskit/icon/core/video';
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "registry": "https://registry.npmjs.org/"
5
5
  },
6
- "version": "0.3.8",
6
+ "version": "0.5.0",
7
7
  "description": "Common UI for Toolbars across the platform",
8
8
  "atlassian": {
9
9
  "team": "Editor: Jenga",
@@ -20,20 +20,18 @@
20
20
  "*.compiled.css"
21
21
  ],
22
22
  "atlaskit:src": "src/index.ts",
23
- "af:exports": {
24
- ".": "./src/index.ts"
25
- },
26
23
  "dependencies": {
27
24
  "@atlaskit/badge": "^18.1.0",
28
25
  "@atlaskit/button": "^23.4.0",
29
26
  "@atlaskit/css": "^0.12.0",
30
27
  "@atlaskit/dropdown-menu": "^16.3.0",
31
- "@atlaskit/icon": "^28.0.0",
32
- "@atlaskit/icon-lab": "^5.6.0",
28
+ "@atlaskit/icon": "^28.1.0",
29
+ "@atlaskit/icon-lab": "^5.7.0",
33
30
  "@atlaskit/logo": "^19.7.0",
34
31
  "@atlaskit/popup": "^4.3.0",
35
- "@atlaskit/primitives": "^14.11.0",
36
- "@atlaskit/tokens": "^6.0.0",
32
+ "@atlaskit/primitives": "^14.12.0",
33
+ "@atlaskit/tmp-editor-statsig": "^11.9.0",
34
+ "@atlaskit/tokens": "^6.1.0",
37
35
  "@atlaskit/tooltip": "^20.4.0",
38
36
  "@babel/runtime": "^7.0.0",
39
37
  "@compiled/react": "^0.18.3",