@kubit-ui-web/react-charts 1.2.0 → 1.3.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.
Files changed (65) hide show
  1. package/README.md +96 -0
  2. package/dist/cjs/components/zoomArea/hooks/useResponsiveCanvas.d.ts.map +1 -1
  3. package/dist/cjs/components/zoomArea/hooks/useResponsiveCanvas.js +6 -1
  4. package/dist/cjs/utils/cssGradientToSvg/cssGradientToSvg.d.ts.map +1 -1
  5. package/dist/cjs/utils/cssGradientToSvg/cssGradientToSvg.js +2 -2
  6. package/dist/cjs/utils/getCanvasDimensions/getCanvasDimensions.d.ts.map +1 -1
  7. package/dist/cjs/utils/getCanvasDimensions/getCanvasDimensions.js +13 -2
  8. package/dist/cjs/utils/index.d.ts +2 -0
  9. package/dist/cjs/utils/index.d.ts.map +1 -1
  10. package/dist/cjs/utils/index.js +2 -0
  11. package/dist/cjs/utils/logger/index.d.ts +2 -0
  12. package/dist/cjs/utils/logger/index.d.ts.map +1 -0
  13. package/dist/cjs/utils/logger/index.js +1 -0
  14. package/dist/cjs/utils/logger/logger.d.ts +45 -0
  15. package/dist/cjs/utils/logger/logger.d.ts.map +1 -0
  16. package/dist/cjs/utils/logger/logger.js +140 -0
  17. package/dist/cjs/utils/ssr/index.d.ts +2 -0
  18. package/dist/cjs/utils/ssr/index.d.ts.map +1 -0
  19. package/dist/cjs/utils/ssr/index.js +1 -0
  20. package/dist/cjs/utils/ssr/ssr.d.ts +80 -0
  21. package/dist/cjs/utils/ssr/ssr.d.ts.map +1 -0
  22. package/dist/cjs/utils/ssr/ssr.js +117 -0
  23. package/dist/cjs/utils/textBound/textBound.d.ts.map +1 -1
  24. package/dist/cjs/utils/textBound/textBound.js +17 -5
  25. package/dist/esm/components/zoomArea/hooks/useResponsiveCanvas.d.ts.map +1 -1
  26. package/dist/esm/components/zoomArea/hooks/useResponsiveCanvas.js +6 -1
  27. package/dist/esm/utils/cssGradientToSvg/cssGradientToSvg.d.ts.map +1 -1
  28. package/dist/esm/utils/cssGradientToSvg/cssGradientToSvg.js +2 -2
  29. package/dist/esm/utils/getCanvasDimensions/getCanvasDimensions.d.ts.map +1 -1
  30. package/dist/esm/utils/getCanvasDimensions/getCanvasDimensions.js +13 -2
  31. package/dist/esm/utils/index.d.ts +2 -0
  32. package/dist/esm/utils/index.d.ts.map +1 -1
  33. package/dist/esm/utils/index.js +2 -0
  34. package/dist/esm/utils/logger/index.d.ts +2 -0
  35. package/dist/esm/utils/logger/index.d.ts.map +1 -0
  36. package/dist/esm/utils/logger/index.js +1 -0
  37. package/dist/esm/utils/logger/logger.d.ts +45 -0
  38. package/dist/esm/utils/logger/logger.d.ts.map +1 -0
  39. package/dist/esm/utils/logger/logger.js +140 -0
  40. package/dist/esm/utils/ssr/index.d.ts +2 -0
  41. package/dist/esm/utils/ssr/index.d.ts.map +1 -0
  42. package/dist/esm/utils/ssr/index.js +1 -0
  43. package/dist/esm/utils/ssr/ssr.d.ts +80 -0
  44. package/dist/esm/utils/ssr/ssr.d.ts.map +1 -0
  45. package/dist/esm/utils/ssr/ssr.js +117 -0
  46. package/dist/esm/utils/textBound/textBound.d.ts.map +1 -1
  47. package/dist/esm/utils/textBound/textBound.js +17 -5
  48. package/dist/kubit-ui-web-react-charts.cjs.js +1 -1
  49. package/dist/kubit-ui-web-react-charts.es.js +1 -1
  50. package/dist/kubit-ui-web-react-charts.umd.js +1 -1
  51. package/dist/types/components/zoomArea/hooks/useResponsiveCanvas.d.ts.map +1 -1
  52. package/dist/types/utils/cssGradientToSvg/cssGradientToSvg.d.ts.map +1 -1
  53. package/dist/types/utils/getCanvasDimensions/getCanvasDimensions.d.ts.map +1 -1
  54. package/dist/types/utils/index.d.ts +2 -0
  55. package/dist/types/utils/index.d.ts.map +1 -1
  56. package/dist/types/utils/logger/index.d.ts +2 -0
  57. package/dist/types/utils/logger/index.d.ts.map +1 -0
  58. package/dist/types/utils/logger/logger.d.ts +45 -0
  59. package/dist/types/utils/logger/logger.d.ts.map +1 -0
  60. package/dist/types/utils/ssr/index.d.ts +2 -0
  61. package/dist/types/utils/ssr/index.d.ts.map +1 -0
  62. package/dist/types/utils/ssr/ssr.d.ts +80 -0
  63. package/dist/types/utils/ssr/ssr.d.ts.map +1 -0
  64. package/dist/types/utils/textBound/textBound.d.ts.map +1 -1
  65. package/package.json +5 -5
