@monolith-forensics/monolith-ui 1.9.3-dev.0 → 1.9.3-dev.1

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 (48) hide show
  1. package/dist/Charts/BarChart/BarChart.js +28 -14
  2. package/dist/Charts/BarChart/BarChart.styled.d.ts +7 -2
  3. package/dist/Charts/BarChart/BarChart.styled.js +5 -1
  4. package/dist/Charts/BarChart/BarChart.types.d.ts +13 -5
  5. package/dist/Charts/ChartUtils/chartSizing.d.ts +20 -0
  6. package/dist/Charts/ChartUtils/chartSizing.js +83 -0
  7. package/dist/Charts/ChartUtils/index.d.ts +1 -0
  8. package/dist/Charts/ChartUtils/index.js +1 -0
  9. package/dist/Charts/HeatMap/HeatMap.js +28 -7
  10. package/dist/Charts/HeatMap/HeatMap.styled.d.ts +6 -2
  11. package/dist/Charts/HeatMap/HeatMap.styled.js +3 -0
  12. package/dist/Charts/HeatMap/HeatMap.types.d.ts +7 -1
  13. package/dist/Charts/LineChart/LineChart.js +34 -15
  14. package/dist/Charts/LineChart/LineChart.styled.d.ts +7 -2
  15. package/dist/Charts/LineChart/LineChart.styled.js +5 -1
  16. package/dist/Charts/LineChart/LineChart.types.d.ts +13 -5
  17. package/dist/Charts/PieChart/PieChart.js +48 -33
  18. package/dist/Charts/PieChart/PieChart.styled.d.ts +7 -2
  19. package/dist/Charts/PieChart/PieChart.styled.js +6 -1
  20. package/dist/Charts/PieChart/PieChart.types.d.ts +7 -3
  21. package/dist/FieldLabel/FieldLabel.js +3 -18
  22. package/dist/RichTextEditor/Extensions/getSlashCommand.d.ts +23 -3
  23. package/dist/RichTextEditor/Extensions/getSlashCommand.js +14 -6
  24. package/dist/RichTextEditor/Extensions/getTiptapExtensions.d.ts +5 -2
  25. package/dist/RichTextEditor/Extensions/getTiptapExtensions.js +3 -1
  26. package/dist/RichTextEditor/RichTextEditor.d.ts +6 -3
  27. package/dist/RichTextEditor/RichTextEditor.js +6 -6
  28. package/dist/SegmentedControl/SegmentedControl.js +1 -1
  29. package/dist/SegmentedControl/SegmentedControl.styles.d.ts +1 -0
  30. package/dist/SegmentedControl/SegmentedControl.styles.js +30 -14
  31. package/dist/SegmentedControl/SegmentedControl.utils.d.ts +1 -0
  32. package/dist/SegmentedControl/SegmentedControl.utils.js +5 -2
  33. package/dist/Table/Table.js +4 -3
  34. package/dist/Table/TableComponents.d.ts +3 -0
  35. package/dist/Table/TableComponents.js +47 -0
  36. package/dist/Table/TableHeader.js +1 -1
  37. package/dist/Table/TableMenu/TableMenu.js +4 -3
  38. package/dist/Table/TableProvider.js +39 -0
  39. package/dist/Table/TableRow.js +1 -1
  40. package/dist/Table/types.d.ts +6 -0
  41. package/dist/Utilities/getImageTextContent.d.ts +78 -0
  42. package/dist/Utilities/getImageTextContent.js +222 -0
  43. package/dist/core/controlSizes.js +9 -9
  44. package/package.json +1 -1
  45. package/dist/RichTextEditor/Components/TableCornerMenu.d.ts +0 -16
  46. package/dist/RichTextEditor/Components/TableCornerMenu.js +0 -202
  47. package/dist/RichTextEditor/Components/TableTools.d.ts +0 -44
  48. package/dist/RichTextEditor/Components/TableTools.js +0 -790
@@ -23,16 +23,17 @@ import { scaleLinear, scalePoint, scaleTime } from "d3-scale";
23
23
  import { forwardRef, useCallback, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState, } from "react";
24
24
  import { useTheme } from "styled-components";
25
25
  import { ChartExportControl } from "../ChartPrimitives";
26
- import { DEFAULT_CHART_EXPORT_FORMATS, copyChartImage, downloadChartImage, } from "../ChartUtils";
26
+ import { DEFAULT_CHART_EXPORT_FORMATS, copyChartImage, downloadChartImage, useChartResponsiveSize, } from "../ChartUtils";
27
27
  import { buildAreaPath, buildLinePath, clamp, easeOutCubic, formatDefaultValue, getGradientStops, getPointKey, getSeriesKey, getSeriesLabelText, getValueDomain, measureSvgPath, mergeChartMargin, normalizeTickValue, parseLineChartXValue, resolveXAxisType, useThemeColor, useThemeColors, } from "./LineChart.lib";
28
28
  import { StyledArea, StyledAxisLine, StyledAxisText, StyledChartActions, StyledChartFrame, StyledChartScroller, StyledContainer, StyledEmptyState, StyledGridLine, StyledHoverTarget, StyledLegend, StyledLegendItem, StyledLegendLabel, StyledLegendLine, StyledLegendValue, StyledLine, StyledPoint, StyledSvg, StyledTooltip, StyledTooltipHeader, StyledTooltipLabel, StyledTooltipMeta, StyledTooltipSwatch, StyledValueLabel, } from "./LineChart.styled";
