@rowsncolumns/utils 9.2.39 → 9.2.41

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 (39) hide show
  1. package/dist/cjs/cell-data-helpers.d.ts +13 -0
  2. package/dist/cjs/cell-data-helpers.d.ts.map +1 -1
  3. package/dist/cjs/cell-data-helpers.js +19 -1
  4. package/dist/cjs/excel-number-format.d.ts +128 -0
  5. package/dist/cjs/excel-number-format.d.ts.map +1 -0
  6. package/dist/cjs/excel-number-format.js +659 -0
  7. package/dist/cjs/formatter.d.ts +20 -0
  8. package/dist/cjs/formatter.d.ts.map +1 -1
  9. package/dist/cjs/formatter.js +300 -2
  10. package/dist/cjs/index.d.ts +2 -0
  11. package/dist/cjs/index.d.ts.map +1 -1
  12. package/dist/cjs/index.js +2 -0
  13. package/dist/cjs/locale.d.ts +15 -0
  14. package/dist/cjs/locale.d.ts.map +1 -1
  15. package/dist/cjs/locale.js +58 -6
  16. package/dist/cjs/sheet-span.d.ts +13 -0
  17. package/dist/cjs/sheet-span.d.ts.map +1 -0
  18. package/dist/cjs/sheet-span.js +24 -0
  19. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  20. package/dist/esm/cell-data-helpers.d.ts +13 -0
  21. package/dist/esm/cell-data-helpers.d.ts.map +1 -1
  22. package/dist/esm/cell-data-helpers.js +14 -0
  23. package/dist/esm/excel-number-format.d.ts +128 -0
  24. package/dist/esm/excel-number-format.d.ts.map +1 -0
  25. package/dist/esm/excel-number-format.js +640 -0
  26. package/dist/esm/formatter.d.ts +20 -0
  27. package/dist/esm/formatter.d.ts.map +1 -1
  28. package/dist/esm/formatter.js +277 -1
  29. package/dist/esm/index.d.ts +2 -0
  30. package/dist/esm/index.d.ts.map +1 -1
  31. package/dist/esm/index.js +2 -0
  32. package/dist/esm/locale.d.ts +15 -0
  33. package/dist/esm/locale.d.ts.map +1 -1
  34. package/dist/esm/locale.js +42 -5
  35. package/dist/esm/sheet-span.d.ts +13 -0
  36. package/dist/esm/sheet-span.d.ts.map +1 -0
  37. package/dist/esm/sheet-span.js +20 -0
  38. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  39. package/package.json +2 -2
@@ -1,9 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ssfFormatColor = exports.ssfFormat = exports.isStandaloneMonthPattern = exports.isTextPattern = exports.isTimePattern = exports.isDateTimePattern = exports.isDatePattern = void 0;
3
+ exports.ssfFormatColor = exports.ssfFormat = exports.withWorkbookSeparators = exports.withShortAmPmMarker = exports.isStandaloneMonthPattern = exports.isTextPattern = exports.isTimePattern = exports.isDateTimePattern = exports.isDatePattern = void 0;
4
4
  var tslib_1 = require("tslib");
5
5
  var numfmt_1 = require("numfmt");
6
6
  var colors_1 = require("./colors");
