@atlaskit/editor-plugin-show-diff 12.1.2 → 12.1.4

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 (36) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/compass.yml +3 -3
  3. package/dist/cjs/pm-plugins/calculateDiff/attrAwareTokenEncoder.js +76 -0
  4. package/dist/cjs/pm-plugins/calculateDiff/calculateDiffDecorations.js +47 -124
  5. package/dist/cjs/pm-plugins/calculateDiff/computeDiffChanges.js +8 -1
  6. package/dist/cjs/pm-plugins/calculateDiff/diffBySteps.js +3 -125
  7. package/dist/cjs/pm-plugins/calculateDiff/smart/classifySmartChanges.js +9 -0
  8. package/dist/cjs/pm-plugins/decorations/colorSchemes/factory.js +678 -0
  9. package/dist/cjs/pm-plugins/decorations/colorSchemes/schemes.js +39 -0
  10. package/dist/cjs/pm-plugins/decorations/colorSchemes/types.js +1 -0
  11. package/dist/es2019/pm-plugins/calculateDiff/attrAwareTokenEncoder.js +64 -0
  12. package/dist/es2019/pm-plugins/calculateDiff/calculateDiffDecorations.js +15 -89
  13. package/dist/es2019/pm-plugins/calculateDiff/computeDiffChanges.js +8 -1
  14. package/dist/es2019/pm-plugins/calculateDiff/diffBySteps.js +2 -105
  15. package/dist/es2019/pm-plugins/calculateDiff/smart/classifySmartChanges.js +9 -0
  16. package/dist/es2019/pm-plugins/decorations/colorSchemes/factory.js +625 -0
  17. package/dist/es2019/pm-plugins/decorations/colorSchemes/schemes.js +33 -0
  18. package/dist/es2019/pm-plugins/decorations/colorSchemes/types.js +0 -0
  19. package/dist/esm/pm-plugins/calculateDiff/attrAwareTokenEncoder.js +70 -0
  20. package/dist/esm/pm-plugins/calculateDiff/calculateDiffDecorations.js +48 -125
  21. package/dist/esm/pm-plugins/calculateDiff/computeDiffChanges.js +8 -1
  22. package/dist/esm/pm-plugins/calculateDiff/diffBySteps.js +2 -124
  23. package/dist/esm/pm-plugins/calculateDiff/smart/classifySmartChanges.js +9 -0
  24. package/dist/esm/pm-plugins/decorations/colorSchemes/factory.js +622 -0
  25. package/dist/esm/pm-plugins/decorations/colorSchemes/schemes.js +33 -0
  26. package/dist/esm/pm-plugins/decorations/colorSchemes/types.js +0 -0
  27. package/dist/types/pm-plugins/calculateDiff/attrAwareTokenEncoder.d.ts +7 -0
  28. package/dist/types/pm-plugins/calculateDiff/diffBySteps.d.ts +0 -20
  29. package/dist/types/pm-plugins/decorations/colorSchemes/factory.d.ts +101 -0
  30. package/dist/types/pm-plugins/decorations/colorSchemes/schemes.d.ts +5 -0
  31. package/dist/types/pm-plugins/decorations/colorSchemes/types.d.ts +38 -0
  32. package/package.json +6 -6
  33. package/dist/cjs/pm-plugins/decorations/createGranularBlockReferenceWidget.js +0 -125
  34. package/dist/es2019/pm-plugins/decorations/createGranularBlockReferenceWidget.js +0 -120
  35. package/dist/esm/pm-plugins/decorations/createGranularBlockReferenceWidget.js +0 -120
  36. package/dist/types/pm-plugins/decorations/createGranularBlockReferenceWidget.d.ts +0 -36
