@adaptabletools/adaptable 23.0.0-canary.7 → 23.0.0-canary.8

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 (90) hide show
  1. package/index.css +75 -9
  2. package/package.json +1 -1
  3. package/src/AdaptableState/StyledColumnState.d.ts +8 -850
  4. package/src/AdaptableState/StyledColumnState.js +1 -9
  5. package/src/AdaptableState/StyledColumns/BadgeStyle.d.ts +143 -0
  6. package/src/AdaptableState/StyledColumns/BadgeStyle.js +9 -0
  7. package/src/AdaptableState/StyledColumns/BulletChartStyle.d.ts +147 -0
  8. package/src/AdaptableState/StyledColumns/BulletChartStyle.js +1 -0
  9. package/src/AdaptableState/StyledColumns/Common/BarChartCellText.d.ts +60 -0
  10. package/src/AdaptableState/StyledColumns/Common/BarChartCellText.js +6 -0
  11. package/src/AdaptableState/StyledColumns/Common/BarChartMarker.d.ts +24 -0
  12. package/src/AdaptableState/StyledColumns/Common/BarChartMarker.js +5 -0
  13. package/src/AdaptableState/StyledColumns/Common/CellTextOptions.d.ts +13 -0
  14. package/src/AdaptableState/StyledColumns/Common/CellTextOptions.js +6 -0
  15. package/src/AdaptableState/StyledColumns/Common/NumericStyledColumn.d.ts +79 -0
  16. package/src/AdaptableState/StyledColumns/Common/NumericStyledColumn.js +9 -0
  17. package/src/AdaptableState/StyledColumns/GradientStyle.d.ts +48 -0
  18. package/src/AdaptableState/StyledColumns/GradientStyle.js +1 -0
  19. package/src/AdaptableState/StyledColumns/IconStyle.d.ts +158 -0
  20. package/src/AdaptableState/StyledColumns/IconStyle.js +1 -0
  21. package/src/AdaptableState/StyledColumns/PercentBarStyle.d.ts +32 -0
  22. package/src/AdaptableState/StyledColumns/PercentBarStyle.js +1 -0
  23. package/src/AdaptableState/StyledColumns/RangeBarStyle.d.ts +155 -0
  24. package/src/AdaptableState/StyledColumns/RangeBarStyle.js +1 -0
  25. package/src/AdaptableState/StyledColumns/RatingStyle.d.ts +111 -0
  26. package/src/AdaptableState/StyledColumns/RatingStyle.js +1 -0
  27. package/src/AdaptableState/StyledColumns/SparklineStyle.d.ts +21 -0
  28. package/src/AdaptableState/StyledColumns/SparklineStyle.js +1 -0
  29. package/src/Api/ColumnScopeApi.d.ts +1 -1
  30. package/src/Api/Implementation/ColumnScopeApiImpl.d.ts +1 -1
  31. package/src/Api/Internal/StyledColumnInternalApi.d.ts +3 -1
  32. package/src/Utilities/Helpers/IconStylePresets.d.ts +1 -1
  33. package/src/Utilities/Helpers/StyledColumnGradientHelper.d.ts +3 -1
  34. package/src/Utilities/Helpers/barChartCellText.d.ts +63 -0
  35. package/src/Utilities/Helpers/barChartCellText.js +316 -0
  36. package/src/Utilities/Helpers/percentBarPreviewHelper.d.ts +2 -1
  37. package/src/Utilities/Helpers/percentBarPreviewHelper.js +3 -8
  38. package/src/View/Alert/Wizard/AlertButtonsEditor.js +159 -126
  39. package/src/View/Alert/Wizard/AlertNotificationWizardSection.js +1 -1
  40. package/src/View/Alert/Wizard/AlertWizard.js +9 -1
  41. package/src/View/Components/AdaptableObjectList/AdaptableObjectCompactList.js +3 -2
  42. package/src/View/Components/AdaptableObjectList/AdaptableObjectList.js +3 -2
  43. package/src/View/Components/AdaptableObjectList/objectListActionButtonStyles.d.ts +2 -0
  44. package/src/View/Components/AdaptableObjectList/objectListActionButtonStyles.js +2 -0
  45. package/src/View/Components/Buttons/EntityListActionButtons.js +1 -1
  46. package/src/View/Components/Buttons/SuspendToggleButton/SuspendToggleButton.d.ts +1 -0
  47. package/src/View/Components/Buttons/SuspendToggleButton/SuspendToggleButton.js +8 -8
  48. package/src/View/Components/ColumnFilter/ColumnFilter.js +14 -1
  49. package/src/View/Components/Popups/AdaptablePopup/AdaptablePopupModuleView.js +1 -1
  50. package/src/View/Components/RangesComponent.d.ts +2 -1
  51. package/src/View/Export/ExportSchedulesTab.js +3 -4
  52. package/src/View/Filter/FilterViewPanel.js +1 -1
  53. package/src/View/Layout/Wizard/sections/RowSummarySection.js +129 -103
  54. package/src/View/StyledColumn/Wizard/BadgePillStyleEditor.d.ts +1 -1
  55. package/src/View/StyledColumn/Wizard/StyledColumnBadgeSection.js +36 -30
  56. package/src/View/StyledColumn/Wizard/StyledColumnSliceStyleEditors.d.ts +1 -3
  57. package/src/View/StyledColumn/Wizard/StyledColumnWizardBulletSection.js +73 -58
  58. package/src/View/StyledColumn/Wizard/StyledColumnWizardIconSection.js +38 -11
  59. package/src/View/StyledColumn/Wizard/StyledColumnWizardRangeBarSection.js +86 -44
  60. package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/BarChartCellTextLayoutEditor.d.ts +9 -0
  61. package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/BarChartCellTextLayoutEditor.js +35 -0
  62. package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/BarChartCellTextPreview.d.ts +23 -0
  63. package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/BarChartCellTextPreview.js +57 -0
  64. package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/BulletRangesSummaryPreview.d.ts +1 -1
  65. package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/GradientSummaryPreview.d.ts +2 -1
  66. package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/RangeBarRangesSummaryPreview.d.ts +1 -1
  67. package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/StyledColumnBadgePreview.js +3 -2
  68. package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/StyledColumnBulletPreview.d.ts +2 -1
  69. package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/StyledColumnBulletPreview.js +13 -17
  70. package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/StyledColumnChartListPreviews.d.ts +2 -1
  71. package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/StyledColumnChartListPreviews.js +5 -5
  72. package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/StyledColumnIconPreview.js +2 -2
  73. package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/StyledColumnPercentBarPreview.js +14 -7
  74. package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/StyledColumnRangeBarPreview.js +11 -17
  75. package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/StyledColumnRatingPreview.d.ts +2 -1
  76. package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/StyledColumnWizardStyleSection.js +18 -54
  77. package/src/agGrid/AgGridColumnAdapter.js +2 -1
  78. package/src/agGrid/cellRenderers/BadgeRenderer.js +7 -5
  79. package/src/agGrid/cellRenderers/BulletChartRenderer.js +43 -42
  80. package/src/agGrid/cellRenderers/IconRenderer.d.ts +2 -1
  81. package/src/agGrid/cellRenderers/IconRenderer.js +13 -11
  82. package/src/agGrid/cellRenderers/PercentBarRenderer.js +24 -96
  83. package/src/agGrid/cellRenderers/RangeBarRenderer.js +49 -46
  84. package/src/env.js +2 -2
  85. package/src/metamodel/adaptable.metamodel.d.ts +80 -14
  86. package/src/metamodel/adaptable.metamodel.js +1 -1
  87. package/src/migration/VersionUpgrade23.d.ts +27 -31
  88. package/src/migration/VersionUpgrade23.js +110 -29
  89. package/src/types.d.ts +12 -1
  90. package/tsconfig.esm.tsbuildinfo +1 -1