29
29
  const LineChartInner = (_a, ref) => {
30
30
  var _b, _c, _d;
31
- var { data, series, seriesLabel = "Series", width = 720, height = 320, margin, xAxisType = "auto", curve = "monotone", lineColor, colors, colorGradient, lineWidth = 2.5, lineOpacity = 1, lineDasharray, showArea = false, areaColor, areaOpacity = 0.14, showPoints = false, pointRadius = 3, activePointRadius = 4, pointColor, pointBorderColor, pointBorderWidth = 1.5, pointOpacity = 1, yMin, yMax, xTickCount = 6, yTickCount = 5, showGridLines = true, showAxisLines = true, showXAxisLabels = true, showYAxisLabels = true, showLegend = false, showLabels = false, emptyLabel = "No data", ariaLabel = "Line chart", animateOnRender = false, animationDuration = 720, showExportButton = false, exportFileName = "line-chart", exportFormats = DEFAULT_CHART_EXPORT_FORMATS, exportScale = 2, exportBackgroundColor, showTooltips = false, valueFormatter, xValueFormatter, xTickFormatter, yTickFormatter, labelFormatter, tooltipFormatter, onPointClick, className } = _a, props = __rest(_a, ["data", "series", "seriesLabel", "width", "height", "margin", "xAxisType", "curve", "lineColor", "colors", "colorGradient", "lineWidth", "lineOpacity", "lineDasharray", "showArea", "areaColor", "areaOpacity", "showPoints", "pointRadius", "activePointRadius", "pointColor", "pointBorderColor", "pointBorderWidth", "pointOpacity", "yMin", "yMax", "xTickCount", "yTickCount", "showGridLines", "showAxisLines", "showXAxisLabels", "showYAxisLabels", "showLegend", "showLabels", "emptyLabel", "ariaLabel", "animateOnRender", "animationDuration", "showExportButton", "exportFileName", "exportFormats", "exportScale", "exportBackgroundColor", "showTooltips", "valueFormatter", "xValueFormatter", "xTickFormatter", "yTickFormatter", "labelFormatter", "tooltipFormatter", "onPointClick", "className"]);
31
+ var { data, series, seriesLabel = "Series", width, height, responsive = false, aspectRatio, minWidth = 240, minHeight = 200, margin, xAxisType = "auto", curve = "monotone", lineColor, colors, colorGradient, lineWidth = 2.5, lineOpacity = 1, lineDasharray, showArea = false, areaColor, areaOpacity = 0.14, showPoints = false, pointRadius = 3, activePointRadius = 4, pointColor, pointBorderColor, pointBorderWidth = 1.5, pointOpacity = 1, yMin, yMax, xTickCount = 6, yTickCount = 5, showGridLines = true, showAxisLines = true, showXAxisLabels = true, showYAxisLabels = true, showLegend = false, showLabels = false, emptyLabel = "No data", ariaLabel = "Line chart", animateOnRender = false, animationDuration = 720, showExportButton = false, exportFileName = "line-chart", exportFormats = DEFAULT_CHART_EXPORT_FORMATS, exportScale = 2, exportBackgroundColor, showTooltips = false, valueFormatter, xValueFormatter, xTickFormatter, yTickFormatter, labelFormatter, tooltipFormatter, onPointClick, className } = _a, props = __rest(_a, ["data", "series", "seriesLabel", "width", "height", "responsive", "aspectRatio", "minWidth", "minHeight", "margin", "xAxisType", "curve", "lineColor", "colors", "colorGradient", "lineWidth", "lineOpacity", "lineDasharray", "showArea", "areaColor", "areaOpacity", "showPoints", "pointRadius", "activePointRadius", "pointColor", "pointBorderColor", "pointBorderWidth", "pointOpacity", "yMin", "yMax", "xTickCount", "yTickCount", "showGridLines", "showAxisLines", "showXAxisLabels", "showYAxisLabels", "showLegend", "showLabels", "emptyLabel", "ariaLabel", "animateOnRender", "animationDuration", "showExportButton", "exportFileName", "exportFormats", "exportScale", "exportBackgroundColor", "showTooltips", "valueFormatter", "xValueFormatter", "xTickFormatter", "yTickFormatter", "labelFormatter", "tooltipFormatter", "onPointClick", "className"]);
32
32
  const descriptionId = useId();
33
33
  const gradientBaseId = useId();
34
34
  const theme = useTheme();
35
35
  const containerRef = useRef(null);
36
+ const chartSizeRef = useRef(null);
36
37
  const chartFrameRef = useRef(null);
37
38
  const svgRef = useRef(null);
38
39
  const tooltipRef = useRef(null);
@@ -46,8 +47,18 @@ const LineChartInner = (_a, ref) => {
46
47
  const themeLineColor = useThemeColor(lineColor);
47
48
  const themeColors = useThemeColors(colors);
48
49
  const resolvedMargin = mergeChartMargin(margin, showXAxisLabels, showYAxisLabels, showLabels);
49
- const safeWidth = Math.max(width, 240);
50
- const safeHeight = Math.max(height, 200);
50
+ const chartSize = useChartResponsiveSize(chartSizeRef, {
51
+ width,
52
+ height,
53
+ responsive,
54
+ aspectRatio,
55
+ defaultWidth: 720,
56
+ defaultHeight: 320,
57
+ minWidth: Math.max(minWidth, 1),
58
+ minHeight: Math.max(minHeight, 1),
59
+ });
60
+ const safeWidth = chartSize.width;
61
+ const safeHeight = chartSize.height;
51
62
  const plotWidth = Math.max(safeWidth - resolvedMargin.left - resolvedMargin.right, 1);
52
63
  const plotHeight = Math.max(safeHeight - resolvedMargin.top - resolvedMargin.bottom, 1);
53
64
  const resolvedGlobalLineWidth = Math.max(lineWidth, 1);
@@ -207,7 +218,7 @@ const LineChartInner = (_a, ref) => {
207
218
  if (resolvedXAxisType !== "time")
208
219
  return null;
209
220
  const timeValues = allPoints
210
- .map((point) => (point.parsedX instanceof Date ? point.parsedX.getTime() : null))
221
+ .map((point) => point.parsedX instanceof Date ? point.parsedX.getTime() : null)
211
222
  .filter((value) => value != null);
212
223
  const min = Math.min(...timeValues);
213
224
  const max = Math.max(...timeValues);
@@ -289,7 +300,8 @@ const LineChartInner = (_a, ref) => {
289
300
  }, [renderedSeries, renderedSeriesKey]);
290
301
  useLayoutEffect(() => {
291
302
  var _a;
292
- if (!animateOnRender || renderedSeries.every((seriesEntry) => !seriesEntry.linePath)) {
303
+ if (!animateOnRender ||
304
+ renderedSeries.every((seriesEntry) => !seriesEntry.linePath)) {
293
305
  setAnimationProgress(1);
294
306
  return;
295
307
  }
@@ -307,7 +319,9 @@ const LineChartInner = (_a, ref) => {
307
319
  if (startTime == null)
308
320
  startTime = timestamp;
309
321
  const elapsed = timestamp - startTime;
310
- const progress = safeDuration === 0 ? 1 : easeOutCubic(clamp(elapsed / safeDuration, 0, 1));
322
+ const progress = safeDuration === 0
323
+ ? 1
324
+ : easeOutCubic(clamp(elapsed / safeDuration, 0, 1));
311
325
  setAnimationProgress(progress);
312
326
  if (progress < 1) {
313
327
  animationFrame = window.requestAnimationFrame(runAnimation);
@@ -337,7 +351,10 @@ const LineChartInner = (_a, ref) => {
337
351
  const yTicks = useMemo(() => Array.from(new Set(yScale
338
352
  .ticks(Math.max(yTickCount, 2))
339
353
  .map((tick) => normalizeTickValue(tick)))), [yScale, yTickCount]);
340
- const formatValue = (datum, sourceSeries) => { var _a; return (_a = valueFormatter === null || valueFormatter === void 0 ? void 0 : valueFormatter(datum.y, datum, sourceSeries)) !== null && _a !== void 0 ? _a : formatDefaultValue(datum.y); };
354
+ const formatValue = (datum, sourceSeries) => {
355
+ var _a;
356
+ return (_a = valueFormatter === null || valueFormatter === void 0 ? void 0 : valueFormatter(datum.y, datum, sourceSeries)) !== null && _a !== void 0 ? _a : formatDefaultValue(datum.y);
357
+ };
341
358
  const formatXValue = (datum, sourceSeries) => {
342
359
  var _a;
343
360
  return (_a = xValueFormatter === null || xValueFormatter === void 0 ? void 0 : xValueFormatter(datum.x, datum, sourceSeries)) !== null && _a !== void 0 ? _a : (datum.x instanceof Date ? datum.x.toLocaleDateString() : String(datum.x));
@@ -428,7 +445,7 @@ const LineChartInner = (_a, ref) => {
428
445
  .join(", ");
429
446
  const shouldAnimateStroke = animateOnRender && animationProgress < 1;
430
447
  const shouldShowDataLabels = showLabels && allPoints.length <= 24;
431
- return (_jsxs(StyledContainer, Object.assign({ ref: containerRef, className: className }, props, { children: [allPoints.length === 0 ? (_jsx(StyledEmptyState, { "$width": safeWidth, "$height": safeHeight, children: emptyLabel })) : (_jsx(StyledChartScroller, { children: _jsxs(StyledChartFrame, { ref: chartFrameRef, children: [showExportButton && exportFormats.length > 0 && (_jsx(StyledChartActions, { "data-chart-export-ignore": "true", children: _jsx(ChartExportControl, { rootRef: containerRef, svgRef: svgRef, fileName: exportFileName, formats: exportFormats, scale: exportScale, backgroundColor: resolvedExportBackgroundColor }) })), _jsxs(StyledSvg, { ref: svgRef, width: safeWidth, height: safeHeight, viewBox: `0 0 ${safeWidth} ${safeHeight}`, role: "img", "aria-label": ariaLabel, "aria-describedby": descriptionId, children: [_jsx("desc", { id: descriptionId, children: description }), _jsx("defs", { children: renderedSeries
448
+ return (_jsxs(StyledContainer, Object.assign({ ref: containerRef, className: className, "$fillAvailableWidth": chartSize.fillAvailableWidth }, props, { children: [_jsx(StyledChartScroller, { ref: chartSizeRef, "$width": chartSize.widthStyle, "$height": chartSize.heightStyle, children: allPoints.length === 0 ? (_jsx(StyledEmptyState, { "$width": safeWidth, "$height": safeHeight, children: emptyLabel })) : (_jsxs(StyledChartFrame, { ref: chartFrameRef, children: [showExportButton && exportFormats.length > 0 && (_jsx(StyledChartActions, { "data-chart-export-ignore": "true", children: _jsx(ChartExportControl, { rootRef: containerRef, svgRef: svgRef, fileName: exportFileName, formats: exportFormats, scale: exportScale, backgroundColor: resolvedExportBackgroundColor }) })), _jsxs(StyledSvg, { ref: svgRef, width: safeWidth, height: safeHeight, viewBox: `0 0 ${safeWidth} ${safeHeight}`, role: "img", "aria-label": ariaLabel, "aria-describedby": descriptionId, children: [_jsx("desc", { id: descriptionId, children: description }), _jsx("defs", { children: renderedSeries
432
449
  .filter((seriesEntry) => { var _a; return (_a = seriesEntry.gradientStops) === null || _a === void 0 ? void 0 : _a.length; })
433
450
  .map((seriesEntry) => {
434
451
  var _a;
@@ -437,7 +454,8 @@ const LineChartInner = (_a, ref) => {
437
454
  return (_jsx("stop", { offset: `${((_a = seriesEntry.gradientStops) !== null && _a !== void 0 ? _a : []).length === 1
438
455
  ? 100
439
456
  : (index /
440
- (((_b = seriesEntry.gradientStops) !== null && _b !== void 0 ? _b : []).length - 1)) *
457
+ (((_b = seriesEntry.gradientStops) !== null && _b !== void 0 ? _b : []).length -
458
+ 1)) *
441
459
  100}%`, stopColor: stop }, `${stop}-${index}`));
442
460
  }) }, seriesEntry.gradientId));
443
461
  }) }), showGridLines &&
@@ -446,10 +464,10 @@ const LineChartInner = (_a, ref) => {
446
464
  xTicks.map((tick, index) => {
447
465
  var _a, _b, _c;
448
466
  const x = resolvedXAxisType === "time"
449
- ? (_a = timeScale === null || timeScale === void 0 ? void 0 : timeScale(tick)) !== null && _a !== void 0 ? _a : 0
467
+ ? ((_a = timeScale === null || timeScale === void 0 ? void 0 : timeScale(tick)) !== null && _a !== void 0 ? _a : 0)
450
468
  : resolvedXAxisType === "linear"
451
- ? (_b = linearScale === null || linearScale === void 0 ? void 0 : linearScale(tick)) !== null && _b !== void 0 ? _b : 0
452
- : (_c = pointScale === null || pointScale === void 0 ? void 0 : pointScale(String(tick))) !== null && _c !== void 0 ? _c : 0;
469
+ ? ((_b = linearScale === null || linearScale === void 0 ? void 0 : linearScale(tick)) !== null && _b !== void 0 ? _b : 0)
470
+ : ((_c = pointScale === null || pointScale === void 0 ? void 0 : pointScale(String(tick))) !== null && _c !== void 0 ? _c : 0);
453
471
  return (_jsx(StyledAxisText, { x: resolvedMargin.left + x, y: resolvedMargin.top + plotHeight + 20, textAnchor: "middle", children: formatXTick(tick) }, `tick-x-${index}`));
454
472
  }), _jsxs("g", { transform: `translate(${resolvedMargin.left}, ${resolvedMargin.top})`, children: [_jsx(StyledHoverTarget, { x: 0, y: 0, width: plotWidth, height: plotHeight, onMouseEnter: (event) => {
455
473
  if (!showTooltips && !showPoints && !onPointClick)
@@ -488,7 +506,8 @@ const LineChartInner = (_a, ref) => {
488
506
  : undefined,
489
507
  opacity: isSeriesDimmed ? 0.7 : 1,
490
508
  } })), seriesEntry.linePath && (_jsx(StyledLine, { "$active": isSeriesActive, "$dimmed": isSeriesDimmed, ref: (node) => {
491
- linePathRefs.current[String(seriesEntry.key)] = node;
509
+ linePathRefs.current[String(seriesEntry.key)] =
510
+ node;
492
511
  }, d: seriesEntry.linePath, stroke: gradientReference, strokeWidth: isSeriesActive
493
512
  ? seriesEntry.lineWidth + 0.8
494
513
  : seriesEntry.lineWidth, strokeOpacity: seriesEntry.lineOpacity, strokeDasharray: shouldAnimateStroke && lineLength > 0
@@ -518,7 +537,7 @@ const LineChartInner = (_a, ref) => {
518
537
  renderedSeries.map((seriesEntry) => seriesEntry.points.map((point) => {
519
538
  var _a;
520
539
  return (_jsx(StyledValueLabel, { x: getPointX(point), y: getPointY(point) - 10, textAnchor: "middle", children: (_a = labelFormatter === null || labelFormatter === void 0 ? void 0 : labelFormatter(point, point.index, seriesEntry.sourceSeries)) !== null && _a !== void 0 ? _a : formatValue(point, seriesEntry.sourceSeries) }, `label-${point.key}`));
521
- }))] })] })] }) })), activeTooltip && activePoint && activeSeries && tooltipStyle && (_jsx(StyledTooltip, { ref: tooltipRef, style: tooltipStyle, children: tooltipFormatter ? (tooltipFormatter(activePoint, activePoint.index, activeSeries.sourceSeries)) : (_jsxs(_Fragment, { children: [_jsxs(StyledTooltipHeader, { children: [_jsx(StyledTooltipSwatch, { "$color": (_d = activePoint.color) !== null && _d !== void 0 ? _d : activeSeries.pointColor }), _jsx(StyledTooltipLabel, { children: formatXValue(activePoint, activeSeries.sourceSeries) })] }), _jsxs(StyledTooltipMeta, { children: [_jsx("span", { children: activePoint.seriesLabel }), _jsx("span", { children: formatValue(activePoint, activeSeries.sourceSeries) })] })] })) })), showLegend && (_jsx(StyledLegend, { children: renderedSeries.map((seriesEntry) => {
540
+ }))] })] })] })) }), activeTooltip && activePoint && activeSeries && tooltipStyle && (_jsx(StyledTooltip, { ref: tooltipRef, style: tooltipStyle, children: tooltipFormatter ? (tooltipFormatter(activePoint, activePoint.index, activeSeries.sourceSeries)) : (_jsxs(_Fragment, { children: [_jsxs(StyledTooltipHeader, { children: [_jsx(StyledTooltipSwatch, { "$color": (_d = activePoint.color) !== null && _d !== void 0 ? _d : activeSeries.pointColor }), _jsx(StyledTooltipLabel, { children: formatXValue(activePoint, activeSeries.sourceSeries) })] }), _jsxs(StyledTooltipMeta, { children: [_jsx("span", { children: activePoint.seriesLabel }), _jsx("span", { children: formatValue(activePoint, activeSeries.sourceSeries) })] })] })) })), showLegend && (_jsx(StyledLegend, { children: renderedSeries.map((seriesEntry) => {
522
541
  const latestPoint = seriesEntry.points[seriesEntry.points.length - 1];
523
542
  if (!latestPoint)
524
543
  return null;
@@ -1,6 +1,11 @@
1
1
  import { StyledChartActions } from "../ChartPrimitives";
2
- export declare const StyledContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
3
- export declare const StyledChartScroller: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
2
+ export declare const StyledContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
3
+ $fillAvailableWidth: boolean;
4
+ }>> & string;
5
+ export declare const StyledChartScroller: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
6
+ $width?: string;
7
+ $height?: string;
8
+ }>> & string;
4
9
  export declare const StyledChartFrame: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
5
10
  export { StyledChartActions };
6
11
  export declare const StyledSvg: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").SVGProps<SVGSVGElement>, never>> & string;
@@ -10,7 +10,7 @@ export const StyledContainer = styled.div `
10
10
  align-items: flex-start;
11
11
  flex-wrap: wrap;
12
12
  gap: 20px;
13
- width: fit-content;
13
+ width: ${({ $fillAvailableWidth }) => $fillAvailableWidth ? "100%" : "fit-content"};
14
14
  max-width: 100%;
15
15
  color: ${({ theme }) => theme.palette.text.primary};
16
16
  box-sizing: border-box;
@@ -18,10 +18,13 @@ export const StyledContainer = styled.div `
18
18
  `;
19
19
  export const StyledChartScroller = styled.div `
20
20
  display: flex;
21
+ width: ${({ $width }) => $width !== null && $width !== void 0 ? $width : "auto"};
22
+ height: ${({ $height }) => $height !== null && $height !== void 0 ? $height : "auto"};
21
23
  max-width: 100%;
22
24
  overflow-x: auto;
23
25
  overflow-y: visible;
24
26
  padding-bottom: 2px;
27
+ box-sizing: border-box;
25
28
  `;
26
29
  export const StyledChartFrame = styled.div `
27
30
  position: relative;
@@ -120,6 +123,7 @@ export const StyledEmptyState = styled.div `
120
123
  justify-content: center;
121
124
  width: ${({ $width }) => $width}px;
122
125
  height: ${({ $height }) => $height}px;
126
+ box-sizing: border-box;
123
127
  border: 1px dashed ${({ theme }) => theme.palette.divider};
124
128
  border-radius: 8px;
125
129
  background: linear-gradient(
@@ -1,5 +1,5 @@
1
1
  import React, { HTMLAttributes } from "react";
2
- import type { ChartExportOptions } from "../ChartUtils";
2
+ import type { ChartDimension, ChartExportOptions } from "../ChartUtils";
3
3
  export type LineChartDatum<TData = unknown> = {
4
4
  /** Stable identifier for the point. Falls back to x and index when omitted. */
5
5
  id?: string | number;
@@ -104,10 +104,18 @@ export type LineChartProps<TData = unknown> = HTMLAttributes<HTMLDivElement> & C
104
104
  series?: LineChartSeries<TData>[];
105
105
  /** Label used for the single-line variant in legend and tooltip context. */
106
106
  seriesLabel?: React.ReactNode;
107
- /** SVG width in pixels. Defaults to 720. */
108
- width?: number;
109
- /** SVG height in pixels. Defaults to 320. */
110
- height?: number;
107
+ /** SVG width in pixels or any CSS length measured from the chart frame. Defaults to 720. */
108
+ width?: ChartDimension;
109
+ /** SVG height in pixels or any CSS length measured from the chart frame. Defaults to 320. */
110
+ height?: ChartDimension;
111
+ /** Measures the chart frame and fits the SVG width to its available space. Defaults to false. */
112
+ responsive?: boolean;
113
+ /** Calculates height from resolved width when height is omitted. */
114
+ aspectRatio?: number;
115
+ /** Minimum rendered SVG width in pixels. Defaults to 240. */
116
+ minWidth?: number;
117
+ /** Minimum rendered SVG height in pixels. Defaults to 200. */
118
+ minHeight?: number;
111
119
  /** Partial chart margin overrides. Defaults are based on visible labels. */
112
120
  margin?: Partial<LineChartMargin>;
113
121
  /** X-axis scale type. Defaults to "auto". */
@@ -23,15 +23,16 @@ import { forwardRef, useEffect, useId, useImperativeHandle, useMemo, useRef, use
23
23
  import { arc, pie } from "d3-shape";
24
24
  import { useTheme } from "styled-components";
25
25
  import { ChartExportControl } from "../ChartPrimitives";
26
- import { DEFAULT_CHART_EXPORT_FORMATS, copyChartImage, downloadChartImage, } from "../ChartUtils";
26
+ import { DEFAULT_CHART_EXPORT_FORMATS, copyChartImage, downloadChartImage, useChartResponsiveSize, } from "../ChartUtils";
27
27
  import { clamp, easeOutCubic, formatDefaultValue, getGradientColor, getSliceKey, useThemeColors, } from "./PieChart.lib";
28
28
  import { StyledCenter, StyledCenterLabel, StyledCenterPanel, StyledCenterValue, StyledChartActions, StyledChartWrap, StyledContainer, StyledEmptyState, StyledLabel, StyledLegend, StyledLegendItem, StyledLegendLabel, StyledLegendMeta, StyledLegendPercent, StyledLegendValue, StyledSlice, StyledSvg, StyledSwatch, StyledTooltip, StyledTooltipHeader, StyledTooltipLabel, StyledTooltipMeta, StyledTooltipSwatch, } from "./PieChart.styled";
29
29
  const PieChartInner = (_a, ref) => {
30
30
  var _b, _c;
31
- var { data, size = 220, innerRadius = 58, outerRadius, cornerRadius = 1, padAngle = 0.004, colors, colorGradient, sliceOpacity = 1, sliceBorderColor, sliceBorderWidth = 1, sliceBorderOpacity = 1, sliceBorderLineJoin = "round", showLegend = true, showLegendSwatches = true, showLegendLabels = true, showLegendValues = true, showLegendPercentages = true, showLabels = false, centerLabel, centerValue, emptyLabel = "No data", ariaLabel = "Pie chart", animateOnRender = false, animationDuration = 520, animationStagger = 35, showExportButton = false, exportFileName = "pie-chart", exportFormats = DEFAULT_CHART_EXPORT_FORMATS, exportScale = 2, exportBackgroundColor, showTooltips = false, valueFormatter, labelFormatter, tooltipFormatter, onSliceClick, onLegendItemClick, className } = _a, props = __rest(_a, ["data", "size", "innerRadius", "outerRadius", "cornerRadius", "padAngle", "colors", "colorGradient", "sliceOpacity", "sliceBorderColor", "sliceBorderWidth", "sliceBorderOpacity", "sliceBorderLineJoin", "showLegend", "showLegendSwatches", "showLegendLabels", "showLegendValues", "showLegendPercentages", "showLabels", "centerLabel", "centerValue", "emptyLabel", "ariaLabel", "animateOnRender", "animationDuration", "animationStagger", "showExportButton", "exportFileName", "exportFormats", "exportScale", "exportBackgroundColor", "showTooltips", "valueFormatter", "labelFormatter", "tooltipFormatter", "onSliceClick", "onLegendItemClick", "className"]);
31
+ var { data, size, responsive = false, minSize = 120, innerRadius, outerRadius, cornerRadius = 1, padAngle = 0.004, colors, colorGradient, sliceOpacity = 1, sliceBorderColor, sliceBorderWidth = 1, sliceBorderOpacity = 1, sliceBorderLineJoin = "round", showLegend = true, showLegendSwatches = true, showLegendLabels = true, showLegendValues = true, showLegendPercentages = true, showLabels = false, centerLabel, centerValue, emptyLabel = "No data", ariaLabel = "Pie chart", animateOnRender = false, animationDuration = 520, animationStagger = 35, showExportButton = false, exportFileName = "pie-chart", exportFormats = DEFAULT_CHART_EXPORT_FORMATS, exportScale = 2, exportBackgroundColor, showTooltips = false, valueFormatter, labelFormatter, tooltipFormatter, onSliceClick, onLegendItemClick, className } = _a, props = __rest(_a, ["data", "size", "responsive", "minSize", "innerRadius", "outerRadius", "cornerRadius", "padAngle", "colors", "colorGradient", "sliceOpacity", "sliceBorderColor", "sliceBorderWidth", "sliceBorderOpacity", "sliceBorderLineJoin", "showLegend", "showLegendSwatches", "showLegendLabels", "showLegendValues", "showLegendPercentages", "showLabels", "centerLabel", "centerValue", "emptyLabel", "ariaLabel", "animateOnRender", "animationDuration", "animationStagger", "showExportButton", "exportFileName", "exportFormats", "exportScale", "exportBackgroundColor", "showTooltips", "valueFormatter", "labelFormatter", "tooltipFormatter", "onSliceClick", "onLegendItemClick", "className"]);
32
32
  const descriptionId = useId();
33
33
  const theme = useTheme();
34
34
  const containerRef = useRef(null);
35
+ const chartSizeRef = useRef(null);
35
36
  const svgRef = useRef(null);
36
37
  const [activeSliceKey, setActiveSliceKey] = useState(null);
37
38
  const [activeTooltip, setActiveTooltip] = useState(null);
@@ -39,7 +40,21 @@ const PieChartInner = (_a, ref) => {
39
40
  const themeColors = useThemeColors(colors);
40
41
  const validData = useMemo(() => data.filter((datum) => Number.isFinite(datum.value) && datum.value > 0), [data]);
41
42
  const total = useMemo(() => validData.reduce((sum, datum) => sum + datum.value, 0), [validData]);
42
- const radius = outerRadius !== null && outerRadius !== void 0 ? outerRadius : Math.max(size / 2 - 6, 0);
43
+ const chartSize = useChartResponsiveSize(chartSizeRef, {
44
+ width: size,
45
+ responsive,
46
+ aspectRatio: 1,
47
+ defaultWidth: 220,
48
+ defaultHeight: 220,
49
+ minWidth: Math.max(minSize, 1),
50
+ minHeight: Math.max(minSize, 1),
51
+ });
52
+ const safeSize = Math.min(chartSize.width, chartSize.height);
53
+ const radius = outerRadius !== null && outerRadius !== void 0 ? outerRadius : Math.max(safeSize / 2 - 6, 0);
54
+ const shouldScaleDefaultInnerRadius = innerRadius == null && (responsive || typeof size === "string");
55
+ const defaultInnerRadius = shouldScaleDefaultInnerRadius
56
+ ? Math.max(radius * (58 / 104), 0)
57
+ : 58;
43
58
  const resolvedSliceOpacity = clamp(sliceOpacity, 0, 1);
44
59
  const resolvedSliceBorderWidth = Math.max(sliceBorderWidth, 0);
45
60
  const resolvedSliceBorderOpacity = clamp(sliceBorderOpacity, 0, 1);
@@ -69,7 +84,7 @@ const PieChartInner = (_a, ref) => {
69
84
  });
70
85
  }),
71
86
  }), [exportFileName, exportScale, resolvedExportBackgroundColor]);
72
- const resolvedInnerRadius = Math.min(innerRadius, radius - 1);
87
+ const resolvedInnerRadius = Math.max(Math.min(innerRadius !== null && innerRadius !== void 0 ? innerRadius : defaultInnerRadius, radius - 1), 0);
73
88
  const centerPanelDiameter = Math.max(resolvedInnerRadius * 1.62, 52);
74
89
  const labelRadius = resolvedInnerRadius > 0
75
90
  ? resolvedInnerRadius + (radius - resolvedInnerRadius) / 2
@@ -155,35 +170,35 @@ const PieChartInner = (_a, ref) => {
155
170
  const activeTooltipSlice = showTooltips && activeTooltip
156
171
  ? slices.find((slice, index) => getSliceKey(slice.data, index) === activeTooltip.sliceKey)
157
172
  : null;
158
- return (_jsxs(StyledContainer, Object.assign({ ref: containerRef, className: className }, props, { children: [slices.length === 0 ? (_jsx(StyledEmptyState, { "$size": size, children: emptyLabel })) : (_jsxs(StyledChartWrap, { children: [showExportButton && exportFormats.length > 0 && (_jsx(StyledChartActions, { "data-chart-export-ignore": "true", children: _jsx(ChartExportControl, { rootRef: containerRef, svgRef: svgRef, fileName: exportFileName, formats: exportFormats, scale: exportScale, backgroundColor: resolvedExportBackgroundColor }) })), _jsxs(StyledSvg, { ref: svgRef, width: size, height: size, viewBox: `0 0 ${size} ${size}`, role: "img", "aria-label": ariaLabel, "aria-describedby": descriptionId, children: [_jsx("desc", { id: descriptionId, children: slices
159
- .map((slice) => `${slice.data.label}: ${formatDefaultValue(slice.data.value)}`)
160
- .join(", ") }), _jsx("g", { transform: `translate(${size / 2}, ${size / 2})`, children: slices.map((slice, index) => {
161
- var _a;
162
- const sliceKey = getSliceKey(slice.data, index);
163
- const sliceAnimationProgress = getSliceAnimationProgress(index);
164
- const animatedSlice = Object.assign(Object.assign({}, slice), { startAngle: animationStartAngle +
165
- (slice.startAngle - animationStartAngle) *
166
- sliceAnimationProgress, endAngle: animationStartAngle +
167
- (slice.endAngle - animationStartAngle) *
168
- sliceAnimationProgress });
169
- const path = arcGenerator(animatedSlice);
170
- const labelPosition = labelArcGenerator.centroid(slice);
171
- const percent = Math.round(slice.percent * 100);
172
- return (_jsxs("g", { children: [_jsx(StyledSlice, { "$active": activeSliceKey === sliceKey, d: path !== null && path !== void 0 ? path : undefined, fill: slice.color, fillOpacity: resolvedSliceOpacity, stroke: resolvedSliceBorderColor, strokeWidth: resolvedSliceBorderWidth, strokeOpacity: resolvedSliceBorderOpacity, strokeLinejoin: sliceBorderLineJoin, tabIndex: 0, onFocus: () => setActiveSliceKey(sliceKey), onBlur: () => setActiveSliceKey(null), onMouseEnter: (event) => {
173
- setActiveSliceKey(sliceKey);
174
- updateTooltipPosition(event, sliceKey);
175
- }, onMouseMove: (event) => updateTooltipPosition(event, sliceKey), onMouseLeave: () => {
176
- setActiveSliceKey(null);
177
- setActiveTooltip(null);
178
- }, onClick: (event) => onSliceClick === null || onSliceClick === void 0 ? void 0 : onSliceClick(event, slice.data), onKeyDown: (event) => {
179
- if (event.key !== "Enter" && event.key !== " ")
180
- return;
181
- event.preventDefault();
182
- onSliceClick === null || onSliceClick === void 0 ? void 0 : onSliceClick(event, slice.data);
183
- }, "aria-label": `${slice.data.label}: ${formatDefaultValue(slice.data.value)}, ${percent}%` }), showLabels &&
184
- slice.percent >= 0.05 &&
185
- sliceAnimationProgress >= 0.92 && (_jsx(StyledLabel, { x: labelPosition[0], y: labelPosition[1], textAnchor: "middle", dominantBaseline: "central", children: (_a = labelFormatter === null || labelFormatter === void 0 ? void 0 : labelFormatter(slice.data, slice.percent)) !== null && _a !== void 0 ? _a : `${percent}%` }))] }, sliceKey));
186
- }) })] }), (centerLabel != null || centerValue != null) && (_jsx(StyledCenter, { children: _jsxs(StyledCenterPanel, { "$diameter": centerPanelDiameter, children: [centerValue != null && (_jsx(StyledCenterValue, { children: centerValue })), centerLabel != null && (_jsx(StyledCenterLabel, { children: centerLabel }))] }) }))] })), shouldShowLegend && (_jsx(StyledLegend, { children: slices.map((slice, index) => {
173
+ return (_jsxs(StyledContainer, Object.assign({ ref: containerRef, className: className, "$fillAvailableWidth": chartSize.fillAvailableWidth }, props, { children: [_jsx(StyledChartWrap, { ref: chartSizeRef, "$width": chartSize.widthStyle, "$height": chartSize.heightStyle, children: slices.length === 0 ? (_jsx(StyledEmptyState, { "$size": safeSize, children: emptyLabel })) : (_jsxs(_Fragment, { children: [showExportButton && exportFormats.length > 0 && (_jsx(StyledChartActions, { "data-chart-export-ignore": "true", children: _jsx(ChartExportControl, { rootRef: containerRef, svgRef: svgRef, fileName: exportFileName, formats: exportFormats, scale: exportScale, backgroundColor: resolvedExportBackgroundColor }) })), _jsxs(StyledSvg, { ref: svgRef, width: safeSize, height: safeSize, viewBox: `0 0 ${safeSize} ${safeSize}`, role: "img", "aria-label": ariaLabel, "aria-describedby": descriptionId, children: [_jsx("desc", { id: descriptionId, children: slices
174
+ .map((slice) => `${slice.data.label}: ${formatDefaultValue(slice.data.value)}`)
175
+ .join(", ") }), _jsx("g", { transform: `translate(${safeSize / 2}, ${safeSize / 2})`, children: slices.map((slice, index) => {
176
+ var _a;
177
+ const sliceKey = getSliceKey(slice.data, index);
178
+ const sliceAnimationProgress = getSliceAnimationProgress(index);
179
+ const animatedSlice = Object.assign(Object.assign({}, slice), { startAngle: animationStartAngle +
180
+ (slice.startAngle - animationStartAngle) *
181
+ sliceAnimationProgress, endAngle: animationStartAngle +
182
+ (slice.endAngle - animationStartAngle) *
183
+ sliceAnimationProgress });
184
+ const path = arcGenerator(animatedSlice);
185
+ const labelPosition = labelArcGenerator.centroid(slice);
186
+ const percent = Math.round(slice.percent * 100);
187
+ return (_jsxs("g", { children: [_jsx(StyledSlice, { "$active": activeSliceKey === sliceKey, d: path !== null && path !== void 0 ? path : undefined, fill: slice.color, fillOpacity: resolvedSliceOpacity, stroke: resolvedSliceBorderColor, strokeWidth: resolvedSliceBorderWidth, strokeOpacity: resolvedSliceBorderOpacity, strokeLinejoin: sliceBorderLineJoin, tabIndex: 0, onFocus: () => setActiveSliceKey(sliceKey), onBlur: () => setActiveSliceKey(null), onMouseEnter: (event) => {
188
+ setActiveSliceKey(sliceKey);
189
+ updateTooltipPosition(event, sliceKey);
190
+ }, onMouseMove: (event) => updateTooltipPosition(event, sliceKey), onMouseLeave: () => {
191
+ setActiveSliceKey(null);
192
+ setActiveTooltip(null);
193
+ }, onClick: (event) => onSliceClick === null || onSliceClick === void 0 ? void 0 : onSliceClick(event, slice.data), onKeyDown: (event) => {
194
+ if (event.key !== "Enter" && event.key !== " ")
195
+ return;
196
+ event.preventDefault();
197
+ onSliceClick === null || onSliceClick === void 0 ? void 0 : onSliceClick(event, slice.data);
198
+ }, "aria-label": `${slice.data.label}: ${formatDefaultValue(slice.data.value)}, ${percent}%` }), showLabels &&
199
+ slice.percent >= 0.05 &&
200
+ sliceAnimationProgress >= 0.92 && (_jsx(StyledLabel, { x: labelPosition[0], y: labelPosition[1], textAnchor: "middle", dominantBaseline: "central", children: (_a = labelFormatter === null || labelFormatter === void 0 ? void 0 : labelFormatter(slice.data, slice.percent)) !== null && _a !== void 0 ? _a : `${percent}%` }))] }, sliceKey));
201
+ }) })] }), (centerLabel != null || centerValue != null) && (_jsx(StyledCenter, { children: _jsxs(StyledCenterPanel, { "$diameter": centerPanelDiameter, children: [centerValue != null && (_jsx(StyledCenterValue, { children: centerValue })), centerLabel != null && (_jsx(StyledCenterLabel, { children: centerLabel }))] }) }))] })) }), shouldShowLegend && (_jsx(StyledLegend, { children: slices.map((slice, index) => {
187
202
  const sliceKey = getSliceKey(slice.data, index);
188
203
  return (_jsxs(StyledLegendItem, { "$active": activeSliceKey === sliceKey, "$showSwatch": showLegendSwatches, "$showLabel": showLegendLabels, "$showMeta": showLegendMeta, tabIndex: 0, onMouseEnter: () => setActiveSliceKey(sliceKey), onMouseLeave: () => setActiveSliceKey(null), onFocus: () => setActiveSliceKey(sliceKey), onBlur: () => setActiveSliceKey(null), onClick: (event) => onLegendItemClick === null || onLegendItemClick === void 0 ? void 0 : onLegendItemClick(event, slice.data), onKeyDown: (event) => {
189
204
  if (event.key !== "Enter" && event.key !== " ")
@@ -1,6 +1,11 @@
1
1
  import { StyledChartActions } from "../ChartPrimitives";
2
- export declare const StyledContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
3
- export declare const StyledChartWrap: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
2
+ export declare const StyledContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
3
+ $fillAvailableWidth: boolean;
4
+ }>> & string;
5
+ export declare const StyledChartWrap: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
6
+ $width?: string;
7
+ $height?: string;
8
+ }>> & string;
4
9
  export { StyledChartActions };
5
10
  export declare const StyledSvg: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").SVGProps<SVGSVGElement>, never>> & string;
6
11
  export declare const StyledSlice: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").SVGProps<SVGPathElement>, {
@@ -11,7 +11,7 @@ export const StyledContainer = styled.div `
11
11
  align-items: center;
12
12
  flex-wrap: wrap;
13
13
  gap: 20px;
14
- width: fit-content;
14
+ width: ${({ $fillAvailableWidth }) => $fillAvailableWidth ? "100%" : "fit-content"};
15
15
  max-width: 100%;
16
16
  color: ${({ theme }) => theme.palette.text.primary};
17
17
  box-sizing: border-box;
@@ -24,6 +24,10 @@ export const StyledChartWrap = styled.div `
24
24
  align-items: stretch;
25
25
  justify-content: center;
26
26
  flex: 0 0 auto;
27
+ width: ${({ $width }) => $width !== null && $width !== void 0 ? $width : "auto"};
28
+ height: ${({ $height }) => $height !== null && $height !== void 0 ? $height : "auto"};
29
+ max-width: 100%;
30
+ box-sizing: border-box;
27
31
  `;
28
32
  export { StyledChartActions };
29
33
  export const StyledSvg = styled.svg `
@@ -146,6 +150,7 @@ export const StyledEmptyState = styled.div `
146
150
  justify-content: center;
147
151
  width: ${({ $size }) => $size}px;
148
152
  height: ${({ $size }) => $size}px;
153
+ box-sizing: border-box;
149
154
  border: 1px dashed ${({ theme }) => theme.palette.divider};
150
155
  border-radius: 50%;
151
156
  background: radial-gradient(
@@ -1,6 +1,6 @@
1
1
  import React, { HTMLAttributes } from "react";
2
2
  import { PieArcDatum } from "d3-shape";
3
- import type { ChartExportOptions } from "../ChartUtils";
3
+ import type { ChartDimension, ChartExportOptions } from "../ChartUtils";
4
4
  export type PieChartDatum<TData = unknown> = {
5
5
  /** Stable identifier for the slice. Falls back to label and index when omitted. */
6
6
  id?: string | number;
@@ -26,8 +26,12 @@ string[]
26
26
  export type PieChartProps<TData = unknown> = HTMLAttributes<HTMLDivElement> & ChartExportOptions & {
27
27
  /** Slice data rendered by the chart. Only positive finite values are displayed. */
28
28
  data: PieChartDatum<TData>[];
29
- /** SVG width and height in pixels. Defaults to 220. */
30
- size?: number;
29
+ /** SVG width and height in pixels or any CSS length measured from the chart frame. Defaults to 220. */
30
+ size?: ChartDimension;
31
+ /** Measures the chart frame and fits the square SVG to its available width. Defaults to false. */
32
+ responsive?: boolean;
33
+ /** Minimum rendered SVG size in pixels. Defaults to 120. */
34
+ minSize?: number;
31
35
  /** Inner radius in pixels. Set to 0 for a solid pie. Defaults to 58. */
32
36
  innerRadius?: number;
33
37
  /** Outer radius in pixels. Defaults to half the size minus chart padding. */
@@ -1,29 +1,14 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import styled from "styled-components";
3
- import * as Tooltip from "@radix-ui/react-tooltip";
4
3
  import { getControlSizeTokens } from "../core";
4
+ import Tooltip from "../Tooltip";
5
5
  export const InfoComponent = styled(({ className, children, description, label }) => {
6
6
  if (!description)
7
7
  return children;
8
- return (_jsx(Tooltip.Provider, { delayDuration: 300, skipDelayDuration: 0, disableHoverableContent: true, children: _jsxs(Tooltip.Root, { children: [_jsx(Tooltip.Trigger, { asChild: true, children: children }), _jsx(Tooltip.Portal, { children: _jsxs(Tooltip.Content, { className: className, side: "right", sideOffset: 15, align: "start", onClick: (e) => e.stopPropagation(), children: [_jsx("div", { className: "title", children: label || "Info" }), _jsx("div", { children: description || "N/A" })] }) })] }) }));
8
+ return (_jsx(Tooltip, { className: className, content: _jsxs(_Fragment, { children: [_jsx("div", { className: "title", children: label || "Info" }), _jsx("div", { children: description })] }), side: "right", hoverableContent: true, sideOffset: 15, align: "start", children: children }));
9
9
  }) `
10
- pointer-events: none;
11
- z-index: 999999;
12
- background-color: ${({ theme }) => theme.palette.background.default};
13
- padding: 15px;
14
- border-radius: 5px;
15
- border: 1px solid ${({ theme }) => theme.palette.divider};
16
- font-size: 0.75rem;
17
10
  max-width: 350px;
18
11
  width: 250px;
19
-
20
- white-space: pre-wrap;
21
-
22
- .title {
23
- font-size: 0.85rem;
24
- font-weight: 600;
25
- margin-bottom: 5px;
26
- }
27
12
  `;
28
13
  const FieldLabel = styled(({ className, children, error, description, size = "sm", style, actionComponent, }) => {
29
14
  return (_jsxs("div", { className: className + " FieldLabel", style: style, children: [_jsxs("div", { className: "label-content", children: [_jsx(InfoComponent, { description: description, label: children, children: _jsx("div", { className: "label", children: children }) }), error && (_jsx("div", { className: "error", title: error, children: error || "Invalid Value" }))] }), actionComponent && (_jsx("div", { className: "action-section", children: actionComponent }))] }));
@@ -1,10 +1,30 @@
1
- import { Extension } from "@tiptap/core";
1
+ import type { ComponentType } from "react";
2
+ import { Extension, Editor } from "@tiptap/core";
2
3
  import { HandleImageUpload } from "../Plugins/UploadImagesPlugin.js";
3
4
  import { SlashCommands } from "../Enums";
4
- type CommandName = keyof typeof SlashCommands;
5
+ export type SlashCommandRange = {
6
+ from: number;
7
+ to: number;
8
+ };
9
+ export type SlashCommandActionProps = {
10
+ editor: Editor;
11
+ range: SlashCommandRange;
12
+ };
13
+ export type CustomSlashCommand = {
14
+ id: string;
15
+ title: string;
16
+ description?: string;
17
+ searchTerms?: string[];
18
+ icon?: ComponentType<{
19
+ size?: number;
20
+ }>;
21
+ command: (props: SlashCommandActionProps) => void;
22
+ };
5
23
  interface SlashCommandOptions {
6
24
  handleImageUpload?: HandleImageUpload;
7
- commands?: CommandName[];
25
+ commands?: SlashCommands[];
26
+ customCommands?: CustomSlashCommand[];
27
+ getCustomCommands?: () => CustomSlashCommand[];
8
28
  }
9
29
  declare const getSlashCommand: (options?: SlashCommandOptions) => Extension;
10
30
  export default getSlashCommand;
@@ -20,14 +20,14 @@ import moment from "moment/moment.js";
20
20
  import { DEFAULT_CODE_BLOCK_LANGUAGE } from "../Utils/codeBlockUtils";
21
21
  const SlashCommandPluginKey = new PluginKey("slash-command");
22
22
  const getCommandItems = (values, options) => {
23
- var _a;
23
+ var _a, _b;
24
24
  if ((_a = options === null || options === void 0 ? void 0 : options.commands) === null || _a === void 0 ? void 0 : _a.includes(SlashCommands.Image)) {
25
25
  // Assert that options.handleImageUpload is defined
26
26
  if (!options.handleImageUpload) {
27
27
  throw new Error("options.handleImageUpload is required when using the Image command.");
28
28
  }
29
29
  }
30
- return [
30
+ const builtInItems = [
31
31
  {
32
32
  title: SlashCommands.Text,
33
33
  description: "Just start typing with plain text.",
@@ -208,14 +208,22 @@ const getCommandItems = (values, options) => {
208
208
  .run();
209
209
  },
210
210
  },
211
- ]
212
- .filter((item) => {
211
+ ].filter((item) => {
213
212
  if (options === null || options === void 0 ? void 0 : options.commands) {
214
213
  return options.commands.includes(item.title);
215
214
  }
216
215
  return true;
217
- })
218
- .filter((item) => {
216
+ });
217
+ const customItems = (((_b = options === null || options === void 0 ? void 0 : options.getCustomCommands) === null || _b === void 0 ? void 0 : _b.call(options)) ||
218
+ (options === null || options === void 0 ? void 0 : options.customCommands) ||
219
+ []).map((command) => ({
220
+ title: command.title,
221
+ description: command.description || "",
222
+ searchTerms: command.searchTerms,
223
+ icon: command.icon || Text,
224
+ command: command.command,
225
+ }));
226
+ return [...builtInItems, ...customItems].filter((item) => {
219
227
  var _a, _b;
220
228
  if (typeof (values === null || values === void 0 ? void 0 : values.query) === "string" && ((_a = values === null || values === void 0 ? void 0 : values.query) === null || _a === void 0 ? void 0 : _a.length) > 0) {
221
229
  const search = (_b = values === null || values === void 0 ? void 0 : values.query) === null || _b === void 0 ? void 0 : _b.toLowerCase();
@@ -1,6 +1,7 @@
1
1
  import { Extension } from "@tiptap/core";
2
2
  import { HandleImageUpload } from "../Plugins";
3
- import { Extensions } from "../Enums";
3
+ import type { CustomSlashCommand } from "./getSlashCommand";
4
+ import { Extensions, SlashCommands } from "../Enums";
4
5
  export type ExtensionPreset = "minimal" | "basic" | "full";
5
6
  export type ExtensionType = (typeof Extensions)[keyof typeof Extensions];
6
7
  export declare const BASIC_EXTENSIONS: ExtensionType[];
@@ -14,7 +15,9 @@ export declare const resolveExtensions: ({ disabledExtensions, extensionPreset,
14
15
  interface GetTipTapExtensionsProps {
15
16
  disabledExtensions?: ExtensionType[];
16
17
  extensions?: ExtensionType[];
17
- slashCommands?: any[];
18
+ slashCommands?: SlashCommands[];
19
+ customSlashCommands?: CustomSlashCommand[];
20
+ getCustomSlashCommands?: () => CustomSlashCommand[];
18
21
  handleImageUpload?: HandleImageUpload;
19
22
  }
20
23
  declare const getTipTapExtensions: (props: GetTipTapExtensionsProps) => Extension[];
@@ -118,7 +118,7 @@ export const resolveExtensions = ({ disabledExtensions = [], extensionPreset = "
118
118
  disabled.forEach((extension) => resolved.delete(extension));
119
119
  return Array.from(resolved);
120
120
  };
121
- const getTipTapExtensions = ({ disabledExtensions = [], extensions = [], slashCommands = [], handleImageUpload, }) => {
121
+ const getTipTapExtensions = ({ disabledExtensions = [], extensions = [], slashCommands = [], customSlashCommands = [], getCustomSlashCommands, handleImageUpload, }) => {
122
122
  const disabled = new Set(disabledExtensions);
123
123
  const enabled = new Set(extensions);
124
124
  const isEnabled = (extension) => enabled.has(extension) && !disabled.has(extension);
@@ -297,6 +297,8 @@ const getTipTapExtensions = ({ disabledExtensions = [], extensions = [], slashCo
297
297
  name: Extensions.SlashCommand,
298
298
  extension: getSlashCommand({
299
299
  commands: slashCommands,
300
+ customCommands: customSlashCommands,
301
+ getCustomCommands: getCustomSlashCommands,
300
302
  handleImageUpload,
301
303
  }),
302
304
  },
@@ -1,15 +1,18 @@
1
1
  import { Editor } from "@tiptap/react";
2
2
  import { ExtensionPreset, ExtensionType } from "./Extensions/getTiptapExtensions";
3
+ import type { CustomSlashCommand } from "./Extensions/getSlashCommand";
4
+ import { SlashCommands } from "./Enums";
3
5
  import { HandleImageUrlUpload, HandleImageUpload } from "./Plugins/UploadImagesPlugin";
4
6
  import { BubbleMenuOptions } from "./Components/BubbleMenu";
5
7
  import { ToolbarOptions } from "./Toolbar/Toolbar";
6
- type RichTextEditorProps = {
8
+ export type RichTextEditorProps = {
7
9
  className?: string;
8
10
  editorInstanceRef?: React.RefObject<Editor | null>;
9
11
  extensions?: ExtensionType[];
10
12
  disabledExtensions?: ExtensionType[];
11
13
  extensionPreset?: ExtensionPreset;
12
- slashCommands?: any[];
14
+ slashCommands?: SlashCommands[];
15
+ customSlashCommands?: CustomSlashCommand[];
13
16
  defaultValue?: string;
14
17
  value?: string;
15
18
  readOnly?: boolean;
@@ -25,5 +28,5 @@ type RichTextEditorProps = {
25
28
  autoFocus?: boolean;
26
29
  style?: React.CSSProperties;
27
30
  };
31
+ export type { CustomSlashCommand, SlashCommandActionProps, SlashCommandRange, } from "./Extensions/getSlashCommand";
28
32
  export declare const RichTextEditor: React.FC<RichTextEditorProps>;
29
- export {};