@json-to-office/core-docx 2.4.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"highcharts.d.ts","sourceRoot":"","sources":["../../src/components/highcharts.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAMxC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAItE,YAAY,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AA6GD;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,eAAe,EACtB,KAAK,EAAE,WAAW,EAClB,cAAc,CAAC,EAAE,uBAAuB,GACvC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAalC"}
1
+ {"version":3,"file":"highcharts.d.ts","sourceRoot":"","sources":["../../src/components/highcharts.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAMxC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAGtE,YAAY,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AA2GD;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,eAAe,EACtB,KAAK,EAAE,WAAW,EAClB,cAAc,CAAC,EAAE,uBAAuB,GACvC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAalC"}
@@ -1 +1 @@
1
- {"version":3,"file":"generationContext.d.ts","sourceRoot":"","sources":["../../src/core/generationContext.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EAClB,MAAM,wBAAwB,CAAC;AAKhC,MAAM,WAAW,mBAAmB;IAClC,YAAY,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAAA;KAAE,CAAC;IAC9C,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,QAAQ,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC/B;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,CAClB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,iBAAiB,EAAE,GAAG,SAAS,EACzC,QAAQ,EAAE,OAAO,KACd,WAAW,CAAC;CAClB;AAED,MAAM,WAAW,sBAAsB;IACrC,2EAA2E;IAC3E,QAAQ,EAAE,yBAAyB,CAAC;IACpC,KAAK,EAAE,WAAW,CAAC;IACnB,+DAA+D;IAC/D,SAAS,EAAE,MAAM,CAAC;CACnB;AAoBD,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,yBAAyB,EACrC,OAAO,GAAE,mBAAwB,GAChC,sBAAsB,CA6DxB"}
1
+ {"version":3,"file":"generationContext.d.ts","sourceRoot":"","sources":["../../src/core/generationContext.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EAClB,MAAM,wBAAwB,CAAC;AAMhC,MAAM,WAAW,mBAAmB;IAClC,YAAY,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAAA;KAAE,CAAC;IAC9C,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,QAAQ,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC/B;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,CAClB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,iBAAiB,EAAE,GAAG,SAAS,EACzC,QAAQ,EAAE,OAAO,KACd,WAAW,CAAC;CAClB;AAED,MAAM,WAAW,sBAAsB;IACrC,2EAA2E;IAC3E,QAAQ,EAAE,yBAAyB,CAAC;IACpC,KAAK,EAAE,WAAW,CAAC;IACnB,+DAA+D;IAC/D,SAAS,EAAE,MAAM,CAAC;CACnB;AAoBD,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,yBAAyB,EACrC,OAAO,GAAE,mBAAwB,GAChC,sBAAsB,CA8DxB"}
package/dist/index.js CHANGED
@@ -15,6 +15,7 @@ var __export = (target, all) => {
15
15
  };
16
16
 
17
17
  // src/themes/defaults.ts
18
+ import { designColors } from "@json-to-office/shared";
18
19
  function ensureThemeDefaults(theme) {
19
20
  return {
20
21
  ...theme,
@@ -47,10 +48,13 @@ function ensureThemeDefaults(theme) {
47
48
  };
48
49
  }
49
50
  function getThemeColors(theme) {
50
- return {
51
- ...DEFAULT_COLORS,
52
- ...theme.colors || {}
53
- };
51
+ return designColors(
52
+ {
53
+ ...DEFAULT_COLORS,
54
+ ...theme.colors || {}
55
+ },
56
+ theme.palette
57
+ );
54
58
  }
55
59
  function getThemeFonts(theme) {
56
60
  return {
@@ -188,6 +192,10 @@ var init_defaults = __esm({
188
192
  });
189
193
 
190
194
  // src/styles/utils/colorUtils.ts
195
+ import {
196
+ DEFAULT_CHART_THEME_COLORS,
197
+ resolveDesignColor
198
+ } from "@json-to-office/shared";
191
199
  function resolveColor(colorValue, theme) {
192
200
  if (colorValue.startsWith("#")) {
193
201
  const hexValue = colorValue.slice(1);
@@ -201,7 +209,11 @@ function resolveColor(colorValue, theme) {
201
209
  const colors = getThemeColors(theme);
202
210
  const resolvedColor = colors[colorValue];
203
211
  if (typeof resolvedColor === "string") {
204
- return resolveColor(resolvedColor, theme);
212
+ const hex = resolveDesignColor(colorValue, colors);
213
+ if (hex) return hex.toUpperCase();
214
+ throw new Error(
215
+ `Unresolvable theme color: "${colorValue}" (missing reference or cycle).`
216
+ );
205
217
  }
206
218
  if (/^[0-9A-Fa-f]{6}$/.test(colorValue)) {
207
219
  return colorValue.toUpperCase();
@@ -210,6 +222,15 @@ function resolveColor(colorValue, theme) {
210
222
  `Invalid color value: "${colorValue}". Must be a hex color with # prefix (e.g., "#000000") or a valid theme color name.`
211
223
  );
212
224
  }
225
+ function chartPaletteValues(theme) {
226
+ const explicit = theme.palette?.chart;
227
+ if (explicit) return [...explicit];
228
+ const colors = getThemeColors(theme);
229
+ return DEFAULT_CHART_THEME_COLORS.flatMap((token) => {
230
+ const value = colors[token];
231
+ return typeof value === "string" && value.length > 0 ? [value] : [];
232
+ });
233
+ }
213
234
  var init_colorUtils = __esm({
214
235
  "src/styles/utils/colorUtils.ts"() {
215
236
  "use strict";
@@ -990,6 +1011,8 @@ function resolveFontProperties(theme, fontRef) {
990
1011
  size: fontDef.size,
991
1012
  color: fontDef.color,
992
1013
  bold: fontDef.bold,
1014
+ fontWeight: fontDef.fontWeight,
1015
+ case: fontDef.case,
993
1016
  italic: fontDef.italic,
994
1017
  underline: fontDef.underline,
995
1018
  alignment: fontDef.alignment,
@@ -2072,6 +2095,9 @@ function runOptions(formatting) {
2072
2095
  options.underline = formatting.underline ? { type: formatting.underline.type } : void 0;
2073
2096
  }
2074
2097
  if (formatting.strike !== void 0) options.strike = formatting.strike;
2098
+ if (formatting.allCaps !== void 0) options.allCaps = formatting.allCaps;
2099
+ if (formatting.smallCaps !== void 0)
2100
+ options.smallCaps = formatting.smallCaps;
2075
2101
  if (formatting.scalePercent !== void 0) {
2076
2102
  options.scale = formatting.scalePercent;
2077
2103
  }
@@ -2762,6 +2788,44 @@ var init_styles2 = __esm({
2762
2788
  }
2763
2789
  });
2764
2790
 
2791
+ // src/utils/normalizeTextCase.ts
2792
+ function normalizeTextCase(zip) {
2793
+ let changed = false;
2794
+ for (const entry of zip.getEntries()) {
2795
+ if (!WORD_XML.test(entry.entryName)) continue;
2796
+ const xml = entry.getData().toString("utf8");
2797
+ if (!ANY_CASE_FLAG.test(xml)) continue;
2798
+ const normalized = xml.replace(RUN_PROPERTIES, completeCaseFlags);
2799
+ if (normalized === xml) continue;
2800
+ zip.updateFile(entry, Buffer.from(normalized, "utf8"));
2801
+ changed = true;
2802
+ }
2803
+ return changed;
2804
+ }
2805
+ function completeCaseFlags(runProperties3) {
2806
+ const flag = CASE_FLAG.exec(runProperties3);
2807
+ if (!flag) return runProperties3;
2808
+ const isCaps = flag[1] === "caps";
2809
+ const opposite = `<w:${isCaps ? "smallCaps" : "caps"} w:val="false"/>`;
2810
+ if (runProperties3.includes(`<w:${isCaps ? "smallCaps" : "caps"}`)) {
2811
+ return runProperties3;
2812
+ }
2813
+ return runProperties3.replace(
2814
+ flag[0],
2815
+ isCaps ? `${flag[0]}${opposite}` : `${opposite}${flag[0]}`
2816
+ );
2817
+ }
2818
+ var WORD_XML, ANY_CASE_FLAG, RUN_PROPERTIES, CASE_FLAG;
2819
+ var init_normalizeTextCase = __esm({
2820
+ "src/utils/normalizeTextCase.ts"() {
2821
+ "use strict";
2822
+ WORD_XML = /^word\/.*\.xml$/;
2823
+ ANY_CASE_FLAG = /<w:(?:caps|smallCaps)\b/;
2824
+ RUN_PROPERTIES = /<w:rPr\b[^>]*>[\s\S]*?<\/w:rPr>/g;
2825
+ CASE_FLAG = /<w:(caps|smallCaps)\b[^>]*(?:\/>|>[\s\S]*?<\/w:\1>)/;
2826
+ }
2827
+ });
2828
+
2765
2829
  // src/utils/packageDocument.ts
2766
2830
  import AdmZip from "adm-zip";
2767
2831
  function resolveGenerationDate(options) {
@@ -2830,6 +2894,7 @@ function canonicalizeRelationshipIds(zip) {
2830
2894
  }
2831
2895
  function canonicalizeDocxBuffer(buffer, generatedAt = DEFAULT_GENERATION_DATE) {
2832
2896
  const zip = new AdmZip(buffer);
2897
+ normalizeTextCase(zip);
2833
2898
  canonicalizeRelationshipIds(zip);
2834
2899
  const isoTimestamp = generatedAt.toISOString();
2835
2900
  const coreProperties3 = zip.getEntry("docProps/core.xml");
@@ -2846,10 +2911,15 @@ function canonicalizeDocxBuffer(buffer, generatedAt = DEFAULT_GENERATION_DATE) {
2846
2911
  }
2847
2912
  return zip.toBuffer();
2848
2913
  }
2914
+ function normalizeDocxCaseBuffer(buffer) {
2915
+ const zip = new AdmZip(buffer);
2916
+ return normalizeTextCase(zip) ? zip.toBuffer() : buffer;
2917
+ }
2849
2918
  var DEFAULT_GENERATION_DATE, STABLE_RELATIONSHIP_ID;
2850
2919
  var init_packageDocument = __esm({
2851
2920
  "src/utils/packageDocument.ts"() {
2852
2921
  "use strict";
2922
+ init_normalizeTextCase();
2853
2923
  DEFAULT_GENERATION_DATE = /* @__PURE__ */ new Date("2000-01-01T00:00:00.000Z");
2854
2924
  STABLE_RELATIONSHIP_ID = /^rId\d+$/;
2855
2925
  }
@@ -2908,7 +2978,8 @@ function createDocxJsRenderer() {
2908
2978
  const document = buildDocument(ir, resources);
2909
2979
  const packed = await Packer.toBuffer(document);
2910
2980
  const fixed = fixFloatingImageIdsInBuffer(packed);
2911
- if (renderOptions?.deterministic === false) return new Uint8Array(fixed);
2981
+ if (renderOptions?.deterministic === false)
2982
+ return new Uint8Array(normalizeDocxCaseBuffer(fixed));
2912
2983
  return new Uint8Array(
2913
2984
  canonicalizeDocxBuffer(
2914
2985
  fixed,
@@ -4187,7 +4258,8 @@ async function createOfficeOpenDocxRenderer() {
4187
4258
  spliceChartParts(zip, charts);
4188
4259
  raw = zip.toBuffer();
4189
4260
  }
4190
- if (options?.deterministic === false) return new Uint8Array(raw);
4261
+ if (options?.deterministic === false)
4262
+ return new Uint8Array(normalizeDocxCaseBuffer(raw));
4191
4263
  return new Uint8Array(
4192
4264
  canonicalizeDocxBuffer(
4193
4265
  raw,
@@ -5045,7 +5117,6 @@ import {
5045
5117
 
5046
5118
  // src/components/highcharts.ts
5047
5119
  init_colorUtils();
5048
- import { DEFAULT_CHART_THEME_COLORS } from "@json-to-office/shared";
5049
5120
  var DEFAULT_EXPORT_SERVER_URL = "http://localhost:7801";
5050
5121
  async function generateChart(config, servicesConfig) {
5051
5122
  if (!isNodeEnvironment()) {
@@ -5099,11 +5170,10 @@ function toChartColor(value, theme) {
5099
5170
  function withThemeColors(config, theme) {
5100
5171
  const options = config.options;
5101
5172
  if (!options || options.colors || !theme?.colors) return config;
5102
- const themeColors = theme.colors;
5103
- const palette = DEFAULT_CHART_THEME_COLORS.map((token) => {
5104
- const value = themeColors[token];
5105
- return typeof value === "string" && value.length > 0 ? toChartColor(value, theme) : void 0;
5106
- }).filter((c) => c !== void 0);
5173
+ const palette = chartPaletteValues(theme).flatMap((value) => {
5174
+ const color = toChartColor(value, theme);
5175
+ return color ? [color] : [];
5176
+ });
5107
5177
  if (palette.length === 0) return config;
5108
5178
  return {
5109
5179
  ...config,
@@ -5349,10 +5419,7 @@ init_colorUtils();
5349
5419
  import {
5350
5420
  FeatureRequirementCollector
5351
5421
  } from "@json-to-office/shared/rendering";
5352
- import {
5353
- synthesizeFamilyName,
5354
- DEFAULT_CHART_THEME_COLORS as DEFAULT_CHART_THEME_COLORS2
5355
- } from "@json-to-office/shared";
5422
+ import { capsFormatting as capsFormatting2, synthesizeFamilyName as synthesizeFamilyName2 } from "@json-to-office/shared";
5356
5423
  import {
5357
5424
  isNativeVisualProps as isNativeVisualProps4
5358
5425
  } from "@json-to-office/shared-docx";
@@ -5868,6 +5935,7 @@ function resolveColors(entries, at, deps) {
5868
5935
  init_themes();
5869
5936
  init_colorUtils();
5870
5937
  init_styleHelpers();
5938
+ import { capsFormatting, synthesizeFamilyName } from "@json-to-office/shared";
5871
5939
  var RIGHT_MARGIN_TAB_TWIPS = 9026 * 2;
5872
5940
  var STATISTIC_NUMBER_STYLE_ID = "StatisticNumber";
5873
5941
  var STATISTIC_DESCRIPTION_STYLE_ID = "StatisticDescription";
@@ -5876,25 +5944,8 @@ var STATISTIC_SIZE_POINTS = {
5876
5944
  medium: 28,
5877
5945
  large: 40
5878
5946
  };
5879
- function isValidStyleName(name) {
5880
- return [
5881
- "normal",
5882
- "heading1",
5883
- "heading2",
5884
- "heading3",
5885
- "heading4",
5886
- "heading5",
5887
- "heading6",
5888
- "title",
5889
- "subtitle"
5890
- ].includes(name);
5891
- }
5892
5947
  function getStyleSafe(theme, styleName) {
5893
- if (!isValidStyleName(styleName)) {
5894
- console.warn(`Invalid style name: ${styleName}`);
5895
- return void 0;
5896
- }
5897
- return theme.styles?.[styleName];
5948
+ return theme.styles && Object.hasOwn(theme.styles, styleName) ? theme.styles[styleName] : void 0;
5898
5949
  }
5899
5950
  function resolveStyleWithBaseStyle(theme, styleName, visited = /* @__PURE__ */ new Set()) {
5900
5951
  if (visited.has(styleName)) {
@@ -5951,9 +6002,17 @@ function resolveSpacing(spacing) {
5951
6002
  ...spacing?.after ? { afterTwips: pointsToTwips(spacing.after) } : {}
5952
6003
  };
5953
6004
  }
6005
+ function weightedFamily(props) {
6006
+ return props.fontWeight === void 0 ? void 0 : synthesizeFamilyName(
6007
+ props.family || "Arial",
6008
+ props.fontWeight,
6009
+ props.italic === true
6010
+ );
6011
+ }
5954
6012
  function convertRunProperties(merged, theme, defaultColor, defaultSize) {
6013
+ const weighted = weightedFamily(merged);
5955
6014
  return {
5956
- fontFamily: merged.family || "Arial",
6015
+ fontFamily: weighted?.family ?? merged.family ?? "Arial",
5957
6016
  sizeHalfPoints: (merged.size || defaultSize || 11) * 2,
5958
6017
  color: {
5959
6018
  hex: resolveColor(
@@ -5963,6 +6022,8 @@ function convertRunProperties(merged, theme, defaultColor, defaultSize) {
5963
6022
  },
5964
6023
  ...merged.bold !== void 0 && { bold: merged.bold },
5965
6024
  ...merged.italic !== void 0 && { italic: merged.italic },
6025
+ ...weighted && { bold: weighted.bold, italic: weighted.italic },
6026
+ ...merged.case !== void 0 && capsFormatting(merged.case),
5966
6027
  ...merged.underline !== void 0 && merged.underline && { underline: { type: "single" } },
5967
6028
  ...merged.characterSpacing && {
5968
6029
  characterSpacingTwentieths: merged.characterSpacing.type === "condensed" ? -merged.characterSpacing.value : merged.characterSpacing.value
@@ -6035,12 +6096,15 @@ function convertBorders(borders3, theme) {
6035
6096
  return Object.keys(converted).length > 0 ? converted : void 0;
6036
6097
  }
6037
6098
  function fallbackRun(fontProps, theme, defaultColor, defaultSize) {
6099
+ const weighted = weightedFamily(fontProps);
6038
6100
  return {
6039
- fontFamily: fontProps.family || "Arial",
6101
+ fontFamily: weighted?.family ?? fontProps.family ?? "Arial",
6040
6102
  sizeHalfPoints: (fontProps.size || defaultSize) * 2,
6041
6103
  color: { hex: resolveColor(fontProps.color || defaultColor, theme) },
6042
6104
  ...fontProps.bold !== void 0 && { bold: fontProps.bold },
6043
6105
  ...fontProps.italic !== void 0 && { italic: fontProps.italic },
6106
+ ...weighted && { bold: weighted.bold, italic: weighted.italic },
6107
+ ...fontProps.case !== void 0 && capsFormatting(fontProps.case),
6044
6108
  ...fontProps.underline !== void 0 && fontProps.underline && { underline: { type: "single" } }
6045
6109
  };
6046
6110
  }
@@ -6070,6 +6134,8 @@ function createDocumentStyles(themeNameOrObject = "minimal", language) {
6070
6134
  size: normalStyle?.size,
6071
6135
  color: normalStyle?.color,
6072
6136
  bold: normalStyle?.bold,
6137
+ fontWeight: normalStyle?.fontWeight,
6138
+ case: normalStyle?.case,
6073
6139
  italic: normalStyle?.italic,
6074
6140
  underline: normalStyle?.underline,
6075
6141
  characterSpacing: normalStyle?.characterSpacing,
@@ -6109,6 +6175,8 @@ function createDocumentStyles(themeNameOrObject = "minimal", language) {
6109
6175
  size: headingStyle.size,
6110
6176
  color: headingStyle.color,
6111
6177
  bold: headingStyle.bold,
6178
+ fontWeight: headingStyle.fontWeight,
6179
+ case: headingStyle.case,
6112
6180
  italic: headingStyle.italic,
6113
6181
  underline: headingStyle.underline,
6114
6182
  characterSpacing: headingStyle.characterSpacing,
@@ -6169,6 +6237,8 @@ function createDocumentStyles(themeNameOrObject = "minimal", language) {
6169
6237
  size: headingStyle.size,
6170
6238
  color: headingStyle.color,
6171
6239
  bold: headingStyle.bold,
6240
+ fontWeight: headingStyle.fontWeight,
6241
+ case: headingStyle.case,
6172
6242
  italic: headingStyle.italic,
6173
6243
  underline: headingStyle.underline,
6174
6244
  characterSpacing: headingStyle.characterSpacing,
@@ -6230,6 +6300,8 @@ function createDocumentStyles(themeNameOrObject = "minimal", language) {
6230
6300
  size: titleStyle.size,
6231
6301
  color: titleStyle.color,
6232
6302
  bold: titleStyle.bold,
6303
+ fontWeight: titleStyle.fontWeight,
6304
+ case: titleStyle.case,
6233
6305
  italic: titleStyle.italic,
6234
6306
  underline: titleStyle.underline,
6235
6307
  characterSpacing: titleStyle.characterSpacing,
@@ -6285,6 +6357,8 @@ function createDocumentStyles(themeNameOrObject = "minimal", language) {
6285
6357
  size: subtitleStyle.size,
6286
6358
  color: subtitleStyle.color,
6287
6359
  bold: subtitleStyle.bold,
6360
+ fontWeight: subtitleStyle.fontWeight,
6361
+ case: subtitleStyle.case,
6288
6362
  italic: subtitleStyle.italic,
6289
6363
  underline: subtitleStyle.underline,
6290
6364
  characterSpacing: subtitleStyle.characterSpacing,
@@ -6407,6 +6481,8 @@ function createDocumentStyles(themeNameOrObject = "minimal", language) {
6407
6481
  size: customStyle.size,
6408
6482
  color: customStyle.color,
6409
6483
  bold: customStyle.bold,
6484
+ fontWeight: customStyle.fontWeight,
6485
+ case: customStyle.case,
6410
6486
  italic: customStyle.italic,
6411
6487
  underline: customStyle.underline,
6412
6488
  characterSpacing: customStyle.characterSpacing,
@@ -8282,6 +8358,7 @@ function compileChromeParagraph(component, scope) {
8282
8358
  italic: font.italic ?? false,
8283
8359
  ...font.underline !== void 0 ? { underline: font.underline } : {},
8284
8360
  ...font.fontWeight !== void 0 ? { fontWeight: font.fontWeight } : {},
8361
+ ...font.case !== void 0 ? { case: font.case } : {},
8285
8362
  ...font.lineSpacing !== void 0 ? { lineSpacing: font.lineSpacing } : {}
8286
8363
  }
8287
8364
  };
@@ -9585,7 +9662,11 @@ function isoDateTime(date) {
9585
9662
  }
9586
9663
  function runFormatting3(font, props, ctx) {
9587
9664
  const hasWeightRequest = font.fontWeight != null || font.bold === true;
9588
- const effectiveFamily = font.family ?? (hasWeightRequest ? resolveBodyFamily(ctx.theme) : void 0);
9665
+ const roleName = props.themeStyle;
9666
+ const role = roleName ? ctx.theme.typography?.roles?.[roleName] : void 0;
9667
+ const roleStyles = ctx.theme.styles;
9668
+ const roleFamily = role && roleName ? resolveFontFamily(ctx.theme, roleStyles?.[roleName]?.font ?? role.face) : void 0;
9669
+ const effectiveFamily = font.family ?? (hasWeightRequest ? roleFamily ?? resolveBodyFamily(ctx.theme) : void 0);
9589
9670
  const weighted = applyFontWeightAlias({
9590
9671
  fontFamily: effectiveFamily,
9591
9672
  bold: font.bold,
@@ -9593,7 +9674,7 @@ function runFormatting3(font, props, ctx) {
9593
9674
  fontWeight: font.fontWeight
9594
9675
  });
9595
9676
  const formatting = {};
9596
- if (font.family || weighted.font && weighted.font !== effectiveFamily) {
9677
+ if (font.family || hasWeightRequest && roleFamily || weighted.font && weighted.font !== effectiveFamily) {
9597
9678
  formatting.fontFamily = weighted.font;
9598
9679
  }
9599
9680
  if (font.size) formatting.sizeHalfPoints = pointsToHalfPoints(font.size);
@@ -9605,6 +9686,8 @@ function runFormatting3(font, props, ctx) {
9605
9686
  formatting.underline = font.underline ? { type: "single" } : void 0;
9606
9687
  }
9607
9688
  if (font.scale) formatting.scalePercent = font.scale;
9689
+ if (font.case !== void 0)
9690
+ Object.assign(formatting, capsFormatting2(font.case));
9608
9691
  if (font.characterSpacing) {
9609
9692
  const { type, value } = font.characterSpacing;
9610
9693
  formatting.characterSpacingTwentieths = type === "condensed" ? -value : value;
@@ -9618,7 +9701,7 @@ function applyFontWeightAlias(opts) {
9618
9701
  return { bold: opts.bold, italic: opts.italic };
9619
9702
  }
9620
9703
  const weight = opts.fontWeight ?? (opts.bold === true ? 700 : void 0);
9621
- const synth = synthesizeFamilyName(
9704
+ const synth = synthesizeFamilyName2(
9622
9705
  opts.fontFamily,
9623
9706
  weight,
9624
9707
  opts.italic === true
@@ -9957,15 +10040,13 @@ function compileChart(component, scope) {
9957
10040
  }
9958
10041
  const colors = Array.isArray(props.chartColors) ? props.chartColors.map(
9959
10042
  (color) => resolveColor(String(color), ctx.theme)
9960
- ) : DEFAULT_CHART_THEME_COLORS2.map((token) => {
9961
- const value = ctx.theme?.colors?.[token];
9962
- if (typeof value !== "string" || value.length === 0) return void 0;
10043
+ ) : chartPaletteValues(ctx.theme).flatMap((value) => {
9963
10044
  try {
9964
- return resolveColor(token, ctx.theme);
10045
+ return [resolveColor(value, ctx.theme)];
9965
10046
  } catch {
9966
- return void 0;
10047
+ return [];
9967
10048
  }
9968
- }).filter((color) => color !== void 0);
10049
+ });
9969
10050
  const page = getPageSetup(ctx.theme);
9970
10051
  const contentWidthInches = (page.size.width - page.margin.left - page.margin.right) / 1440;
9971
10052
  const widthInches = typeof props.width === "number" ? props.width : contentWidthInches;
@@ -11310,6 +11391,7 @@ import {
11310
11391
  normalizeHighchartsChart
11311
11392
  } from "@json-to-office/quality";
11312
11393
  import { DEFAULT_DOCX_RENDERER_ID as DEFAULT_DOCX_RENDERER_ID2 } from "@json-to-office/shared-docx";
11394
+ import { designColors as designColors2, resolveDesignColor as resolveDesignColor2 } from "@json-to-office/shared";
11313
11395
 
11314
11396
  // src/core/generationContext.ts
11315
11397
  import { applyExportMode } from "@json-to-office/shared";
@@ -11333,6 +11415,7 @@ function resolveBuiltInTheme(themeName, options = {}) {
11333
11415
  }
11334
11416
 
11335
11417
  // src/themes/overrides.ts
11418
+ import { mergeWithDefaults as mergeWithDefaults3 } from "@json-to-office/shared";
11336
11419
  function applyThemeOverrides(theme, overrides) {
11337
11420
  if (!overrides) return theme;
11338
11421
  const fonts = { ...theme.fonts };
@@ -11346,12 +11429,87 @@ function applyThemeOverrides(theme, overrides) {
11346
11429
  }
11347
11430
  return {
11348
11431
  ...theme,
11432
+ ...Object.fromEntries(
11433
+ ["palette", "typography", "spacing", "chrome", "motif"].flatMap(
11434
+ (name) => {
11435
+ const key = name;
11436
+ return overrides[key] === void 0 ? [] : [[key, mergeWithDefaults3(overrides[key], theme[key] ?? {})]];
11437
+ }
11438
+ )
11439
+ ),
11349
11440
  colors: { ...theme.colors, ...overrides.colors ?? {} },
11350
11441
  fonts,
11351
11442
  ...Object.keys(styles).length > 0 && { styles }
11352
11443
  };
11353
11444
  }
11354
11445
 
11446
+ // src/themes/design-system.ts
11447
+ init_defaults();
11448
+ import {
11449
+ designCanvas,
11450
+ resolveTypeRoles,
11451
+ validateDesignColors
11452
+ } from "@json-to-office/shared";
11453
+ function resolveDocxDesignSystem(theme) {
11454
+ validateDesignColors(theme, getThemeColors(theme));
11455
+ if (!theme.typography && !theme.spacing) return theme;
11456
+ const canvas = designCanvas("docx", theme.page.size);
11457
+ const roles = resolveTypeRoles(theme, canvas, theme.fonts.body.size ?? 11);
11458
+ const styles = { ...theme.styles };
11459
+ for (const [name, role] of Object.entries(roles)) {
11460
+ const spacing = {
11461
+ ...role.spaceBefore !== void 0 && { before: role.spaceBefore },
11462
+ ...role.spaceAfter !== void 0 && { after: role.spaceAfter }
11463
+ };
11464
+ styles[name] = {
11465
+ font: role.face ?? "body",
11466
+ size: role.size,
11467
+ ...role.weight !== void 0 && { fontWeight: role.weight },
11468
+ ...role.color !== void 0 && { color: role.color },
11469
+ ...role.case !== void 0 && { case: role.case },
11470
+ ...role.lineHeight !== void 0 && {
11471
+ lineSpacing: { type: "multiple", value: role.lineHeight }
11472
+ },
11473
+ ...role.tracking !== void 0 && {
11474
+ characterSpacing: {
11475
+ type: role.tracking < 0 ? "condensed" : "expanded",
11476
+ value: Math.abs(role.tracking) * role.size / 5
11477
+ }
11478
+ },
11479
+ ...Object.keys(spacing).length && { spacing },
11480
+ ...styles[name]
11481
+ };
11482
+ }
11483
+ const gap = theme.spacing?.blockGap?.normal ?? theme.spacing?.basePt;
11484
+ const scale = theme.typography?.scale?.[canvas];
11485
+ if (scale || gap !== void 0) {
11486
+ styles.normal = {
11487
+ ...scale && { size: scale.base },
11488
+ ...gap !== void 0 && { spacing: { after: gap } },
11489
+ ...styles.normal
11490
+ };
11491
+ }
11492
+ const space = theme.spacing?.canvas?.[canvas];
11493
+ const safe = space?.safeAreaIn;
11494
+ return {
11495
+ ...theme,
11496
+ styles,
11497
+ page: {
11498
+ ...theme.page,
11499
+ margins: {
11500
+ ...theme.page.margins,
11501
+ ...safe !== void 0 && {
11502
+ top: safe * 1440,
11503
+ bottom: safe * 1440,
11504
+ left: safe * 1440,
11505
+ right: safe * 1440
11506
+ },
11507
+ ...space?.gutterIn !== void 0 && { gutter: space.gutterIn * 1440 }
11508
+ }
11509
+ }
11510
+ };
11511
+ }
11512
+
11355
11513
  // src/core/generationContext.ts
11356
11514
  function defaultNamedThemeLookup(themeName, customThemes, warnings) {
11357
11515
  if (customThemes) {
@@ -11384,6 +11542,7 @@ function resolveThemeContext(documentIn, options = {}) {
11384
11542
  if (themeOverrides) {
11385
11543
  theme = applyThemeOverrides(theme, themeOverrides);
11386
11544
  }
11545
+ theme = resolveDocxDesignSystem(theme);
11387
11546
  const mode = applyExportMode({ doc: document, theme, fonts });
11388
11547
  for (const w of mode.warnings) {
11389
11548
  if (warnings) {
@@ -11934,16 +12093,27 @@ function prepareDocxQualityDocument(document, options = {}) {
11934
12093
  };
11935
12094
  };
11936
12095
  const paletteHexes = {};
11937
- for (const [token, value] of Object.entries(
11938
- resolved.theme.colors ?? {}
11939
- )) {
12096
+ const visualColors = designColors2(
12097
+ resolved.theme.colors,
12098
+ resolved.theme.palette
12099
+ );
12100
+ const entries = {
12101
+ ...visualColors,
12102
+ ...Object.fromEntries(
12103
+ (resolved.theme.palette?.chart ?? []).map((value) => {
12104
+ const hex = resolveDesignColor2(value, visualColors);
12105
+ return [hex ? `#${hex}` : value, value];
12106
+ })
12107
+ )
12108
+ };
12109
+ for (const [token, value] of Object.entries(entries)) {
11940
12110
  if (typeof value !== "string") continue;
11941
- const hex = normalizeHex(value);
12111
+ const hex = normalizeHex(resolveDesignColor2(value, visualColors) ?? value);
11942
12112
  if (hex) paletteHexes[token] = hex;
11943
12113
  }
11944
- const paletteTokens = SERIES_COLOR_TOKENS.filter(
11945
- (token) => paletteHexes[token] !== void 0
11946
- );
12114
+ const paletteTokens = resolved.theme.palette?.chart?.map(
12115
+ (value) => `#${resolveDesignColor2(value, visualColors)}`
12116
+ ) ?? SERIES_COLOR_TOKENS.filter((token) => paletteHexes[token] !== void 0);
11947
12117
  const authoredPropsAt = (pointer) => asRecord(asRecord(nodeAtPointer(context.document, pointer))?.props);
11948
12118
  addFact({
11949
12119
  id: "docx:theme",