@@ -0,0 +1,9 @@
1
+ import * as React from 'react';
2
+ import { BarChartCellTextPlacement, BarChartCellTextProperties } from '../../../../../AdaptableState/StyledColumns/Common/BarChartCellText';
3
+ import { CellTextOption } from '../../../../../AdaptableState/StyledColumns/Common/CellTextOptions';
4
+ export declare const BarChartCellTextLayoutEditor: React.FunctionComponent<{
5
+ disabled?: boolean;
6
+ cellTextProperties?: BarChartCellTextProperties;
7
+ onToggle: (token: CellTextOption, show: boolean) => void;
8
+ onPlacementChange: (token: CellTextOption, patch: Partial<BarChartCellTextPlacement>) => void;
9
+ }>;
@@ -0,0 +1,35 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import * as React from 'react';
3
+ import { resolveBarChartCellTextLayout } from '../../../../../Utilities/Helpers/barChartCellText';
4
+ import { CheckBox } from '../../../../../components/CheckBox';
5
+ import { Box, Flex } from '../../../../../components/Flex';
6
+ import { SingleSelect } from '../../../../../components/NewSelect';
7
+ const TOKEN_LABELS = {
8
+ CellValue: 'Cell Value',
9
+ PercentageValue: 'Percent Value',
10
+ };
11
+ const TOKENS = ['CellValue', 'PercentageValue'];
12
+ const HORIZONTAL_CHOICES = [
13
+ { value: 'Left', label: 'Left' },
14
+ { value: 'Center', label: 'Center' },
15
+ { value: 'Right', label: 'Right' },
16
+ ];
17
+ const VERTICAL_CHOICES = [
18
+ { value: 'Above', label: 'Above Bar' },
19
+ { value: 'Below', label: 'Below Bar' },
20
+ { value: 'Merged', label: 'Merged' },
21
+ ];
22
+ const tokenKey = (token) => token === 'CellValue' ? 'CellValue' : 'PercentValue';
23
+ export const BarChartCellTextLayoutEditor = ({ disabled, cellTextProperties, onToggle, onPlacementChange }) => {
24
+ const layout = resolveBarChartCellTextLayout(cellTextProperties);
25
+ return (_jsxs(Box, { className: "twa:inline-grid twa:grid-cols-[160px_140px_140px] twa:gap-x-4 twa:gap-y-2 twa:items-center", children: [_jsx(Box, { className: "twa:text-xs twa:font-medium twa:opacity-80", children: "Value" }), _jsx(Box, { className: "twa:text-xs twa:font-medium twa:opacity-80", children: "Horizontal" }), _jsx(Box, { className: "twa:text-xs twa:font-medium twa:opacity-80", children: "Vertical" }), TOKENS.map((token) => {
26
+ const placement = layout[tokenKey(token)];
27
+ const isShown = Boolean(placement);
28
+ const rowDisabled = disabled || !isShown;
29
+ return (_jsxs(React.Fragment, { children: [_jsx(Flex, { alignItems: "center", children: _jsx(CheckBox, { disabled: disabled, checked: isShown, onChange: (checked) => onToggle(token, checked), children: TOKEN_LABELS[token] }) }), _jsx(Box, { children: _jsx(SingleSelect, { className: "twa:w-full", disabled: rowDisabled, value: placement?.Horizontal ?? 'Left', onValueChange: (v) => onPlacementChange(token, {
30
+ Horizontal: v,
31
+ }), items: HORIZONTAL_CHOICES }) }), _jsx(Box, { children: _jsx(SingleSelect, { className: "twa:w-full", disabled: rowDisabled, value: placement?.Vertical ?? 'Below', onValueChange: (v) => onPlacementChange(token, {
32
+ Vertical: v,
33
+ }), items: VERTICAL_CHOICES }) })] }, token));
34
+ })] }));
35
+ };
@@ -0,0 +1,23 @@
1
+ import * as React from 'react';
2
+ import { BarChartCellTextProperties } from '../../../../../AdaptableState/StyledColumns/Common/BarChartCellText';
3
+ import { BarChartCellTextLabels } from '../../../../../Utilities/Helpers/barChartCellText';
4
+ /**
5
+ * Preview of the per-value cell-text layout. Renders three potential bands:
6
+ * - `Above` slots (above the bar)
7
+ * - `Merged` slots (overlay on top of the bar — uses `mergedOverlayClassName`)
8
+ * - `Below` slots (below the bar)
9
+ *
10
+ * Each band has three horizontal slots (Left/Center/Right) so the spacing is
11
+ * stable. When `vertical` is provided, only the band matching that value is
12
+ * rendered (used by the preview cards to position bands around the bar).
13
+ */
14
+ export declare const BarChartCellTextPreview: React.FunctionComponent<{
15
+ className?: string;
16
+ style?: React.CSSProperties;
17
+ cellTextProperties?: BarChartCellTextProperties;
18
+ labels: BarChartCellTextLabels;
19
+ mergedOverlayClassName?: string;
20
+ /** Render only the band matching this vertical position. */
21
+ vertical?: 'Above' | 'Below' | 'Merged';
22
+ }>;
23
+ export declare const shouldShowBarChartCellTextOutsideBar: (cellTextProperties: BarChartCellTextProperties | undefined, hasCellText: boolean) => boolean;
@@ -0,0 +1,57 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { getBarChartCellTextSlotPresence, hasBarChartCellTextConfigured, resolveBarChartCellTextSlots, } from '../../../../../Utilities/Helpers/barChartCellText';
3
+ import { Box, Flex } from '../../../../../components/Flex';
4
+ const HORIZONTAL_ORDER = ['Left', 'Center', 'Right'];
5
+ const HORIZONTAL_JUSTIFY = {
6
+ Left: 'flex-start',
7
+ Center: 'center',
8
+ Right: 'flex-end',
9
+ };
10
+ const HORIZONTAL_TEXT_ALIGN = {
11
+ Left: 'left',
12
+ Center: 'center',
13
+ Right: 'right',
14
+ };
15
+ const CellTextRow = ({ className, style, slots }) => (_jsx(Flex, { className: className, alignItems: "center", style: { ...style, width: '100%', gap: 4 }, children: HORIZONTAL_ORDER.map((horizontal) => {
16
+ const slot = slots.find((s) => s.horizontal === horizontal);
17
+ return (_jsx(Box, { className: "twa:truncate", style: {
18
+ flex: 1,
19
+ minWidth: 0,
20
+ display: 'flex',
21
+ justifyContent: HORIZONTAL_JUSTIFY[horizontal],
22
+ alignItems: 'center',
23
+ textAlign: HORIZONTAL_TEXT_ALIGN[horizontal],
24
+ }, children: slot?.text ?? '' }, horizontal));
25
+ }) }));
26
+ /**
27
+ * Preview of the per-value cell-text layout. Renders three potential bands:
28
+ * - `Above` slots (above the bar)
29
+ * - `Merged` slots (overlay on top of the bar — uses `mergedOverlayClassName`)
30
+ * - `Below` slots (below the bar)
31
+ *
32
+ * Each band has three horizontal slots (Left/Center/Right) so the spacing is
33
+ * stable. When `vertical` is provided, only the band matching that value is
34
+ * rendered (used by the preview cards to position bands around the bar).
35
+ */
36
+ export const BarChartCellTextPreview = ({ className, style, cellTextProperties, labels, mergedOverlayClassName, vertical }) => {
37
+ if (!labels.cellValue && !labels.percentage) {
38
+ return null;
39
+ }
40
+ const slots = resolveBarChartCellTextSlots(cellTextProperties, labels);
41
+ if (!slots.length) {
42
+ return null;
43
+ }
44
+ const bandSlots = vertical ? slots.filter((s) => s.vertical === vertical) : slots;
45
+ if (!bandSlots.length) {
46
+ return null;
47
+ }
48
+ const usedClassName = vertical === 'Merged' ? mergedOverlayClassName ?? className : className;
49
+ return (_jsx(CellTextRow, { className: usedClassName, style: style, slots: bandSlots.map((s) => ({ horizontal: s.horizontal, text: s.text })) }));
50
+ };
51
+ export const shouldShowBarChartCellTextOutsideBar = (cellTextProperties, hasCellText) => {
52
+ if (!hasCellText || !hasBarChartCellTextConfigured(cellTextProperties)) {
53
+ return false;
54
+ }
55
+ const { hasAbove, hasBelow } = getBarChartCellTextSlotPresence(cellTextProperties);
56
+ return hasAbove || hasBelow;
57
+ };
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { BulletChartStyle } from '../../../../../AdaptableState/StyledColumnState';
2
+ import { BulletChartStyle } from '../../../../../AdaptableState/StyledColumns/BulletChartStyle';
3
3
  export declare const BulletRangesSummaryPreview: React.FunctionComponent<{
4
4
  bulletStyle: BulletChartStyle;
5
5
  }>;
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
- import { CellColorRange, ColumnComparison, GradientStyle, GradientZeroCentredColors, NumericStyledColumn } from '../../../../../AdaptableState/StyledColumnState';
2
+ import { CellColorRange, ColumnComparison, NumericStyledColumn } from '../../../../../AdaptableState/StyledColumns/Common/NumericStyledColumn';
3
+ import { GradientStyle, GradientZeroCentredColors } from '../../../../../AdaptableState/StyledColumns/GradientStyle';
3
4
  import { AdaptableApi } from '../../../../../types';
