@bicharts/chart-host 0.5.105 → 0.5.106

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.
package/dist/index.mjs CHANGED
@@ -934,6 +934,14 @@ function cleanFormat(raw, dialect) {
934
934
  if (!s2.trim() || /^general$/i.test(s2.trim())) return null;
935
935
  return hasDateToken(s2, dialect) ? s2 : null;
936
936
  }
937
+ function isExcelDateFormat(raw) {
938
+ if (!raw) return false;
939
+ const bare = stripLiterals(firstSection(String(raw), "excel"), "excel");
940
+ if (/\[(h+|m+|s+)\]/i.test(bare)) return false;
941
+ const tokens = bare.replace(/\[[^\]]*\]/g, "").trim();
942
+ if (!tokens || /^general$/i.test(tokens)) return false;
943
+ return /[ymdhs]/i.test(tokens);
944
+ }
937
945
  function firstSection(s2, dialect) {
938
946
  let out = "";
939
947
  let quote = "";
@@ -971,6 +979,10 @@ function stripLiterals(s2, dialect) {
971
979
  i2++;
972
980
  continue;
973
981
  }
982
+ if (dialect === "excel" && (ch === "_" || ch === "*")) {
983
+ i2++;
984
+ continue;
985
+ }
974
986
  if (ch === '"' || dialect === "dotnet" && ch === "'") {
975
987
  const end = s2.indexOf(ch, i2 + 1);
976
988
  i2 = end < 0 ? s2.length : end;
@@ -2337,6 +2349,7 @@ export {
2337
2349
  inlineFilterGate,
2338
2350
  isBlankRender,
2339
2351
  isBlindMarker,
2352
+ isExcelDateFormat,
2340
2353
  isHorizontalLabelRow,
2341
2354
  isPhantomBox,
2342
2355
  isPillBackdropAlpha,
@@ -16,7 +16,7 @@ export { qualifyGroupHeadingFor, newQualifyGroupState, type QualifyGroupRow, typ
16
16
  export { qualifyPick, qualifyAuto, qualifyCancel, launchGenerates, launchFavorStyle, chooserFitsViewport, shouldOpenChooserOnGenerate, shouldOpenInlineChooserOnGenerate, canConfirmLaunch, confirmLaunch, qualifyFailureFallsOpen, CHOOSER_MIN_WIDTH_PX, CHOOSER_MIN_HEIGHT_PX, type QualifyLaunchOutcome, type ChooserGateInput, } from "./qualifyLaunch";
17
17
  export { normalizeFilterTerm, filterQualifyRows, readQualifyChartRow, readQualifyRefusalRow, filterFitsChooser, listNeedsFilter, qualifyFilterGate, inlineFilterGate, FILTER_MIN_TERM_CHARS, FILTER_ROW_PX, FILTER_MIN_WIDTH_PX, FILTER_MIN_HEIGHT_PX, INLINE_FILTER_MIN_ROWS, computeQualifyFilterView, qualifyFilterCountText, type QualifyFilterTier, type QualifyFilterResult, type QualifyFilterRead, type QualifyFilterGateReason, type QualifyFilterGateInput, type QualifyFilterRow, type QualifyFilterGroup, type QualifyFilterView, type QualifyFilterNoteKind, } from "./qualifyFilter";
18
18
  export { computeSelectionCard, normaliseAggregation, type SelectionCardModel, type SelectionCardLine, type SelectionCardOptions, } from "./selectionCard";
19
- export { formatSourceDate, formatSourceDateFor, type SourceFormats, type SourceFormatDialect, type SourceDateOptions, } from "./sourceDateFormat";
19
+ export { formatSourceDate, formatSourceDateFor, isExcelDateFormat, type SourceFormats, type SourceFormatDialect, type SourceDateOptions, } from "./sourceDateFormat";
20
20
  export { composeSummaryText } from "./summaryText";
21
21
  export { ensureCrossfilterHitTargets, type HitTargetReport } from "./hitTargets";
22
22
  export { applyLabelContrast, LABEL_CONTRAST_DONE_ATTR, LABEL_CONTRAST_CAP, type LabelContrastOptions, type LabelContrastReport, } from "./labelContrastDom";
@@ -28,3 +28,22 @@ export interface SourceDateOptions {
28
28
  export declare function formatSourceDate(raw: any, opts?: SourceDateOptions): string | null;
29
29
  /** Convenience for a caller holding a `SourceFormats` map and a column name. */
30
30
  export declare function formatSourceDateFor(raw: any, columnName: string, formats: SourceFormats | null | undefined, culture?: string): string | null;
31
+ /**
32
+ * Does an EXCEL number format make the cell a date? The question a host asks before it turns a
33
+ * serial number into a Date (2026-09-16).
34
+ *
35
+ * Excel stores 2026-03-01 as 46082 and only the format says which one it is, so reading a format
36
+ * wrongly in EITHER direction corrupts a column without an error anywhere. A bare letter test over
37
+ * the raw string gets it wrong in the direction that hurts: `0.00;[Red]0.00` - Excel's own built-in
38
+ * "Number, red negatives" - has a `d` in its colour, `[$USD] #,##0.00` an `s` in its currency tag,
39
+ * and a revenue of 1,234.50 read through either became a date in May 1903.
40
+ *
41
+ * So the format is reduced the way `cleanFormat` reduces it before rendering: the FIRST section (the
42
+ * one a positive serial takes), literals removed, bracket decorations removed. Only then does a
43
+ * remaining `y m d h s` make it a date.
44
+ *
45
+ * ELAPSED TIME IS A DURATION, NOT A DATE. `[h]:mm:ss` counts hours past 24: its value is a length of
46
+ * time, and turning it into an instant in January 1900 is the same trap as `0.00" days"`. A section
47
+ * carrying an elapsed bracket answers false, and the column stays a number.
48
+ */
49
+ export declare function isExcelDateFormat(raw: string | null | undefined): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bicharts/chart-host",
3
- "version": "0.5.105",
3
+ "version": "0.5.106",
4
4
  "description": "Run a BIC-generated D3 chart in any web host: compiles the generated render() function, applies the shared option defaults, resolves mark clicks (through tooltip overlays), owns the selection affordance, and translates row indices between cross-filtered charts. The same contract the BIC Power BI visual implements, minus Power BI. React bindings at @bicharts/chart-host/react.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",