7
+ var excel_number_format_1 = require("./excel-number-format");
7
8
  /**
8
9
  * Pattern-based type inference (Excel parity). xlsx files routinely carry
9
10
  * a `numberFormat.pattern` without an accompanying `type` field — these
@@ -188,12 +189,309 @@ var localeForPattern = function (pattern, locale) {
188
189
  }
189
190
  return standalone ? ((_a = getStandaloneMonthLocale(locale)) !== null && _a !== void 0 ? _a : locale) : locale;
190
191
  };
192
+ var shortAmPmLocales = new Map();
193
+ /**
194
+ * Excel's `A/P` renders one letter (`6:00 P`) in every locale, but numfmt
195
+ * honours the short form only when no locale is passed — under a locale it
196
+ * emits that locale's full designator (`6:00 PM`). Patterns with `A/P` render
197
+ * under a companion locale whose AM/PM designators are `A`/`P`. `locale` is a
198
+ * BCP 47 tag or an Excel LCID (`409`), as numfmt accepts both.
199
+ */
200
+ var getShortAmPmLocale = function (locale) {
201
+ var _a;
202
+ var cached = shortAmPmLocales.get(locale);
203
+ if (cached !== undefined)
204
+ return cached;
205
+ var overlay = locale;
206
+ try {
207
+ overlay = "ampm_".concat(locale.replace(/[^a-z\d]/gi, ""));
208
+ (0, numfmt_1.addLocale)(tslib_1.__assign(tslib_1.__assign({}, ((_a = (0, numfmt_1.getLocale)(locale)) !== null && _a !== void 0 ? _a : {})), { ampm: ["A", "P"] }), overlay);
209
+ }
210
+ catch (_b) {
211
+ overlay = locale;
212
+ }
213
+ shortAmPmLocales.set(locale, overlay);
214
+ return overlay;
215
+ };
216
+ /**
217
+ * An Excel `[$-LCID]` / `[$symbol-LCID]` token pins the section's locale, and
218
+ * numfmt resolves it to that LCID's own table — ahead of the companion locale
219
+ * `ssfFormat` passes, so `[$-409]h:mm A/P` would still render `6:00 PM`.
220
+ * Re-point a known LCID or tag at its companion (`$-409` → `$-ampm_409`); an
221
+ * LCID numfmt does not know (`F400`) or one carrying calendar bits stays as
222
+ * written.
223
+ */
224
+ var shortAmPmLocaleToken = function (token) {
225
+ var dash = token.indexOf("-");
226
+ if (dash < 0)
227
+ return token;
228
+ var code = token.slice(dash + 1);
229
+ var wincode = Number.parseInt(code, 16);
230
+ if (Number.isFinite(wincode) && wincode & 0xff0000)
231
+ return token;
232
+ if (!(0, numfmt_1.getLocale)(code))
233
+ return token;
234
+ return "".concat(token.slice(0, dash + 1)).concat(getShortAmPmLocale(code));
235
+ };
236
+ /**
237
+ * Does the pattern carry Excel's short `A/P` marker outside quoted literals,
238
+ * bracket directives and escapes? Returns the pattern with the marker
239
+ * upper-cased (Excel accepts `a/p` and renders it `A`/`P`; numfmt only
240
+ * tokenizes `A/P`) and its `[$-LCID]` tokens re-pointed at the companion
241
+ * `A`/`P` locale, or `undefined` when there is none.
242
+ */
243
+ var withShortAmPmMarker = function (pattern) {
244
+ var e_1, _a;
245
+ var _b;
246
+ var chunks = [];
247
+ var localeChunks = [];
248
+ var found = false;
249
+ var inQuotes = false;
250
+ var inBrackets = false;
251
+ for (var i = 0; i < pattern.length; i++) {
252
+ var char = pattern[i];
253
+ if (inQuotes) {
254
+ inQuotes = char !== '"';
255
+ }
256
+ else if (inBrackets) {
257
+ inBrackets = char !== "]";
258
+ }
259
+ else if (char === '"') {
260
+ inQuotes = true;
261
+ }
262
+ else if (char === "[") {
263
+ var end = pattern[i + 1] === "$" ? pattern.indexOf("]", i) : -1;
264
+ if (end > 0) {
265
+ localeChunks.push(chunks.length);
266
+ chunks.push(pattern.slice(i + 1, end));
267
+ i = end;
268
+ continue;
269
+ }
270
+ inBrackets = true;
271
+ }
272
+ else if (char === "\\" || char === "_" || char === "*") {
273
+ chunks.push(char + ((_b = pattern[i + 1]) !== null && _b !== void 0 ? _b : ""));
274
+ i++;
275
+ continue;
276
+ }
277
+ else if ((char === "A" || char === "a") &&
278
+ pattern[i + 1] === "/" &&
279
+ (pattern[i + 2] === "P" || pattern[i + 2] === "p")) {
280
+ chunks.push("A/P");
281
+ found = true;
282
+ i += 2;
283
+ continue;
284
+ }
285
+ chunks.push(char);
286
+ }
287
+ if (!found)
288
+ return undefined;
289
+ try {
290
+ for (var localeChunks_1 = tslib_1.__values(localeChunks), localeChunks_1_1 = localeChunks_1.next(); !localeChunks_1_1.done; localeChunks_1_1 = localeChunks_1.next()) {
291
+ var index = localeChunks_1_1.value;
292
+ chunks[index] = "[".concat(shortAmPmLocaleToken(chunks[index]), "]");
293
+ }
294
+ }
295
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
296
+ finally {
297
+ try {
298
+ if (localeChunks_1_1 && !localeChunks_1_1.done && (_a = localeChunks_1.return)) _a.call(localeChunks_1);
299
+ }
300
+ finally { if (e_1) throw e_1.error; }
301
+ }
302
+ return chunks.join("");
303
+ };
304
+ exports.withShortAmPmMarker = withShortAmPmMarker;
305
+ var shortAmPmPatternCache = new Map();
306
+ var DEFAULT_SEPARATORS = { decimal: ".", group: "," };
307
+ var separatorsFor = function (locale) {
308
+ var _a, _b;
309
+ if (!locale)
310
+ return DEFAULT_SEPARATORS;
311
+ var l10n = (0, numfmt_1.getLocale)(locale);
312
+ if (!l10n)
313
+ return DEFAULT_SEPARATORS;
314
+ return {
315
+ decimal: (_a = l10n.decimal) !== null && _a !== void 0 ? _a : ".",
316
+ group: (_b = l10n.group) !== null && _b !== void 0 ? _b : ",",
317
+ };
318
+ };
319
+ /**
320
+ * Rewrite the `[$symbol-LCID]` tokens of one section through `rewrite`,
321
+ * which receives the bracket content (`€-407`) and returns the new content,
322
+ * or an empty string to drop the token. Quoted literals, escapes and other
323
+ * bracket directives are left as written.
324
+ */
325
+ var rewriteSectionLocaleTokens = function (section, rewrite) {
326
+ var _a;
327
+ var out = "";
328
+ var inQuotes = false;
329
+ var inBrackets = false;
330
+ for (var i = 0; i < section.length; i++) {
331
+ var char = section[i];
332
+ if (inQuotes) {
333
+ inQuotes = char !== '"';
334
+ }
335
+ else if (inBrackets) {
336
+ inBrackets = char !== "]";
337
+ }
338
+ else if (char === '"') {
339
+ inQuotes = true;
340
+ }
341
+ else if (char === "[") {
342
+ var end = section[i + 1] === "$" ? section.indexOf("]", i) : -1;
343
+ if (end > 0) {
344
+ var token = rewrite(section.slice(i + 1, end));
345
+ if (token)
346
+ out += "[".concat(token, "]");
347
+ i = end;
348
+ continue;
349
+ }
350
+ inBrackets = true;
351
+ }
352
+ else if (char === "\\" || char === "_" || char === "*") {
353
+ out += char + ((_a = section[i + 1]) !== null && _a !== void 0 ? _a : "");
354
+ i++;
355
+ continue;
356
+ }
357
+ out += char;
358
+ }
359
+ return out;
360
+ };
361
+ /** `[$€-407]` → `[$€]`; a bare `[$-407]` goes away. */
362
+ var currencySymbolOnly = function (token) {
363
+ var dash = token.indexOf("-");
364
+ var symbol = dash < 0 ? token : token.slice(0, dash);
365
+ return symbol.length > 1 ? symbol : "";
366
+ };
367
+ var separatorLocales = new Map();
368
+ /**
369
+ * Companion numfmt locale carrying `locale`'s calendar names and AM/PM with
370
+ * the workbook's decimal / group separators, so a date section pinned to
371
+ * `[$-407]` renders German names but a workbook decimal mark in `ss.00`.
372
+ * Returns `locale` itself when its separators already match.
373
+ */
374
+ var getWorkbookSeparatorLocale = function (locale, separators) {
375
+ var key = "".concat(locale, "\0").concat(separators.decimal, "\0").concat(separators.group);
376
+ var cached = separatorLocales.get(key);
377
+ if (cached !== undefined)
378
+ return cached;
379
+ var overlay = locale;
380
+ try {
381
+ var base = (0, numfmt_1.getLocale)(locale);
382
+ if (base &&
383
+ (base.decimal !== separators.decimal || base.group !== separators.group)) {
384
+ // numfmt locale ids are `[a-z\d]+` with one optional `_` part.
385
+ var hex = function (text) {
386
+ return tslib_1.__spreadArray([], tslib_1.__read(text), false).map(function (c) { return c.codePointAt(0).toString(16); }).join("x");
387
+ };
388
+ overlay = "sep".concat(hex(separators.decimal), "x").concat(hex(separators.group), "_").concat(locale.replace(/[^a-z\d]/gi, ""));
389
+ (0, numfmt_1.addLocale)(tslib_1.__assign(tslib_1.__assign({}, base), { decimal: separators.decimal, group: separators.group }), overlay);
390
+ }
391
+ }
392
+ catch (_a) {
393
+ overlay = locale;
394
+ }
395
+ separatorLocales.set(key, overlay);
396
+ return overlay;
397
+ };
398
+ /**
399
+ * Re-point a date section's `[$symbol-LCID]` token at the companion locale
400
+ * with the workbook's separators (`$-407` → `$-sep2ex2c_407`). An LCID numfmt
401
+ * does not know or one carrying calendar bits stays as written.
402
+ */
403
+ var workbookSeparatorLocaleToken = function (separators) {
404
+ return function (token) {
405
+ var dash = token.indexOf("-");
406
+ if (dash < 0)
407
+ return token;
408
+ var code = token.slice(dash + 1);
409
+ var wincode = Number.parseInt(code, 16);
410
+ if (Number.isFinite(wincode) && wincode & 0xff0000)
411
+ return token;
412
+ if (!(0, numfmt_1.getLocale)(code))
413
+ return token;
414
+ return "".concat(token.slice(0, dash + 1)).concat(getWorkbookSeparatorLocale(code, separators));
415
+ };
416
+ };
417
+ var isDateSection = function (section) {
418
+ try {
419
+ return (0, numfmt_1.isDateFormat)(section);
420
+ }
421
+ catch (_a) {
422
+ return false;
423
+ }
424
+ };
425
+ /**
426
+ * Excel's `[$symbol-LCID]` token selects the currency symbol and the
427
+ * language of day/month names and AM/PM; digit grouping and the decimal
428
+ * separator follow the workbook locale (`[$€-407] #,##0.00` is
429
+ * `€ 1,234.50` on a US host). numfmt applies the token's locale to the whole
430
+ * section, separators included, so the locale part is dropped from every
431
+ * section that is not a date (number, scientific, fraction, text, …); a
432
+ * date section keeps the token for its names, re-pointed at a companion
433
+ * locale that carries the workbook's separators for fractional seconds.
434
+ * Returns `undefined` when nothing had to change.
435
+ */
436
+ var withWorkbookSeparators = function (pattern, locale) {
437
+ if (!pattern.includes("[$"))
438
+ return undefined;
439
+ var sections = (0, excel_number_format_1.splitFormatSections)(pattern);
440
+ var changed = false;
441
+ var dateTokens;
442
+ var rewritten = sections.map(function (section) {
443
+ if (!section.includes("[$"))
444
+ return section;
445
+ var rewrite = currencySymbolOnly;
446
+ if (isDateSection(section)) {
447
+ dateTokens !== null && dateTokens !== void 0 ? dateTokens : (dateTokens = workbookSeparatorLocaleToken(separatorsFor(locale)));
448
+ rewrite = dateTokens;
449
+ }
450
+ var stripped = rewriteSectionLocaleTokens(section, rewrite);
451
+ changed || (changed = stripped !== section);
452
+ return stripped;
453
+ });
454
+ return changed ? rewritten.join(";") : undefined;
455
+ };
456
+ exports.withWorkbookSeparators = withWorkbookSeparators;
457
+ var workbookSeparatorPatternCache = new Map();
458
+ var withWorkbookSeparatorsCached = function (code, locale) {
459
+ var _a;
460
+ var key = "".concat(locale !== null && locale !== void 0 ? locale : "", "\0").concat(code);
461
+ var rewritten = workbookSeparatorPatternCache.get(key);
462
+ if (rewritten === undefined) {
463
+ rewritten = (_a = (0, exports.withWorkbookSeparators)(code, locale)) !== null && _a !== void 0 ? _a : code;
464
+ workbookSeparatorPatternCache.set(key, rewritten);
465
+ }
466
+ return rewritten;
467
+ };
191
468
  var ssfFormat = function (pattern, value, locale) {
192
469
  try {
470
+ var shortAmPm = shortAmPmPatternCache.get(pattern);
471
+ if (shortAmPm === undefined && !shortAmPmPatternCache.has(pattern)) {
472
+ shortAmPm = (0, exports.withShortAmPmMarker)(pattern);
473
+ shortAmPmPatternCache.set(pattern, shortAmPm);
474
+ }
475
+ var code = withWorkbookSeparatorsCached(shortAmPm !== null && shortAmPm !== void 0 ? shortAmPm : pattern, locale);
476
+ var patternLocale = localeForPattern(pattern, locale);
477
+ if (shortAmPm !== undefined && patternLocale) {
478
+ patternLocale = getShortAmPmLocale(patternLocale);
479
+ }
480
+ var options_1 = { locale: patternLocale };
481
+ if (typeof value === "number") {
482
+ // Excel decides rounding, `General`, huge magnitudes and conditional
483
+ // sections from the 15-significant-digit decimal, not the binary
484
+ // double (#546 U8 / U21).
485
+ var pre = (0, excel_number_format_1.excelNumberPrePass)(code, value, separatorsFor(locale), function (section, sectionValue) { return (0, numfmt_1.format)(section, sectionValue, options_1); });
486
+ if (pre.text !== undefined) {
487
+ return pre.text;
488
+ }
489
+ value = pre.value;
490
+ }
193
491
  var isNegativeElapsedTime = typeof value === "number" &&
194
492
  value < 0 &&
195
493
  isSingleSectionElapsedTimePattern(pattern);
196
- var formatted = (0, numfmt_1.format)(pattern, isNegativeElapsedTime ? Math.abs(value) : value, { locale: localeForPattern(pattern, locale) });
494
+ var formatted = (0, numfmt_1.format)(code, isNegativeElapsedTime ? Math.abs(value) : value, options_1);
197
495
  return isNegativeElapsedTime ? "-".concat(formatted) : formatted;
198
496
  }
199
497
  catch (err) {
@@ -9,6 +9,7 @@ export * from "./locale";
9
9
  export * from "./date";
10
10
  export * from "./log";
11
11
  export * from "./array";
12
+ export * from "./excel-number-format";
12
13
  export * from "./formatter";
13
14
  export * from "./memoize";
14
15
  export * from "./cell-data-helpers";
@@ -22,4 +23,5 @@ export * from "./data-validation";
22
23
  export * from "./content-hash";
23
24
  export * from "./shared-string-canonical";
24
25
  export * from "./keyboard";
26
+ export * from "./sheet-span";
25
27
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,OAAO,CAAC;AACtB,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,QAAQ,CAAC;AACvB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,OAAO,CAAC;AACtB,cAAc,SAAS,CAAC;AACxB,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,QAAQ,CAAC;AACvB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC"}
package/dist/cjs/index.js CHANGED
@@ -12,6 +12,7 @@ tslib_1.__exportStar(require("./locale"), exports);
12
12
  tslib_1.__exportStar(require("./date"), exports);
13
13
  tslib_1.__exportStar(require("./log"), exports);
14
14
  tslib_1.__exportStar(require("./array"), exports);
15
+ tslib_1.__exportStar(require("./excel-number-format"), exports);
15
16
  tslib_1.__exportStar(require("./formatter"), exports);
16
17
  tslib_1.__exportStar(require("./memoize"), exports);
17
18
  tslib_1.__exportStar(require("./cell-data-helpers"), exports);
@@ -25,3 +26,4 @@ tslib_1.__exportStar(require("./data-validation"), exports);
25
26
  tslib_1.__exportStar(require("./content-hash"), exports);
26
27
  tslib_1.__exportStar(require("./shared-string-canonical"), exports);
27
28
  tslib_1.__exportStar(require("./keyboard"), exports);
29
+ tslib_1.__exportStar(require("./sheet-span"), exports);
@@ -16,6 +16,21 @@ export declare const getLocaleDateParts: (locale: string) => [DatePartType, stri
16
16
  * de-DE → `d.m.yyyy`, hu-HU → `yyyy. mm. dd.`, en-CA → `yyyy-mm-dd`.
17
17
  */
18
18
  export declare const getDefaultDateFormat: (locale?: string) => string;
19
+ export interface DateFieldTokens {
20
+ day: "d" | "dd";
21
+ month: "m" | "mm";
22
+ year: "yy" | "yyyy";
23
+ }
24
+ /**
25
+ * The day / month / year tokens of {@link getDefaultDateFormat} for a
26
+ * locale, i.e. whether the locale zero-pads each numeric field — ru-RU
27
+ * (`dd.mm.yyyy`) → `{ day: "dd", month: "mm", year: "yyyy" }`, en-US
28
+ * (`m/d/yyyy`) → `{ day: "d", month: "m", year: "yyyy" }`. A date typed
29
+ * as digits is displayed with the locale's own padding (Excel re-renders
30
+ * `30.9.2025` as `30.09.2025` under ru-RU), so the date parser assigns
31
+ * these tokens rather than echoing the padding the user happened to type.
32
+ */
33
+ export declare const getDefaultDateFieldTokens: (locale?: string) => DateFieldTokens;
19
34
  /**
20
35
  * Default time pattern for a locale, honoring its 12/24-hour convention,
21
36
  * separators and hour padding — e.g. en-US → `h:mm:ss AM/PM`,
@@ -1 +1 @@
1
- {"version":3,"file":"locale.d.ts","sourceRoot":"","sources":["../../locale.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,gBAAgB,cAU5B,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;AAEpD;;;;;;GAMG;AACH,eAAO,MAAM,6BAA6B,GAAI,QAAQ,MAAM,qCAkC3D,CAAC;AAEF,eAAO,MAAM,kBAAkB,sDAAyC,CAAC;AAqFzE;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAAI,SAAQ,MAA2B,WAClC,CAAC;AAuCvC;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAC/B,SAAQ,MAA2B,EACnC,YAAW,QAAQ,GAAG,QAAmB,WACS,CAAC;AAErD,eAAO,MAAM,wBAAwB,GAAI,SAAS,MAAM,WAEvD,CAAC;AA2CF;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAAI,SAAQ,MAA2B,WAClC,CAAC"}
1
+ {"version":3,"file":"locale.d.ts","sourceRoot":"","sources":["../../locale.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,gBAAgB,cAU5B,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;AAEpD;;;;;;GAMG;AACH,eAAO,MAAM,6BAA6B,GAAI,QAAQ,MAAM,qCAkC3D,CAAC;AAEF,eAAO,MAAM,kBAAkB,sDAAyC,CAAC;AAiGzE;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAAI,SAAQ,MAA2B,WAClC,CAAC;AAEvC,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,GAAG,GAAG,IAAI,CAAC;IAChB,KAAK,EAAE,GAAG,GAAG,IAAI,CAAC;IAClB,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC;CACrB;AAwBD;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,GACpC,SAAQ,MAA2B,KAClC,eAA4D,CAAC;AAuChE;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAC/B,SAAQ,MAA2B,EACnC,YAAW,QAAQ,GAAG,QAAmB,WACS,CAAC;AAErD,eAAO,MAAM,wBAAwB,GAAI,SAAS,MAAM,WAEvD,CAAC;AA2CF;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAAI,SAAQ,MAA2B,WAClC,CAAC"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getLongDateFormat = exports.getDefaultDateTimeFormat = exports.getDefaultTimeFormat = exports.getDefaultDateFormat = exports.getLocaleDateParts = exports.getLocaleDatePartsNotMemoized = exports.getCurrentLocale = void 0;
3
+ exports.getLongDateFormat = exports.getDefaultDateTimeFormat = exports.getDefaultTimeFormat = exports.getDefaultDateFieldTokens = exports.getDefaultDateFormat = exports.getLocaleDateParts = exports.getLocaleDatePartsNotMemoized = exports.getCurrentLocale = void 0;
4
4
  var tslib_1 = require("tslib");
5
5
  var memoize_1 = require("./memoize");
6
6
  var defaultLocale;
@@ -134,9 +134,15 @@ var buildPatternFromParts = function (parts, toToken) {
134
134
  // trailing fields we skipped (e.g. an era) — trim stray whitespace.
135
135
  return pattern.trim();
136
136
  };
137
- var getDefaultDateFormatMemoized = (0, memoize_1.memoize)(function (locale) {
137
+ /**
138
+ * `formatToParts` of the locale's numeric short date for the sample
139
+ * instant — the single source both the default pattern and its per-field
140
+ * tokens are read from, so they can never disagree. Empty when Intl has
141
+ * no data for the locale.
142
+ */
143
+ var getDefaultDateParts = (0, memoize_1.memoize)(function (locale) {
138
144
  try {
139
- var parts = new Intl.DateTimeFormat(locale, {
145
+ return new Intl.DateTimeFormat(locale, {
140
146
  calendar: "gregory",
141
147
  numberingSystem: "latn",
142
148
  year: "numeric",
@@ -144,13 +150,15 @@ var getDefaultDateFormatMemoized = (0, memoize_1.memoize)(function (locale) {
144
150
  day: "numeric",
145
151
  timeZone: "UTC",
146
152
  }).formatToParts(FORMAT_SAMPLE_DATE);
147
- var pattern = buildPatternFromParts(parts, dateFieldToken);
148
- return pattern || "m/d/yyyy";
149
153
  }
150
154
  catch (err) {
151
- return "m/d/yyyy";
155
+ return [];
152
156
  }
153
157
  });
158
+ var getDefaultDateFormatMemoized = (0, memoize_1.memoize)(function (locale) {
159
+ var pattern = buildPatternFromParts(getDefaultDateParts(locale), dateFieldToken);
160
+ return pattern || "m/d/yyyy";
161
+ });
154
162
  /**
155
163
  * Default numeric (short) date pattern for a locale, preserving the
156
164
  * locale's field order, separators, literal text and zero-padding as
@@ -162,6 +170,50 @@ var getDefaultDateFormat = function (locale) {
162
170
  return getDefaultDateFormatMemoized(locale);
163
171
  };
164
172
  exports.getDefaultDateFormat = getDefaultDateFormat;
173
+ var getDefaultDateFieldTokensMemoized = (0, memoize_1.memoize)(function (locale) {
174
+ var e_3, _a;
175
+ var tokens = { day: "d", month: "m", year: "yyyy" };
176
+ try {
177
+ for (var _b = tslib_1.__values(getDefaultDateParts(locale)), _c = _b.next(); !_c.done; _c = _b.next()) {
178
+ var part = _c.value;
179
+ switch (part.type) {
180
+ case "day":
181
+ tokens.day = part.value.length === 2 ? "dd" : "d";
182
+ break;
183
+ case "month":
184
+ tokens.month = part.value.length === 2 ? "mm" : "m";
185
+ break;
186
+ case "year":
187
+ tokens.year = part.value.length === 2 ? "yy" : "yyyy";
188
+ break;
189
+ default:
190
+ break;
191
+ }
192
+ }
193
+ }
194
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
195
+ finally {
196
+ try {
197
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
198
+ }
199
+ finally { if (e_3) throw e_3.error; }
200
+ }
201
+ return tokens;
202
+ });
203
+ /**
204
+ * The day / month / year tokens of {@link getDefaultDateFormat} for a
205
+ * locale, i.e. whether the locale zero-pads each numeric field — ru-RU
206
+ * (`dd.mm.yyyy`) → `{ day: "dd", month: "mm", year: "yyyy" }`, en-US
207
+ * (`m/d/yyyy`) → `{ day: "d", month: "m", year: "yyyy" }`. A date typed
208
+ * as digits is displayed with the locale's own padding (Excel re-renders
209
+ * `30.9.2025` as `30.09.2025` under ru-RU), so the date parser assigns
210
+ * these tokens rather than echoing the padding the user happened to type.
211
+ */
212
+ var getDefaultDateFieldTokens = function (locale) {
213
+ if (locale === void 0) { locale = (0, exports.getCurrentLocale)(); }
214
+ return getDefaultDateFieldTokensMemoized(locale);
215
+ };
216
+ exports.getDefaultDateFieldTokens = getDefaultDateFieldTokens;
165
217
  var getDefaultTimeFormatMemoized = (0, memoize_1.memoize)(function (locale, precision) {
166
218
  try {
167
219
  var parts = new Intl.DateTimeFormat(locale, tslib_1.__assign(tslib_1.__assign({ numberingSystem: "latn", hour: "numeric", minute: "numeric" }, (precision === "second" ? { second: "numeric" } : {})), { timeZone: "UTC" })).formatToParts(FORMAT_SAMPLE_DATE);
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Sheets covered by a 3-D reference span `first:last` (`Sheet1:Sheet3!A1`):
3
+ * every name between the two endpoints in tab order, inclusive. Excel spans
4
+ * the tabs between the endpoints whichever one is written first and matches
5
+ * sheet names case-insensitively. Returns undefined when an endpoint is not a
6
+ * sheet (the caller reports #REF!).
7
+ * @param sheetNames sheet names in tab order
8
+ * @param first
9
+ * @param last
10
+ * @returns
11
+ */
12
+ export declare const resolveSheetSpan: (sheetNames: readonly string[], first: string, last: string) => string[] | undefined;
13
+ //# sourceMappingURL=sheet-span.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sheet-span.d.ts","sourceRoot":"","sources":["../../sheet-span.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB,GAC3B,YAAY,SAAS,MAAM,EAAE,EAC7B,OAAO,MAAM,EACb,MAAM,MAAM,KACX,MAAM,EAAE,GAAG,SAQb,CAAC"}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveSheetSpan = void 0;
4
+ /**
5
+ * Sheets covered by a 3-D reference span `first:last` (`Sheet1:Sheet3!A1`):
6
+ * every name between the two endpoints in tab order, inclusive. Excel spans
7
+ * the tabs between the endpoints whichever one is written first and matches
8
+ * sheet names case-insensitively. Returns undefined when an endpoint is not a
9
+ * sheet (the caller reports #REF!).
10
+ * @param sheetNames sheet names in tab order
11
+ * @param first
12
+ * @param last
13
+ * @returns
14
+ */
15
+ var resolveSheetSpan = function (sheetNames, first, last) {
16
+ var lower = sheetNames.map(function (name) { return name.toLowerCase(); });
17
+ var start = lower.indexOf(first.toLowerCase());
18
+ var end = lower.indexOf(last.toLowerCase());
19
+ if (start === -1 || end === -1) {
20
+ return undefined;
21
+ }
22
+ return sheetNames.slice(Math.min(start, end), Math.max(start, end) + 1);
23
+ };
24
+ exports.resolveSheetSpan = resolveSheetSpan;
@@ -1 +1 @@
1
- {"root":["../../array.ts","../../cell-data-helpers.ts","../../color.ts","../../colors.ts","../../conditional-format.ts","../../content-hash.ts","../../data-validation.ts","../../date.ts","../../dom.ts","../../formatter.ts","../../formula-refs.ts","../../formula.ts","../../index.ts","../../keyboard.ts","../../locale.ts","../../log.ts","../../memoize.ts","../../numbers.ts","../../selection.ts","../../shared-string-canonical.ts","../../sort.ts","../../string.ts","../../table-styles.ts","../../typeguards.ts","../../uuid.ts","../../vitest.config.ts"],"version":"5.8.3"}
1
+ {"root":["../../array.ts","../../cell-data-helpers.ts","../../color.ts","../../colors.ts","../../conditional-format.ts","../../content-hash.ts","../../data-validation.ts","../../date.ts","../../dom.ts","../../excel-number-format.ts","../../formatter.ts","../../formula-refs.ts","../../formula.ts","../../index.ts","../../keyboard.ts","../../locale.ts","../../log.ts","../../memoize.ts","../../numbers.ts","../../selection.ts","../../shared-string-canonical.ts","../../sheet-span.ts","../../sort.ts","../../string.ts","../../table-styles.ts","../../typeguards.ts","../../uuid.ts","../../vitest.config.ts"],"version":"5.8.3"}
@@ -31,6 +31,19 @@ export declare const getExtendedValueError: (extValue?: Record<string, any> | nu
31
31
  * `getDefaultHorizontalAlignment(sheetId, rowIndex, columnIndex)` so a toolbar
32
32
  * alignment selector reports the alignment the grid actually draws.
33
33
  */
34
+ /**
35
+ * Excel's `justify` and `distributed` alignments imply word wrap: the cell
36
+ * wraps inside its own width even without `wrapStrategy: "wrap"` (there is
37
+ * nothing to spread across otherwise) and the row auto-fits the wrapped
38
+ * lines. Shared by the canvas renderer (wrap + overflow decision) and the
39
+ * state hooks' row auto-height so both agree on which cells wrap.
40
+ */
41
+ export declare const alignmentImpliesWrap: (align: HorizontalAlign | string | null | undefined) => boolean;
42
+ /**
43
+ * Whether a cell format wraps its text — explicit `wrapStrategy: "wrap"` or
44
+ * an alignment that wraps implicitly ({@link alignmentImpliesWrap}).
45
+ */
46
+ export declare const cellFormatWrapsText: (format: Pick<CellFormat, "wrapStrategy" | "horizontalAlignment"> | null | undefined) => boolean;
34
47
  export declare const resolveDefaultHorizontalAlignment: ({ errorValue, userEnteredValue, effectiveValue, dataValidation, }: {
35
48
  errorValue: unknown;
36
49
  userEnteredValue: Record<string, any> | null | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"cell-data-helpers.d.ts","sourceRoot":"","sources":["../../cell-data-helpers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,QAAQ,EACR,UAAU,EACV,kBAAkB,EAClB,eAAe,EACf,cAAc,EACf,MAAM,4BAA4B,CAAC;AAEpC,eAAO,MAAM,uBAAuB,GAAI,CAAC,SAAS,QAAQ,EACxD,OAAO,CAAC,GAAG,IAAI,KACd,CAAC,CAAC,IAAI,CAER,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,CAAC,SAAS,QAAQ,EACtD,OAAO,CAAC,GAAG,IAAI,KACd,CAAC,CAAC,IAAI,CAER,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAI,CAAC,SAAS,QAAQ,EACzD,OAAO,CAAC,GAAG,IAAI,KACd,CAAC,CAAC,IAAI,CAER,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,CAAC,SAAS,QAAQ,EACvD,OAAO,CAAC,GAAG,IAAI,KACd,UAAU,GAAG,cAAc,GAAG,IAAI,GAAG,SAEvC,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,CAAC,SAAS,QAAQ,EACtD,OAAO,CAAC,GAAG,IAAI,KACd,MAAM,GAAG,SAAS,GAAG,IAEvB,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,UAAU,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAG,MAE1D,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,WAAW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,KACpC,MAAM,GAAG,SAEX,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,WAAW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,KACpC,MAAM,GAAG,SAEX,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,WAAW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,KACpC,OAAO,GAAG,SAEZ,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAClC,WAAW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,KACpC,MAAM,GAAG,SAEX,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,WAAW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,KACpC,GAAG,GAAG,SAER,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,iCAAiC,GAAI,mEAK/C;IACD,UAAU,EAAE,OAAO,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IACzD,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IACvD,cAAc,EAAE,IAAI,CAAC,kBAAkB,EAAE,WAAW,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;CAC1E,KAAG,eAAe,GAAG,SASrB,CAAC"}
1
+ {"version":3,"file":"cell-data-helpers.d.ts","sourceRoot":"","sources":["../../cell-data-helpers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,QAAQ,EACR,UAAU,EACV,kBAAkB,EAClB,eAAe,EACf,cAAc,EACf,MAAM,4BAA4B,CAAC;AAEpC,eAAO,MAAM,uBAAuB,GAAI,CAAC,SAAS,QAAQ,EACxD,OAAO,CAAC,GAAG,IAAI,KACd,CAAC,CAAC,IAAI,CAER,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,CAAC,SAAS,QAAQ,EACtD,OAAO,CAAC,GAAG,IAAI,KACd,CAAC,CAAC,IAAI,CAER,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAI,CAAC,SAAS,QAAQ,EACzD,OAAO,CAAC,GAAG,IAAI,KACd,CAAC,CAAC,IAAI,CAER,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,CAAC,SAAS,QAAQ,EACvD,OAAO,CAAC,GAAG,IAAI,KACd,UAAU,GAAG,cAAc,GAAG,IAAI,GAAG,SAEvC,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,CAAC,SAAS,QAAQ,EACtD,OAAO,CAAC,GAAG,IAAI,KACd,MAAM,GAAG,SAAS,GAAG,IAEvB,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,UAAU,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAG,MAE1D,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,WAAW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,KACpC,MAAM,GAAG,SAEX,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,WAAW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,KACpC,MAAM,GAAG,SAEX,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,WAAW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,KACpC,OAAO,GAAG,SAEZ,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAClC,WAAW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,KACpC,MAAM,GAAG,SAEX,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,WAAW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,KACpC,GAAG,GAAG,SAER,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,GAC/B,OAAO,eAAe,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,KACjD,OAAyD,CAAC;AAE7D;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAC9B,QACI,IAAI,CAAC,UAAU,EAAE,cAAc,GAAG,qBAAqB,CAAC,GACxD,IAAI,GACJ,SAAS,KACZ,OAEgD,CAAC;AAEpD,eAAO,MAAM,iCAAiC,GAAI,mEAK/C;IACD,UAAU,EAAE,OAAO,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IACzD,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IACvD,cAAc,EAAE,IAAI,CAAC,kBAAkB,EAAE,WAAW,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;CAC1E,KAAG,eAAe,GAAG,SASrB,CAAC"}
@@ -52,6 +52,20 @@ export const getExtendedValueError = (extValue) => {
52
52
  * `getDefaultHorizontalAlignment(sheetId, rowIndex, columnIndex)` so a toolbar
53
53
  * alignment selector reports the alignment the grid actually draws.
54
54
  */
55
+ /**
56
+ * Excel's `justify` and `distributed` alignments imply word wrap: the cell
57
+ * wraps inside its own width even without `wrapStrategy: "wrap"` (there is
58
+ * nothing to spread across otherwise) and the row auto-fits the wrapped
59
+ * lines. Shared by the canvas renderer (wrap + overflow decision) and the
60
+ * state hooks' row auto-height so both agree on which cells wrap.
61
+ */
62
+ export const alignmentImpliesWrap = (align) => align === "justify" || align === "distributed";
63
+ /**
64
+ * Whether a cell format wraps its text — explicit `wrapStrategy: "wrap"` or
65
+ * an alignment that wraps implicitly ({@link alignmentImpliesWrap}).
66
+ */
67
+ export const cellFormatWrapsText = (format) => format?.wrapStrategy === "wrap" ||
68
+ alignmentImpliesWrap(format?.horizontalAlignment);
55
69
  export const resolveDefaultHorizontalAlignment = ({ errorValue, userEnteredValue, effectiveValue, dataValidation, }) => {
56
70
  const isBoolean = getExtendedValueBool(userEnteredValue) !== undefined;
57
71
  const isCheckbox = dataValidation?.condition?.type === "BOOLEAN";