@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
package/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # @atlaskit/editor-toolbar
2
2
 
3
+ ## 0.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`bf3ab0c552ba7`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/bf3ab0c552ba7) -
8
+ [ux] ED-29000 Add keyboard navigation to colour palette and minor UI fixes
9
+
10
+ ### Patch Changes
11
+
12
+ - [`4ef462fecb522`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/4ef462fecb522) -
13
+ [ux] [ED-29003] Register loom component as a dropdown menu item in overflow menu
14
+ - Updated dependencies
15
+
16
+ ## 0.4.0
17
+
18
+ ### Minor Changes
19
+
20
+ - [`1eba43a7b680d`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/1eba43a7b680d) -
21
+ [ux] ED-29000 - Address paper cut issues in ColorPalette
22
+
23
+ ### Patch Changes
24
+
25
+ - Updated dependencies
26
+
3
27
  ## 0.3.8
4
28
 
5
29
  ### Patch Changes
package/dist/cjs/index.js CHANGED
@@ -226,6 +226,12 @@ Object.defineProperty(exports, "ListNumberedIcon", {
226
226
  return _ListNumberedIcon.ListNumberedIcon;
227
227
  }
228
228
  });
229
+ Object.defineProperty(exports, "LoomIcon", {
230
+ enumerable: true,
231
+ get: function get() {
232
+ return _LoomIcon.LoomIcon;
233
+ }
234
+ });
229
235
  Object.defineProperty(exports, "MentionIcon", {
230
236
  enumerable: true,
231
237
  get: function get() {
@@ -412,6 +418,12 @@ Object.defineProperty(exports, "UndoIcon", {
412
418
  return _UndoIcon.UndoIcon;
413
419
  }
414
420
  });
421
+ Object.defineProperty(exports, "getContrastingBackgroundColor", {
422
+ enumerable: true,
423
+ get: function get() {
424
+ return _utils.getContrastingBackgroundColor;
425
+ }
426
+ });
415
427
  Object.defineProperty(exports, "useToolbarDropdownMenu", {
416
428
  enumerable: true,
417
429
  get: function get() {
@@ -490,5 +502,7 @@ var _TaskIcon = require("./ui/icons/TaskIcon");
490
502
  var _UndoIcon = require("./ui/icons/UndoIcon");
491
503
  var _RedoIcon = require("./ui/icons/RedoIcon");
492
504
  var _HistoryIcon = require("./ui/icons/HistoryIcon");
505
+ var _LoomIcon = require("./ui/icons/LoomIcon");
493
506
  var _ColorPalette = _interopRequireDefault(require("./ui/ColorPalette"));
507
+ var _utils = require("./ui/ColorPalette/utils");
494
508
  var _uiContext = require("./hooks/ui-context");
@@ -1,7 +1,6 @@
1
1
 
2
2
  ._19itcf40{border:var(--_1wr0y6w)}
3
- ._2rko1hkb{border-radius:var(--ds-border-radius-050,4px)}
4
- ._2rkoiti9{border-radius:var(--ds-border-radius-100,4px)}._189et94y{border-width:1px}
3
+ ._2rko12b0{border-radius:var(--ds-radius-small,4px)}._189et94y{border-width:1px}
5
4
  ._1dqonqa1{border-style:solid}
6
5
  ._1h6d1j28{border-color:transparent}
7
6
  ._19bvidpf{padding-left:0}
@@ -51,7 +51,7 @@ var Color = exports.Color = /*#__PURE__*/(0, _react.memo)(function (_ref) {
51
51
  return /*#__PURE__*/_react.default.createElement(_tooltip.default, {
52
52
  content: label
53
53
  }, /*#__PURE__*/_react.default.createElement("span", {
54
- className: (0, _runtime.ax)(["_2rkoiti9 _1h6d1j28 _1dqonqa1 _189et94y _1e0c1txw _4cvr1h6o _ca0qv77o _u5f3v77o _n3tdv77o _19bvv77o _858umuej _jyzfmuej _4cvxmuej"])
54
+ className: (0, _runtime.ax)(["_2rko12b0 _1h6d1j28 _1dqonqa1 _189et94y _1e0c1txw _4cvr1h6o _ca0qv77o _u5f3v77o _n3tdv77o _19bvv77o _858umuej _jyzfmuej _4cvxmuej"])
55
55
  }, /*#__PURE__*/_react.default.createElement("button", {
56
56
  type: "button",
57
57
  "aria-label": label,
@@ -62,7 +62,7 @@ var Color = exports.Color = /*#__PURE__*/(0, _react.memo)(function (_ref) {
62
62
  onMouseDown: handleMouseDown,
63
63
  tabIndex: tabIndex,
64
64
  autoFocus: autoFocus,
65
- className: (0, _runtime.ax)(["_ca0qidpf _u5f3idpf _n3tdidpf _19bvidpf _2rko1hkb _19itcf40 _4t3icr4y _1bsbcr4y _bfhkm7j4 _80omtlke _1e0c1ule _kqswh2mm _y2mv12j9 _1bg4v77o"]),
65
+ className: (0, _runtime.ax)(["_ca0qidpf _u5f3idpf _n3tdidpf _19bvidpf _2rko12b0 _19itcf40 _4t3icr4y _1bsbcr4y _bfhkm7j4 _80omtlke _1e0c1ule _kqswh2mm _y2mv12j9 _1bg4v77o"]),
66
66
  style: {
67
67
  backgroundColor: colorStyle || "var(--ds-background-input, #FFFFFF)",
68
68
  border: "1px solid ".concat(borderColor),
@@ -70,6 +70,7 @@ var Color = exports.Color = /*#__PURE__*/(0, _react.memo)(function (_ref) {
70
70
  "--_toyvsf": (0, _runtime.ix)("2px solid ".concat("var(--ds-border-focused, #388BFF)"))
71
71
  }
72
72
  }, !decorator && isSelected && /*#__PURE__*/_react.default.createElement(_checkMarkEditorDone.default, {
73
+ color: checkMarkColor,
73
74
  LEGACY_primaryColor: checkMarkColor,
74
75
  label: ""
75
76
  }), decorator)));
@@ -13,6 +13,7 @@ var _react = _interopRequireWildcard(require("react"));
13
13
  var _chromatism = _interopRequireDefault(require("chromatism"));
14
14
  var _reactIntlNext = require("react-intl-next");
15
15
  var _compiled = require("@atlaskit/primitives/compiled");
16
+ var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
16
17
  var _tokens = require("@atlaskit/tokens");
17
18
  var _Color = require("./Color");
18
19
  var _getColorMessage = _interopRequireDefault(require("./getColorMessage"));
@@ -28,7 +29,7 @@ var styles = {
28
29
  *
29
30
  * @param color color string, supports HEX, RGB, RGBA etc.
30
31
  * @param useIconToken boolean, describes if a token should be used for the icon color
31
- * @return Highest contrast color in pool
32
+ * @returns Highest contrast color in pool
32
33
  */
33
34
  function getCheckMarkColor(color, useIconToken) {
34
35
  var tokenVal = (0, _utils.getTokenCSSVariableValue)(color);
@@ -75,15 +76,203 @@ var ColorPalette = function ColorPalette(_ref) {
75
76
  var _useThemeObserver = (0, _tokens.useThemeObserver)(),
76
77
  tokenTheme = _useThemeObserver.colorMode;
77
78
  var useIconToken = !!hexToPaletteColor;
79
+
80
+ // Refs for keyboard navigation
81
+ var paletteRef = (0, _react.useRef)(null);
82
+ var currentFocusRef = (0, _react.useRef)({
83
+ row: 0,
84
+ col: 0
85
+ });
78
86
  var colorsPerRow = (0, _react.useMemo)(function () {
79
87
  return (0, _utils.getColorsPerRowFromPalette)(palette, cols);
80
88
  }, [palette, cols]);
81
- return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, colorsPerRow.map(function (row) {
82
- return /*#__PURE__*/_react.default.createElement(_compiled.Box, {
83
- xcss: styles.paletteWrapper,
89
+
90
+ // Get initial focus position based on selected color
91
+ var _useMemo = (0, _react.useMemo)(function () {
92
+ return (0, _utils.getSelectedRowAndColumnFromPalette)(palette, selectedColor, cols);
93
+ }, [palette, selectedColor, cols]),
94
+ selectedRowIndex = _useMemo.selectedRowIndex,
95
+ selectedColumnIndex = _useMemo.selectedColumnIndex;
96
+
97
+ // Focus management utility
98
+ var focusColorAt = (0, _react.useCallback)(function (row, col) {
99
+ var _rowElement$children$, _rowElement$children$2;
100
+ if (!paletteRef.current) {
101
+ return;
102
+ }
103
+ var rowElement = paletteRef.current.children[row];
104
+ if (!(rowElement instanceof HTMLElement)) {
105
+ return;
106
+ }
107
+ 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');
108
+ var colorButton = colorButtonCandidate instanceof HTMLButtonElement ? colorButtonCandidate : null;
109
+ if (colorButton) {
110
+ colorButton.focus();
111
+ currentFocusRef.current = {
112
+ row: row,
113
+ col: col
114
+ };
115
+ }
116
+ }, []);
117
+
118
+ // Initialize focus position and handle autofocus
119
+ (0, _react.useEffect)(function () {
120
+ if (!(0, _expValEquals.expValEquals)('platform_editor_toolbar_aifc_patch_1', 'isEnabled', true)) {
121
+ return;
122
+ }
123
+ if (selectedRowIndex >= 0 && selectedColumnIndex >= 0) {
124
+ currentFocusRef.current = {
125
+ row: selectedRowIndex,
126
+ col: selectedColumnIndex
127
+ };
128
+ } else {
129
+ currentFocusRef.current = {
130
+ row: 0,
131
+ col: 0
132
+ };
133
+ }
134
+ }, [selectedRowIndex, selectedColumnIndex]);
135
+
136
+ // Keyboard navigation handler
137
+ var handleKeyDown = (0, _react.useCallback)(function (value, label, event) {
138
+ var _colorsPerRow$row;
139
+ var _currentFocusRef$curr = currentFocusRef.current,
140
+ row = _currentFocusRef$curr.row,
141
+ col = _currentFocusRef$curr.col;
142
+ var maxRow = colorsPerRow.length - 1;
143
+ var maxCol = ((_colorsPerRow$row = colorsPerRow[row]) === null || _colorsPerRow$row === void 0 ? void 0 : _colorsPerRow$row.length) - 1 || 0;
144
+ switch (event.key) {
145
+ case 'ArrowRight':
146
+ {
147
+ event.preventDefault();
148
+ if (col < maxCol) {
149
+ focusColorAt(row, col + 1);
150
+ } else if (row < maxRow) {
151
+ // Move to first color of next row
152
+ focusColorAt(row + 1, 0);
153
+ } else {
154
+ // Wrap to first color of first row
155
+ focusColorAt(0, 0);
156
+ }
157
+ break;
158
+ }
159
+ case 'ArrowLeft':
160
+ {
161
+ event.preventDefault();
162
+ if (col > 0) {
163
+ focusColorAt(row, col - 1);
164
+ } else if (row > 0) {
165
+ var _colorsPerRow;
166
+ // Move to last color of previous row
167
+ var prevRowMaxCol = ((_colorsPerRow = colorsPerRow[row - 1]) === null || _colorsPerRow === void 0 ? void 0 : _colorsPerRow.length) - 1 || 0;
168
+ focusColorAt(row - 1, prevRowMaxCol);
169
+ } else {
170
+ var _colorsPerRow$maxRow;
171
+ // Wrap to last color of last row
172
+ var lastRowMaxCol = ((_colorsPerRow$maxRow = colorsPerRow[maxRow]) === null || _colorsPerRow$maxRow === void 0 ? void 0 : _colorsPerRow$maxRow.length) - 1 || 0;
173
+ focusColorAt(maxRow, lastRowMaxCol);
174
+ }
175
+ break;
176
+ }
177
+ case 'ArrowDown':
178
+ {
179
+ event.preventDefault();
180
+ if (row < maxRow) {
181
+ var _colorsPerRow2;
182
+ // Move to same column in next row, or last available column
183
+ var nextRowMaxCol = ((_colorsPerRow2 = colorsPerRow[row + 1]) === null || _colorsPerRow2 === void 0 ? void 0 : _colorsPerRow2.length) - 1 || 0;
184
+ var targetCol = Math.min(col, nextRowMaxCol);
185
+ focusColorAt(row + 1, targetCol);
186
+ } else {
187
+ var _colorsPerRow$;
188
+ // Wrap to same column in first row
189
+ var firstRowMaxCol = ((_colorsPerRow$ = colorsPerRow[0]) === null || _colorsPerRow$ === void 0 ? void 0 : _colorsPerRow$.length) - 1 || 0;
190
+ var _targetCol = Math.min(col, firstRowMaxCol);
191
+ focusColorAt(0, _targetCol);
192
+ }
193
+ break;
194
+ }
195
+ case 'ArrowUp':
196
+ {
197
+ event.preventDefault();
198
+ if (row > 0) {
199
+ var _colorsPerRow3;
200
+ // Move to same column in previous row, or last available column
201
+ var _prevRowMaxCol = ((_colorsPerRow3 = colorsPerRow[row - 1]) === null || _colorsPerRow3 === void 0 ? void 0 : _colorsPerRow3.length) - 1 || 0;
202
+ var _targetCol2 = Math.min(col, _prevRowMaxCol);
203
+ focusColorAt(row - 1, _targetCol2);
204
+ } else {
205
+ var _colorsPerRow$maxRow2;
206
+ // Wrap to same column in last row
207
+ var _lastRowMaxCol = ((_colorsPerRow$maxRow2 = colorsPerRow[maxRow]) === null || _colorsPerRow$maxRow2 === void 0 ? void 0 : _colorsPerRow$maxRow2.length) - 1 || 0;
208
+ var _targetCol3 = Math.min(col, _lastRowMaxCol);
209
+ focusColorAt(maxRow, _targetCol3);
210
+ }
211
+ break;
212
+ }
213
+ case 'Home':
214
+ {
215
+ event.preventDefault();
216
+ focusColorAt(row, 0);
217
+ break;
218
+ }
219
+ case 'End':
220
+ {
221
+ event.preventDefault();
222
+ focusColorAt(row, maxCol);
223
+ break;
224
+ }
225
+ case 'PageUp':
226
+ {
227
+ event.preventDefault();
228
+ focusColorAt(0, col);
229
+ break;
230
+ }
231
+ case 'PageDown':
232
+ {
233
+ var _colorsPerRow$maxRow3;
234
+ event.preventDefault();
235
+ var _lastRowMaxCol2 = ((_colorsPerRow$maxRow3 = colorsPerRow[maxRow]) === null || _colorsPerRow$maxRow3 === void 0 ? void 0 : _colorsPerRow$maxRow3.length) - 1 || 0;
236
+ var _targetCol4 = Math.min(col, _lastRowMaxCol2);
237
+ focusColorAt(maxRow, _targetCol4);
238
+ break;
239
+ }
240
+ case 'Tab':
241
+ {
242
+ // Allow Tab to move to next focusable element (don't prevent default)
243
+ // This will allow Tab to move between color palettes
244
+ if (onKeyDown) {
245
+ onKeyDown(value, label, event);
246
+ }
247
+ break;
248
+ }
249
+ case 'Enter':
250
+ case ' ':
251
+ {
252
+ event.preventDefault();
253
+ onClick(value, label);
254
+ break;
255
+ }
256
+ default:
257
+ {
258
+ // Pass through to custom onKeyDown handler if provided
259
+ if (onKeyDown) {
260
+ onKeyDown(value, label, event);
261
+ }
262
+ break;
263
+ }
264
+ }
265
+ }, [colorsPerRow, focusColorAt, onClick, onKeyDown]);
266
+ return (0, _expValEquals.expValEquals)('platform_editor_toolbar_aifc_patch_1', 'isEnabled', true) ? /*#__PURE__*/_react.default.createElement(_compiled.Grid, {
267
+ gap: "space.050",
268
+ ref: paletteRef,
269
+ role: "group"
270
+ }, colorsPerRow.map(function (row, rowIndex) {
271
+ return /*#__PURE__*/_react.default.createElement(_compiled.Inline, {
272
+ rowSpace: "space.050",
84
273
  key: "row-first-color-".concat(row[0].value),
85
274
  role: "radiogroup"
86
- }, row.map(function (_ref2) {
275
+ }, row.map(function (_ref2, colIndex) {
87
276
  var value = _ref2.value,
88
277
  label = _ref2.label,
89
278
  border = _ref2.border,
@@ -91,6 +280,51 @@ var ColorPalette = function ColorPalette(_ref) {
91
280
  decorator = _ref2.decorator;
92
281
  var tooltipMessage = message;
93
282
 
283
+ // Override with theme-specific tooltip messages if provided
284
+ if (paletteColorTooltipMessages) {
285
+ if (tokenTheme === 'dark') {
286
+ tooltipMessage = (0, _getColorMessage.default)(paletteColorTooltipMessages.dark, value.toUpperCase());
287
+ }
288
+ if (tokenTheme === 'light') {
289
+ tooltipMessage = (0, _getColorMessage.default)(paletteColorTooltipMessages.light, value.toUpperCase());
290
+ }
291
+ }
292
+
293
+ // Determine if this color should be focusable
294
+ var isSelectedColor = value === selectedColor;
295
+ var isFirstColor = rowIndex === 0 && colIndex === 0;
296
+
297
+ // Only the selected color or first color should be focusable via Tab
298
+ // This allows Tab to move between color palettes
299
+ var shouldBeFocusable = isSelectedColor || !selectedColor && isFirstColor;
300
+ return /*#__PURE__*/_react.default.createElement(_Color.Color, {
301
+ key: value,
302
+ value: value,
303
+ borderColor: border,
304
+ label: tooltipMessage ? formatMessage(tooltipMessage) : label,
305
+ onClick: onClick,
306
+ onKeyDown: handleKeyDown,
307
+ isSelected: isSelectedColor,
308
+ checkMarkColor: getCheckMarkColor(value, useIconToken),
309
+ hexToPaletteColor: hexToPaletteColor,
310
+ decorator: decorator,
311
+ tabIndex: shouldBeFocusable ? 0 : -1,
312
+ autoFocus: isSelectedColor && rowIndex === selectedRowIndex && colIndex === selectedColumnIndex
313
+ });
314
+ }));
315
+ })) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, colorsPerRow.map(function (row) {
316
+ return /*#__PURE__*/_react.default.createElement(_compiled.Box, {
317
+ xcss: styles.paletteWrapper,
318
+ key: "row-first-color-".concat(row[0].value),
319
+ role: "radiogroup"
320
+ }, row.map(function (_ref3) {
321
+ var value = _ref3.value,
322
+ label = _ref3.label,
323
+ border = _ref3.border,
324
+ message = _ref3.message,
325
+ decorator = _ref3.decorator;
326
+ var tooltipMessage = message;
327
+
94
328
  // Override with theme-specific tooltip messages if provided
95
329
  if (paletteColorTooltipMessages) {
96
330
  if (tokenTheme === 'dark') {
@@ -1,13 +1,16 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
3
4
  Object.defineProperty(exports, "__esModule", {
4
5
  value: true
5
6
  });
6
7
  exports.DEFAULT_COLOR_PICKER_COLUMNS = void 0;
7
8
  exports.getColorsPerRowFromPalette = getColorsPerRowFromPalette;
9
+ exports.getContrastingBackgroundColor = getContrastingBackgroundColor;
8
10
  exports.getSelectedRowAndColumn = getSelectedRowAndColumn;
9
11
  exports.getSelectedRowAndColumnFromPalette = getSelectedRowAndColumnFromPalette;
10
12
  exports.getTokenCSSVariableValue = void 0;
13
+ var _chromatism = _interopRequireDefault(require("chromatism"));
11
14
  /**
12
15
  * Default number of columns in the color picker
13
16
  */
@@ -91,4 +94,40 @@ var getTokenCSSVariableValue = exports.getTokenCSSVariableValue = function getTo
91
94
  return value || fallback;
92
95
  }
93
96
  return '';
94
- };
97
+ };
98
+
99
+ /**
100
+ * Get the best contrasting background color for a given text color
101
+ * Ensures WCAG AA compliance for accessibility
102
+ *
103
+ * @param textColor - The text color to find a contrasting background for (supports HEX, RGB, RGBA etc.)
104
+ * @param useTokens - Whether to return design tokens instead of raw hex values
105
+ * @returns The best contrasting background color (hex value or design token)
106
+ *
107
+ * @example
108
+ * ```typescript
109
+ * // Get contrasting color for white text
110
+ * const bgForWhite = getContrastingBackgroundColor('#FFFFFF', false);
111
+ * // Returns: '#42526E' (dark gray)
112
+ *
113
+ * // Get contrasting color for black text with design tokens
114
+ * const bgForBlack = getContrastingBackgroundColor('#000000', true);
115
+ * // Returns: token('elevation.surface', '#FFFFFF')
116
+ * ```
117
+ */
118
+ function getContrastingBackgroundColor(textColor) {
119
+ var candidates = ['#FFFFFF',
120
+ // white - surface
121
+ '#172B4D' // dark blue-gray - text color
122
+ ];
123
+
124
+ // Extract actual color value if it's a CSS variable
125
+ var tokenVal = getTokenCSSVariableValue(textColor);
126
+ var colorValue = !!tokenVal ? tokenVal : textColor;
127
+
128
+ // Find the color with the highest contrast ratio
129
+ var bestContrast = candidates.sort(function (a, b) {
130
+ return _chromatism.default.difference(b, colorValue) - _chromatism.default.difference(a, colorValue);
131
+ })[0];
132
+ return bestContrast;
133
+ }
@@ -12,6 +12,7 @@ var _react = _interopRequireWildcard(require("react"));
12
12
  var _css = require("@atlaskit/css");
13
13
  var _dropdownMenu = require("@atlaskit/dropdown-menu");
14
14
  var _compiled = require("@atlaskit/primitives/compiled");
15
+ var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
15
16
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
16
17
  var styles = {
17
18
  toolbarDropdownItem: "_18zrpxbi _1rjcu2gc _1e0c1txw _kqswh2mm _bfhksm61 _1bsb1osq _1tke14no _1ul9163w _1basglpi _1ah31i6y",
@@ -51,7 +52,10 @@ var ToolbarDropdownItem = exports.ToolbarDropdownItem = function ToolbarDropdown
51
52
  hasNestedDropdownMenu = _ref2.hasNestedDropdownMenu,
52
53
  triggerRef = _ref2.triggerRef,
53
54
  testId = _ref2.testId,
54
- ariaKeyshortcuts = _ref2.ariaKeyshortcuts;
55
+ ariaKeyshortcuts = _ref2.ariaKeyshortcuts,
56
+ href = _ref2.href,
57
+ target = _ref2.target,
58
+ rel = _ref2.rel;
55
59
  return /*#__PURE__*/_react.default.createElement(_dropdownMenu.DropdownItem, {
56
60
  onClick: onClick,
57
61
  elemBefore: elemBefore,
@@ -62,7 +66,10 @@ var ToolbarDropdownItem = exports.ToolbarDropdownItem = function ToolbarDropdown
62
66
  "aria-pressed": isSelected,
63
67
  "aria-keyshortcuts": ariaKeyshortcuts,
64
68
  ref: triggerRef,
65
- component: CustomDropdownMenuItemButton,
69
+ href: href,
70
+ target: target,
71
+ rel: rel,
72
+ component: href && (0, _expValEquals.expValEquals)('platform_editor_toolbar_migrate_loom', 'isEnabled', true) ? undefined : CustomDropdownMenuItemButton,
66
73
  testId: testId
67
74
  }, children);
68
75
  };
@@ -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}
@@ -11,12 +11,14 @@ require("./ToolbarDropdownMenu.compiled.css");
11
11
  var _runtime = require("@compiled/react/runtime");
12
12
  var _react = _interopRequireWildcard(require("react"));
13
13
  var _dropdownMenu = _interopRequireDefault(require("@atlaskit/dropdown-menu"));
14
+ var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
14
15
  var _uiContext = require("../hooks/ui-context");
15
16
  var _ToolbarButton = require("./ToolbarButton");
16
17
  var _ToolbarDropdownMenuContext = require("./ToolbarDropdownMenuContext");
17
18
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
18
19
  var styles = {
19
- sectionMargin: "_1mou1b66"
20
+ sectionMargin: "_1mou1b66",
21
+ firstSectionSeparator: "_18l8n7od"
20
22
  };
21
23
  var ToolbarDropdownMenuContent = function ToolbarDropdownMenuContent(_ref) {
22
24
  var iconBefore = _ref.iconBefore,
@@ -81,6 +83,6 @@ var ToolbarDropdownMenu = exports.ToolbarDropdownMenu = function ToolbarDropdown
81
83
  testId: testId,
82
84
  label: label
83
85
  }, /*#__PURE__*/_react.default.createElement("div", {
84
- className: (0, _runtime.ax)([hasSectionMargin && styles.sectionMargin])
86
+ className: (0, _runtime.ax)([hasSectionMargin && styles.sectionMargin, (0, _expValEquals.expValEquals)('platform_editor_toolbar_migrate_loom', 'isEnabled', true) && styles.firstSectionSeparator])
85
87
  }, children)));
86
88
  };
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ Object.defineProperty(exports, "LoomIcon", {
8
+ enumerable: true,
9
+ get: function get() {
10
+ return _video.default;
11
+ }
12
+ });
13
+ var _video = _interopRequireDefault(require("@atlaskit/icon/core/video"));
@@ -65,5 +65,7 @@ export { TaskIcon } from './ui/icons/TaskIcon';
65
65
  export { UndoIcon } from './ui/icons/UndoIcon';
66
66
  export { RedoIcon } from './ui/icons/RedoIcon';
67
67
  export { HistoryIcon } from './ui/icons/HistoryIcon';
68
+ export { LoomIcon } from './ui/icons/LoomIcon';
68
69
  export { default as ColorPalette } from './ui/ColorPalette';
70
+ export { getContrastingBackgroundColor } from './ui/ColorPalette/utils';
69
71
  export { useToolbarUI, ToolbarUIProvider } from './hooks/ui-context';
@@ -1,7 +1,6 @@
1
1
 
2
2
  ._19itv4vr{border:1px solid var(--ds-border-inverse,#fff)}
3
- ._2rko1hkb{border-radius:var(--ds-border-radius-050,4px)}
4
- ._2rkoiti9{border-radius:var(--ds-border-radius-100,4px)}._189et94y{border-width:1px}
3
+ ._2rko12b0{border-radius:var(--ds-radius-small,4px)}._189et94y{border-width:1px}
5
4
  ._1dqonqa1{border-style:solid}
6
5
  ._1h6d1j28{border-color:transparent}
7
6
  ._19bvidpf{padding-left:0}
@@ -42,7 +42,7 @@ export const Color = /*#__PURE__*/memo(({
42
42
  return /*#__PURE__*/React.createElement(Tooltip, {
43
43
  content: label
44
44
  }, /*#__PURE__*/React.createElement("span", {
45
- className: ax(["_2rkoiti9 _1h6d1j28 _1dqonqa1 _189et94y _1e0c1txw _4cvr1h6o _ca0qv77o _u5f3v77o _n3tdv77o _19bvv77o _858umuej _jyzfmuej _4cvxmuej"])
45
+ className: ax(["_2rko12b0 _1h6d1j28 _1dqonqa1 _189et94y _1e0c1txw _4cvr1h6o _ca0qv77o _u5f3v77o _n3tdv77o _19bvv77o _858umuej _jyzfmuej _4cvxmuej"])
46
46
  }, /*#__PURE__*/React.createElement("button", {
47
47
  type: "button",
48
48
  "aria-label": label,
@@ -57,8 +57,9 @@ export const Color = /*#__PURE__*/memo(({
57
57
  border: `1px solid ${borderColor}`
58
58
  },
59
59
  autoFocus: autoFocus,
60
- className: ax(["_ca0qidpf _u5f3idpf _n3tdidpf _19bvidpf _2rko1hkb _19itv4vr _4t3icr4y _1bsbcr4y _bfhkm7j4 _80omtlke _1e0c1ule _kqswh2mm _y2mvugt7 _1bg4v77o"])
60
+ className: ax(["_ca0qidpf _u5f3idpf _n3tdidpf _19bvidpf _2rko12b0 _19itv4vr _4t3icr4y _1bsbcr4y _bfhkm7j4 _80omtlke _1e0c1ule _kqswh2mm _y2mvugt7 _1bg4v77o"])
61
61
  }, !decorator && isSelected && /*#__PURE__*/React.createElement(EditorDoneIcon, {
62
+ color: checkMarkColor,
62
63
  LEGACY_primaryColor: checkMarkColor,
63
64
  label: ""
64
65
  }), decorator)));