@@ -0,0 +1,625 @@
1
+ import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
2
+ // token() is a build-time transform needing static literals, so pre-compute every colour's
3
+ // tokens here and index by name at runtime.
4
+
5
+ const bgSubtlestMap = {
6
+ green: "var(--ds-background-accent-green-subtlest, #DCFFF1)",
7
+ teal: "var(--ds-background-accent-teal-subtlest, #E7F9FF)",
8
+ blue: "var(--ds-background-accent-blue-subtlest, #E9F2FE)",
9
+ purple: "var(--ds-background-accent-purple-subtlest, #F8EEFE)",
10
+ red: "var(--ds-background-accent-red-subtlest, #FFECEB)",
11
+ orange: "var(--ds-background-accent-orange-subtlest, #FFF5DB)",
12
+ yellow: "var(--ds-background-accent-yellow-subtlest, #FEF7C8)",
13
+ magenta: "var(--ds-background-accent-magenta-subtlest, #FFECF8)",
14
+ gray: "var(--ds-background-accent-gray-subtlest, #F0F1F2)"
15
+ };
16
+ const bgSubtlestPressedMap = {
17
+ green: "var(--ds-background-accent-green-subtlest-pressed, #97EDC9)",
18
+ teal: "var(--ds-background-accent-teal-subtlest-pressed, #B1E4F7)",
19
+ blue: "var(--ds-background-accent-blue-subtlest-pressed, #ADCBFB)",
20
+ purple: "var(--ds-background-accent-purple-subtlest-pressed, #E3BDFA)",
21
+ red: "var(--ds-background-accent-red-subtlest-pressed, #FFB8B2)",
22
+ orange: "var(--ds-background-accent-orange-subtlest-pressed, #FBD779)",
23
+ yellow: "var(--ds-background-accent-yellow-subtlest-pressed, #EFDD4E)",
24
+ magenta: "var(--ds-background-accent-magenta-subtlest-pressed, #FCB6E1)",
25
+ gray: "var(--ds-background-accent-gray-subtlest-pressed, #B7B9BE)"
26
+ };
27
+ const bgSubtlerPressedMap = {
28
+ green: "var(--ds-background-accent-green-subtler-pressed, #7EE2B8)",
29
+ teal: "var(--ds-background-accent-teal-subtler-pressed, #9DD9EE)",
30
+ blue: "var(--ds-background-accent-blue-subtler-pressed, #8FB8F6)",
31
+ purple: "var(--ds-background-accent-purple-subtler-pressed, #D8A0F7)",
32
+ red: "var(--ds-background-accent-red-subtler-pressed, #FD9891)",
33
+ orange: "var(--ds-background-accent-orange-subtler-pressed, #FBC828)",
34
+ yellow: "var(--ds-background-accent-yellow-subtler-pressed, #EED12B)",
35
+ magenta: "var(--ds-background-accent-magenta-subtler-pressed, #F797D2)",
36
+ gray: "var(--ds-background-accent-gray-subtler-pressed, #8C8F97)"
37
+ };
38
+ const borderAccentMap = {
39
+ green: "var(--ds-border-accent-green, #22A06B)",
40
+ teal: "var(--ds-border-accent-teal, #2898BD)",
41
+ blue: "var(--ds-border-accent-blue, #357DE8)",
42
+ purple: "var(--ds-border-accent-purple, #AF59E1)",
43
+ red: "var(--ds-border-accent-red, #E2483D)",
44
+ orange: "var(--ds-border-accent-orange, #E06C00)",
45
+ yellow: "var(--ds-border-accent-yellow, #B38600)",
46
+ magenta: "var(--ds-border-accent-magenta, #CD519D)",
47
+ gray: "var(--ds-border-accent-gray, #7D818A)"
48
+ };
49
+ const textAccentMap = {
50
+ green: "var(--ds-text-accent-green, #216E4E)",
51
+ teal: "var(--ds-text-accent-teal, #206A83)",
52
+ blue: "var(--ds-text-accent-blue, #1558BC)",
53
+ purple: "var(--ds-text-accent-purple, #803FA5)",
54
+ red: "var(--ds-text-accent-red, #AE2E24)",
55
+ orange: "var(--ds-text-accent-orange, #9E4C00)",
56
+ yellow: "var(--ds-text-accent-yellow, #7F5F01)",
57
+ magenta: "var(--ds-text-accent-magenta, #943D73)",
58
+ gray: "var(--ds-text-accent-gray, #505258)"
59
+ };
60
+ function bgSubtlest(color) {
61
+ return bgSubtlestMap[color];
62
+ }
63
+ function bgSubtlestPressed(color) {
64
+ return bgSubtlestPressedMap[color];
65
+ }
66
+ function bgSubtlerPressed(color) {
67
+ return bgSubtlerPressedMap[color];
68
+ }
69
+ function borderAccent(color) {
70
+ return borderAccentMap[color];
71
+ }
72
+ function textAccent(color) {
73
+ return textAccentMap[color];
74
+ }
75
+
76
+ /** Outline colour for deleted table-cell overlays. */
77
+ function deletedCellOutline(colors) {
78
+ return colors.deletedCellBorderProminence === 'subtle' ? "var(--ds-border-disabled, #0515240F)" : borderAccent(colors.deletedCellColor);
79
+ }
80
+
81
+ /** Ring colour for an active (scroll-target) deleted block outline. */
82
+ function deletedBlockOutlineActiveRing(colors) {
83
+ return colors.deletedBlockOutlineActiveEmphasis === 'border' ? borderAccent(colors.deleteActiveColor) : bgSubtlerPressed(colors.deleteActiveColor);
84
+ }
85
+
86
+ // --- Inserted content styles ---
87
+
88
+ /** Inline inserted content — default state. */
89
+ export function buildInsertStyle(colors) {
90
+ return convertToInlineCss({
91
+ background: bgSubtlest(colors.insertColor),
92
+ textDecoration: 'underline',
93
+ textDecorationStyle: colors.insertUnderlineStyle,
94
+ textDecorationThickness: "var(--ds-space-025, 2px)",
95
+ textDecorationColor: borderAccent(colors.insertColor)
96
+ });
97
+ }
98
+
99
+ /** Inline insert style for content within a block node (no background, underline only). */
100
+ export function buildInsertStyleInBlock(colors) {
101
+ return convertToInlineCss({
102
+ textDecoration: 'underline',
103
+ textDecorationStyle: colors.insertUnderlineStyle,
104
+ textDecorationThickness: "var(--ds-space-025, 2px)",
105
+ textDecorationColor: borderAccent(colors.insertColor)
106
+ });
107
+ }
108
+
109
+ /** Extended insert style — background + border-bottom underline. */
110
+ export function buildInsertStyleExtended(colors) {
111
+ return convertToInlineCss({
112
+ background: bgSubtlest(colors.insertColor),
113
+ borderBottom: `2px solid ${borderAccent(colors.insertColor)}`,
114
+ padding: `1px 0 2px`
115
+ });
116
+ }
117
+
118
+ /** Extended insert style for content within a block node (border-bottom only, no background). */
119
+ export function buildInsertStyleInBlockExtended(colors) {
120
+ return convertToInlineCss({
121
+ borderBottom: `2px solid ${borderAccent(colors.insertColor)}`,
122
+ padding: `1px 0 2px`
123
+ });
124
+ }
125
+
126
+ /** Active state of the extended insert style. */
127
+ export function buildInsertStyleExtendedActive(colors) {
128
+ return convertToInlineCss({
129
+ background: bgSubtlerPressed(colors.insertActiveColor),
130
+ borderBottom: `2px solid ${borderAccent(colors.insertColor)}`,
131
+ padding: `1px 0 2px`
132
+ });
133
+ }
134
+
135
+ /** Extended insert style without underline — background + padding only. */
136
+ export function buildInsertStyleExtendedNoUnderline(colors) {
137
+ return convertToInlineCss({
138
+ background: bgSubtlest(colors.insertColor),
139
+ padding: `1px 0 2px`
140
+ });
141
+ }
142
+
143
+ /** Active state of the no-underline extended insert style. */
144
+ export function buildInsertStyleExtendedNoUnderlineActive(colors) {
145
+ return convertToInlineCss({
146
+ background: bgSubtlerPressed(colors.insertActiveColor),
147
+ padding: `1px 0 2px`
148
+ });
149
+ }
150
+
151
+ /** No-underline extended insert style for block content (padding only). */
152
+ export function buildInsertStyleInBlockExtendedNoUnderline(_colors) {
153
+ return convertToInlineCss({
154
+ padding: `1px 0 2px`
155
+ });
156
+ }
157
+
158
+ /** Inline inserted content — active/focused state. */
159
+ export function buildInsertStyleActive(colors) {
160
+ return convertToInlineCss({
161
+ background: bgSubtlerPressed(colors.insertActiveColor),
162
+ textDecoration: 'underline',
163
+ textDecorationStyle: colors.insertUnderlineStyle,
164
+ textDecorationThickness: "var(--ds-space-025, 2px)",
165
+ textDecorationColor: textAccent(colors.insertActiveColor)
166
+ });
167
+ }
168
+
169
+ // --- Deleted inline content styles ---
170
+
171
+ function deletedInlineStyleBase(colors) {
172
+ return {
173
+ textDecorationColor: borderAccent(colors.deleteColor),
174
+ textDecoration: 'line-through',
175
+ position: 'relative',
176
+ opacity: 1
177
+ };
178
+ }
179
+ function deletedInlineStyleActiveBase(colors) {
180
+ return {
181
+ ...deletedInlineStyleBase(colors),
182
+ textDecorationThickness: '2px',
183
+ backgroundColor: bgSubtlestPressed(colors.deleteActiveColor)
184
+ };
185
+ }
186
+
187
+ /** Strikethrough for removed inline / widget content (non-marker decorations). */
188
+ export function buildDeletedInlineStyle(colors, isActive) {
189
+ return isActive ? convertToInlineCss(deletedInlineStyleActiveBase(colors)) : convertToInlineCss(deletedInlineStyleBase(colors));
190
+ }
191
+
192
+ /** Strikethrough line (unbounded span) for deleted content — default state. */
193
+ export function buildDeletedContentStyleUnbounded(colors) {
194
+ return convertToInlineCss({
195
+ position: 'absolute',
196
+ top: '50%',
197
+ width: '100%',
198
+ display: 'inline-block',
199
+ borderTop: `1px solid ${borderAccent(colors.deleteColor)}`,
200
+ pointerEvents: 'none',
201
+ zIndex: 1
202
+ });
203
+ }
204
+
205
+ /** Strikethrough line (unbounded span) for deleted content — active state. */
206
+ export function buildDeletedContentStyleUnboundedActive(colors) {
207
+ return convertToInlineCss({
208
+ position: 'absolute',
209
+ top: '50%',
210
+ width: '100%',
211
+ display: 'inline-block',
212
+ borderTop: `2px solid ${borderAccent(colors.deleteColor)}`,
213
+ pointerEvents: 'none',
214
+ zIndex: 1
215
+ });
216
+ }
217
+
218
+ // --- Deleted block node styles — quote node ---
219
+
220
+ /** Unbounded strikethrough overlay for deleted inline content (absolute positioned line). */
221
+ export function buildDeletedInlineStyleUnbounded(colors) {
222
+ return convertToInlineCss({
223
+ position: 'absolute',
224
+ top: '50%',
225
+ width: '100%',
226
+ display: 'inline-block',
227
+ borderTop: `1px solid ${textAccent(colors.deleteColor)}`,
228
+ pointerEvents: 'none',
229
+ zIndex: 1
230
+ });
231
+ }
232
+
233
+ /** Deleted lozenge-style quote node with box-shadow ring. */
234
+ export function buildDeletedStyleQuoteNodeWithLozenge(colors) {
235
+ return convertToInlineCss({
236
+ marginTop: "var(--ds-space-150, 12px)",
237
+ paddingTop: "var(--ds-space-025, 2px)",
238
+ paddingBottom: "var(--ds-space-025, 2px)",
239
+ paddingLeft: "var(--ds-space-025, 2px)",
240
+ boxShadow: `0 0 0 1px ${borderAccent(colors.deleteColor)}`,
241
+ borderRadius: "var(--ds-radius-small, 4px)"
242
+ });
243
+ }
244
+
245
+ /** Active state of the deleted lozenge-style quote node — stronger ring. */
246
+ export function buildDeletedStyleQuoteNodeWithLozengeActive(colors) {
247
+ return convertToInlineCss({
248
+ marginTop: "var(--ds-space-150, 12px)",
249
+ paddingTop: "var(--ds-space-025, 2px)",
250
+ paddingBottom: "var(--ds-space-025, 2px)",
251
+ paddingLeft: "var(--ds-space-025, 2px)",
252
+ boxShadow: `0 0 0 4px ${borderAccent(colors.deleteActiveColor)}`,
253
+ borderRadius: "var(--ds-radius-small, 4px)"
254
+ });
255
+ }
256
+
257
+ /** Deleted quote node — a 2px left border, or a 1px ring with padding, per `deletedQuoteNodeShape`. */
258
+ export function buildDeletedStyleQuoteNode(colors) {
259
+ if (colors.deletedQuoteNodeShape === 'borderLeft') {
260
+ return convertToInlineCss({
261
+ borderLeft: `2px solid ${borderAccent(colors.deleteColor)}`
262
+ });
263
+ }
264
+ return convertToInlineCss({
265
+ marginTop: "var(--ds-space-150, 12px)",
266
+ paddingTop: "var(--ds-space-025, 2px)",
267
+ paddingBottom: "var(--ds-space-025, 2px)",
268
+ paddingLeft: "var(--ds-space-025, 2px)",
269
+ boxShadow: `0 0 0 1px ${borderAccent(colors.deleteColor)}`,
270
+ borderRadius: "var(--ds-radius-small, 4px)"
271
+ });
272
+ }
273
+
274
+ /** Quote node outline for deleted content — active state. */
275
+ export function buildDeletedStyleQuoteNodeActive(colors) {
276
+ return convertToInlineCss({
277
+ marginTop: "var(--ds-space-150, 12px)",
278
+ paddingTop: "var(--ds-space-025, 2px)",
279
+ paddingBottom: "var(--ds-space-025, 2px)",
280
+ paddingLeft: "var(--ds-space-025, 2px)",
281
+ boxShadow: `0 0 0 4px ${bgSubtlerPressed(colors.deleteActiveColor)}`,
282
+ borderRadius: "var(--ds-radius-small, 4px)"
283
+ });
284
+ }
285
+
286
+ // --- Deleted block node styles — generic block outline ---
287
+
288
+ /** Generic block node outline for deleted content — default state (small radius). */
289
+ export function buildDeletedBlockOutline(colors) {
290
+ return convertToInlineCss({
291
+ boxShadow: `0 0 0 1px ${borderAccent(colors.deleteColor)}`,
292
+ borderRadius: "var(--ds-radius-small, 4px)"
293
+ });
294
+ }
295
+
296
+ /** Generic block node outline for deleted content — active state (small radius). */
297
+ export function buildDeletedBlockOutlineActive(colors) {
298
+ return convertToInlineCss({
299
+ boxShadow: `0 0 0 4px ${deletedBlockOutlineActiveRing(colors)}`,
300
+ borderRadius: "var(--ds-radius-small, 4px)"
301
+ });
302
+ }
303
+
304
+ /** Generic block node outline for deleted content — default state (rounded/xsmall+1px radius). */
305
+ export function buildDeletedBlockOutlineRounded(colors) {
306
+ return convertToInlineCss({
307
+ boxShadow: `0 0 0 1px ${borderAccent(colors.deleteColor)}`,
308
+ borderRadius: `calc(${"var(--ds-radius-xsmall, 2px)"} + 1px)`
309
+ });
310
+ }
311
+
312
+ /** Generic block node outline for deleted content — active state (rounded/xsmall+1px radius). */
313
+ export function buildDeletedBlockOutlineRoundedActive(colors) {
314
+ return convertToInlineCss({
315
+ boxShadow: `0 0 0 4px ${deletedBlockOutlineActiveRing(colors)}`,
316
+ borderRadius: `calc(${"var(--ds-radius-xsmall, 2px)"} + 1px)`
317
+ });
318
+ }
319
+
320
+ /** Scroll-navigation "new" emphasis: 4px ring — default state (small radius). */
321
+ export function buildDeletedBlockOutlineNew(colors) {
322
+ return convertToInlineCss({
323
+ boxShadow: `0 0 0 4px ${bgSubtlest(colors.deleteColor)}`,
324
+ borderRadius: "var(--ds-radius-small, 4px)"
325
+ });
326
+ }
327
+
328
+ /** Scroll-navigation "new" emphasis: 4px ring — default state (rounded radius). */
329
+ export function buildDeletedBlockOutlineRoundedNew(colors) {
330
+ return convertToInlineCss({
331
+ boxShadow: `0 0 0 4px ${bgSubtlest(colors.deleteColor)}`,
332
+ borderRadius: `calc(${"var(--ds-radius-xsmall, 2px)"} + 1px)`
333
+ });
334
+ }
335
+
336
+ // --- Deleted table row style ---
337
+
338
+ /** Table row style for deleted rows. See `deletedRowTreatment`. */
339
+ export function buildDeletedRowStyle(colors) {
340
+ const base = {
341
+ textDecoration: 'line-through',
342
+ opacity: 0.6,
343
+ display: 'table-row'
344
+ };
345
+ return colors.deletedRowTreatment === 'textTint' ? convertToInlineCss({
346
+ ...base,
347
+ color: textAccent(colors.deleteColor)
348
+ }) : convertToInlineCss({
349
+ ...base,
350
+ textDecorationColor: borderAccent(colors.deleteColor)
351
+ });
352
+ }
353
+
354
+ // --- Inserted block node styles — quote, rule, generic node, card ---
355
+
356
+ /** Quote node (blockquote) left-border style for inserted content — default state. */
357
+ export function buildInsertStyleQuoteNode(colors) {
358
+ return convertToInlineCss({
359
+ borderLeft: `2px solid ${borderAccent(colors.insertColor)}`
360
+ });
361
+ }
362
+
363
+ /** Quote node left-border style for inserted content — "new" scroll-nav state. */
364
+ export function buildInsertStyleQuoteNodeNew(colors) {
365
+ return convertToInlineCss({
366
+ borderLeft: `4px solid ${bgSubtlest(colors.insertColor)}`
367
+ });
368
+ }
369
+
370
+ /** Quote node left-border style for inserted content — active state. */
371
+ export function buildInsertStyleQuoteNodeActive(colors) {
372
+ return convertToInlineCss({
373
+ borderLeft: `4px solid ${bgSubtlerPressed(colors.insertActiveColor)}`
374
+ });
375
+ }
376
+
377
+ /** Horizontal rule style for inserted content — default state. */
378
+ export function buildInsertStyleRuleNode(colors) {
379
+ return convertToInlineCss({
380
+ backgroundColor: borderAccent(colors.insertColor)
381
+ });
382
+ }
383
+
384
+ /** Horizontal rule style for inserted content — "new" scroll-nav state. */
385
+ export function buildInsertStyleRuleNodeNew(colors) {
386
+ return convertToInlineCss({
387
+ backgroundColor: bgSubtlest(colors.insertColor),
388
+ border: 'none',
389
+ height: '4px',
390
+ borderRadius: "var(--ds-radius-small, 4px)"
391
+ });
392
+ }
393
+
394
+ /** Horizontal rule style for inserted content — active state. */
395
+ export function buildInsertStyleRuleNodeActive(colors) {
396
+ return convertToInlineCss({
397
+ backgroundColor: bgSubtlerPressed(colors.insertActiveColor),
398
+ border: 'none',
399
+ height: '4px',
400
+ borderRadius: "var(--ds-radius-small, 4px)"
401
+ });
402
+ }
403
+
404
+ /** Generic node outline for inserted content — default state (small radius). */
405
+ export function buildInsertStyleNode(colors) {
406
+ return convertToInlineCss({
407
+ boxShadow: `0 0 0 1px ${borderAccent(colors.insertColor)}`,
408
+ borderRadius: "var(--ds-radius-small, 4px)"
409
+ });
410
+ }
411
+
412
+ /** Generic node outline for inserted content — "new" scroll-nav state (small radius). */
413
+ export function buildInsertStyleNodeNew(colors) {
414
+ return convertToInlineCss({
415
+ boxShadow: `0 0 0 4px ${bgSubtlest(colors.insertColor)}`,
416
+ borderRadius: "var(--ds-radius-small, 4px)"
417
+ });
418
+ }
419
+
420
+ /** Generic node outline for inserted content — active state (small radius). */
421
+ export function buildInsertStyleNodeActive(colors) {
422
+ return convertToInlineCss({
423
+ boxShadow: `0 0 0 4px ${bgSubtlerPressed(colors.insertActiveColor)}`,
424
+ borderRadius: "var(--ds-radius-small, 4px)"
425
+ });
426
+ }
427
+
428
+ /** Card block node outline for inserted content — default state (medium radius). */
429
+ export function buildInsertStyleCardBlockNode(colors) {
430
+ return convertToInlineCss({
431
+ boxShadow: `0 0 0 1px ${borderAccent(colors.insertColor)}`,
432
+ borderRadius: "var(--ds-radius-medium, 6px)"
433
+ });
434
+ }
435
+
436
+ /** Card block node outline for inserted content — "new" scroll-nav state (medium radius). */
437
+ export function buildInsertStyleCardBlockNodeNew(colors) {
438
+ return convertToInlineCss({
439
+ boxShadow: `0 0 0 4px ${bgSubtlest(colors.insertColor)}`,
440
+ borderRadius: "var(--ds-radius-medium, 6px)"
441
+ });
442
+ }
443
+
444
+ /** Card block node outline for inserted content — active state (medium radius). */
445
+ export function buildInsertStyleCardBlockNodeActive(colors) {
446
+ return convertToInlineCss({
447
+ boxShadow: `0 0 0 4px ${bgSubtlerPressed(colors.insertActiveColor)}`,
448
+ borderRadius: "var(--ds-radius-medium, 6px)"
449
+ });
450
+ }
451
+
452
+ // --- CSS custom properties ---
453
+ // Applied inline on the decoration wrapper; cascade down to child/pseudo-element selectors in the
454
+ // global stylesheet.
455
+
456
+ /** CSS variables for an inserted node decoration marker — default state. */
457
+ export function buildDecorationMarkerVariable(colors) {
458
+ return convertToInlineCss({
459
+ '--diff-decoration-marker-color': borderAccent(colors.insertColor),
460
+ '--diff-decoration-marker-ring-width': '1px'
461
+ });
462
+ }
463
+
464
+ /** CSS variables for an inserted node decoration marker — "new" scroll-nav state. */
465
+ export function buildDecorationMarkerVariableNew(colors) {
466
+ return convertToInlineCss({
467
+ '--diff-decoration-marker-color': bgSubtlest(colors.insertColor),
468
+ '--diff-decoration-marker-ring-width': '4px'
469
+ });
470
+ }
471
+
472
+ /** CSS variables for an inserted node decoration marker — active state. */
473
+ export function buildDecorationMarkerVariableActive(colors) {
474
+ return convertToInlineCss({
475
+ '--diff-decoration-marker-color': bgSubtlerPressed(colors.insertActiveColor),
476
+ '--diff-decoration-marker-ring-width': '4px'
477
+ });
478
+ }
479
+
480
+ /** Deleted node decoration marker (extension / embedCard / listItem) — default state. */
481
+ export function buildDeletedDecorationMarkerVariable(colors) {
482
+ return convertToInlineCss({
483
+ ...deletedInlineStyleBase(colors),
484
+ '--diff-decoration-marker-color': borderAccent(colors.deleteColor),
485
+ '--diff-decoration-marker-ring-width': '1px'
486
+ });
487
+ }
488
+
489
+ /** Opacity only, no position or strikethrough. Used by the standard scheme. */
490
+ export function buildDeletedDecorationMarkerVariableSimple(colors) {
491
+ return convertToInlineCss({
492
+ opacity: 0.8,
493
+ '--diff-decoration-marker-color': borderAccent(colors.deleteColor),
494
+ '--diff-decoration-marker-ring-width': '1px'
495
+ });
496
+ }
497
+
498
+ /** Extended deleted inline style — background highlight + border-bottom underline (standard scheme). */
499
+ export function buildDeletedInlineContentStyleExtended(colors) {
500
+ return convertToInlineCss({
501
+ backgroundColor: bgSubtlest(colors.deleteColor),
502
+ borderBottom: `2px solid ${borderAccent(colors.deleteColor)}`,
503
+ padding: `1px 0 2px`
504
+ });
505
+ }
506
+
507
+ /** Standard deleted inline style — colours the glyph itself, not just the strikethrough. */
508
+ export function buildDeletedInlineStyleStandard(colors, state) {
509
+ if (state === 'active') {
510
+ return convertToInlineCss({
511
+ color: "var(--ds-text, #292A2E)",
512
+ textDecoration: 'line-through',
513
+ textDecorationColor: textAccent(colors.deleteColor),
514
+ position: 'relative',
515
+ opacity: 1
516
+ });
517
+ }
518
+ return convertToInlineCss({
519
+ color: textAccent(colors.deleteColor),
520
+ textDecoration: 'line-through',
521
+ position: 'relative',
522
+ opacity: state === 'new' ? 0.83 : 0.6
523
+ });
524
+ }
525
+
526
+ /** Deleted node decoration marker — "new" state. */
527
+ export function buildDeletedDecorationMarkerVariableNew(colors) {
528
+ return convertToInlineCss({
529
+ ...deletedInlineStyleBase(colors),
530
+ '--diff-decoration-marker-color': bgSubtlest(colors.deleteColor),
531
+ '--diff-decoration-marker-ring-width': '4px'
532
+ });
533
+ }
534
+
535
+ /** Deleted node decoration marker — active state. */
536
+ export function buildDeletedDecorationMarkerVariableActive(colors) {
537
+ return convertToInlineCss({
538
+ ...deletedInlineStyleActiveBase(colors),
539
+ '--diff-decoration-marker-color': bgSubtlerPressed(colors.deleteActiveColor),
540
+ '--diff-decoration-marker-ring-width': '4px'
541
+ });
542
+ }
543
+
544
+ // --- Table cell overlay styles ---
545
+
546
+ /** Cell overlay for added table cells — default state. Stacking order varies by scheme. */
547
+ export function buildAddedCellOverlayStyle(colors) {
548
+ return convertToInlineCss({
549
+ position: 'absolute',
550
+ top: 0,
551
+ left: 0,
552
+ width: '100%',
553
+ height: '100%',
554
+ backgroundColor: `rgba(from ${bgSubtlest(colors.insertColor)} r g b / ${colors.insertedCellOpacity})`,
555
+ zIndex: colors.addedCellOverlayZIndex,
556
+ outline: `1px solid ${borderAccent(colors.insertColor)}`,
557
+ pointerEvents: 'none'
558
+ });
559
+ }
560
+
561
+ /** Added cell overlay — rounded variant. See `roundedAddedCellOverlayInheritsBorder`. */
562
+ export function buildAddedCellOverlayRoundedStyle(colors) {
563
+ return convertToInlineCss({
564
+ position: 'absolute',
565
+ top: 0,
566
+ left: 0,
567
+ width: '100%',
568
+ height: '100%',
569
+ backgroundColor: `rgba(from ${bgSubtlest(colors.insertColor)} r g b / ${colors.insertedCellOpacity})`,
570
+ zIndex: 2,
571
+ outline: `1px solid ${borderAccent(colors.insertColor)}`,
572
+ pointerEvents: 'none',
573
+ ...(colors.roundedAddedCellOverlayInheritsBorder ? {
574
+ border: 'inherit'
575
+ } : {}),
576
+ borderRadius: 'inherit'
577
+ });
578
+ }
579
+
580
+ /** Cell overlay for added table cells — "new" scroll-nav state. */
581
+ export function buildAddedCellOverlayStyleNew(colors) {
582
+ return convertToInlineCss({
583
+ position: 'absolute',
584
+ top: 0,
585
+ left: 0,
586
+ width: '100%',
587
+ height: '100%',
588
+ backgroundColor: `rgba(from ${bgSubtlest(colors.insertColor)} r g b / ${colors.insertedCellOpacity})`,
589
+ zIndex: 1,
590
+ outline: `1px solid ${bgSubtlerPressed(colors.insertActiveColor)}`,
591
+ pointerEvents: 'none'
592
+ });
593
+ }
594
+
595
+ /** Cell overlay for deleted table cells — default state (zIndex 1). Uses deletedCellColor. */
596
+ export function buildDeletedCellOverlayStyle(colors) {
597
+ return convertToInlineCss({
598
+ position: 'absolute',
599
+ top: 0,
600
+ left: 0,
601
+ width: '100%',
602
+ height: '100%',
603
+ backgroundColor: `rgba(from ${bgSubtlest(colors.deletedCellColor)} r g b / 0.5)`,
604
+ zIndex: 1,
605
+ outline: `1px solid ${deletedCellOutline(colors)}`,
606
+ pointerEvents: 'none'
607
+ });
608
+ }
609
+
610
+ /** Cell overlay for deleted table cells — rounded variant (zIndex 2, inherits border/radius). */
611
+ export function buildDeletedCellOverlayRoundedStyle(colors) {
612
+ return convertToInlineCss({
613
+ position: 'absolute',
614
+ top: 0,
615
+ left: 0,
616
+ width: '100%',
617
+ height: '100%',
618
+ backgroundColor: `rgba(from ${bgSubtlest(colors.deletedCellColor)} r g b / 0.5)`,
619
+ zIndex: 2,
620
+ outline: `1px solid ${deletedCellOutline(colors)}`,
621
+ pointerEvents: 'none',
622
+ border: 'inherit',
623
+ borderRadius: 'inherit'
624
+ });
625
+ }
@@ -0,0 +1,33 @@
1
+ /** Green insertions, red deletions. */
2
+ export const traditionalScheme = {
3
+ insertColor: 'green',
4
+ insertUnderlineStyle: 'solid',
5
+ insertActiveColor: 'green',
6
+ deleteColor: 'red',
7
+ deleteActiveColor: 'red',
8
+ deletedCellColor: 'gray',
9
+ insertedCellOpacity: 0.5,
10
+ deletedQuoteNodeShape: 'ring',
11
+ deletedCellBorderProminence: 'subtle',
12
+ deletedRowTreatment: 'strikeColor',
13
+ deletedBlockOutlineActiveEmphasis: 'background',
14
+ addedCellOverlayZIndex: 1,
15
+ roundedAddedCellOverlayInheritsBorder: true
16
+ };
17
+
18
+ /** Purple insertions, gray deletions (red on active). */
19
+ export const standardScheme = {
20
+ insertColor: 'purple',
21
+ insertUnderlineStyle: 'dotted',
22
+ insertActiveColor: 'purple',
23
+ deleteColor: 'gray',
24
+ deleteActiveColor: 'red',
25
+ deletedCellColor: 'gray',
26
+ insertedCellOpacity: 0.2,
27
+ deletedQuoteNodeShape: 'borderLeft',
28
+ deletedCellBorderProminence: 'accent',
29
+ deletedRowTreatment: 'textTint',
30
+ deletedBlockOutlineActiveEmphasis: 'border',
31
+ addedCellOverlayZIndex: 2,
32
+ roundedAddedCellOverlayInheritsBorder: false
33
+ };