@atlaskit/adf-schema 35.11.0 → 35.12.1

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 (44) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cjs/index.js +12 -0
  3. package/dist/cjs/schema/create-schema.js +3 -0
  4. package/dist/cjs/schema/index.js +12 -0
  5. package/dist/cjs/schema/marks/background-color.js +117 -0
  6. package/dist/cjs/schema/marks/index.js +14 -1
  7. package/dist/cjs/schema/marks/text-color.js +3 -3
  8. package/dist/cjs/schema/nodes/mention.js +1 -1
  9. package/dist/cjs/schema/nodes/paragraph.js +1 -1
  10. package/dist/cjs/utils/colors.js +7 -1
  11. package/dist/cjs/utils/editor-palette.js +38 -0
  12. package/dist/es2019/index.js +1 -1
  13. package/dist/es2019/schema/create-schema.js +4 -1
  14. package/dist/es2019/schema/index.js +1 -1
  15. package/dist/es2019/schema/marks/background-color.js +105 -0
  16. package/dist/es2019/schema/marks/index.js +2 -1
  17. package/dist/es2019/schema/marks/text-color.js +2 -2
  18. package/dist/es2019/schema/nodes/mention.js +1 -1
  19. package/dist/es2019/schema/nodes/paragraph.js +1 -1
  20. package/dist/es2019/utils/colors.js +6 -0
  21. package/dist/es2019/utils/editor-palette.js +36 -0
  22. package/dist/esm/index.js +1 -1
  23. package/dist/esm/schema/create-schema.js +4 -1
  24. package/dist/esm/schema/index.js +1 -1
  25. package/dist/esm/schema/marks/background-color.js +111 -0
  26. package/dist/esm/schema/marks/index.js +2 -1
  27. package/dist/esm/schema/marks/text-color.js +2 -2
  28. package/dist/esm/schema/nodes/mention.js +1 -1
  29. package/dist/esm/schema/nodes/paragraph.js +1 -1
  30. package/dist/esm/utils/colors.js +6 -0
  31. package/dist/esm/utils/editor-palette.js +36 -0
  32. package/dist/json-schema/v1/full.json +31 -0
  33. package/dist/json-schema/v1/stage-0.json +31 -0
  34. package/dist/types/index.d.ts +2 -2
  35. package/dist/types/schema/index.d.ts +2 -2
  36. package/dist/types/schema/marks/background-color.d.ts +15 -0
  37. package/dist/types/schema/marks/index.d.ts +2 -0
  38. package/dist/types/schema/marks/text-color.d.ts +3 -0
  39. package/dist/types/schema/nodes/types/inline-content.d.ts +2 -2
  40. package/dist/types/utils/colors.d.ts +6 -0
  41. package/dist/types/utils/editor-palette.d.ts +34 -0
  42. package/json-schema/v1/full.json +31 -0
  43. package/json-schema/v1/stage-0.json +31 -0
  44. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @atlaskit/adf-schema
2
2
 
3
+ ## 35.12.1
4
+
5
+ ### Patch Changes
6
+
7
+ - aea8879: NO-ISSUE Fixed a serialisation bug resulting in invalid ADF JSON in mention nodes
8
+
9
+ ## 35.12.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 24014bb: [ED-23064] Added the background color mark
14
+
3
15
  ## 35.11.0
4
16
 
5
17
  ### Minor Changes
package/dist/cjs/index.js CHANGED
@@ -321,6 +321,18 @@ Object.defineProperty(exports, "annotation", {
321
321
  return _schema.annotation;
322
322
  }
323
323
  });