4
5
  export declare function gradientRangeStripCss(color: string, reverseGradient: boolean, minAlpha: number, maxAlpha: number): string;
5
6
  export interface GradientRangesSummaryPreviewProps {
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { RangeBarStyle } from '../../../../../AdaptableState/StyledColumnState';
2
+ import { RangeBarStyle } from '../../../../../AdaptableState/StyledColumns/RangeBarStyle';
3
3
  export declare const RangeBarRangesSummaryPreview: React.FunctionComponent<{
4
4
  rangeStyle: RangeBarStyle;
5
5
  }>;
@@ -51,12 +51,13 @@ export const StyledColumnBadgePreview = ({ data }) => {
51
51
  : {}),
52
52
  };
53
53
  return (_jsx(Box, { className: PREVIEW_CELL_CLASS, style: cellStyle, children: _jsx("div", { className: wrapperClassName, style: wrapperStyle, children: badgeStyle.Badges.map((badge, index) => {
54
- const badgeValue = badge.IconOnly
54
+ const iconProps = badge.IconProperties;
55
+ const badgeValue = iconProps?.IconOnly
55
56
  ? ''
56
57
  : dataType === 'number'
57
58
  ? DEFAULT_INTEGER_DISPLAY_VALUE
58
59
  : DEFAULT_STRING_DISPLAY_VALUE;
59
- return (_jsx(Badge, { icon: badge.Icon, pillStyle: badge.PillStyle, iconPosition: badge.IconPosition, shape: badge.Shape, density: badgeStyle.Density ?? 'Normal', iconGap: badge.IconGap, children: badgeValue }, index));
60
+ return (_jsx(Badge, { icon: iconProps?.Icon, pillStyle: badge.PillStyle, iconPosition: iconProps?.Position, shape: badge.Shape, density: badgeStyle.Density ?? 'Normal', iconGap: iconProps?.Gap, children: badgeValue }, index));
60
61
  }) }) }));
61
62
  };
62
63
  export const StyledColumnBadgePreviewCard = ({ data }) => (_jsxs(Card, { shadow: false, children: [_jsx(Card.Title, { children: _jsx(Box, { className: "twa:font-medium", children: "Preview" }) }), _jsx(Card.Body, { className: "twa:p-1", children: _jsx(StyledColumnBadgePreview, { data: data }) })] }));
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
- import { BulletChartStyle, StyledColumn } from '../../../../../AdaptableState/StyledColumnState';
2
+ import { StyledColumn } from '../../../../../AdaptableState/StyledColumnState';
3
+ import { BulletChartStyle } from '../../../../../AdaptableState/StyledColumns/BulletChartStyle';
3
4
  export declare const StyledColumnBulletPreview: React.FunctionComponent<React.PropsWithChildren<{
4
5
  data: StyledColumn;
5
6
  }>>;
@@ -1,9 +1,11 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { convertAdaptableStyleToCSS } from '../../../../../Utilities/Helpers/StyleHelper';
3
+ import { buildBarChartCellTextLabels, getBarChartCellTextSlotPresence, hasBarChartCellTextConfigured, } from '../../../../../Utilities/Helpers/barChartCellText';
3
4
  import { Box, Flex } from '../../../../../components/Flex';
4
5
  import { Card } from '../../../../../components/Card';
5
6
  import { Tag } from '../../../../../components/Tag';
6
7
  import { StyledColumnBulletChartListPreview } from './StyledColumnChartListPreviews';
8
+ import { BarChartCellTextPreview } from './BarChartCellTextPreview';
7
9
  const PREVIEW_CELL_CLASS = 'ab-BulletPreviewCell twa:inline-flex twa:items-center twa:min-w-[180px] twa:min-h-[36px] twa:px-2 twa:py-1 twa:rounded-standard twa:border twa:border-[color-mix(in_srgb,var(--ab-color-foreground)_15%,transparent)]';
8
10
  const getBulletPreviewSample = (bullet) => {
9
11
  const ranges = bullet.CellRanges ?? [];
@@ -23,29 +25,23 @@ const getBulletPreviewSample = (bullet) => {
23
25
  valueFraction: Math.max(0, Math.min(1, valueFraction)),
24
26
  };
25
27
  };
