@atlaskit/editor-toolbar 0.2.3 → 0.3.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 (56) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/cjs/index.js +15 -0
  3. package/dist/cjs/ui/ColorPalette/Color.compiled.css +25 -0
  4. package/dist/cjs/ui/ColorPalette/Color.js +76 -0
  5. package/dist/cjs/ui/ColorPalette/getColorMessage.js +20 -0
  6. package/dist/cjs/ui/ColorPalette/index.compiled.css +1 -0
  7. package/dist/cjs/ui/ColorPalette/index.js +118 -0
  8. package/dist/cjs/ui/ColorPalette/types.js +5 -0
  9. package/dist/cjs/ui/ColorPalette/utils.js +94 -0
  10. package/dist/cjs/ui/ToolbarDropdownMenu.js +43 -4
  11. package/dist/cjs/ui/ToolbarDropdownMenuContext.js +40 -0
  12. package/dist/es2019/index.js +2 -0
  13. package/dist/es2019/ui/ColorPalette/Color.compiled.css +25 -0
  14. package/dist/es2019/ui/ColorPalette/Color.js +65 -0
  15. package/dist/es2019/ui/ColorPalette/getColorMessage.js +18 -0
  16. package/dist/es2019/ui/ColorPalette/index.compiled.css +1 -0
  17. package/dist/es2019/ui/ColorPalette/index.js +110 -0
  18. package/dist/es2019/ui/ColorPalette/types.js +1 -0
  19. package/dist/es2019/ui/ColorPalette/utils.js +83 -0
  20. package/dist/es2019/ui/ToolbarDropdownMenu.js +43 -4
  21. package/dist/es2019/ui/ToolbarDropdownMenuContext.js +26 -0
  22. package/dist/esm/index.js +2 -0
  23. package/dist/esm/ui/ColorPalette/Color.compiled.css +25 -0
  24. package/dist/esm/ui/ColorPalette/Color.js +67 -0
  25. package/dist/esm/ui/ColorPalette/getColorMessage.js +14 -0
  26. package/dist/esm/ui/ColorPalette/index.compiled.css +1 -0
  27. package/dist/esm/ui/ColorPalette/index.js +109 -0
  28. package/dist/esm/ui/ColorPalette/types.js +1 -0
  29. package/dist/esm/ui/ColorPalette/utils.js +84 -0
  30. package/dist/esm/ui/ToolbarDropdownMenu.js +41 -4
  31. package/dist/esm/ui/ToolbarDropdownMenuContext.js +31 -0
  32. package/dist/types/index.d.ts +2 -0
  33. package/dist/types/ui/ColorPalette/Color.d.ts +11 -0
  34. package/dist/types/ui/ColorPalette/getColorMessage.d.ts +8 -0
  35. package/dist/types/ui/ColorPalette/index.d.ts +15 -0
  36. package/dist/types/ui/ColorPalette/types.d.ts +89 -0
  37. package/dist/types/ui/ColorPalette/utils.d.ts +40 -0
  38. package/dist/types/ui/ToolbarDropdownMenu.d.ts +3 -0
  39. package/dist/types/ui/ToolbarDropdownMenuContext.d.ts +12 -0
  40. package/dist/types-ts4.5/index.d.ts +2 -0
  41. package/dist/types-ts4.5/ui/ColorPalette/Color.d.ts +11 -0
  42. package/dist/types-ts4.5/ui/ColorPalette/getColorMessage.d.ts +8 -0
  43. package/dist/types-ts4.5/ui/ColorPalette/index.d.ts +15 -0
  44. package/dist/types-ts4.5/ui/ColorPalette/types.d.ts +89 -0
  45. package/dist/types-ts4.5/ui/ColorPalette/utils.d.ts +40 -0
  46. package/dist/types-ts4.5/ui/ToolbarDropdownMenu.d.ts +3 -0
  47. package/dist/types-ts4.5/ui/ToolbarDropdownMenuContext.d.ts +12 -0
  48. package/package.json +5 -3
  49. package/src/index.ts +3 -0
  50. package/src/ui/ColorPalette/Color.tsx +110 -0
  51. package/src/ui/ColorPalette/getColorMessage.ts +27 -0
  52. package/src/ui/ColorPalette/index.tsx +125 -0
  53. package/src/ui/ColorPalette/types.ts +96 -0
  54. package/src/ui/ColorPalette/utils.ts +102 -0
  55. package/src/ui/ToolbarDropdownMenu.tsx +51 -5
  56. package/src/ui/ToolbarDropdownMenuContext.tsx +44 -0