@@ -1,15 +1,27 @@
1
+ import { createSVGElement, isBrowser, safeDocument } from '../ssr/ssr';
1
2
  export const textBound = ({ bound, data, fontSize, svgHeight, svgWidth, viewBox, }) => {
2
- if (!window || !document || !data.length) {
3
+ // SSR-safe: Return 0 if not in browser or no data
4
+ if (!isBrowser() || !data.length) {
5
+ return 0;
6
+ }
7
+ const doc = safeDocument();
8
+ if (!doc) {
9
+ return 0;
10
+ }
11
+ const svgContainer = createSVGElement('svg');
12
+ if (!svgContainer) {
3
13
  return 0;
4
14
  }
5
- const svgContainer = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
6
15
  svgContainer.setAttribute('style', 'position: absolute; visibility: hidden; top: -9999px; left: -9999px;');
7
16
  svgContainer.setAttribute('viewBox', viewBox);
8
17
  svgContainer.setAttribute('width', svgWidth);
9
18
  svgContainer.setAttribute('height', svgHeight);
10
- document.body.appendChild(svgContainer);
19
+ doc.body.appendChild(svgContainer);
11
20
  const sizes = data.map((d) => {
12
- const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
21
+ const text = createSVGElement('text');
22
+ if (!text) {
23
+ return 0;
24
+ }
13
25
  text.setAttribute('font-size', fontSize);
14
26
  text.textContent = d;
15
27
  svgContainer.appendChild(text);
@@ -18,5 +30,5 @@ export const textBound = ({ bound, data, fontSize, svgHeight, svgWidth, viewBox,
18
30
  return size;
19
31
  });
20
32
  svgContainer.remove();
21
- return Math.max(...sizes);
33
+ return Math.max(...sizes, 0); // Ensure at least 0 is returned
22
34
  };
@@ -1 +1 @@
1
- {"version":3,"file":"useResponsiveCanvas.d.ts","sourceRoot":"","sources":["../../../../../src/components/zoomArea/hooks/useResponsiveCanvas.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAIxD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,UAAU,yBAAyB;IACjC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC9B;AAED,UAAU,yBAAyB;IACjC,yCAAyC;IACzC,YAAY,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,yBAAyB;IACzB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,mBAAmB,GAAI,0DAMjC,yBAAyB,KAAG,yBAyF9B,CAAC"}
1
+ {"version":3,"file":"useResponsiveCanvas.d.ts","sourceRoot":"","sources":["../../../../../src/components/zoomArea/hooks/useResponsiveCanvas.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAKxD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,UAAU,yBAAyB;IACjC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC9B;AAED,UAAU,yBAAyB;IACjC,yCAAyC;IACzC,YAAY,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,yBAAyB;IACzB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,mBAAmB,GAAI,0DAMjC,yBAAyB,KAAG,yBA8F9B,CAAC"}
@@ -2,6 +2,7 @@ import { useEffect, useMemo, useState } from 'react';
2
2
  import { buildViewBox } from '../../../components/svgContainer/utils/buildViewBox/buildViewBox';
3
3
  import { getCanvasDimensions } from '../../../utils/getCanvasDimensions/getCanvasDimensions';
4
4
  import { parseStringToNumberPx } from '../../../utils/parseStringToNumberPx.ts/parseStringToNumberPx';
5
+ import { isBrowser, safeQuerySelector } from '../../../utils/ssr/ssr';
5
6
  export const useResponsiveCanvas = ({ canvasConfig, dataTestId, extraSpace = 0, height, width, }) => {
6
7
  // State for parsed/calculated dimensions
7
8
  const [parsedCanvas, setParsedCanvas] = useState({
@@ -28,8 +29,12 @@ export const useResponsiveCanvas = ({ canvasConfig, dataTestId, extraSpace = 0,
28
29
  : undefined;
29
30
  // Set up responsive dimensions with ResizeObserver
30
31
  useEffect(() => {
32
+ // SSR-safe: Skip effect if not in browser
33
+ if (!isBrowser()) {
34
+ return;
35
+ }
31
36
  // Find the SVG element for this specific component instance
32
- const svgElement = document.querySelector(`[data-testid="${dataTestId}"]`);
37
+ const svgElement = safeQuerySelector(`[data-testid="${dataTestId}"]`);
33
38
  if (!svgElement) {
34
39
  return;
35
40
  }
@@ -1 +1 @@
1
- {"version":3,"file":"cssGradientToSvg.d.ts","sourceRoot":"","sources":["../../../../src/utils/cssGradientToSvg/cssGradientToSvg.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,gBAAgB,GAAI,aAAa,MAAM,EAAE,WAAoB,KAAG,GAAG,CAAC,OA0ChF,CAAC"}
1
+ {"version":3,"file":"cssGradientToSvg.d.ts","sourceRoot":"","sources":["../../../../src/utils/cssGradientToSvg/cssGradientToSvg.tsx"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,gBAAgB,GAAI,aAAa,MAAM,EAAE,WAAoB,KAAG,GAAG,CAAC,OAwChF,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
+ import { logger } from '../logger/logger';
2
3
  /**
3
4
  * Converts a CSS linear gradient string into an SVG linear gradient.
4
5
  *
@@ -38,8 +39,7 @@ export const cssGradientToSVG = (cssGradient, id = 'gradientePath') => {
38
39
  x1 = '100%';
39
40
  break;
40
41
  default:
41
- // eslint-disable-next-line no-console
42
- console.error('Unsupported angle');
42
+ logger.warn(`Unsupported gradient angle: ${angle}°. Supported angles are 90, 180, 270.`);
43
43
  return _jsx(_Fragment, {}); // Return an empty fragment for unsupported angles
44
44
  }
45
45
  return (_jsx("defs", { children: _jsx("linearGradient", { id: id, x1: x1, x2: x2, y1: y1, y2: y2, children: stops.map((stop, index) => (_jsx("stop", { offset: stop.offset, stopColor: stop.color }, `${index}-${stop.offset}`.toString()))) }) }));
@@ -1 +1 @@
1
- {"version":3,"file":"getCanvasDimensions.d.ts","sourceRoot":"","sources":["../../../../src/utils/getCanvasDimensions/getCanvasDimensions.ts"],"names":[],"mappings":"AAyFA,UAAU,wBAAwB;IAChC,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,UAAU,EAAE,aAAa,CAAC;CAC3B;AAED,UAAU,yBAAyB;IACjC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAAI,4CAIjC,wBAAwB,KAAG,yBAkB7B,CAAC"}
1
+ {"version":3,"file":"getCanvasDimensions.d.ts","sourceRoot":"","sources":["../../../../src/utils/getCanvasDimensions/getCanvasDimensions.ts"],"names":[],"mappings":"AAsGA,UAAU,wBAAwB;IAChC,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,UAAU,EAAE,aAAa,CAAC;CAC3B;AAED,UAAU,yBAAyB;IACjC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAAI,4CAIjC,wBAAwB,KAAG,yBAkB7B,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { safeDocument, safeGetComputedStyle } from '../ssr/ssr';
1
2
  import { Unit } from '../../types/unit.enum';
2
3
  /**
3
4
  * A mapping of string representations of units to their corresponding `Unit` enum values.
@@ -62,13 +63,23 @@ const calculatePercentage = (value, dimension, svgElement) => {
62
63
  };
63
64
  /**
64
65
  * Calculates the rem value based on the root font size.
66
+ * SSR-safe: Returns default 16px if not in browser environment.
65
67
  *
66
68
  * @param {number} value - The value in rem to be converted to pixels.
67
69
  * @returns {number} The calculated pixel value.
68
70
  */
69
71
  const calculateRem = (value) => {
70
- const remValue = parseFloat(getComputedStyle(document.documentElement).fontSize);
71
- return value * remValue;
72
+ const doc = safeDocument();
73
+ if (!doc) {
74
+ // SSR fallback: Default browser font size is typically 16px
75
+ return value * 16;
76
+ }
77
+ const style = safeGetComputedStyle(doc.documentElement);
78
+ if (!style) {
79
+ return value * 16;
80
+ }
81
+ const remValue = parseFloat(style.fontSize);
82
+ return value * (remValue || 16); // Fallback to 16 if fontSize is invalid
72
83
  };
73
84
  /**
74
85
  * Calculates the dimensions of an SVG element based on the provided width and height values.
@@ -3,7 +3,9 @@ export * from './buildTickValues/buildTickValues';
3
3
  export * from './classNames/classNames';
4
4
  export * from './cssGradientToSvg/cssGradientToSvg';
5
5
  export * from './cursorNear/isNear';
6
+ export * from './logger';
6
7
  export * from './shadowSvg/shadowSvg';
7
8
  export * from './shadowSvg/shadowSvg.types';
9
+ export * from './ssr';
8
10
  export * from './textBound/textBound';
9
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,qCAAqC,CAAC;AACpD,cAAc,mCAAmC,CAAC;AAClD,cAAc,yBAAyB,CAAC;AACxC,cAAc,qCAAqC,CAAC;AACpD,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,qCAAqC,CAAC;AACpD,cAAc,mCAAmC,CAAC;AAClD,cAAc,yBAAyB,CAAC;AACxC,cAAc,qCAAqC,CAAC;AACpD,cAAc,qBAAqB,CAAC;AACpC,cAAc,UAAU,CAAC;AACzB,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,OAAO,CAAC;AACtB,cAAc,uBAAuB,CAAC"}
@@ -3,6 +3,8 @@ export * from './buildTickValues/buildTickValues';
3
3
  export * from './classNames/classNames';
4
4
  export * from './cssGradientToSvg/cssGradientToSvg';
5
5
  export * from './cursorNear/isNear';
6
+ export * from './logger';
6
7
  export * from './shadowSvg/shadowSvg';
7
8
  export * from './shadowSvg/shadowSvg.types';
9
+ export * from './ssr';
8
10
  export * from './textBound/textBound';
@@ -0,0 +1,2 @@
1
+ export { logger, configureLogger, resetLogger } from './logger';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/utils/logger/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1 @@
1
+ export { logger, configureLogger, resetLogger } from './logger';
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Logger utility for @kubit/web-ui-charts
3
+ *
4
+ * Provides a centralized logging system that:
5
+ * - Respects NODE_ENV (disabled in production builds)
6
+ * - Supports different log levels
7
+ * - Can be configured/disabled by consumers
8
+ * - Will be stripped out in production builds via terser
9
+ */
10
+ type LogLevel = 'debug' | 'info' | 'warn' | 'error';
11
+ interface LoggerConfig {
12
+ enabled: boolean;
13
+ minLevel: LogLevel;
14
+ prefix: string;
15
+ }
16
+ /**
17
+ * Configure the logger behavior
18
+ * @param newConfig - Partial configuration to merge with current settings
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * // Disable all logging
23
+ * configureLogger({ enabled: false });
24
+ *
25
+ * // Enable debug logs in development
26
+ * configureLogger({ minLevel: 'debug' });
27
+ * ```
28
+ */
29
+ export declare const configureLogger: (newConfig: Partial<LoggerConfig>) => void;
30
+ /**
31
+ * Reset logger to default configuration
32
+ */
33
+ export declare const resetLogger: () => void;
34
+ /**
35
+ * Main logger object
36
+ * Export as singleton to ensure consistent configuration
37
+ */
38
+ export declare const logger: {
39
+ debug: (message: string, ...args: unknown[]) => void;
40
+ error: (message: string, ...args: unknown[]) => void;
41
+ info: (message: string, ...args: unknown[]) => void;
42
+ warn: (message: string, ...args: unknown[]) => void;
43
+ };
44
+ export {};
45
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../../src/utils/logger/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,KAAK,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAEpD,UAAU,YAAY;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB;AA+BD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,eAAe,GAAI,WAAW,OAAO,CAAC,YAAY,CAAC,KAAG,IAElE,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,WAAW,QAAO,IAE9B,CAAC;AAkFF;;;GAGG;AACH,eAAO,MAAM,MAAM;qBA1DK,MAAM,WAAW,OAAO,EAAE,KAAG,IAAI;qBA+CjC,MAAM,WAAW,OAAO,EAAE,KAAG,IAAI;oBAhClC,MAAM,WAAW,OAAO,EAAE,KAAG,IAAI;oBAgBjC,MAAM,WAAW,OAAO,EAAE,KAAG,IAAI;CAgCvD,CAAC"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Logger utility for @kubit/web-ui-charts
3
+ *
4
+ * Provides a centralized logging system that:
5
+ * - Respects NODE_ENV (disabled in production builds)
6
+ * - Supports different log levels
7
+ * - Can be configured/disabled by consumers
8
+ * - Will be stripped out in production builds via terser
9
+ */
10
+ /**
11
+ * Detect if we're in a production build
12
+ * Uses globalThis to be compatible with different environments (browser, Node, SSR)
13
+ */
14
+ const isProduction = () => {
15
+ // Check if globalThis.process exists (Node/SSR environments)
16
+ if (typeof globalThis !== 'undefined' && 'process' in globalThis) {
17
+ const proc = globalThis.process;
18
+ return proc?.env?.NODE_ENV === 'production';
19
+ }
20
+ // In browser or other environments, assume development unless explicitly set
21
+ return false;
22
+ };
23
+ const DEFAULT_CONFIG = {
24
+ enabled: !isProduction(),
25
+ minLevel: 'info',
26
+ prefix: '[Kubit Charts]',
27
+ };
28
+ let config = { ...DEFAULT_CONFIG };
29
+ const LOG_LEVELS = {
30
+ debug: 0,
31
+ error: 3,
32
+ info: 1,
33
+ warn: 2,
34
+ };
35
+ /**
36
+ * Configure the logger behavior
37
+ * @param newConfig - Partial configuration to merge with current settings
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * // Disable all logging
42
+ * configureLogger({ enabled: false });
43
+ *
44
+ * // Enable debug logs in development
45
+ * configureLogger({ minLevel: 'debug' });
46
+ * ```
47
+ */
48
+ export const configureLogger = (newConfig) => {
49
+ config = { ...config, ...newConfig };
50
+ };
51
+ /**
52
+ * Reset logger to default configuration
53
+ */
54
+ export const resetLogger = () => {
55
+ config = { ...DEFAULT_CONFIG };
56
+ };
57
+ /**
58
+ * Check if a log level should be output based on configuration
59
+ */
60
+ const shouldLog = (level) => {
61
+ if (!config.enabled) {
62
+ return false;
63
+ }
64
+ return LOG_LEVELS[level] >= LOG_LEVELS[config.minLevel];
65
+ };
66
+ /**
67
+ * Format log message with prefix
68
+ */
69
+ const formatMessage = (message) => {
70
+ return `${config.prefix} ${message}`;
71
+ };
72
+ /**
73
+ * Log debug messages (development only)
74
+ * Useful for detailed debugging information
75
+ *
76
+ * @example
77
+ * ```ts
78
+ * logger.debug('Chart dimensions calculated', { width: 400, height: 300 });
79
+ * ```
80
+ */
81
+ const debug = (message, ...args) => {
82
+ if (shouldLog('debug')) {
83
+ // eslint-disable-next-line no-console
84
+ console.debug(formatMessage(message), ...args);
85
+ }
86
+ };
87
+ /**
88
+ * Log informational messages
89
+ *
90
+ * @example
91
+ * ```ts
92
+ * logger.info('Chart rendered successfully');
93
+ * ```
94
+ */
95
+ const info = (message, ...args) => {
96
+ if (shouldLog('info')) {
97
+ // eslint-disable-next-line no-console
98
+ console.info(formatMessage(message), ...args);
99
+ }
100
+ };
101
+ /**
102
+ * Log warning messages
103
+ * Use for non-breaking issues that developers should be aware of
104
+ *
105
+ * @example
106
+ * ```ts
107
+ * logger.warn('Invalid gradient angle, falling back to default', angle);
108
+ * ```
109
+ */
110
+ const warn = (message, ...args) => {
111
+ if (shouldLog('warn')) {
112
+ // eslint-disable-next-line no-console
113
+ console.warn(formatMessage(message), ...args);
114
+ }
115
+ };
116
+ /**
117
+ * Log error messages
118
+ * Use for errors that don't prevent execution but indicate problems
119
+ *
120
+ * @example
121
+ * ```ts
122
+ * logger.error('Failed to calculate text bounds, using fallback', error);
123
+ * ```
124
+ */
125
+ const error = (message, ...args) => {
126
+ if (shouldLog('error')) {
127
+ // eslint-disable-next-line no-console
128
+ console.error(formatMessage(message), ...args);
129
+ }
130
+ };
131
+ /**
132
+ * Main logger object
133
+ * Export as singleton to ensure consistent configuration
134
+ */
135
+ export const logger = {
136
+ debug,
137
+ error,
138
+ info,
139
+ warn,
140
+ };
@@ -0,0 +1,2 @@
1
+ export { isBrowser, isServer, safeWindow, safeDocument, safeExecute, safeExecuteWithFallback, createSVGElement, safeGetComputedStyle, safeQuerySelector, } from './ssr';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/utils/ssr/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,WAAW,EACX,uBAAuB,EACvB,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,OAAO,CAAC"}
@@ -0,0 +1 @@
1
+ export { isBrowser, isServer, safeWindow, safeDocument, safeExecute, safeExecuteWithFallback, createSVGElement, safeGetComputedStyle, safeQuerySelector, } from './ssr';
@@ -0,0 +1,80 @@
1
+ /**
2
+ * SSR (Server-Side Rendering) utilities
3
+ *
4
+ * Provides safe access to browser APIs when rendering on the server.
5
+ * Compatible with Next.js, Remix, Gatsby, and other SSR frameworks.
6
+ */
7
+ /**
8
+ * Check if code is running in a browser environment
9
+ * @returns true if window is defined (browser), false otherwise (SSR)
10
+ */
11
+ export declare const isBrowser: () => boolean;
12
+ /**
13
+ * Check if code is running in a server environment
14
+ * @returns true if running on server (no window), false otherwise
15
+ */
16
+ export declare const isServer: () => boolean;
17
+ /**
18
+ * Safely access window object
19
+ * @returns window object if in browser, undefined if on server
20
+ */
21
+ export declare const safeWindow: () => Window | undefined;
22
+ /**
23
+ * Safely access document object
24
+ * @returns document object if in browser, undefined if on server
25
+ */
26
+ export declare const safeDocument: () => Document | undefined;
27
+ /**
28
+ * Safely execute code that requires browser APIs
29
+ * Returns undefined on server, executes callback in browser
30
+ *
31
+ * @param callback - Function to execute in browser environment
32
+ * @returns Result of callback if in browser, undefined if on server
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * const width = safeExecute(() => window.innerWidth) ?? 0;
37
+ * ```
38
+ */
39
+ export declare const safeExecute: <T>(callback: () => T) => T | undefined;
40
+ /**
41
+ * Safely execute code with a fallback value for SSR
42
+ *
43
+ * @param callback - Function to execute in browser environment
44
+ * @param fallback - Value to return if on server or if callback fails
45
+ * @returns Result of callback if in browser, fallback otherwise
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * const fontSize = safeExecuteWithFallback(
50
+ * () => parseFloat(getComputedStyle(document.documentElement).fontSize),
51
+ * 16
52
+ * );
53
+ * ```
54
+ */
55
+ export declare const safeExecuteWithFallback: <T>(callback: () => T, fallback: T) => T;
56
+ /**
57
+ * Create an SVG element safely (browser-only)
58
+ * Returns undefined on server
59
+ *
60
+ * @param tagName - SVG element tag name
61
+ * @returns SVG element if in browser, undefined if on server
62
+ */
63
+ export declare const createSVGElement: <K extends keyof SVGElementTagNameMap>(tagName: K) => SVGElementTagNameMap[K] | undefined;
64
+ /**
65
+ * Get computed style safely
66
+ * Returns undefined on server
67
+ *
68
+ * @param element - Element to get computed style for
69
+ * @returns CSSStyleDeclaration if in browser, undefined if on server
70
+ */
71
+ export declare const safeGetComputedStyle: (element: Element) => CSSStyleDeclaration | undefined;
72
+ /**
73
+ * Query selector safely
74
+ * Returns null on server or if not found
75
+ *
76
+ * @param selector - CSS selector string
77
+ * @returns Element if found in browser, null otherwise
78
+ */
79
+ export declare const safeQuerySelector: <T extends Element = Element>(selector: string) => T | null;
80
+ //# sourceMappingURL=ssr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssr.d.ts","sourceRoot":"","sources":["../../../../src/utils/ssr/ssr.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;GAGG;AACH,eAAO,MAAM,SAAS,QAAO,OAE5B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,QAAQ,QAAO,OAE3B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,UAAU,QAAO,MAAM,GAAG,SAEtC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,YAAY,QAAO,QAAQ,GAAG,SAE1C,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,EAAE,UAAU,MAAM,CAAC,KAAG,CAAC,GAAG,SAStD,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,uBAAuB,GAAI,CAAC,EAAE,UAAU,MAAM,CAAC,EAAE,UAAU,CAAC,KAAG,CAE3E,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAAI,CAAC,SAAS,MAAM,oBAAoB,EACnE,SAAS,CAAC,KACT,oBAAoB,CAAC,CAAC,CAAC,GAAG,SAM5B,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,GAC/B,SAAS,OAAO,KACf,mBAAmB,GAAG,SAMxB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,OAAO,GAAG,OAAO,EAC3D,UAAU,MAAM,KACf,CAAC,GAAG,IAMN,CAAC"}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * SSR (Server-Side Rendering) utilities
3
+ *
4
+ * Provides safe access to browser APIs when rendering on the server.
5
+ * Compatible with Next.js, Remix, Gatsby, and other SSR frameworks.
6
+ */
7
+ /**
8
+ * Check if code is running in a browser environment
9
+ * @returns true if window is defined (browser), false otherwise (SSR)
10
+ */
11
+ export const isBrowser = () => {
12
+ return typeof window !== 'undefined' && typeof document !== 'undefined';
13
+ };
14
+ /**
15
+ * Check if code is running in a server environment
16
+ * @returns true if running on server (no window), false otherwise
17
+ */
18
+ export const isServer = () => {
19
+ return !isBrowser();
20
+ };
21
+ /**
22
+ * Safely access window object
23
+ * @returns window object if in browser, undefined if on server
24
+ */
25
+ export const safeWindow = () => {
26
+ return isBrowser() ? window : undefined;
27
+ };
28
+ /**
29
+ * Safely access document object
30
+ * @returns document object if in browser, undefined if on server
31
+ */
32
+ export const safeDocument = () => {
33
+ return isBrowser() ? document : undefined;
34
+ };
35
+ /**
36
+ * Safely execute code that requires browser APIs
37
+ * Returns undefined on server, executes callback in browser
38
+ *
39
+ * @param callback - Function to execute in browser environment
40
+ * @returns Result of callback if in browser, undefined if on server
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * const width = safeExecute(() => window.innerWidth) ?? 0;
45
+ * ```
46
+ */
47
+ export const safeExecute = (callback) => {
48
+ if (!isBrowser()) {
49
+ return undefined;
50
+ }
51
+ try {
52
+ return callback();
53
+ }
54
+ catch (error) {
55
+ return undefined;
56
+ }
57
+ };
58
+ /**
59
+ * Safely execute code with a fallback value for SSR
60
+ *
61
+ * @param callback - Function to execute in browser environment
62
+ * @param fallback - Value to return if on server or if callback fails
63
+ * @returns Result of callback if in browser, fallback otherwise
64
+ *
65
+ * @example
66
+ * ```ts
67
+ * const fontSize = safeExecuteWithFallback(
68
+ * () => parseFloat(getComputedStyle(document.documentElement).fontSize),
69
+ * 16
70
+ * );
71
+ * ```
72
+ */
73
+ export const safeExecuteWithFallback = (callback, fallback) => {
74
+ return safeExecute(callback) ?? fallback;
75
+ };
76
+ /**
77
+ * Create an SVG element safely (browser-only)
78
+ * Returns undefined on server
79
+ *
80
+ * @param tagName - SVG element tag name
81
+ * @returns SVG element if in browser, undefined if on server
82
+ */
83
+ export const createSVGElement = (tagName) => {
84
+ const doc = safeDocument();
85
+ if (!doc) {
86
+ return undefined;
87
+ }
88
+ return doc.createElementNS('http://www.w3.org/2000/svg', tagName);
89
+ };
90
+ /**
91
+ * Get computed style safely
92
+ * Returns undefined on server
93
+ *
94
+ * @param element - Element to get computed style for
95
+ * @returns CSSStyleDeclaration if in browser, undefined if on server
96
+ */
97
+ export const safeGetComputedStyle = (element) => {
98
+ const win = safeWindow();
99
+ if (!win) {
100
+ return undefined;
101
+ }
102
+ return win.getComputedStyle(element);
103
+ };
104
+ /**
105
+ * Query selector safely
106
+ * Returns null on server or if not found
107
+ *
108
+ * @param selector - CSS selector string
109
+ * @returns Element if found in browser, null otherwise
110
+ */
111
+ export const safeQuerySelector = (selector) => {
112
+ const doc = safeDocument();
113
+ if (!doc) {
114
+ return null;
115
+ }
116
+ return doc.querySelector(selector);
117
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"textBound.d.ts","sourceRoot":"","sources":["../../../../src/utils/textBound/textBound.ts"],"names":[],"mappings":"AAAA,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,SAAS,GAAI,0DAOvB,cAAc,KAAG,MA0BnB,CAAC"}
1
+ {"version":3,"file":"textBound.d.ts","sourceRoot":"","sources":["../../../../src/utils/textBound/textBound.ts"],"names":[],"mappings":"AAEA,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,SAAS,GAAI,0DAOvB,cAAc,KAAG,MAwCnB,CAAC"}
@@ -1,15 +1,27 @@
1
+ import { createSVGElement, isBrowser, safeDocument } from '../ssr/ssr';
1
2
  export const textBound = ({ bound, data, fontSize, svgHeight, svgWidth, viewBox, }) => {
2
- if (!window || !document || !data.length) {
3
+ // SSR-safe: Return 0 if not in browser or no data
4
+ if (!isBrowser() || !data.length) {
5
+ return 0;
6
+ }
7
+ const doc = safeDocument();
8
+ if (!doc) {
9
+ return 0;
10
+ }
11
+ const svgContainer = createSVGElement('svg');
12
+ if (!svgContainer) {
3
13
  return 0;
4
14
  }
5
- const svgContainer = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
6
15
  svgContainer.setAttribute('style', 'position: absolute; visibility: hidden; top: -9999px; left: -9999px;');
7
16
  svgContainer.setAttribute('viewBox', viewBox);
8
17
  svgContainer.setAttribute('width', svgWidth);
9
18
  svgContainer.setAttribute('height', svgHeight);
10
- document.body.appendChild(svgContainer);
19
+ doc.body.appendChild(svgContainer);
11
20
  const sizes = data.map((d) => {
12
- const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
21
+ const text = createSVGElement('text');
22
+ if (!text) {
23
+ return 0;
24
+ }
13
25
  text.setAttribute('font-size', fontSize);
14
26
  text.textContent = d;
15
27
  svgContainer.appendChild(text);
@@ -18,5 +30,5 @@ export const textBound = ({ bound, data, fontSize, svgHeight, svgWidth, viewBox,
18
30
  return size;
19
31
  });
20
32
  svgContainer.remove();
21
- return Math.max(...sizes);
33
+ return Math.max(...sizes, 0); // Ensure at least 0 is returned
22
34
  };