26
- const formatBulletPreviewCellText = (sampleValue, valueFraction, bullet) => {
27
- const parts = [];
28
- if (bullet.CellText?.includes('CellValue')) {
29
- parts.push(Number.isInteger(sampleValue) ? String(sampleValue) : sampleValue.toFixed(1));
30
- }
31
- if (bullet.CellText?.includes('PercentageValue')) {
32
- parts.push(`${(valueFraction * 100).toFixed(0)}%`);
33
- }
34
- return parts.join(' ');
35
- };
36
28
  const BulletChartPreviewContent = ({ bullet, }) => {
37
29
  const { sampleValue, valueFraction } = getBulletPreviewSample(bullet);
38
- const cellText = formatBulletPreviewCellText(sampleValue, valueFraction, bullet);
39
- const hasCellText = Boolean(bullet.CellText?.length && cellText);
40
- const textPosition = bullet.CellTextPosition ?? 'Below';
30
+ const cellTextProperties = bullet.CellTextProperties;
31
+ const labels = buildBarChartCellTextLabels(cellTextProperties, Number.isInteger(sampleValue) ? String(sampleValue) : sampleValue.toFixed(1), `${(valueFraction * 100).toFixed(0)}%`);
32
+ const hasCellText = hasBarChartCellTextConfigured(cellTextProperties) &&
33
+ Boolean(labels.cellValue || labels.percentage);
34
+ const presence = getBarChartCellTextSlotPresence(cellTextProperties);
41
35
  const fontStyle = bullet.Font ? convertAdaptableStyleToCSS(bullet.Font) : undefined;
42
36
  const isVertical = bullet.Orientation === 'Vertical';
37
+ const cellTextClassName = 'ab-BulletChart__text twa:text-2 twa:leading-tight twa:truncate twa:max-w-full';
43
38
  const chartEl = _jsx(StyledColumnBulletChartListPreview, { bullet: bullet });
44
- const textEl = hasCellText ? (_jsx(Box, { className: "ab-BulletChart__text twa:text-2 twa:leading-tight twa:truncate twa:max-w-full", style: fontStyle, children: cellText })) : null;
45
- if (hasCellText && textPosition === 'Merged') {
46
- return (_jsxs(Box, { className: "ab-BulletChart__wrapper twa:relative twa:inline-flex", children: [chartEl, _jsx(Box, { className: "ab-BulletChart__text twa:absolute twa:inset-x-0 twa:top-1/2 twa:-translate-y-1/2 twa:px-1 twa:text-2 twa:truncate twa:pointer-events-none", style: fontStyle, children: cellText })] }));
39
+ // Merged-only with no outside bands relative container so the overlay sits
40
+ // on top of the chart, matching the runtime renderer's behaviour.
41
+ if (hasCellText && presence.hasMerged && !presence.hasAbove && !presence.hasBelow) {
42
+ return (_jsxs(Box, { className: "ab-BulletChart__wrapper twa:relative twa:inline-flex", children: [chartEl, _jsx(BarChartCellTextPreview, { mergedOverlayClassName: "ab-BulletChart__text twa:absolute twa:inset-x-0 twa:top-1/2 twa:-translate-y-1/2 twa:px-1 twa:text-2 twa:truncate twa:pointer-events-none", style: fontStyle, cellTextProperties: cellTextProperties, labels: labels, vertical: "Merged" })] }));
47
43
  }
48
- return (_jsxs(Flex, { className: "ab-BulletChart__wrapper", flexDirection: "column", alignItems: isVertical ? 'center' : 'stretch', style: { justifyContent: 'center', gap: hasCellText ? 2 : 0 }, children: [hasCellText && textPosition === 'Above' && textEl, chartEl, hasCellText && textPosition === 'Below' && textEl] }));
44
+ return (_jsxs(Flex, { className: "ab-BulletChart__wrapper twa:relative", flexDirection: "column", alignItems: isVertical ? 'center' : 'stretch', style: { justifyContent: 'center', gap: hasCellText ? 2 : 0 }, children: [hasCellText && presence.hasAbove && (_jsx(BarChartCellTextPreview, { className: cellTextClassName, style: fontStyle, cellTextProperties: cellTextProperties, labels: labels, vertical: "Above" })), _jsxs(Box, { className: "twa:relative twa:w-full", style: { display: 'inline-flex' }, children: [chartEl, hasCellText && presence.hasMerged && (_jsx(BarChartCellTextPreview, { mergedOverlayClassName: "ab-BulletChart__text twa:absolute twa:inset-x-0 twa:top-1/2 twa:-translate-y-1/2 twa:px-1 twa:text-2 twa:truncate twa:pointer-events-none", style: fontStyle, cellTextProperties: cellTextProperties, labels: labels, vertical: "Merged" }))] }), hasCellText && presence.hasBelow && (_jsx(BarChartCellTextPreview, { className: cellTextClassName, style: fontStyle, cellTextProperties: cellTextProperties, labels: labels, vertical: "Below" }))] }));
49
45
  };
50
46
  export const StyledColumnBulletPreview = ({ data }) => {
51
47
  const bullet = data.BulletChartStyle;
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
- import { BulletChartStyle, RangeBarStyle } from '../../../../../AdaptableState/StyledColumnState';
2
+ import { BulletChartStyle } from '../../../../../AdaptableState/StyledColumns/BulletChartStyle';
3
+ import { RangeBarStyle } from '../../../../../AdaptableState/StyledColumns/RangeBarStyle';
3
4
  /**
4
5
  * Compact schematic of a Range Bar (bands + track + value / reference markers)
5
6
  * for the Styled Columns object list and wizard step summaries.
@@ -41,10 +41,10 @@ const DEFAULT_MARKER = 'var(--ab-color-foreground, #333)';
41
41
  export const StyledColumnRangeBarListPreview = (props) => {
42
42
  const { range } = props;
43
43
  const segments = bandSegmentsForPreview(range.CellRanges);
44
- const trackFill = range.TrackColor ?? DEFAULT_TRACK;
44
+ const trackFill = range.Track?.Color ?? DEFAULT_TRACK;
45
45
  const valueColor = range.Marker?.Color || DEFAULT_BAR;
46
- const refColor = range.ReferenceMarker?.Color || DEFAULT_MARKER;
47
- const hasRef = range.Reference != undefined;
46
+ const refColor = range.Reference?.Marker?.Color || DEFAULT_MARKER;
47
+ const hasRef = range.Reference?.Value != undefined;
48
48
  const isVertical = range.Orientation === 'Vertical';
49
49
  return (_jsx(Box, { className: "twa:rounded twa:border twa:border-[color-mix(in_srgb,var(--ab-color-foreground)_12%,transparent)] twa:bg-[color-mix(in_srgb,var(--ab-color-primary)_40%,transparent)] twa:px-1 twa:py-0.5", style: { width: PREVIEW_WIDTH, height: PREVIEW_HEIGHT }, children: _jsxs("svg", { width: "100%", height: "100%", viewBox: `0 0 ${VB_W} ${VB_H}`, preserveAspectRatio: "none", "aria-hidden": true, children: [segments.length === 0 ? (_jsx("rect", { x: "0", y: "0", width: VB_W, height: VB_H, fill: range.BackColor ?? 'transparent' })) : (segments.map((s, i) => (_jsx("rect", { x: s.x0 * VB_W, y: "0", width: (s.x1 - s.x0) * VB_W, height: VB_H, fill: s.color, opacity: 0.55 }, i)))), isVertical ? (_jsxs(_Fragment, { children: [_jsx("rect", { x: VB_W * 0.42, y: "2", width: "5", height: VB_H - 4, rx: "1", fill: trackFill }), hasRef && (_jsx("line", { x1: VB_W * 0.46, y1: "3", x2: VB_W * 0.46, y2: VB_H - 3, stroke: refColor, strokeWidth: "2", vectorEffect: "non-scaling-stroke" })), _jsx("polygon", { points: `${VB_W * 0.52},${VB_H * 0.35} ${VB_W * 0.62},${VB_H * 0.5} ${VB_W * 0.52},${VB_H * 0.65}`, fill: valueColor })] })) : (_jsxs(_Fragment, { children: [_jsx("rect", { x: "2", y: VB_H * 0.38, width: VB_W - 4, height: "5", rx: "1", fill: trackFill }), hasRef && (_jsx("line", { x1: VB_W * 0.38, y1: VB_H * 0.2, x2: VB_W * 0.38, y2: VB_H * 0.8, stroke: refColor, strokeWidth: "2", vectorEffect: "non-scaling-stroke" })), _jsx("polygon", { points: `${VB_W * 0.72},${VB_H * 0.2} ${VB_W * 0.82},${VB_H * 0.5} ${VB_W * 0.72},${VB_H * 0.8}`, fill: valueColor })] }))] }) }));
50
50
  };
@@ -55,7 +55,7 @@ export const StyledColumnRangeBarListPreview = (props) => {
55
55
  export const StyledColumnBulletChartListPreview = (props) => {
56
56
  const { bullet } = props;
57
57
  const segments = bandSegmentsForPreview(bullet.CellRanges);
58
- const barColor = bullet.BarColor ?? DEFAULT_BAR;
59
- const markerColor = bullet.TargetMarker?.Color || DEFAULT_MARKER;
58
+ const barColor = bullet.Bar?.Color ?? DEFAULT_BAR;
59
+ const markerColor = bullet.TargetProperties?.Marker?.Color || DEFAULT_MARKER;
60
60
  return (_jsx(Box, { className: "twa:rounded twa:border twa:border-[color-mix(in_srgb,var(--ab-color-foreground)_12%,transparent)] twa:bg-[color-mix(in_srgb,var(--ab-color-primary)_40%,transparent)] twa:px-1 twa:py-0.5", style: { width: PREVIEW_WIDTH, height: PREVIEW_HEIGHT }, children: _jsxs("svg", { width: "100%", height: "100%", viewBox: `0 0 ${VB_W} ${VB_H}`, preserveAspectRatio: "none", "aria-hidden": true, children: [segments.length === 0 ? (_jsx("rect", { x: "0", y: "0", width: VB_W, height: VB_H, fill: bullet.BackColor ?? 'transparent' })) : (segments.map((s, i) => (_jsx("rect", { x: s.x0 * VB_W, y: "2", width: (s.x1 - s.x0) * VB_W, height: VB_H - 4, fill: s.color, opacity: 0.5 }, i)))), _jsx("rect", { x: VB_W * 0.04, y: VB_H * 0.35, width: VB_W * 0.58, height: VB_H * 0.3, rx: "1", fill: barColor }), _jsx("line", { x1: VB_W * 0.78, y1: VB_H * 0.12, x2: VB_W * 0.78, y2: VB_H * 0.88, stroke: markerColor, strokeWidth: "2.5", vectorEffect: "non-scaling-stroke" })] }) }));
61
61
  };
@@ -36,7 +36,7 @@ const renderIconSpecForPreview = (spec, size) => {
36
36
  return null;
37
37
  };
38
38
  const buildPreviewText = (mapping, iconStyle) => {
39
- const cellTextTokens = iconStyle.CellText ?? [];
39
+ const cellTextTokens = iconStyle.CellTextProperties?.CellText ?? [];
40
40
  const formatted = String(mapping.Key);
41
41
  const textParts = [];
42
42
  if (cellTextTokens.includes('CellValue') && formatted) {
@@ -50,7 +50,7 @@ const buildPreviewText = (mapping, iconStyle) => {
50
50
  const IconCellPreviewTree = ({ iconStyle, mapping }) => {
51
51
  const size = iconStyle.Size ?? DEFAULT_ICON_STYLE_SIZE;
52
52
  const gap = iconStyle.Gap ?? DEFAULT_ICON_STYLE_GAP;
53
- const textPosition = iconStyle.CellTextPosition ?? 'After';
53
+ const textPosition = iconStyle.CellTextProperties?.CellTextPosition ?? 'After';
54
54
  const text = buildPreviewText(mapping, iconStyle);
55
55
  const fontStyle = iconStyle.Font ? convertAdaptableStyleToCSS(iconStyle.Font) : undefined;
56
56
  const iconNode = renderIconSpecForPreview(mapping.Icon, size);
@@ -1,26 +1,33 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { convertAdaptableStyleToCSS } from '../../../../../Utilities/Helpers/StyleHelper';
3
- import { formatPercentBarPreviewCellText, getPercentBarPreviewGeometry, getPercentBarPreviewResolvedBarColor, getPercentBarPreviewSampleValues, getPercentBarPreviewScale, getPercentBarPreviewTrackColor, hasPercentBarRangesConfigured, } from '../../../../../Utilities/Helpers/percentBarPreviewHelper';
3
+ import { getPercentBarPreviewGeometry, getPercentBarPreviewResolvedBarColor, getPercentBarPreviewSampleValues, getPercentBarPreviewScale, getPercentBarPreviewTrackColor, hasPercentBarRangesConfigured, } from '../../../../../Utilities/Helpers/percentBarPreviewHelper';
4
+ import { buildBarChartCellTextLabels, getBarChartCellTextSlotPresence, hasBarChartCellTextConfigured, } from '../../../../../Utilities/Helpers/barChartCellText';
4
5
  import { Box, Flex } from '../../../../../components/Flex';
5
6
  import { Card } from '../../../../../components/Card';
6
7
  import { Tag } from '../../../../../components/Tag';
8
+ import { BarChartCellTextPreview, shouldShowBarChartCellTextOutsideBar, } from './BarChartCellTextPreview';
7
9
  const PREVIEW_CELL_CLASS = 'ab-PercentBarPreviewCell twa:w-[72px] twa:min-h-[32px] twa:px-1 twa:py-1 twa:rounded-standard twa:border twa:border-[color-mix(in_srgb,var(--ab-color-foreground)_15%,transparent)]';
8
10
  const PercentBarPreviewCell = ({ styledColumn, value, min, max }) => {
9
11
  const pb = styledColumn.PercentBarStyle;
10
12
  const { barLeftPercent, barWidthPercent, percentageValue, barColor } = getPercentBarPreviewGeometry(value, pb, min, max);
11
13
  const trackColor = getPercentBarPreviewTrackColor(pb);
12
14
  const fillColor = getPercentBarPreviewResolvedBarColor(barColor);
13
- const cellText = formatPercentBarPreviewCellText(value, percentageValue, pb);
14
- const hasCellText = Boolean(pb.CellText?.length && cellText);
15
- const textPosition = pb.CellTextPosition ?? 'Below';
15
+ const cellTextProperties = pb.CellTextProperties;
16
+ const labels = buildBarChartCellTextLabels(cellTextProperties, Number.isInteger(value) ? String(value) : value.toFixed(1), `${percentageValue.toFixed(0)}%`);
17
+ const hasCellText = hasBarChartCellTextConfigured(cellTextProperties) &&
18
+ Boolean(labels.cellValue || labels.percentage);
19
+ const presence = getBarChartCellTextSlotPresence(cellTextProperties);
16
20
  const fontStyle = pb.Font ? convertAdaptableStyleToCSS(pb.Font) : undefined;
17
- const textEl = hasCellText ? (_jsx(Box, { className: "ab-PercentBar__text twa:text-2 twa:leading-tight twa:truncate", style: fontStyle, children: cellText })) : null;
21
+ const cellTextClassName = 'ab-PercentBar__text twa:text-2 twa:leading-tight twa:truncate';
18
22
  const barEl = (_jsxs(Box, { className: "ab-PercentBar__bar twa:relative twa:flex-1 twa:min-h-[6px]", style: trackColor ? { background: getPercentBarPreviewResolvedBarColor(trackColor) } : undefined, children: [fillColor && (_jsx(Box, { className: "ab-PercentBar__barInside twa:absolute twa:top-0 twa:h-full", style: {
19
23
  background: fillColor,
20
24
  left: `${barLeftPercent.toFixed(2)}%`,
21
25
  width: `${barWidthPercent.toFixed(2)}%`,
22
- } })), hasCellText && textPosition === 'Merged' && (_jsx(Box, { className: "ab-PercentBar__text twa:absolute twa:inset-x-0 twa:top-1/2 twa:-translate-y-1/2 twa:px-1 twa:text-2 twa:truncate", style: fontStyle, children: cellText }))] }));
23
- return (_jsxs(Flex, { className: `ab-PercentBar__wrapper ${PREVIEW_CELL_CLASS}`, flexDirection: "column", style: { justifyContent: 'center', height: hasCellText && textPosition !== 'Merged' ? '100%' : undefined }, children: [hasCellText && textPosition === 'Above' && textEl, barEl, hasCellText && textPosition === 'Below' && textEl] }));
26
+ } })), hasCellText && presence.hasMerged && (_jsx(BarChartCellTextPreview, { mergedOverlayClassName: "ab-PercentBar__text twa:absolute twa:inset-x-0 twa:top-1/2 twa:-translate-y-1/2 twa:px-1 twa:text-2 twa:truncate", style: fontStyle, cellTextProperties: cellTextProperties, labels: labels, vertical: "Merged" }))] }));
27
+ return (_jsxs(Flex, { className: `ab-PercentBar__wrapper ${PREVIEW_CELL_CLASS}`, flexDirection: "column", style: {
28
+ justifyContent: 'center',
29
+ height: shouldShowBarChartCellTextOutsideBar(cellTextProperties, hasCellText) ? '100%' : undefined,
30
+ }, children: [hasCellText && presence.hasAbove && (_jsx(BarChartCellTextPreview, { className: cellTextClassName, style: fontStyle, cellTextProperties: cellTextProperties, labels: labels, vertical: "Above" })), barEl, hasCellText && presence.hasBelow && (_jsx(BarChartCellTextPreview, { className: cellTextClassName, style: fontStyle, cellTextProperties: cellTextProperties, labels: labels, vertical: "Below" }))] }));
24
31
  };
25
32
  export const StyledColumnPercentBarPreview = ({ data }) => {
26
33
  const pb = data.PercentBarStyle;
@@ -1,8 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { buildBarChartCellTextLabels, getBarChartCellTextSlotPresence, hasBarChartCellTextConfigured, } from '../../../../../Utilities/Helpers/barChartCellText';
2
3
  import { Box, Flex } from '../../../../../components/Flex';
3
4
  import { Card } from '../../../../../components/Card';
4
5
  import { Tag } from '../../../../../components/Tag';
5
6
  import { StyledColumnRangeBarListPreview } from './StyledColumnChartListPreviews';
7
+ import { BarChartCellTextPreview } from './BarChartCellTextPreview';
6
8
  const PREVIEW_CELL_CLASS = 'ab-RangeBarPreviewCell twa:inline-flex twa:items-center twa:min-w-[180px] twa:min-h-[36px] twa:px-2 twa:py-1 twa:rounded-standard twa:border twa:border-[color-mix(in_srgb,var(--ab-color-foreground)_15%,transparent)]';
7
9
  const getRangeBarPreviewSample = (range) => {
8
10
  let min = 0;
@@ -20,28 +22,20 @@ const getRangeBarPreviewSample = (range) => {
20
22
  valueFraction: Math.max(0, Math.min(1, valueFraction)),
21
23
  };
22
24
  };
23
- const formatRangeBarPreviewCellText = (sampleValue, valueFraction, range) => {
24
- const parts = [];
25
- if (range.CellText?.includes('CellValue')) {
26
- parts.push(Number.isInteger(sampleValue) ? String(sampleValue) : sampleValue.toFixed(1));
27
- }
28
- if (range.CellText?.includes('PercentageValue')) {
29
- parts.push(`${(valueFraction * 100).toFixed(0)}%`);
30
- }
31
- return parts.join(' ');
32
- };
33
25
  const RangeBarPreviewContent = ({ range }) => {
34
26
  const { sampleValue, valueFraction } = getRangeBarPreviewSample(range);
35
- const cellText = formatRangeBarPreviewCellText(sampleValue, valueFraction, range);
36
- const hasCellText = Boolean(range.CellText?.length && cellText);
37
- const textPosition = range.CellTextPosition ?? 'Below';
27
+ const cellTextProperties = range.CellTextProperties;
28
+ const labels = buildBarChartCellTextLabels(cellTextProperties, Number.isInteger(sampleValue) ? String(sampleValue) : sampleValue.toFixed(1), `${(valueFraction * 100).toFixed(0)}%`);
29
+ const hasCellText = hasBarChartCellTextConfigured(cellTextProperties) &&
30
+ Boolean(labels.cellValue || labels.percentage);
31
+ const presence = getBarChartCellTextSlotPresence(cellTextProperties);
38
32
  const isVertical = range.Orientation === 'Vertical';
33
+ const cellTextClassName = 'ab-RangeBar__text twa:text-2 twa:leading-tight twa:truncate twa:max-w-full';
39
34
  const chartEl = _jsx(StyledColumnRangeBarListPreview, { range: range });
40
- const textEl = hasCellText ? (_jsx(Box, { className: "ab-RangeBar__text twa:text-2 twa:leading-tight twa:truncate twa:max-w-full", children: cellText })) : null;
41
- if (hasCellText && textPosition === 'Merged') {
42
- return (_jsxs(Box, { className: "ab-RangeBar__wrapper twa:relative twa:inline-flex", children: [chartEl, _jsx(Box, { className: "ab-RangeBar__text twa:absolute twa:inset-x-0 twa:top-1/2 twa:-translate-y-1/2 twa:px-1 twa:text-2 twa:truncate twa:pointer-events-none", children: cellText })] }));
35
+ if (hasCellText && presence.hasMerged && !presence.hasAbove && !presence.hasBelow) {
36
+ return (_jsxs(Box, { className: "ab-RangeBar__wrapper twa:relative twa:inline-flex", children: [chartEl, _jsx(BarChartCellTextPreview, { mergedOverlayClassName: "ab-RangeBar__text twa:absolute twa:inset-x-0 twa:top-1/2 twa:-translate-y-1/2 twa:px-1 twa:text-2 twa:truncate twa:pointer-events-none", cellTextProperties: cellTextProperties, labels: labels, vertical: "Merged" })] }));
43
37
  }
44
- return (_jsxs(Flex, { className: "ab-RangeBar__wrapper", flexDirection: "column", alignItems: isVertical ? 'center' : 'stretch', style: { justifyContent: 'center', gap: hasCellText ? 2 : 0 }, children: [hasCellText && textPosition === 'Above' && textEl, chartEl, hasCellText && textPosition === 'Below' && textEl] }));
38
+ return (_jsxs(Flex, { className: "ab-RangeBar__wrapper twa:relative", flexDirection: "column", alignItems: isVertical ? 'center' : 'stretch', style: { justifyContent: 'center', gap: hasCellText ? 2 : 0 }, children: [hasCellText && presence.hasAbove && (_jsx(BarChartCellTextPreview, { className: cellTextClassName, cellTextProperties: cellTextProperties, labels: labels, vertical: "Above" })), _jsxs(Box, { className: "twa:relative twa:w-full", style: { display: 'inline-flex' }, children: [chartEl, hasCellText && presence.hasMerged && (_jsx(BarChartCellTextPreview, { mergedOverlayClassName: "ab-RangeBar__text twa:absolute twa:inset-x-0 twa:top-1/2 twa:-translate-y-1/2 twa:px-1 twa:text-2 twa:truncate twa:pointer-events-none", cellTextProperties: cellTextProperties, labels: labels, vertical: "Merged" }))] }), hasCellText && presence.hasBelow && (_jsx(BarChartCellTextPreview, { className: cellTextClassName, cellTextProperties: cellTextProperties, labels: labels, vertical: "Below" }))] }));
45
39
  };
46
40
  export const StyledColumnRangeBarPreview = ({ data }) => {
47
41
  const range = data.RangeBarStyle;
@@ -1,6 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import type { CellBoxStyle } from '../../../../../AdaptableState/Common/AdaptableStyle';
3
- import { RatingIconShape, RatingStyle, StyledColumn } from '../../../../../AdaptableState/StyledColumnState';
3
+ import { StyledColumn } from '../../../../../AdaptableState/StyledColumnState';
4
+ import { RatingIconShape, RatingStyle } from '../../../../../AdaptableState/StyledColumns/RatingStyle';
4
5
  export declare const DEFAULT_RATING_MAX = 5;
5
6
  export declare const DEFAULT_RATING_SIZE = 14;
6
7
  export declare const DEFAULT_RATING_GAP = 2;
@@ -3,13 +3,13 @@ import { CheckBox } from '../../../../components/CheckBox';
3
3
  import ErrorBox from '../../../../components/ErrorBox';
4
4
  import FormLayout, { FormRow } from '../../../../components/FormLayout';
5
5
  import { Tag } from '../../../../components/Tag';
6
+ import { formatBarChartCellTextLayoutSummary, getActiveBarChartCellTextTokens, hasBarChartCellTextConfigured, patchBarChartCellTextPlacement, resolveBarChartCellTextLayout, toggleBarChartCellTextToken, } from '../../../../Utilities/Helpers/barChartCellText';
7
+ import { BarChartCellTextLayoutEditor } from './Components/BarChartCellTextLayoutEditor';
6
8
  import { OptionalColorPicker } from '../../../../components/ColorPicker';
7
9
  import { getGraySwatchColor } from '../../../UIHelper';
8
10
  import { useOnePageAdaptableWizardContext } from '../../../Wizard/OnePageAdaptableWizard';
9
- import ArrayExtensions from '../../../../Utilities/Extensions/ArrayExtensions';
10
11
  import { Box, Flex } from '../../../../components/Flex';
11
12
  import Radio, { RadioGroup } from '../../../../components/Radio';
12
- import { Toggle, ToggleGroup } from '../../../../components/Toggle';
13
13
  import { getCellFontStyleSummaryItems, StyledColumnFontStyleEditor, } from '../StyledColumnSliceStyleEditors';
14
14
  import { Card } from '../../../../components/Card';
15
15
  import { renderSummaryStringTags } from '../../../Wizard/SummaryColorTag';
@@ -36,11 +36,12 @@ const formatPercentBarToolTipSummary = (toolTipText) => toolTipText
36
36
  .join(' + ') ?? '';
37
37
  const buildStyledColumnPercentBarStyleSummaryStrings = (pb, options) => {
38
38
  const items = [`Origin: ${formatOriginLabel(pb.Origin)}`];
39
- if (pb.CellText?.length) {
40
- items.push(`Cell Text: ${formatPercentBarCellTextSummary(pb.CellText)}`);
41
- items.push(`Cell Text Position: ${pb.CellTextPosition ?? 'Below'}`);
42
- if (pb.CellTextAlignment != null) {
43
- items.push(`Cell Text Alignment: ${pb.CellTextAlignment}`);
39
+ if (hasBarChartCellTextConfigured(pb.CellTextProperties)) {
40
+ const tokens = getActiveBarChartCellTextTokens(pb.CellTextProperties);
41
+ items.push(`Cell Text: ${formatPercentBarCellTextSummary(tokens)}`);
42
+ const layoutSummary = formatBarChartCellTextLayoutSummary(resolveBarChartCellTextLayout(pb.CellTextProperties));
43
+ if (layoutSummary) {
44
+ items.push(`Placement: ${layoutSummary}`);
44
45
  }
45
46
  }
46
47
  else if (options.includeEmptyCellText) {
@@ -92,11 +93,6 @@ export const renderFormatColumnStyleWizardSummary = (data) => {
92
93
  // Pinning the width forces colons to line up vertically across cards rather than
93
94
  // each FormLayout sizing its label column independently from its own longest label.
94
95
  const STYLE_FORM_SIZES = ['200px', '1fr'];
95
- const CELL_TEXT_POSITION_CHOICES = [
96
- { value: 'Above', label: 'Above Bar' },
97
- { value: 'Below', label: 'Below Bar' },
98
- { value: 'Merged', label: 'Merged' },
99
- ];
100
96
  const ORIGIN_CHOICES = [
101
97
  {
102
98
  value: 'Auto',
@@ -121,6 +117,7 @@ export const StyledColumnWizardStyleSection = (props) => {
121
117
  return (_jsx(Box, { children: !data.ColumnId && (_jsx(ErrorBox, { className: "twa:mt-2", children: "You need to select a column before styling." })) }));
122
118
  }
123
119
  const pb = data.PercentBarStyle;
120
+ const cellTextProperties = pb.CellTextProperties;
124
121
  // ---- updaters -----------------------------------------------------------
125
122
  const update = (patch) => {
126
123
  props.onChange({
@@ -128,12 +125,13 @@ export const StyledColumnWizardStyleSection = (props) => {
128
125
  PercentBarStyle: { ...pb, ...patch },
129
126
  });
130
127
  };
131
- const onCellTextChanged = (token, checked) => {
132
- const current = pb.CellText ?? [];
133
- const next = checked
134
- ? Array.from(new Set([...current, token]))
135
- : current.filter((t) => t !== token);
136
- update({ CellText: next });
128
+ const onCellTextLayoutToggle = (token, show) => {
129
+ update(toggleBarChartCellTextToken(cellTextProperties, token, show));
130
+ };
131
+ const onCellTextPlacementChange = (token, patch) => {
132
+ update({
133
+ CellTextProperties: patchBarChartCellTextPlacement(cellTextProperties, token, patch),
134
+ });
137
135
  };
138
136
  const onToolTipTextChanged = (token, checked) => {
139
137
  const current = pb.ToolTipText ?? [];
@@ -142,38 +140,7 @@ export const StyledColumnWizardStyleSection = (props) => {
142
140
  : current.filter((t) => t !== token);
143
141
  update({ ToolTipText: next });
144
142
  };
145
- const handleCellTextPositionChange = (pos) => update({ CellTextPosition: pos });
146
143
  const handleOriginChange = (origin) => update({ Origin: origin });
147
- const handleCellTextAlignmentChange = (choice) => {
148
- if (choice === 'Inherit') {
149
- const next = { ...pb };
150
- delete next.CellTextAlignment;
151
- props.onChange({ ...data, PercentBarStyle: next });
152
- return;
153
- }
154
- update({ CellTextAlignment: choice });
155
- };
156
- const onAutoCellTextAlignmentChecked = (checked) => {
157
- if (!checked) {
158
- handleCellTextAlignmentChange('Inherit');
159
- return;
160
- }
161
- let nextFont = pb.Font ? { ...pb.Font } : undefined;
162
- if (nextFont) {
163
- delete nextFont.Alignment;
164
- if (Object.keys(nextFont).length === 0) {
165
- nextFont = undefined;
166
- }
167
- }
168
- props.onChange({
169
- ...data,
170
- PercentBarStyle: {
171
- ...pb,
172
- CellTextAlignment: 'Auto',
173
- Font: nextFont,
174
- },
175
- });
176
- };
177
144
  const onBackColorChange = (color) => {
178
145
  if (color) {
179
146
  update({ BackColor: color });
@@ -182,14 +149,11 @@ export const StyledColumnWizardStyleSection = (props) => {
182
149
  const { BackColor: _removed, ...rest } = pb;
183
150
  props.onChange({ ...data, PercentBarStyle: rest });
184
151
  };
185
- const cellTextDisabled = ArrayExtensions.IsNullOrEmpty(pb.CellText) || disabled;
186
- const currentAlignment = pb.CellTextAlignment ?? 'Inherit';
152
+ const cellTextDisabled = !hasBarChartCellTextConfigured(cellTextProperties) || disabled;
187
153
  const currentOrigin = typeof pb.Origin === 'number'
188
154
  ? 'Min' // numeric origin doesn't fit the radio set; treat as Min for selection state
189
155
  : pb.Origin ?? 'Auto';
190
- return (_jsxs(Box, { children: [_jsxs(Card, { shadow: false, className: "twa:mb-3", children: [_jsxs(Card.Title, { children: [_jsx(Box, { className: "twa:font-medium", children: "Bar Position" }), _jsx(Box, { className: "twa:text-xs twa:opacity-70 twa:font-normal twa:max-w-[520px]", children: "Set the position of the cell text relative to the bar" })] }), _jsx(Card.Body, { children: _jsx(RadioGroup, { orientation: "vertical", name: "ab-percentbar-origin", value: currentOrigin, onRadioChange: handleOriginChange, children: ORIGIN_CHOICES.map((choice) => (_jsx(Radio, { value: choice.value, disabled: disabled, children: _jsxs(Flex, { alignItems: "center", children: [_jsx(Box, { className: "twa:min-w-[60px]", children: choice.label }), _jsx(Box, { className: "twa:text-xs twa:opacity-70", children: choice.hint })] }) }, choice.value))) }) })] }), _jsxs(Card, { shadow: false, className: "twa:mb-3", children: [_jsxs(Card.Title, { children: [_jsx(Box, { className: "twa:font-medium", children: "Cell Text" }), _jsx(Box, { className: "twa:text-xs twa:opacity-70 twa:font-normal twa:max-w-[540px]", children: "Choose whether and how to display cell text (font properties take precedence over Format Column)" })] }), _jsxs(Card.Body, { children: [_jsxs(FormLayout, { sizes: [...STYLE_FORM_SIZES], children: [_jsxs(FormRow, { label: "Cell Display:", children: [_jsx(CheckBox, { disabled: disabled, checked: pb.CellText?.includes('CellValue'), onChange: (checked) => onCellTextChanged('CellValue', checked), children: "Cell Value" }), ' ', _jsx(CheckBox, { disabled: disabled, className: "twa:ml-3", checked: pb.CellText?.includes('PercentageValue'), onChange: (checked) => onCellTextChanged('PercentageValue', checked), children: "Percent Value" })] }), _jsx(FormRow, { label: "Cell Display Position:", children: _jsx(RadioGroup, { orientation: "horizontal", name: "ab-percentbar-cell-text-position", value: pb.CellTextPosition ?? 'Below', onRadioChange: handleCellTextPositionChange, className: "twa:gap-4", children: CELL_TEXT_POSITION_CHOICES.map((choice) => (_jsx(Radio, { value: choice.value, disabled: cellTextDisabled, children: choice.label }, choice.value))) }) }), _jsx(FormRow, { label: "Auto Text Alignment:", children: _jsxs(Flex, { alignItems: "center", className: "twa:gap-2", children: [_jsx(CheckBox, { disabled: cellTextDisabled, checked: pb.CellTextAlignment === 'Auto', onChange: onAutoCellTextAlignmentChecked }), _jsx(Box, { className: "twa:text-xs twa:opacity-70 twa:max-w-[420px]", children: "Follows bar (if Position is Auto or Zero); overrides fixed alignment below" })] }) }), _jsx(FormRow, { label: "Cell Text Alignment:", children: _jsx(Flex, { alignItems: "center", className: "twa:gap-2", children: _jsx(Box, { className: cellTextDisabled || pb.CellTextAlignment === 'Auto'
191
- ? 'twa:opacity-50 twa:pointer-events-none'
192
- : '', children: _jsx(Flex, { alignItems: "center", className: "twa:gap-2", children: _jsxs(ToggleGroup, { children: [_jsx(Toggle, { icon: "align-left", pressed: currentAlignment === 'Left', onPressedChange: (pressed) => handleCellTextAlignmentChange(pressed ? 'Left' : 'Inherit') }), _jsx(Toggle, { icon: "align-center", pressed: currentAlignment === 'Center', onPressedChange: (pressed) => handleCellTextAlignmentChange(pressed ? 'Center' : 'Inherit') }), _jsx(Toggle, { icon: "align-right", pressed: currentAlignment === 'Right', onPressedChange: (pressed) => handleCellTextAlignmentChange(pressed ? 'Right' : 'Inherit') })] }) }) }) }) })] }), _jsx(Box, { className: `twa:mt-3 twa:pt-3 twa:border-t twa:border-foreground/15 ${cellTextDisabled ? 'twa:opacity-50' : ''}`, children: _jsx(StyledColumnFontStyleEditor, { api: api, disabled: cellTextDisabled, hideAlignment: true, value: pb.Font, onChange: (next) => {
156
+ return (_jsxs(Box, { children: [_jsxs(Card, { shadow: false, className: "twa:mb-3", children: [_jsxs(Card.Title, { children: [_jsx(Box, { className: "twa:font-medium", children: "Bar Position" }), _jsx(Box, { className: "twa:text-xs twa:opacity-70 twa:font-normal twa:max-w-[520px]", children: "Set the position of the cell text relative to the bar" })] }), _jsx(Card.Body, { children: _jsx(RadioGroup, { orientation: "vertical", name: "ab-percentbar-origin", value: currentOrigin, onRadioChange: handleOriginChange, children: ORIGIN_CHOICES.map((choice) => (_jsx(Radio, { value: choice.value, disabled: disabled, children: _jsxs(Flex, { alignItems: "center", children: [_jsx(Box, { className: "twa:min-w-[60px]", children: choice.label }), _jsx(Box, { className: "twa:text-xs twa:opacity-70", children: choice.hint })] }) }, choice.value))) }) })] }), _jsxs(Card, { shadow: false, className: "twa:mb-3", children: [_jsxs(Card.Title, { children: [_jsx(Box, { className: "twa:font-medium", children: "Cell Text" }), _jsx(Box, { className: "twa:text-xs twa:opacity-70 twa:font-normal twa:max-w-[540px]", children: "Pick which values to display and where each one sits around the bar (font properties take precedence over Format Column)" })] }), _jsxs(Card.Body, { children: [_jsx(FormLayout, { sizes: [...STYLE_FORM_SIZES], children: _jsx(FormRow, { label: "Cell Text Layout:", children: _jsx(BarChartCellTextLayoutEditor, { disabled: disabled, cellTextProperties: cellTextProperties, onToggle: onCellTextLayoutToggle, onPlacementChange: onCellTextPlacementChange }) }) }), _jsx(Box, { className: `twa:mt-3 twa:pt-3 twa:border-t twa:border-foreground/15 ${cellTextDisabled ? 'twa:opacity-50' : ''}`, children: _jsx(StyledColumnFontStyleEditor, { api: api, disabled: cellTextDisabled, value: pb.Font, onChange: (next) => {
193
157
  if (next) {
194
158
  update({ Font: next });
195
159
  }
@@ -2,6 +2,7 @@ import kebabCase from '../Utilities/utils/kebabCase';
2
2
  import { resolveDisplayFormat } from '../AdaptableState/Common/AdaptableFormatPresets';
3
3
  import merge from '../Utilities/utils/merge';
4
4
  import { resolveSparklineOptionsForRender } from '../Utilities/Helpers/SparklineOptionsHelper';
5
+ import { hasBarChartCellTextConfigured } from '../Utilities/Helpers/barChartCellText';
5
6
  import { convertAdaptableStyleToCSS, getAutoContrastTextColor, getVariableColor, hasCellBoxStyle, hasCellFontStyle, normalizeStyleForAgGrid, } from '../Utilities/Helpers/StyleHelper';
6
7
  import StringExtensions from '../Utilities/Extensions/StringExtensions';
7
8
  import { ACTION_COLUMN_TYPE, CALCULATED_COLUMN_TYPE, FDC3_COLUMN_TYPE, FREE_TEXT_COLUMN_TYPE, } from '../AdaptableState/Common/AdaptableColumn';
@@ -1445,7 +1446,7 @@ export class AgGridColumnAdapter {
1445
1446
  }
1446
1447
  }
1447
1448
  }
1448
- if (styledColumn.PercentBarStyle && styledColumn.PercentBarStyle.CellText) {
1449
+ if (styledColumn.PercentBarStyle && hasBarChartCellTextConfigured(styledColumn.PercentBarStyle.CellTextProperties)) {
1449
1450
  style.paddingTop = 0;
1450
1451
  style.paddingBottom = 0;
1451
1452
  }
@@ -83,7 +83,9 @@ export const getBadgeRendererForColumn = (styledColumn, abColumn, api) => {
83
83
  ...adaptableApi.internalApi.buildBaseContext(),
84
84
  };
85
85
  const badge = api.styledColumnApi.internalApi.getApplicableBadge(badgeStyle, predicateDefHandlerContext);
86
- const formattedValue = badge?.IconOnly ? '' : params.formatValue?.(value) ?? value ?? '';
86
+ const formattedValue = badge?.IconProperties?.IconOnly
87
+ ? ''
88
+ : params.formatValue?.(value) ?? value ?? '';
87
89
  const isNullValue = formattedValue === '' || formattedValue === null || formattedValue === undefined;
88
90
  if (!isNullValue) {
89
91
  const config = { value: formattedValue };
@@ -113,7 +115,7 @@ export const getBadgeRendererForColumn = (styledColumn, abColumn, api) => {
113
115
  this.eGui.innerHTML = formattedValue;
114
116
  return;
115
117
  }
116
- if (badge.IconOnly) {
118
+ if (badge.IconProperties?.IconOnly) {
117
119
  formattedValue = '';
118
120
  }
119
121
  this.renderBadges([
@@ -137,11 +139,11 @@ export const getBadgeRendererForColumn = (styledColumn, abColumn, api) => {
137
139
  key: index,
138
140
  pillStyle: badge.PillStyle,
139
141
  children: value,
140
- icon: badge.Icon,
141
- iconPosition: badge.IconPosition ?? 'start',
142
+ icon: badge.IconProperties?.Icon,
143
+ iconPosition: badge.IconProperties?.Position ?? 'start',
142
144
  shape: badge.Shape,
143
145
  density: badgeStyle.Density ?? 'Normal',
144
- iconGap: badge.IconGap,
146
+ iconGap: badge.IconProperties?.Gap,
145
147
  });
146
148
  });
147
149
  this.unmountReactRoot = api.internalApi