@@ -0,0 +1,110 @@
1
+ /* index.tsx generated by @compiled/babel-plugin v0.36.1 */
2
+ import "./index.compiled.css";
3
+ import { ax, ix } from "@compiled/react/runtime";
4
+ import React, { useMemo } from 'react';
5
+ import chromatism from 'chromatism';
6
+ import { useIntl } from 'react-intl-next';
7
+ import { Box } from '@atlaskit/primitives/compiled';
8
+ import { useThemeObserver } from '@atlaskit/tokens';
9
+ import { Color } from './Color';
10
+ import getColorMessage from './getColorMessage';
11
+ import { DEFAULT_COLOR_PICKER_COLUMNS, getColorsPerRowFromPalette, getTokenCSSVariableValue } from './utils';
12
+ const styles = {
13
+ paletteWrapper: "_1e0c1txw"
14
+ };
15
+
16
+ /**
17
+ * For a given color pick the color from a list of colors with
18
+ * the highest contrast
19
+ *
20
+ * @param color color string, supports HEX, RGB, RGBA etc.
21
+ * @param useIconToken boolean, describes if a token should be used for the icon color
22
+ * @return Highest contrast color in pool
23
+ */
24
+ function getCheckMarkColor(color, useIconToken) {
25
+ const tokenVal = getTokenCSSVariableValue(color);
26
+ const colorValue = !!tokenVal ? tokenVal : color;
27
+
28
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage
29
+ const contrastColor = ['#FFFFFF', '#42526E'].sort((a, b) => chromatism.difference(b, colorValue) - chromatism.difference(a, colorValue))[0];
30
+ if (!useIconToken) {
31
+ return contrastColor;
32
+ }
33
+
34
+ // Use of these token comes from guidance from designers in the Design System team
35
+ // they are only intended for use with text colors (and there are different tokens
36
+ // planned to be used when this extended to be used with other palettes).
37
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage
38
+ return contrastColor === '#FFFFFF' ? "var(--ds-icon-inverse, #FFFFFF)" : "var(--ds-icon, #44546F)";
39
+ }
40
+
41
+ /**
42
+ * ColorPalette component for displaying a grid of selectable colors
43
+ *
44
+ * Features:
45
+ * - Responsive grid layout
46
+ * - Keyboard navigation support
47
+ * - Accessibility compliance (ARIA attributes)
48
+ * - Theme-aware tooltips
49
+ * - Design token integration
50
+ * - Customizable color mapping
51
+ */
52
+ const ColorPalette = ({
53
+ cols = DEFAULT_COLOR_PICKER_COLUMNS,
54
+ onClick,
55
+ onKeyDown,
56
+ selectedColor,
57
+ paletteOptions
58
+ }) => {
59
+ const {
60
+ formatMessage
61
+ } = useIntl();
62
+ const {
63
+ palette,
64
+ hexToPaletteColor,
65
+ paletteColorTooltipMessages
66
+ } = paletteOptions;
67
+ const {
68
+ colorMode: tokenTheme
69
+ } = useThemeObserver();
70
+ const useIconToken = !!hexToPaletteColor;
71
+ const colorsPerRow = useMemo(() => {
72
+ return getColorsPerRowFromPalette(palette, cols);
73
+ }, [palette, cols]);
74
+ return /*#__PURE__*/React.createElement(React.Fragment, null, colorsPerRow.map(row => /*#__PURE__*/React.createElement(Box, {
75
+ xcss: styles.paletteWrapper,
76
+ key: `row-first-color-${row[0].value}`,
77
+ role: "radiogroup"
78
+ }, row.map(({
79
+ value,
80
+ label,
81
+ border,
82
+ message,
83
+ decorator
84
+ }) => {
85
+ let tooltipMessage = message;
86
+
87
+ // Override with theme-specific tooltip messages if provided
88
+ if (paletteColorTooltipMessages) {
89
+ if (tokenTheme === 'dark') {
90
+ tooltipMessage = getColorMessage(paletteColorTooltipMessages.dark, value.toUpperCase());
91
+ }
92
+ if (tokenTheme === 'light') {
93
+ tooltipMessage = getColorMessage(paletteColorTooltipMessages.light, value.toUpperCase());
94
+ }
95
+ }
96
+ return /*#__PURE__*/React.createElement(Color, {
97
+ key: value,
98
+ value: value,
99
+ borderColor: border,
100
+ label: tooltipMessage ? formatMessage(tooltipMessage) : label,
101
+ onClick: onClick,
102
+ onKeyDown: onKeyDown,
103
+ isSelected: value === selectedColor,
104
+ checkMarkColor: getCheckMarkColor(value, useIconToken),
105
+ hexToPaletteColor: hexToPaletteColor,
106
+ decorator: decorator
107
+ });
108
+ }))));
109
+ };
110
+ export default ColorPalette;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Default number of columns in the color picker
3
+ */
4
+ export const DEFAULT_COLOR_PICKER_COLUMNS = 7;
5
+
6
+ /**
7
+ * Splits a palette array into rows based on the specified number of columns
8
+ * @param palette - Array of palette colors
9
+ * @param cols - Number of columns per row
10
+ * @returns Array of color rows
11
+ */
12
+ export function getColorsPerRowFromPalette(palette, cols = DEFAULT_COLOR_PICKER_COLUMNS) {
13
+ return palette.reduce((resultArray, item, index) => {
14
+ const chunkIndex = Math.floor(index / cols);
15
+ resultArray[chunkIndex] = resultArray[chunkIndex] || []; // start a new chunk
16
+ resultArray[chunkIndex].push(item);
17
+ return resultArray;
18
+ }, []);
19
+ }
20
+
21
+ /**
22
+ * Finds the row and column indices of a selected color in the palette grid
23
+ * @param colorsPerRow - 2D array of colors organized by rows
24
+ * @param selectedColor - The currently selected color value
25
+ * @returns Object containing row and column indices
26
+ */
27
+ export function getSelectedRowAndColumn(colorsPerRow, selectedColor) {
28
+ let selectedRowIndex = -1;
29
+ let selectedColumnIndex = -1;
30
+ colorsPerRow.forEach((row, rowIndex) => {
31
+ row.forEach(({
32
+ value
33
+ }, columnIndex) => {
34
+ if (value === selectedColor) {
35
+ selectedRowIndex = rowIndex;
36
+ selectedColumnIndex = columnIndex;
37
+ }
38
+ });
39
+ });
40
+ return {
41
+ selectedRowIndex,
42
+ selectedColumnIndex
43
+ };
44
+ }
45
+
46
+ /**
47
+ * Finds the row and column indices of a selected color in a flat palette array
48
+ * @param palette - Flat array of palette colors
49
+ * @param selectedColor - The currently selected color value
50
+ * @param cols - Number of columns per row
51
+ * @returns Object containing row and column indices
52
+ */
53
+ export function getSelectedRowAndColumnFromPalette(palette, selectedColor, cols = DEFAULT_COLOR_PICKER_COLUMNS) {
54
+ const colorsPerRow = getColorsPerRowFromPalette(palette, cols);
55
+ return getSelectedRowAndColumn(colorsPerRow, selectedColor);
56
+ }
57
+
58
+ /**
59
+ * Extracts the actual color value from a CSS variable expression
60
+ * Handles both token variables and fallback values
61
+ * @param variableExpression - CSS variable expression (e.g., "var(--ds-background-accent-blue-subtle, #0052CC)")
62
+ * @returns The resolved color value or empty string if not found
63
+ */
64
+ export const getTokenCSSVariableValue = variableExpression => {
65
+ // Match CSS variable pattern: var(--variable-name, fallback)
66
+ // Ignored via go/ees005
67
+ // eslint-disable-next-line require-unicode-regexp
68
+ const matcher = variableExpression.match(/var\(([^,\)]+)(,.*)?/);
69
+ if (matcher) {
70
+ const variable = matcher[1].trim();
71
+ const fallback = matcher[2] ? matcher[2].replace(',', '').trim() : '';
72
+
73
+ // Return fallback if we're in a server environment
74
+ if (typeof document === 'undefined') {
75
+ return fallback;
76
+ }
77
+
78
+ // Get the computed value from the document
79
+ const value = window.getComputedStyle(document.documentElement).getPropertyValue(variable).trim();
80
+ return value || fallback;
81
+ }
82
+ return '';
83
+ };
@@ -1,8 +1,9 @@
1
- import React from 'react';
1
+ import React, { useCallback } from 'react';
2
2
  import DropdownMenu from '@atlaskit/dropdown-menu';