324
+ Object.defineProperty(exports, "backgroundColor", {
325
+ enumerable: true,
326
+ get: function get() {
327
+ return _schema.backgroundColor;
328
+ }
329
+ });
330
+ Object.defineProperty(exports, "backgroundColorPalette", {
331
+ enumerable: true,
332
+ get: function get() {
333
+ return _schema.backgroundColorPalette;
334
+ }
335
+ });
324
336
  Object.defineProperty(exports, "blockCard", {
325
337
  enumerable: true,
326
338
  get: function get() {
@@ -263,6 +263,9 @@ var marksInOrder = [{
263
263
  }, {
264
264
  name: 'border',
265
265
  spec: _marks.border
266
+ }, {
267
+ name: 'backgroundColor',
268
+ spec: _marks.backgroundColor
266
269
  }, {
267
270
  name: 'unsupportedMark',
268
271
  spec: _marks.unsupportedMark
@@ -39,6 +39,18 @@ Object.defineProperty(exports, "annotation", {
39
39
  return _marks.annotation;
40
40
  }
41
41
  });
42
+ Object.defineProperty(exports, "backgroundColor", {
43
+ enumerable: true,
44
+ get: function get() {
45
+ return _marks.backgroundColor;
46
+ }
47
+ });
48
+ Object.defineProperty(exports, "backgroundColorPalette", {
49
+ enumerable: true,
50
+ get: function get() {
51
+ return _marks.backgroundColorPalette;
52
+ }
53
+ });
42
54
  Object.defineProperty(exports, "blockCard", {
43
55
  enumerable: true,
44
56
  get: function get() {
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.backgroundColorPalette = exports.backgroundColor = void 0;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
10
+ var _editorPalette = require("../../utils/editor-palette");
11
+ var _groups = require("../groups");
12
+ var _colors = require("../../utils/colors");
13
+ var _textColor = require("./text-color");
14
+ var _lchColorInversion = require("../../utils/lch-color-inversion");
15
+ /**
16
+ * @name backgroundColor_mark
17
+ */
18
+
19
+ var colorArrayPalette = [[_colors.Neutral300, 'Gray'],
20
+ // token: color.background.accent.gray.subtler
21
+ [_colors.T200, 'Teal'],
22
+ // token: color.background.accent.teal.subtler
23
+ [_colors.L200, 'Lime'],
24
+ // token: color.background.accent.lime.subtler
25
+ [_colors.O200, 'Orange'],
26
+ // token: color.background.accent.orange.subtler
27
+ [_colors.M200, 'Magenta'],
28
+ // token: color.background.accent.magenta.subtler
29
+ [_colors.P200, 'Purple'] // token: color.background.accent.purple.subtler
30
+ ];
31
+
32
+ // @see https://product-fabric.atlassian.net/wiki/spaces/E/pages/55979455/Colour+picker+decisions#Colourpickerdecisions-Visualdesigndecisions
33
+ var backgroundColorPalette = exports.backgroundColorPalette = new Map();
34
+ colorArrayPalette.forEach(function (_ref) {
35
+ var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
36
+ color = _ref2[0],
37
+ label = _ref2[1];
38
+ return backgroundColorPalette.set(color.toLowerCase(), label);
39
+ });
40
+ var backgroundColor = exports.backgroundColor = {
41
+ attrs: {
42
+ color: {}
43
+ },
44
+ inclusive: true,
45
+ group: _groups.COLOR,
46
+ parseDOM: [{
47
+ style: 'background-color',
48
+ getAttrs: function getAttrs(maybeValue) {
49
+ var value = maybeValue;
50
+ var hexColor;
51
+ if (value.match(/^rgb/i)) {
52
+ hexColor = (0, _colors.rgbToHex)(value);
53
+ } else if (value[0] === '#') {
54
+ hexColor = value.toLowerCase();
55
+ }
56
+ // else handle other colour formats
57
+ return hexColor && backgroundColorPalette.has(hexColor) ? {
58
+ color: hexColor
59
+ } : false;
60
+ }
61
+ },
62
+ // This rule ensures when loading from a renderer or editor where the
63
+ // presented text color does not match the stored hex color -- that the
64
+ // text color is preserved.
65
+ //
66
+ // This is used to support the work-around that converts the hex color to
67
+ // a design system token to enable light / dark mode (through a CSS variable --custom-palette-color)
68
+ {
69
+ tag: '.fabric-background-color-mark',
70
+ getAttrs: function getAttrs(maybeElement) {
71
+ if (!(maybeElement instanceof HTMLElement)) {
72
+ return false;
73
+ }
74
+ var hexColor = maybeElement.dataset.backgroundCustomColor;
75
+ return hexColor && backgroundColorPalette.has(hexColor) ? {
76
+ color: hexColor
77
+ } : false;
78
+ }
79
+ }],
80
+ toDOM: function toDOM(mark) {
81
+ var paletteColorValue;
82
+ /**
83
+ * Documents can contain custom colors when content has been migrated from the old editor, or created via APIs.
84
+ *
85
+ * This behaviour predates the introduction of dark mode.
86
+ *
87
+ * Without the inversion logic below, text with custom colors, can be hard to read when the user loads the page in dark mode.
88
+ *
89
+ * This introduces inversion of the presentation of the custom text colors when the user is in dark mode.
90
+ *
91
+ * This can be done without additional changes to account for users copying and pasting content inside the Editor, because of
92
+ * how we detect text colors copied from external editor sources. Where we load the background color from a
93
+ * separate attribute (data-text-custom-color), instead of the inline style.
94
+ *
95
+ * See the following document for more details on this behaviour
96
+ * https://hello.atlassian.net/wiki/spaces/CCECO/pages/2908658046/Unsupported+custom+text+colors+in+dark+theme+Editor+Job+Story
97
+ */
98
+ var tokenColor = (0, _editorPalette.hexToEditorTextBackgroundPaletteColor)(mark.attrs.color);
99
+ if (tokenColor) {
100
+ paletteColorValue = tokenColor;
101
+ } else {
102
+ if ((0, _textColor.getGlobalTheme)().colorMode === 'dark') {
103
+ // if we have a custom color, we need to check if we are in dark mode
104
+ paletteColorValue = (0, _lchColorInversion.getDarkModeLCHColor)(mark.attrs.color);
105
+ } else {
106
+ // if we are in light mode, we can just set the color
107
+ paletteColorValue = mark.attrs.color;
108
+ }
109
+ }
110
+ return ['span', (0, _defineProperty2.default)({
111
+ class: 'fabric-background-color-mark',
112
+ // Editor common has a common style which uses this css variable as the value for
113
+ // the color property using the `fabric-text-background-color-mark` selector applied above.
114
+ style: "--custom-palette-color: ".concat(paletteColorValue)
115
+ }, 'data-background-custom-color', mark.attrs.color)];
116
+ }
117
+ };
@@ -33,6 +33,18 @@ Object.defineProperty(exports, "annotation", {
33
33
  return _annotation.annotation;
34
34
  }
35
35
  });
36
+ Object.defineProperty(exports, "backgroundColor", {
37
+ enumerable: true,
38
+ get: function get() {
39
+ return _backgroundColor.backgroundColor;
40
+ }
41
+ });
42
+ Object.defineProperty(exports, "backgroundColorPalette", {
43
+ enumerable: true,
44
+ get: function get() {
45
+ return _backgroundColor.backgroundColorPalette;
46
+ }
47
+ });
36
48
  Object.defineProperty(exports, "border", {
37
49
  enumerable: true,
38
50
  get: function get() {
@@ -195,4 +207,5 @@ var _unsupportedMark = require("./unsupported-mark");
195
207
  var _unsupportedNodeAttributes = require("./unsupported-node-attributes");
196
208
  var _dataConsumer = require("./data-consumer");
197
209
  var _fragment = require("./fragment");
198
- var _border = require("./border");
210
+ var _border = require("./border");
211
+ var _backgroundColor = require("./background-color");
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.textColor = exports.setGlobalTheme = exports.colorPaletteExtended = exports.colorPalette = void 0;
7
+ exports.textColor = exports.setGlobalTheme = exports.getGlobalTheme = exports.colorPaletteExtended = exports.colorPalette = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
9
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
10
10
  var _editorPalette = require("../../utils/editor-palette");
@@ -79,7 +79,7 @@ var setGlobalTheme = exports.setGlobalTheme = function setGlobalTheme(theme) {
79
79
  // This is a minimal duplication of the method from @atlaskit/tokens
80
80
  // to minimise the number of dependencies required as these changes are expected
81
81
  // to be patched onto CR8.
82
- var getGlobalTheme = function getGlobalTheme() {
82
+ var getGlobalTheme = exports.getGlobalTheme = function getGlobalTheme() {
83
83
  // This should only be hit during tests.
84
84
  //
85
85
  // At time of writing Jest mocks are not working in this repository.
@@ -161,7 +161,7 @@ var textColor = exports.textColor = {
161
161
  */
162
162
  var tokenColor = (0, _editorPalette.hexToEditorTextPaletteColor)(mark.attrs.color);
163
163
  if (tokenColor) {
164
- paletteColorValue = (0, _editorPalette.hexToEditorTextPaletteColor)(mark.attrs.color) || mark.attrs.color;
164
+ paletteColorValue = tokenColor;
165
165
  } else {
166
166
  if (getGlobalTheme().colorMode === 'dark') {
167
167
  // if we have a custom color, we need to check if we are in dark mode
@@ -77,7 +77,7 @@ var mention = exports.mention = {
77
77
  }
78
78
  };
79
79
  var isOptional = function isOptional(key) {
80
- return ['userType'].indexOf(key) > -1;
80
+ return ['userType', 'localId'].indexOf(key) > -1;
81
81
  };
82
82
  var toJSON = exports.toJSON = function toJSON(node) {
83
83
  return {
@@ -34,7 +34,7 @@ var paragraph = exports.paragraph = {
34
34
  selectable: false,
35
35
  content: 'inline*',
36
36
  group: 'block',
37
- marks: 'strong code em link border strike subsup textColor typeAheadQuery underline confluenceInlineComment action annotation unsupportedMark unsupportedNodeAttribute dataConsumer fragment',
37
+ marks: 'strong code em link border strike subsup textColor typeAheadQuery underline confluenceInlineComment action annotation unsupportedMark unsupportedNodeAttribute dataConsumer fragment backgroundColor',
38
38
  parseDOM: [{
39
39
  tag: 'p'
40
40
  }],
@@ -5,7 +5,7 @@ var _typeof = require("@babel/runtime/helpers/typeof");
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.Y75 = exports.Y500 = exports.Y50 = exports.Y400 = exports.Y200 = exports.T75 = exports.T500 = exports.T50 = exports.T300 = exports.T100 = exports.R75 = exports.R500 = exports.R50 = exports.R400 = exports.R300 = exports.R100 = exports.P75 = exports.P500 = exports.P50 = exports.P400 = exports.P300 = exports.P100 = exports.N90 = exports.N800 = exports.N80 = exports.N600 = exports.N60 = exports.N500 = exports.N50 = exports.N40 = exports.N300A = exports.N300 = exports.N30 = exports.N200 = exports.N20 = exports.N1000 = exports.N0 = exports.G75 = exports.G500 = exports.G50 = exports.G400 = exports.G300 = exports.G200 = exports.B75 = exports.B500 = exports.B50 = exports.B400 = exports.B100 = void 0;
8
+ exports.Y75 = exports.Y500 = exports.Y50 = exports.Y400 = exports.Y200 = exports.T75 = exports.T500 = exports.T50 = exports.T300 = exports.T200 = exports.T100 = exports.R75 = exports.R500 = exports.R50 = exports.R400 = exports.R300 = exports.R100 = exports.P75 = exports.P500 = exports.P50 = exports.P400 = exports.P300 = exports.P200 = exports.P100 = exports.O200 = exports.Neutral300 = exports.N90 = exports.N800 = exports.N80 = exports.N600 = exports.N60 = exports.N500 = exports.N50 = exports.N40 = exports.N300A = exports.N300 = exports.N30 = exports.N200 = exports.N20 = exports.N1000 = exports.N0 = exports.M200 = exports.L200 = exports.G75 = exports.G500 = exports.G50 = exports.G400 = exports.G300 = exports.G200 = exports.B75 = exports.B500 = exports.B50 = exports.B400 = exports.B100 = void 0;
9
9
  exports.hexToRgb = hexToRgb;
10
10
  exports.hexToRgba = hexToRgba;
11
11
  exports.isHex = isHex;
@@ -45,6 +45,7 @@ var B75 = exports.B75 = '#B3D4FF';
45
45
  var B100 = exports.B100 = '#4C9AFF';
46
46
  var B400 = exports.B400 = '#0052CC';
47
47
  var B500 = exports.B500 = '#0747A6';
48
+ var L200 = exports.L200 = '#D3F1A7';
48
49
  var N0 = exports.N0 = '#FFFFFF';
49
50
  var N20 = exports.N20 = '#F4F5F7';
50
51
  var N30 = exports.N30 = '#EBECF0';
@@ -55,20 +56,25 @@ var N80 = exports.N80 = '#97A0AF';
55
56
  var N90 = exports.N90 = '#8993A4';
56
57
  var N200 = exports.N200 = '#6B778C';
57
58
  var N300 = exports.N300 = '#5E6C84';
59
+ var Neutral300 = exports.Neutral300 = '#DCDFE4';
58
60
  var N300A = exports.N300A = '#091E4224';
59
61
  var N500 = exports.N500 = '#42526E';
60
62
  var N600 = exports.N600 = '#758195';
61
63
  var N800 = exports.N800 = '#172B4D';
62
64
  var N1000 = exports.N1000 = '#172B4D';
65
+ var M200 = exports.M200 = '#FDD0EC';
66
+ var O200 = exports.O200 = '#FEDEC8';
63
67
  var P50 = exports.P50 = '#EAE6FF';
64
68
  var P75 = exports.P75 = '#C0B6F2';
65
69
  var P100 = exports.P100 = '#998DD9';
70
+ var P200 = exports.P200 = '#DFD8FD';
66
71
  var P300 = exports.P300 = '#6554C0';
67
72
  var P400 = exports.P400 = '#5243AA';
68
73
  var P500 = exports.P500 = '#403294';
69
74
  var T50 = exports.T50 = '#E6FCFF';
70
75
  var T75 = exports.T75 = '#B3F5FF';
71
76
  var T100 = exports.T100 = '#79E2F2';
77
+ var T200 = exports.T200 = '#C6EDFB';
72
78
  var T300 = exports.T300 = '#00B8D9';
73
79
  var T500 = exports.T500 = '#008DA6';
74
80
 
@@ -6,7 +6,9 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.editorTextPalette = exports.editorBorderPalette = exports.editorBackgroundPalette = void 0;
7
7
  exports.hexToEditorBackgroundPaletteRawValue = hexToEditorBackgroundPaletteRawValue;
8
8
  exports.hexToEditorBorderPaletteColor = hexToEditorBorderPaletteColor;
9
+ exports.hexToEditorTextBackgroundPaletteColor = hexToEditorTextBackgroundPaletteColor;
9
10
  exports.hexToEditorTextPaletteColor = hexToEditorTextPaletteColor;
11
+ exports.textBackgroundColorPalette = void 0;
10
12
  /**
11
13
  * This takes an adf hex color and returns a matching border palette color.
12
14
  *
@@ -105,6 +107,42 @@ var editorTextPalette = exports.editorTextPalette = {
105
107
  '#172B4D': 'var(--ds-text, #172B4D)'
106
108
  };
107
109
 
110
+ /**
111
+ * This takes an ADF hex color and returns a matching text background palette color.
112
+ *
113
+ * By providing a design token, this enables ADF content to be rendered in new themes such as dark mode.
114
+ *
115
+ * Example usage
116
+ * ```tsx
117
+ * const cssValue = hexToEditorTextBackgroundPaletteColor('#0747A6');
118
+ * // ^? const cssValue: string
119
+ * <span style={{backgroundColor: cssValue}} />
120
+ * ```
121
+ * The names of tokens can change over time, and the values of tokens will differ between themes.
122
+ * The exact output of this function is an implementation detail and should only be used when rendering
123
+ * content to the user, on a client with a matching major version of `@atlaskit/tokens`.
124
+ * - **DO NOT**: store the output of these functions in any user-generated content or back-end.
125
+ * - **DO**: store the ADF hex color, and use these utilities at render time to display the themed version of the color
126
+ */
127
+ function hexToEditorTextBackgroundPaletteColor(hexColor) {
128
+ // Ts ignore was used to allow use of conditional return type
129
+ // (preferring better type on consumption over safety in implementation)
130
+ return textBackgroundColorPalette[hexColor.toUpperCase()];
131
+ }
132
+ var textBackgroundColorPalette = exports.textBackgroundColorPalette = {
133
+ /** Gray - light */
134
+ '#DCDFE4': 'var(--ds-background-accent-gray-subtler, #DCDFE4)',
135
+ /** Teal - light */
136
+ '#C6EDFB': 'var(--ds-background-accent-teal-subtler, #C6EDFB)',
137
+ /** Lime - light */
138
+ '#D3F1A7': 'var(--ds-background-accent-lime-subtler, #D3F1A7)',
139
+ /** Orange - light */
140
+ '#FEDEC8': 'var(--ds-background-accent-orange-subtler, #FEDEC8)',
141
+ /** Magenta - light */
142
+ '#FDD0EC': 'var(--ds-background-accent-magenta-subtler, #FDD0EC)',
143
+ /** Purple - light */
144
+ '#DFD8FD': 'var(--ds-background-accent-purple-subtler, #DFD8FD)'
145
+ };
108
146
  /**
109
147
  * Takes an ADF hex color and returns the rendered hex code for the associated background palette design token using getTokenValue.
110
148
  * If the provided color does not exist in the Editor color palette, this function returns undefined.
@@ -1,3 +1,3 @@
1
1
  export { PanelType, AnnotationTypes, alignment, alignmentPositionMap, annotation, blockCard, blockquote, blockquoteWithList, bodiedExtension, breakout, bulletList, bulletListSelector, caption, code, codeBlock, codeBlockToJSON, colorPalette, /** @deprecated [ED-15849] The extended palette is now rolled into the main one. Use `colorPalette` instead. */
2
- colorPaletteExtended, confluenceInlineComment, confluenceJiraIssue, confluenceUnsupportedBlock, confluenceUnsupportedInline, copyPrivateMediaAttributes, createSchema, dataConsumer, dataConsumerToJSON, date, decisionItem, decisionList, decisionListSelector, doc, em, embedCard, emoji, expand, expandToJSON, extension, fragment, fragmentToJSON, hardBreak, heading, image, indentation, inlineCard, inlineExtension, inlineNodes, layoutColumn, layoutSection, link, linkToJSON, listItem, listItemWithTask, media, mediaGroup, mediaSingle, mediaSingleWithCaption, mediaSingleWithWidthType, mediaSingleFull, mediaSingleSpec, mediaInline, mediaSingleToJSON, mediaToJSON, mention, mentionToJSON, nestedExpand, extendedNestedExpand, orderedList, orderedListSelector, orderedListWithOrder, panel, extendedPanel, paragraph, placeholder, rule, sanitizeNodes, getCellAttrs, getCellDomAttrs, status, strike, strong, subsup, table, tableStage0, tableWithCustomWidth, tableBackgroundBorderColor, tableBackgroundColorNames, tableBackgroundColorPalette, tableCell, tableCellContentDomSelector, tableCellContentWrapperSelector, tableCellSelector, tableHeader, tableHeaderSelector, tablePrefixSelector, tableRow, tableToJSON, taskItem, taskList, taskListSelector, text, textColor, toJSONTableCell, toJSONTableHeader, typeAheadQuery, underline, unknownBlock, unsupportedBlock, unsupportedInline, unsupportedNodeTypesForMediaCards, buildAnnotationMarkDataAttributes, AnnotationMarkStates, unsupportedMark, unsupportedNodeAttribute, border, borderColorPalette, extensionFrame, multiBodiedExtension } from './schema';
2
+ colorPaletteExtended, confluenceInlineComment, confluenceJiraIssue, confluenceUnsupportedBlock, confluenceUnsupportedInline, copyPrivateMediaAttributes, createSchema, dataConsumer, dataConsumerToJSON, date, decisionItem, decisionList, decisionListSelector, doc, em, embedCard, emoji, expand, expandToJSON, extension, fragment, fragmentToJSON, hardBreak, heading, image, indentation, inlineCard, inlineExtension, inlineNodes, layoutColumn, layoutSection, link, linkToJSON, listItem, listItemWithTask, media, mediaGroup, mediaSingle, mediaSingleWithCaption, mediaSingleWithWidthType, mediaSingleFull, mediaSingleSpec, mediaInline, mediaSingleToJSON, mediaToJSON, mention, mentionToJSON, nestedExpand, extendedNestedExpand, orderedList, orderedListSelector, orderedListWithOrder, panel, extendedPanel, paragraph, placeholder, rule, sanitizeNodes, getCellAttrs, getCellDomAttrs, status, strike, strong, subsup, table, tableStage0, tableWithCustomWidth, tableBackgroundBorderColor, tableBackgroundColorNames, tableBackgroundColorPalette, tableCell, tableCellContentDomSelector, tableCellContentWrapperSelector, tableCellSelector, tableHeader, tableHeaderSelector, tablePrefixSelector, tableRow, tableToJSON, taskItem, taskList, taskListSelector, text, textColor, toJSONTableCell, toJSONTableHeader, typeAheadQuery, underline, unknownBlock, unsupportedBlock, unsupportedInline, unsupportedNodeTypesForMediaCards, buildAnnotationMarkDataAttributes, AnnotationMarkStates, unsupportedMark, unsupportedNodeAttribute, border, borderColorPalette, extensionFrame, multiBodiedExtension, backgroundColor, backgroundColorPalette } from './schema';
3
3
  export { B100, B400, B50, B500, B75, G200, G300, G400, G50, G500, G75, N0, N20, N200, N30, N300, N40, N50, N500, N60, N80, N800, N90, P100, P300, P400, P50, P500, P75, R100, R300, R400, R50, R500, R75, T100, T300, T50, T500, T75, Y200, Y400, Y50, Y500, Y75, acNameToEmoji, acShortcutToEmoji, emojiIdToAcName, generateUuid, getEmojiAcName, getLinkMatch, hexToRgb, hexToRgba, isHex, isRgb, isSafeUrl, linkify, linkifyMatch, normalizeHexColor, normalizeUrl, rgbToHex, uuid, getDarkModeLCHColor } from './utils';
@@ -1,6 +1,6 @@
1
1
  import { Schema } from '@atlaskit/editor-prosemirror/model';
2
2
  import { COLOR, FONT_STYLE, SEARCH_QUERY, LINK } from './groups';
3
- import { link, em, strong, textColor, strike, subsup, underline, code, typeAheadQuery, confluenceInlineComment, breakout, alignment, indentation, annotation, unsupportedMark, unsupportedNodeAttribute, dataConsumer, fragment, border } from './marks';
3
+ import { link, em, strong, textColor, strike, subsup, underline, code, typeAheadQuery, confluenceInlineComment, breakout, alignment, indentation, annotation, unsupportedMark, unsupportedNodeAttribute, dataConsumer, fragment, border, backgroundColor } from './marks';
4
4
  import { confluenceJiraIssue, confluenceUnsupportedBlock, confluenceUnsupportedInline, doc, paragraph, text, bulletList, orderedListWithOrder, listItemWithTask, heading, blockquoteWithList, codeBlock, extendedPanel, rule, image, mention, media, mediaInline, mediaSingleFull, mediaGroup, hardBreak, emoji, table, tableCell, tableHeader, tableRow, decisionList, decisionItem, taskList, taskItem, unknownBlock, extension, inlineExtension, bodiedExtension, multiBodiedExtension, extensionFrame, date, placeholder, layoutSection, layoutColumn, inlineCard, blockCard, unsupportedBlock, unsupportedInline, status, expand, extendedNestedExpand, embedCard, caption } from './nodes';
5
5
  function addItems(builtInItems, config, customSpecs = {}) {
6
6
  if (!config) {
@@ -248,6 +248,9 @@ const marksInOrder = [{
248
248
  }, {
249
249
  name: 'border',
250
250
  spec: border
251
+ }, {
252
+ name: 'backgroundColor',
253
+ spec: backgroundColor
251
254
  }, {
252
255
  name: 'unsupportedMark',
253
256
  spec: unsupportedMark
@@ -1,6 +1,6 @@
1
1
  export { PanelType, blockCard, blockquote, blockquoteWithList, bodiedExtension, bulletList, bulletListSelector, caption, codeBlock, codeBlockToJSON, confluenceJiraIssue, confluenceUnsupportedBlock, confluenceUnsupportedInline, copyPrivateMediaAttributes, date, decisionItem, decisionList, decisionListSelector, doc, embedCard, emoji, expand, expandToJSON, extension, hardBreak, heading, image, inlineCard, inlineExtension, layoutColumn, layoutSection, layoutSectionWithSingleColumn, listItem, listItemWithTask, media, mediaGroup, mediaSingle, mediaSingleSpec, mediaInline, mediaSingleWithCaption, mediaSingleWithWidthType, mediaSingleFull, mediaSingleToJSON, mediaToJSON, mention, mentionToJSON, nestedExpand, extendedNestedExpand, orderedList, orderedListSelector, orderedListWithOrder, panel, extendedPanel, paragraph, placeholder, rule, getCellAttrs, getCellDomAttrs, status, table, tableStage0, tableWithCustomWidth, tableBackgroundBorderColor, tableBackgroundColorNames, tableBackgroundColorPalette, tableCell, tableCellContentDomSelector, tableCellContentWrapperSelector, tableCellSelector, tableHeader, tableHeaderSelector, tablePrefixSelector, tableRow, tableToJSON, taskItem, taskList, taskListSelector, text, toJSONTableCell, toJSONTableHeader, unknownBlock, unsupportedBlock, unsupportedInline, extensionFrame, multiBodiedExtension } from './nodes';
2
2
  export { AnnotationTypes, alignment, alignmentPositionMap, annotation, breakout, code, colorPalette, /** @deprecated [ED-15849] The extended palette is now rolled into the main one. Use `colorPalette` instead. */
3
- colorPaletteExtended, confluenceInlineComment, dataConsumer, dataConsumerToJSON, em, fragment, fragmentToJSON, indentation, link, linkToJSON, strike, strong, subsup, textColor, typeAheadQuery, underline, buildAnnotationMarkDataAttributes, AnnotationMarkStates, unsupportedMark, unsupportedNodeAttribute, border, borderColorPalette } from './marks';
3
+ colorPaletteExtended, confluenceInlineComment, dataConsumer, dataConsumerToJSON, em, fragment, fragmentToJSON, indentation, link, linkToJSON, strike, strong, subsup, textColor, typeAheadQuery, underline, buildAnnotationMarkDataAttributes, AnnotationMarkStates, unsupportedMark, unsupportedNodeAttribute, border, borderColorPalette, backgroundColor, backgroundColorPalette } from './marks';
4
4
  export { unsupportedNodeTypesForMediaCards } from './unsupported';
5
5
  export { inlineNodes } from './inline-nodes';
6
6
  export { sanitizeNodes, createSchema } from './create-schema';
@@ -0,0 +1,105 @@
1
+ import { hexToEditorTextBackgroundPaletteColor } from '../../utils/editor-palette';
2
+ import { COLOR } from '../groups';
3
+ import { rgbToHex, L200, T200, P200, M200, Neutral300, O200 } from '../../utils/colors';
4
+ import { getGlobalTheme } from './text-color';
5
+ import { getDarkModeLCHColor } from '../../utils/lch-color-inversion';
6
+
7
+ /**
8
+ * @name backgroundColor_mark
9
+ */
10
+
11
+ const colorArrayPalette = [[Neutral300, 'Gray'],
12
+ // token: color.background.accent.gray.subtler
13
+ [T200, 'Teal'],
14
+ // token: color.background.accent.teal.subtler
15
+ [L200, 'Lime'],
16
+ // token: color.background.accent.lime.subtler
17
+ [O200, 'Orange'],
18
+ // token: color.background.accent.orange.subtler
19
+ [M200, 'Magenta'],
20
+ // token: color.background.accent.magenta.subtler
21
+ [P200, 'Purple'] // token: color.background.accent.purple.subtler
22
+ ];
23
+
24
+ // @see https://product-fabric.atlassian.net/wiki/spaces/E/pages/55979455/Colour+picker+decisions#Colourpickerdecisions-Visualdesigndecisions
25
+ export const backgroundColorPalette = new Map();
26
+ colorArrayPalette.forEach(([color, label]) => backgroundColorPalette.set(color.toLowerCase(), label));
27
+ export const backgroundColor = {
28
+ attrs: {
29
+ color: {}
30
+ },
31
+ inclusive: true,
32
+ group: COLOR,
33
+ parseDOM: [{
34
+ style: 'background-color',
35
+ getAttrs: maybeValue => {
36
+ const value = maybeValue;
37
+ let hexColor;
38
+ if (value.match(/^rgb/i)) {
39
+ hexColor = rgbToHex(value);
40
+ } else if (value[0] === '#') {
41
+ hexColor = value.toLowerCase();
42
+ }
43
+ // else handle other colour formats
44
+ return hexColor && backgroundColorPalette.has(hexColor) ? {
45
+ color: hexColor
46
+ } : false;
47
+ }
48
+ },
49
+ // This rule ensures when loading from a renderer or editor where the
50
+ // presented text color does not match the stored hex color -- that the
51
+ // text color is preserved.
52
+ //
53
+ // This is used to support the work-around that converts the hex color to
54
+ // a design system token to enable light / dark mode (through a CSS variable --custom-palette-color)
55
+ {
56
+ tag: '.fabric-background-color-mark',
57
+ getAttrs: maybeElement => {
58
+ if (!(maybeElement instanceof HTMLElement)) {
59
+ return false;
60
+ }
61
+ const hexColor = maybeElement.dataset.backgroundCustomColor;
62
+ return hexColor && backgroundColorPalette.has(hexColor) ? {
63
+ color: hexColor
64
+ } : false;
65
+ }
66
+ }],
67
+ toDOM(mark) {
68
+ let paletteColorValue;
69
+ /**
70
+ * Documents can contain custom colors when content has been migrated from the old editor, or created via APIs.
71
+ *
72
+ * This behaviour predates the introduction of dark mode.
73
+ *
74
+ * Without the inversion logic below, text with custom colors, can be hard to read when the user loads the page in dark mode.
75
+ *
76
+ * This introduces inversion of the presentation of the custom text colors when the user is in dark mode.
77
+ *
78
+ * This can be done without additional changes to account for users copying and pasting content inside the Editor, because of
79
+ * how we detect text colors copied from external editor sources. Where we load the background color from a
80
+ * separate attribute (data-text-custom-color), instead of the inline style.
81
+ *
82
+ * See the following document for more details on this behaviour
83
+ * https://hello.atlassian.net/wiki/spaces/CCECO/pages/2908658046/Unsupported+custom+text+colors+in+dark+theme+Editor+Job+Story
84
+ */
85
+ const tokenColor = hexToEditorTextBackgroundPaletteColor(mark.attrs.color);
86
+ if (tokenColor) {
87
+ paletteColorValue = tokenColor;
88
+ } else {
89
+ if (getGlobalTheme().colorMode === 'dark') {
90
+ // if we have a custom color, we need to check if we are in dark mode
91
+ paletteColorValue = getDarkModeLCHColor(mark.attrs.color);
92
+ } else {
93
+ // if we are in light mode, we can just set the color
94
+ paletteColorValue = mark.attrs.color;
95
+ }
96
+ }
97
+ return ['span', {
98
+ class: 'fabric-background-color-mark',
99
+ // Editor common has a common style which uses this css variable as the value for
100
+ // the color property using the `fabric-text-background-color-mark` selector applied above.
101
+ style: `--custom-palette-color: ${paletteColorValue}`,
102
+ ['data-background-custom-color']: mark.attrs.color
103
+ }];
104
+ }
105
+ };
@@ -16,4 +16,5 @@ export { unsupportedMark } from './unsupported-mark';
16
16
  export { unsupportedNodeAttribute } from './unsupported-node-attributes';
17
17
  export { dataConsumer, toJSON as dataConsumerToJSON } from './data-consumer';
18
18
  export { fragment, toJSON as fragmentToJSON } from './fragment';
19
- export { border, borderColorPalette } from './border';
19
+ export { border, borderColorPalette } from './border';
20
+ export { backgroundColor, backgroundColorPalette } from './background-color';
@@ -66,7 +66,7 @@ export const setGlobalTheme = theme => {
66
66
  // This is a minimal duplication of the method from @atlaskit/tokens
67
67
  // to minimise the number of dependencies required as these changes are expected
68
68
  // to be patched onto CR8.
69
- const getGlobalTheme = () => {
69
+ export const getGlobalTheme = () => {
70
70
  // This should only be hit during tests.
71
71
  //
72
72
  // At time of writing Jest mocks are not working in this repository.
@@ -148,7 +148,7 @@ export const textColor = {
148
148
  */
149
149
  const tokenColor = hexToEditorTextPaletteColor(mark.attrs.color);
150
150
  if (tokenColor) {
151
- paletteColorValue = hexToEditorTextPaletteColor(mark.attrs.color) || mark.attrs.color;
151
+ paletteColorValue = tokenColor;
152
152
  } else {
153
153
  if (getGlobalTheme().colorMode === 'dark') {
154
154
  // if we have a custom color, we need to check if we are in dark mode
@@ -70,7 +70,7 @@ export const mention = {
70
70
  }
71
71
  };
72
72
  const isOptional = key => {
73
- return ['userType'].indexOf(key) > -1;
73
+ return ['userType', 'localId'].indexOf(key) > -1;
74
74
  };
75
75
  export const toJSON = node => ({
76
76
  attrs: Object.keys(node.attrs).reduce((obj, key) => {
@@ -28,7 +28,7 @@ export const paragraph = {
28
28
  selectable: false,
29
29
  content: 'inline*',
30
30
  group: 'block',
31
- marks: 'strong code em link border strike subsup textColor typeAheadQuery underline confluenceInlineComment action annotation unsupportedMark unsupportedNodeAttribute dataConsumer fragment',
31
+ marks: 'strong code em link border strike subsup textColor typeAheadQuery underline confluenceInlineComment action annotation unsupportedMark unsupportedNodeAttribute dataConsumer fragment backgroundColor',
32
32
  parseDOM: [{
33
33
  tag: 'p'
34
34
  }],
@@ -29,6 +29,7 @@ export const B75 = '#B3D4FF';
29
29
  export const B100 = '#4C9AFF';
30
30
  export const B400 = '#0052CC';
31
31
  export const B500 = '#0747A6';
32
+ export const L200 = '#D3F1A7';
32
33
  export const N0 = '#FFFFFF';
33
34
  export const N20 = '#F4F5F7';
34
35
  export const N30 = '#EBECF0';
@@ -39,20 +40,25 @@ export const N80 = '#97A0AF';
39
40
  export const N90 = '#8993A4';
40
41
  export const N200 = '#6B778C';
41
42
  export const N300 = '#5E6C84';
43
+ export const Neutral300 = '#DCDFE4';
42
44
  export const N300A = '#091E4224';
43
45
  export const N500 = '#42526E';
44
46
  export const N600 = '#758195';
45
47
  export const N800 = '#172B4D';
46
48
  export const N1000 = '#172B4D';
49
+ export const M200 = '#FDD0EC';
50
+ export const O200 = '#FEDEC8';
47
51
  export const P50 = '#EAE6FF';
48
52
  export const P75 = '#C0B6F2';
49
53
  export const P100 = '#998DD9';
54
+ export const P200 = '#DFD8FD';
50
55
  export const P300 = '#6554C0';
51
56
  export const P400 = '#5243AA';
52
57
  export const P500 = '#403294';
53
58
  export const T50 = '#E6FCFF';
54
59
  export const T75 = '#B3F5FF';
55
60
  export const T100 = '#79E2F2';
61
+ export const T200 = '#C6EDFB';
56
62
  export const T300 = '#00B8D9';
57
63
  export const T500 = '#008DA6';
58
64
 
@@ -96,6 +96,42 @@ export const editorTextPalette = {
96
96
  '#172B4D': 'var(--ds-text, #172B4D)'
97
97
  };
98
98
 
99
+ /**
100
+ * This takes an ADF hex color and returns a matching text background palette color.
101
+ *
102
+ * By providing a design token, this enables ADF content to be rendered in new themes such as dark mode.
103
+ *
104
+ * Example usage
105
+ * ```tsx
106
+ * const cssValue = hexToEditorTextBackgroundPaletteColor('#0747A6');
107
+ * // ^? const cssValue: string
108
+ * <span style={{backgroundColor: cssValue}} />
109
+ * ```
110
+ * The names of tokens can change over time, and the values of tokens will differ between themes.
111
+ * The exact output of this function is an implementation detail and should only be used when rendering
112
+ * content to the user, on a client with a matching major version of `@atlaskit/tokens`.
113
+ * - **DO NOT**: store the output of these functions in any user-generated content or back-end.
114
+ * - **DO**: store the ADF hex color, and use these utilities at render time to display the themed version of the color
115
+ */
116
+ export function hexToEditorTextBackgroundPaletteColor(hexColor) {
117
+ // Ts ignore was used to allow use of conditional return type
118
+ // (preferring better type on consumption over safety in implementation)
119
+ return textBackgroundColorPalette[hexColor.toUpperCase()];
120
+ }
121
+ export const textBackgroundColorPalette = {
122
+ /** Gray - light */
123
+ '#DCDFE4': 'var(--ds-background-accent-gray-subtler, #DCDFE4)',
124
+ /** Teal - light */
125
+ '#C6EDFB': 'var(--ds-background-accent-teal-subtler, #C6EDFB)',
126
+ /** Lime - light */
127
+ '#D3F1A7': 'var(--ds-background-accent-lime-subtler, #D3F1A7)',
128
+ /** Orange - light */
129
+ '#FEDEC8': 'var(--ds-background-accent-orange-subtler, #FEDEC8)',
130
+ /** Magenta - light */
131
+ '#FDD0EC': 'var(--ds-background-accent-magenta-subtler, #FDD0EC)',
132
+ /** Purple - light */
133
+ '#DFD8FD': 'var(--ds-background-accent-purple-subtler, #DFD8FD)'
134
+ };
99
135
  /**
100
136
  * Takes an ADF hex color and returns the rendered hex code for the associated background palette design token using getTokenValue.
101
137
  * If the provided color does not exist in the Editor color palette, this function returns undefined.
package/dist/esm/index.js CHANGED
@@ -1,3 +1,3 @@
1
1
  export { PanelType, AnnotationTypes, alignment, alignmentPositionMap, annotation, blockCard, blockquote, blockquoteWithList, bodiedExtension, breakout, bulletList, bulletListSelector, caption, code, codeBlock, codeBlockToJSON, colorPalette, /** @deprecated [ED-15849] The extended palette is now rolled into the main one. Use `colorPalette` instead. */
2
- colorPaletteExtended, confluenceInlineComment, confluenceJiraIssue, confluenceUnsupportedBlock, confluenceUnsupportedInline, copyPrivateMediaAttributes, createSchema, dataConsumer, dataConsumerToJSON, date, decisionItem, decisionList, decisionListSelector, doc, em, embedCard, emoji, expand, expandToJSON, extension, fragment, fragmentToJSON, hardBreak, heading, image, indentation, inlineCard, inlineExtension, inlineNodes, layoutColumn, layoutSection, link, linkToJSON, listItem, listItemWithTask, media, mediaGroup, mediaSingle, mediaSingleWithCaption, mediaSingleWithWidthType, mediaSingleFull, mediaSingleSpec, mediaInline, mediaSingleToJSON, mediaToJSON, mention, mentionToJSON, nestedExpand, extendedNestedExpand, orderedList, orderedListSelector, orderedListWithOrder, panel, extendedPanel, paragraph, placeholder, rule, sanitizeNodes, getCellAttrs, getCellDomAttrs, status, strike, strong, subsup, table, tableStage0, tableWithCustomWidth, tableBackgroundBorderColor, tableBackgroundColorNames, tableBackgroundColorPalette, tableCell, tableCellContentDomSelector, tableCellContentWrapperSelector, tableCellSelector, tableHeader, tableHeaderSelector, tablePrefixSelector, tableRow, tableToJSON, taskItem, taskList, taskListSelector, text, textColor, toJSONTableCell, toJSONTableHeader, typeAheadQuery, underline, unknownBlock, unsupportedBlock, unsupportedInline, unsupportedNodeTypesForMediaCards, buildAnnotationMarkDataAttributes, AnnotationMarkStates, unsupportedMark, unsupportedNodeAttribute, border, borderColorPalette, extensionFrame, multiBodiedExtension } from './schema';
2
+ colorPaletteExtended, confluenceInlineComment, confluenceJiraIssue, confluenceUnsupportedBlock, confluenceUnsupportedInline, copyPrivateMediaAttributes, createSchema, dataConsumer, dataConsumerToJSON, date, decisionItem, decisionList, decisionListSelector, doc, em, embedCard, emoji, expand, expandToJSON, extension, fragment, fragmentToJSON, hardBreak, heading, image, indentation, inlineCard, inlineExtension, inlineNodes, layoutColumn, layoutSection, link, linkToJSON, listItem, listItemWithTask, media, mediaGroup, mediaSingle, mediaSingleWithCaption, mediaSingleWithWidthType, mediaSingleFull, mediaSingleSpec, mediaInline, mediaSingleToJSON, mediaToJSON, mention, mentionToJSON, nestedExpand, extendedNestedExpand, orderedList, orderedListSelector, orderedListWithOrder, panel, extendedPanel, paragraph, placeholder, rule, sanitizeNodes, getCellAttrs, getCellDomAttrs, status, strike, strong, subsup, table, tableStage0, tableWithCustomWidth, tableBackgroundBorderColor, tableBackgroundColorNames, tableBackgroundColorPalette, tableCell, tableCellContentDomSelector, tableCellContentWrapperSelector, tableCellSelector, tableHeader, tableHeaderSelector, tablePrefixSelector, tableRow, tableToJSON, taskItem, taskList, taskListSelector, text, textColor, toJSONTableCell, toJSONTableHeader, typeAheadQuery, underline, unknownBlock, unsupportedBlock, unsupportedInline, unsupportedNodeTypesForMediaCards, buildAnnotationMarkDataAttributes, AnnotationMarkStates, unsupportedMark, unsupportedNodeAttribute, border, borderColorPalette, extensionFrame, multiBodiedExtension, backgroundColor, backgroundColorPalette } from './schema';
3
3
  export { B100, B400, B50, B500, B75, G200, G300, G400, G50, G500, G75, N0, N20, N200, N30, N300, N40, N50, N500, N60, N80, N800, N90, P100, P300, P400, P50, P500, P75, R100, R300, R400, R50, R500, R75, T100, T300, T50, T500, T75, Y200, Y400, Y50, Y500, Y75, acNameToEmoji, acShortcutToEmoji, emojiIdToAcName, generateUuid, getEmojiAcName, getLinkMatch, hexToRgb, hexToRgba, isHex, isRgb, isSafeUrl, linkify, linkifyMatch, normalizeHexColor, normalizeUrl, rgbToHex, uuid, getDarkModeLCHColor } from './utils';