3
3
  import { useToolbarUI } from '../hooks/ui-context';
4
4
  import { ToolbarButton } from './ToolbarButton';
5
- export const ToolbarDropdownMenu = ({
5
+ import { ToolbarDropdownMenuProvider, useToolbarDropdownMenu } from './ToolbarDropdownMenuContext';
6
+ const ToolbarDropdownMenuContent = ({
6
7
  iconBefore,
7
8
  groupLocation,
8
9
  children,
@@ -13,6 +14,24 @@ export const ToolbarDropdownMenu = ({
13
14
  const {
14
15
  onDropdownOpenChanged
15
16
  } = useToolbarUI();
17
+ const {
18
+ closeMenu,
19
+ isOpen,
20
+ openMenu
21
+ } = useToolbarDropdownMenu();
22
+ const handleOpenChange = useCallback(args => {
23
+ onDropdownOpenChanged(args);
24
+ if (!args.isOpen) {
25
+ closeMenu();
26
+ }
27
+ }, [closeMenu, onDropdownOpenChanged]);
28
+ const handleClick = useCallback(() => {
29
+ if (!isOpen) {
30
+ openMenu();
31
+ } else {
32
+ closeMenu();
33
+ }
34
+ }, [closeMenu, openMenu, isOpen]);
16
35
  return /*#__PURE__*/React.createElement(DropdownMenu, {
17
36
  trigger: triggerProps => /*#__PURE__*/React.createElement(ToolbarButton, {
18
37
  ref: triggerProps.triggerRef,
@@ -21,7 +40,10 @@ export const ToolbarDropdownMenu = ({
21
40
  "aria-haspopup": triggerProps['aria-haspopup'],
22
41
  "aria-controls": triggerProps['aria-controls'],
23
42
  onBlur: triggerProps.onBlur,
24
- onClick: triggerProps.onClick,
43
+ onClick: e => {
44
+ handleClick();
45
+ triggerProps.onClick && triggerProps.onClick(e);
46
+ },
25
47
  onFocus: triggerProps.onFocus,
26
48
  testId: testId,
27
49
  iconBefore: iconBefore,
@@ -29,6 +51,23 @@ export const ToolbarDropdownMenu = ({
29
51
  isDisabled: isDisabled,
30
52
  label: label
31
53
  }),
32
- onOpenChange: onDropdownOpenChanged
54
+ onOpenChange: handleOpenChange,
55
+ isOpen: isOpen
33
56
  }, children);
57
+ };
58
+ export const ToolbarDropdownMenu = ({
59
+ iconBefore,
60
+ groupLocation,
61
+ children,
62
+ isDisabled,
63
+ testId,
64
+ label
65
+ }) => {
66
+ return /*#__PURE__*/React.createElement(ToolbarDropdownMenuProvider, null, /*#__PURE__*/React.createElement(ToolbarDropdownMenuContent, {
67
+ iconBefore: iconBefore,
68
+ groupLocation: groupLocation,
69
+ isDisabled: isDisabled,
70
+ testId: testId,
71
+ label: label
72
+ }, children));
34
73
  };
@@ -0,0 +1,26 @@
1
+ import React, { createContext, useContext, useState } from 'react';
2
+ const ToolbarDropdownMenuContext = /*#__PURE__*/createContext(undefined);
3
+ export const useToolbarDropdownMenu = () => {
4
+ const context = useContext(ToolbarDropdownMenuContext);
5
+ if (!context) {
6
+ throw new Error('useToolbarDropdownMenu must be used within ToolbarDropdownMenuProvider');
7
+ }
8
+ return context;
9
+ };
10
+ export const ToolbarDropdownMenuProvider = ({
11
+ children
12
+ }) => {
13
+ const [isOpen, setIsOpen] = useState(false);
14
+ const openMenu = () => setIsOpen(true);
15
+ const closeMenu = () => {
16
+ setIsOpen(false);
17
+ };
18
+ const contextValue = {
19
+ openMenu,
20
+ closeMenu,
21
+ isOpen
22
+ };
23
+ return /*#__PURE__*/React.createElement(ToolbarDropdownMenuContext.Provider, {
24
+ value: contextValue
25
+ }, children);
26
+ };
package/dist/esm/index.js CHANGED
@@ -11,6 +11,7 @@ export { ToolbarSection } from './ui/ToolbarSection';
11
11
  export { ToolbarTooltip } from './ui/ToolbarTooltip';
12
12
  export { ToolbarDropdownDivider } from './ui/ToolbarDropdownDivider';
13
13
  export { ToolbarColorSwatch } from './ui/ToolbarColorSwatch';
14
+ export { useToolbarDropdownMenu } from './ui/ToolbarDropdownMenuContext';
14
15
  export { AIAdjustLengthIcon } from './ui/icons/AIAdjustLengthIcon';
15
16
  export { AIChatIcon } from './ui/icons/AIChatIcon';
16
17
  export { AIBriefcaseIcon } from './ui/icons/AIProfessionalIcon';
@@ -56,4 +57,5 @@ export { AlignTextCenterIcon } from './ui/icons/AlignTextCenterIcon';
56
57
  export { AlignTextRightIcon } from './ui/icons/AlignTextRightIcon';
57
58
  export { IndentIcon } from './ui/icons/IndentIcon';
58
59
  export { OutdentIcon } from './ui/icons/OutdentIcon';
60
+ export { default as ColorPalette } from './ui/ColorPalette';
59
61
  export { useToolbarUI, ToolbarUIProvider } from './hooks/ui-context';
@@ -0,0 +1,25 @@
1
+
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}
5
+ ._1dqonqa1{border-style:solid}
6
+ ._1h6d1j28{border-color:transparent}
7
+ ._19bvidpf{padding-left:0}
8
+ ._19bvv77o{padding-left:var(--ds-space-025,2px)}
9
+ ._1bsbcr4y{width:var(--ds-space-300,26px)}
10
+ ._1e0c1txw{display:flex}
11
+ ._1e0c1ule{display:block}
12
+ ._4cvr1h6o{align-items:center}
13
+ ._4t3icr4y{height:var(--ds-space-300,26px)}
14
+ ._80omtlke{cursor:pointer}
15
+ ._bfhkm7j4{background-color:var(--ds-background-neutral,#091e420f)}
16
+ ._ca0qidpf{padding-top:0}
17
+ ._ca0qv77o{padding-top:var(--ds-space-025,2px)}
18
+ ._kqswh2mm{position:relative}
19
+ ._n3tdidpf{padding-bottom:0}
20
+ ._n3tdv77o{padding-bottom:var(--ds-space-025,2px)}
21
+ ._u5f3idpf{padding-right:0}
22
+ ._u5f3v77o{padding-right:var(--ds-space-025,2px)}
23
+ ._y2mv12j9:focus{outline:var(--_toyvsf)}
24
+ ._858umuej:focus, ._jyzfmuej:focus-within, ._4cvxmuej:hover{border-color:var(--ds-border,#091e4224)}
25
+ ._1bg4v77o:focus{outline-offset:var(--ds-space-025,2px)}
@@ -0,0 +1,67 @@
1
+ /* Color.tsx generated by @compiled/babel-plugin v0.36.1 */
2
+ import "./Color.compiled.css";
3
+ import { ax, ix } from "@compiled/react/runtime";
4
+ import React, { useCallback, memo } from 'react';
5
+ import EditorDoneIcon from '@atlaskit/icon/core/migration/check-mark--editor-done';
6
+ import Tooltip from '@atlaskit/tooltip';
7
+ var buttonWrapperStyles = null;
8
+ var buttonStyles = null;
9
+
10
+ /**
11
+ * Individual color palette item component
12
+ * Displays a single color swatch with tooltip and selection state
13
+ */
14
+ export var Color = /*#__PURE__*/memo(function (_ref) {
15
+ var autoFocus = _ref.autoFocus,
16
+ tabIndex = _ref.tabIndex,
17
+ value = _ref.value,
18
+ label = _ref.label,
19
+ isSelected = _ref.isSelected,
20
+ borderColor = _ref.borderColor,
21
+ _ref$checkMarkColor = _ref.checkMarkColor,
22
+ checkMarkColor = _ref$checkMarkColor === void 0 ? "var(--ds-icon-inverse, #FFFFFF)" : _ref$checkMarkColor,
23
+ hexToPaletteColor = _ref.hexToPaletteColor,
24
+ decorator = _ref.decorator,
25
+ onClick = _ref.onClick,
26
+ onKeyDown = _ref.onKeyDown;
27
+ var colorStyle = hexToPaletteColor ? hexToPaletteColor(value) : value;
28
+ var handleMouseDown = useCallback(function (e) {
29
+ e.preventDefault();
30
+ }, []);
31
+ var handleClick = useCallback(function (e) {
32
+ e.preventDefault();
33
+ onClick(value, label);
34
+ }, [onClick, value, label]);
35
+ var handleKeyDown = useCallback(function (e) {
36
+ if (!onKeyDown) {
37
+ return;
38
+ }
39
+ e.preventDefault();
40
+ onKeyDown(value, label, e);
41
+ }, [onKeyDown, value, label]);
42
+ return /*#__PURE__*/React.createElement(Tooltip, {
43
+ content: label
44
+ }, /*#__PURE__*/React.createElement("span", {
45
+ className: ax(["_2rkoiti9 _1h6d1j28 _1dqonqa1 _189et94y _1e0c1txw _4cvr1h6o _ca0qv77o _u5f3v77o _n3tdv77o _19bvv77o _858umuej _jyzfmuej _4cvxmuej"])
46
+ }, /*#__PURE__*/React.createElement("button", {
47
+ type: "button",
48
+ "aria-label": label,
49
+ role: "radio",
50
+ "aria-checked": isSelected,
51
+ onClick: handleClick,
52
+ onKeyDown: handleKeyDown,
53
+ onMouseDown: handleMouseDown,
54
+ tabIndex: tabIndex,
55
+ autoFocus: autoFocus,
56
+ className: ax(["_ca0qidpf _u5f3idpf _n3tdidpf _19bvidpf _2rko1hkb _19itcf40 _4t3icr4y _1bsbcr4y _bfhkm7j4 _80omtlke _1e0c1ule _kqswh2mm _y2mv12j9 _1bg4v77o"]),
57
+ style: {
58
+ backgroundColor: colorStyle || "var(--ds-background-input, #FFFFFF)",
59
+ border: "1px solid ".concat(borderColor),
60
+ "--_1wr0y6w": ix("1px solid ".concat("var(--ds-border-inverse, #FFFFFF)")),
61
+ "--_toyvsf": ix("2px solid ".concat("var(--ds-border-focused, #388BFF)"))
62
+ }
63
+ }, !decorator && isSelected && /*#__PURE__*/React.createElement(EditorDoneIcon, {
64
+ LEGACY_primaryColor: checkMarkColor,
65
+ label: ""
66
+ }), decorator)));
67
+ });
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Retrieves the appropriate internationalization message for a given color
3
+ * @param messages - Record of color values to message descriptors
4
+ * @param color - The color value to look up
5
+ * @returns The message descriptor or undefined if not found
6
+ */
7
+ export default function getColorMessage(messages, color) {
8
+ var message = messages[color];
9
+ if (!message) {
10
+ // eslint-disable-next-line no-console
11
+ console.warn("Color palette does not have an internationalization message for color ".concat(color.toUpperCase(), ".\nYou must add a message description to properly translate this color.\nUsing current label as default message.\nThis could have happened when someone changed the 'colorPalette' from 'adf-schema' without updating this file.\n"));
12
+ }
13
+ return message;
14
+ }
@@ -0,0 +1 @@
1
+ ._1e0c1txw{display:flex}
@@ -0,0 +1,109 @@
1
+ /* index.tsx generated by @compiled/babel-plugin v0.36.1 */
2
+ import "./index.compiled.css";
3
+ import { ax, ix } from "@compiled/react/runtime";
4
+ import React, { useMemo } from 'react';
5
+ import chromatism from 'chromatism';
6
+ import { useIntl } from 'react-intl-next';
7
+ import { Box } from '@atlaskit/primitives/compiled';
8
+ import { useThemeObserver } from '@atlaskit/tokens';
9
+ import { Color } from './Color';
10
+ import getColorMessage from './getColorMessage';
11
+ import { DEFAULT_COLOR_PICKER_COLUMNS, getColorsPerRowFromPalette, getTokenCSSVariableValue } from './utils';
12
+ var styles = {
13
+ paletteWrapper: "_1e0c1txw"
14
+ };
15
+
16
+ /**
17
+ * For a given color pick the color from a list of colors with
18
+ * the highest contrast
19
+ *
20
+ * @param color color string, supports HEX, RGB, RGBA etc.
21
+ * @param useIconToken boolean, describes if a token should be used for the icon color
22
+ * @return Highest contrast color in pool
23
+ */
24
+ function getCheckMarkColor(color, useIconToken) {
25
+ var tokenVal = getTokenCSSVariableValue(color);
26
+ var colorValue = !!tokenVal ? tokenVal : color;
27
+
28
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage
29
+ var contrastColor = ['#FFFFFF', '#42526E'].sort(function (a, b) {
30
+ return chromatism.difference(b, colorValue) - chromatism.difference(a, colorValue);
31
+ })[0];
32
+ if (!useIconToken) {
33
+ return contrastColor;
34
+ }
35
+
36
+ // Use of these token comes from guidance from designers in the Design System team
37
+ // they are only intended for use with text colors (and there are different tokens
38
+ // planned to be used when this extended to be used with other palettes).
39
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage
40
+ return contrastColor === '#FFFFFF' ? "var(--ds-icon-inverse, #FFFFFF)" : "var(--ds-icon, #44546F)";
41
+ }
42
+
43
+ /**
44
+ * ColorPalette component for displaying a grid of selectable colors
45
+ *
46
+ * Features:
47
+ * - Responsive grid layout
48
+ * - Keyboard navigation support
49
+ * - Accessibility compliance (ARIA attributes)
50
+ * - Theme-aware tooltips
51
+ * - Design token integration
52
+ * - Customizable color mapping
53
+ */
54
+ var ColorPalette = function ColorPalette(_ref) {
55
+ var _ref$cols = _ref.cols,
56
+ cols = _ref$cols === void 0 ? DEFAULT_COLOR_PICKER_COLUMNS : _ref$cols,
57
+ onClick = _ref.onClick,
58
+ onKeyDown = _ref.onKeyDown,
59
+ selectedColor = _ref.selectedColor,
60
+ paletteOptions = _ref.paletteOptions;
61
+ var _useIntl = useIntl(),
62
+ formatMessage = _useIntl.formatMessage;
63
+ var palette = paletteOptions.palette,
64
+ hexToPaletteColor = paletteOptions.hexToPaletteColor,
65
+ paletteColorTooltipMessages = paletteOptions.paletteColorTooltipMessages;
66
+ var _useThemeObserver = useThemeObserver(),
67
+ tokenTheme = _useThemeObserver.colorMode;
68
+ var useIconToken = !!hexToPaletteColor;
69
+ var colorsPerRow = useMemo(function () {
70
+ return getColorsPerRowFromPalette(palette, cols);
71
+ }, [palette, cols]);
72
+ return /*#__PURE__*/React.createElement(React.Fragment, null, colorsPerRow.map(function (row) {
73
+ return /*#__PURE__*/React.createElement(Box, {
74
+ xcss: styles.paletteWrapper,
75
+ key: "row-first-color-".concat(row[0].value),
76
+ role: "radiogroup"
77
+ }, row.map(function (_ref2) {
78
+ var value = _ref2.value,
79
+ label = _ref2.label,
80
+ border = _ref2.border,
81
+ message = _ref2.message,
82
+ decorator = _ref2.decorator;
83
+ var tooltipMessage = message;
84
+
85
+ // Override with theme-specific tooltip messages if provided
86
+ if (paletteColorTooltipMessages) {
87
+ if (tokenTheme === 'dark') {
88
+ tooltipMessage = getColorMessage(paletteColorTooltipMessages.dark, value.toUpperCase());
89
+ }
90
+ if (tokenTheme === 'light') {
91
+ tooltipMessage = getColorMessage(paletteColorTooltipMessages.light, value.toUpperCase());
92
+ }
93
+ }
94
+ return /*#__PURE__*/React.createElement(Color, {
95
+ key: value,
96
+ value: value,
97
+ borderColor: border,
98
+ label: tooltipMessage ? formatMessage(tooltipMessage) : label,
99
+ onClick: onClick,
100
+ onKeyDown: onKeyDown,
101
+ isSelected: value === selectedColor,
102
+ checkMarkColor: getCheckMarkColor(value, useIconToken),
103
+ hexToPaletteColor: hexToPaletteColor,
104
+ decorator: decorator
105
+ });
106
+ }));
107
+ }));
108
+ };
109
+ export default ColorPalette;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Default number of columns in the color picker
3
+ */
4
+ export var DEFAULT_COLOR_PICKER_COLUMNS = 7;
5
+
6
+ /**
7
+ * Splits a palette array into rows based on the specified number of columns
8
+ * @param palette - Array of palette colors
9
+ * @param cols - Number of columns per row
10
+ * @returns Array of color rows
11
+ */
12
+ export function getColorsPerRowFromPalette(palette) {
13
+ var cols = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_COLOR_PICKER_COLUMNS;
14
+ return palette.reduce(function (resultArray, item, index) {
15
+ var chunkIndex = Math.floor(index / cols);
16
+ resultArray[chunkIndex] = resultArray[chunkIndex] || []; // start a new chunk
17
+ resultArray[chunkIndex].push(item);
18
+ return resultArray;
19
+ }, []);
20
+ }
21
+
22
+ /**
23
+ * Finds the row and column indices of a selected color in the palette grid
24
+ * @param colorsPerRow - 2D array of colors organized by rows
25
+ * @param selectedColor - The currently selected color value
26
+ * @returns Object containing row and column indices
27
+ */
28
+ export function getSelectedRowAndColumn(colorsPerRow, selectedColor) {
29
+ var selectedRowIndex = -1;
30
+ var selectedColumnIndex = -1;
31
+ colorsPerRow.forEach(function (row, rowIndex) {
32
+ row.forEach(function (_ref, columnIndex) {
33
+ var value = _ref.value;
34
+ if (value === selectedColor) {
35
+ selectedRowIndex = rowIndex;
36
+ selectedColumnIndex = columnIndex;
37
+ }
38
+ });
39
+ });
40
+ return {
41
+ selectedRowIndex: selectedRowIndex,
42
+ selectedColumnIndex: selectedColumnIndex
43
+ };
44
+ }
45
+
46
+ /**
47
+ * Finds the row and column indices of a selected color in a flat palette array
48
+ * @param palette - Flat array of palette colors
49
+ * @param selectedColor - The currently selected color value
50
+ * @param cols - Number of columns per row
51
+ * @returns Object containing row and column indices
52
+ */
53
+ export function getSelectedRowAndColumnFromPalette(palette, selectedColor) {
54
+ var cols = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : DEFAULT_COLOR_PICKER_COLUMNS;
55
+ var colorsPerRow = getColorsPerRowFromPalette(palette, cols);
56
+ return getSelectedRowAndColumn(colorsPerRow, selectedColor);
57
+ }
58
+
59
+ /**
60
+ * Extracts the actual color value from a CSS variable expression
61
+ * Handles both token variables and fallback values
62
+ * @param variableExpression - CSS variable expression (e.g., "var(--ds-background-accent-blue-subtle, #0052CC)")
63
+ * @returns The resolved color value or empty string if not found
64
+ */
65
+ export var getTokenCSSVariableValue = function getTokenCSSVariableValue(variableExpression) {
66
+ // Match CSS variable pattern: var(--variable-name, fallback)
67
+ // Ignored via go/ees005
68
+ // eslint-disable-next-line require-unicode-regexp
69
+ var matcher = variableExpression.match(/var\(([^,\)]+)(,.*)?/);
70
+ if (matcher) {
71
+ var variable = matcher[1].trim();
72
+ var fallback = matcher[2] ? matcher[2].replace(',', '').trim() : '';
73
+
74
+ // Return fallback if we're in a server environment
75
+ if (typeof document === 'undefined') {
76
+ return fallback;
77
+ }
78
+
79
+ // Get the computed value from the document
80
+ var value = window.getComputedStyle(document.documentElement).getPropertyValue(variable).trim();
81
+ return value || fallback;
82
+ }
83
+ return '';
84
+ };