@pallasoft/ps-mobile-components 1.7.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/dist/components/ps-accessibility-gate/index.d.ts +2 -0
  2. package/dist/components/ps-accessibility-gate/index.js +2 -0
  3. package/dist/components/ps-accessibility-gate/ps-accessibility-gate-props.d.ts +5 -0
  4. package/dist/components/ps-accessibility-gate/ps-accessibility-gate-props.js +1 -0
  5. package/dist/components/ps-accessibility-gate/ps-accessibility-gate.d.ts +2 -0
  6. package/dist/components/ps-accessibility-gate/ps-accessibility-gate.js +4 -0
  7. package/dist/components/ps-app-lock-screen/ps-app-lock-screen.js +1 -1
  8. package/dist/components/ps-cartesian-chart/ps-cartesian-chart.d.ts +1 -1
  9. package/dist/components/ps-cartesian-chart/ps-cartesian-chart.js +25 -17
  10. package/dist/components/ps-chart-empty-state/ps-chart-empty-state.js +5 -1
  11. package/dist/components/ps-chart-frame/ps-chart-frame.js +10 -1
  12. package/dist/components/ps-chart-legend/ps-chart-legend.js +11 -2
  13. package/dist/components/ps-chart-readout/ps-chart-readout-props.d.ts +1 -0
  14. package/dist/components/ps-chart-readout/ps-chart-readout.d.ts +1 -1
  15. package/dist/components/ps-chart-readout/ps-chart-readout.js +8 -2
  16. package/dist/components/ps-chart-skeleton/ps-chart-skeleton.d.ts +1 -1
  17. package/dist/components/ps-chart-skeleton/ps-chart-skeleton.js +5 -1
  18. package/dist/components/ps-donut-chart/ps-donut-chart.js +23 -5
  19. package/dist/components/ps-kpi-card/ps-kpi-card.js +4 -1
  20. package/dist/components/ps-privacy-cover/ps-privacy-cover-props.d.ts +1 -0
  21. package/dist/components/ps-privacy-cover/ps-privacy-cover.d.ts +1 -1
  22. package/dist/components/ps-privacy-cover/ps-privacy-cover.js +12 -3
  23. package/dist/components/ps-sortable-grid/ps-sortable-grid.js +8 -4
  24. package/dist/components/ps-sortable-grid/ps-sortable-item-props.d.ts +1 -0
  25. package/dist/components/ps-sortable-grid/ps-sortable-item.d.ts +1 -1
  26. package/dist/components/ps-sortable-grid/ps-sortable-item.js +3 -2
  27. package/dist/components/ps-sparkline/ps-sparkline.d.ts +1 -1
  28. package/dist/components/ps-sparkline/ps-sparkline.js +3 -1
  29. package/dist/components/ps-waterfall-chart/ps-waterfall-chart.d.ts +1 -1
  30. package/dist/components/ps-waterfall-chart/ps-waterfall-chart.js +15 -9
  31. package/dist/constants/ps-accessibility-config.d.ts +5 -0
  32. package/dist/constants/ps-accessibility-config.js +5 -0
  33. package/dist/constants/ps-chart-config.d.ts +26 -1
  34. package/dist/constants/ps-chart-config.js +26 -1
  35. package/dist/constants/ps-screen-capture-config.d.ts +4 -0
  36. package/dist/constants/ps-screen-capture-config.js +4 -0
  37. package/dist/contexts/ps-widget-fill-context.d.ts +1 -0
  38. package/dist/contexts/ps-widget-fill-context.js +2 -0
  39. package/dist/hooks/use-ps-screen-capture-prevention.d.ts +2 -0
  40. package/dist/hooks/use-ps-screen-capture-prevention.js +12 -0
  41. package/dist/hooks/use-ps-widget-fill.d.ts +1 -0
  42. package/dist/hooks/use-ps-widget-fill.js +3 -0
  43. package/dist/index.d.ts +4 -0
  44. package/dist/index.js +4 -0
  45. package/dist/interfaces/ps-chart-bar-group.d.ts +4 -0
  46. package/dist/interfaces/ps-chart-bar-group.js +1 -0
  47. package/dist/interfaces/ps-chart-x-labels.d.ts +4 -0
  48. package/dist/interfaces/ps-chart-x-labels.js +1 -0
  49. package/dist/interfaces/ps-donut-chart-layout.d.ts +4 -0
  50. package/dist/interfaces/ps-donut-chart-layout.js +1 -0
  51. package/dist/interfaces/ps-screen-capture-native.d.ts +4 -0
  52. package/dist/interfaces/ps-screen-capture-native.js +1 -0
  53. package/dist/interfaces/use-ps-screen-capture-prevention-options.d.ts +3 -0
  54. package/dist/interfaces/use-ps-screen-capture-prevention-options.js +1 -0
  55. package/dist/services/ps-chart-axis-service.d.ts +5 -0
  56. package/dist/services/ps-chart-axis-service.js +32 -0
  57. package/dist/services/ps-chart-bar-service.d.ts +2 -0
  58. package/dist/services/ps-chart-bar-service.js +11 -4
  59. package/dist/services/ps-chart-donut-service.d.ts +3 -0
  60. package/dist/services/ps-chart-donut-service.js +11 -0
  61. package/dist/services/ps-chart-readout-service.d.ts +3 -0
  62. package/dist/services/ps-chart-readout-service.js +25 -0
  63. package/dist/services/ps-chart-scale-service.d.ts +1 -1
  64. package/dist/services/ps-chart-scale-service.js +2 -2
  65. package/dist/services/ps-chart-text-service.d.ts +6 -0
  66. package/dist/services/ps-chart-text-service.js +23 -0
  67. package/dist/services/ps-screen-capture-service.d.ts +6 -0
  68. package/dist/services/ps-screen-capture-service.js +35 -0
  69. package/dist/services/ps-sortable-grid-service.d.ts +2 -0
  70. package/dist/services/ps-sortable-grid-service.js +10 -3
  71. package/dist/services/ps-waterfall-service.js +2 -3
  72. package/package.json +5 -1
@@ -0,0 +1,2 @@
1
+ export * from './ps-accessibility-gate';
2
+ export * from './ps-accessibility-gate-props';
@@ -0,0 +1,2 @@
1
+ export * from './ps-accessibility-gate';
2
+ export * from './ps-accessibility-gate-props';
@@ -0,0 +1,5 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface PsAccessibilityGateProps {
3
+ children: ReactNode;
4
+ isHidden: boolean;
5
+ }
@@ -0,0 +1,2 @@
1
+ import type { PsAccessibilityGateProps } from './ps-accessibility-gate-props';
2
+ export declare const PsAccessibilityGate: ({ children, isHidden }: PsAccessibilityGateProps) => import("react").JSX.Element;
@@ -0,0 +1,4 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { View } from 'react-native';
3
+ import { PsAccessibilityConfig } from '../../constants/ps-accessibility-config';
4
+ export const PsAccessibilityGate = ({ children, isHidden }) => (_jsx(View, { accessibilityElementsHidden: isHidden, importantForAccessibility: isHidden ? PsAccessibilityConfig.hiddenImportance : PsAccessibilityConfig.visibleImportance, style: { flex: 1 }, testID: 'ps-accessibility-gate', children: children }));
@@ -5,7 +5,7 @@ import { PsAppLockConfig } from '../../constants/ps-app-lock-config';
5
5
  import { PsButton } from '../ps-button/ps-button';
6
6
  import { PsPrivacyCover } from '../ps-privacy-cover/ps-privacy-cover';
7
7
  import { PsTextLink } from '../ps-text-link/ps-text-link';
8
- export const PsAppLockScreen = ({ children, isUnlocking = false, onSignOut, onUnlock, signOutLabel, unlockLabel, }) => (_jsx(PsPrivacyCover, { children: _jsx(SafeAreaView, { style: {
8
+ export const PsAppLockScreen = ({ children, isUnlocking = false, onSignOut, onUnlock, signOutLabel, unlockLabel, }) => (_jsx(PsPrivacyCover, { shouldTakeFocus: true, children: _jsx(SafeAreaView, { style: {
9
9
  alignItems: 'center',
10
10
  flex: 1,
11
11
  justifyContent: 'center',
@@ -1,2 +1,2 @@
1
1
  import type { PsCartesianChartProps } from './ps-cartesian-chart-props';
2
- export declare const PsCartesianChart: ({ data, emptyLabel, formatTick, formatValue, height, isLoading, kind, series, showLegend, }: PsCartesianChartProps) => import("react").JSX.Element;
2
+ export declare const PsCartesianChart: ({ data, emptyLabel, formatTick, formatValue, height: baseHeight, isLoading, kind, series, showLegend, }: PsCartesianChartProps) => import("react").JSX.Element;
@@ -7,47 +7,55 @@ import { usePsChartReveal } from '../../hooks/use-ps-chart-reveal';
7
7
  import { usePsChartScrub } from '../../hooks/use-ps-chart-scrub';
8
8
  import { usePsChartWidth } from '../../hooks/use-ps-chart-width';
9
9
  import { usePsMobileTheme } from '../../hooks/use-ps-mobile-theme';
10
+ import { usePsWidgetFill } from '../../hooks/use-ps-widget-fill';
11
+ import { PsChartAxisService } from '../../services/ps-chart-axis-service';
10
12
  import { PsChartBarService } from '../../services/ps-chart-bar-service';
11
13
  import { PsChartKindService } from '../../services/ps-chart-kind-service';
12
14
  import { PsChartReadoutService } from '../../services/ps-chart-readout-service';
13
15
  import { PsChartScaleService } from '../../services/ps-chart-scale-service';
14
16
  import { PsChartSeriesService } from '../../services/ps-chart-series-service';
15
17
  import { PsChartShapeService } from '../../services/ps-chart-shape-service';
18
+ import { PsChartTextService } from '../../services/ps-chart-text-service';
16
19
  import { PsChartBar } from '../ps-chart-bar/ps-chart-bar';
17
20
  import { PsChartEmptyState } from '../ps-chart-empty-state/ps-chart-empty-state';
18
21
  import { PsChartLegend } from '../ps-chart-legend/ps-chart-legend';
19
22
  import { PsChartLine } from '../ps-chart-line/ps-chart-line';
20
23
  import { PsChartReadout } from '../ps-chart-readout/ps-chart-readout';
21
24
  import { PsChartSkeleton } from '../ps-chart-skeleton/ps-chart-skeleton';
22
- export const PsCartesianChart = ({ data, emptyLabel, formatTick, formatValue, height = PsChartConfig.chartHeight, isLoading = false, kind, series, showLegend = true, }) => {
25
+ export const PsCartesianChart = ({ data, emptyLabel, formatTick, formatValue, height: baseHeight = PsChartConfig.chartHeight, isLoading = false, kind, series, showLegend = true, }) => {
23
26
  const theme = usePsMobileTheme();
24
27
  const { onLayout, width } = usePsChartWidth();
28
+ const height = baseHeight + usePsWidgetFill();
25
29
  const isBars = PsChartKindService.isBars(kind);
26
30
  const isStacked = kind === PsCartesianChartKind.StackedBar;
27
- const plot = PsChartScaleService.plot(width, height);
31
+ const barIndexes = PsChartShapeService.barIndexes(kind, series);
32
+ const lineIndexes = PsChartShapeService.lineIndexes(kind, series);
33
+ const barSeries = barIndexes.map((position) => series[position]);
34
+ const lineSeries = lineIndexes.map((position) => series[position]);
35
+ const domain = PsChartScaleService.domain(isStacked
36
+ ? [
37
+ ...PsChartSeriesService.stackedValues(data, barSeries),
38
+ ...PsChartSeriesService.values(data, lineSeries),
39
+ ]
40
+ : PsChartSeriesService.values(data, series));
41
+ const tickLabels = PsChartScaleService.ticks(domain).map((tick) => formatTick(tick));
42
+ const yAxisWidth = PsChartAxisService.yAxisWidth(tickLabels, width);
43
+ const plot = PsChartScaleService.plot(width, height, yAxisWidth);
28
44
  const { index, panHandlers } = usePsChartScrub(data.length, isBars, plot);
29
45
  const progress = usePsChartReveal(PsChartSeriesService.signature(kind, data, series));
30
46
  if (isLoading)
31
- return _jsx(PsChartSkeleton, { height: height, variant: PsChartKindService.skeletonVariant(kind) });
47
+ return (_jsx(PsChartSkeleton, { height: baseHeight, variant: PsChartKindService.skeletonVariant(kind) }));
32
48
  if (data.length === 0 || PsChartSeriesService.isEmpty(data, series))
33
- return _jsx(PsChartEmptyState, { height: height, label: emptyLabel });
49
+ return _jsx(PsChartEmptyState, { height: baseHeight, label: emptyLabel });
34
50
  const colors = series.map((entry, position) => PsChartSeriesService.color({
35
51
  count: series.length,
36
52
  explicit: entry.color,
37
53
  index: position,
38
54
  theme,
39
55
  }));
40
- const barIndexes = PsChartShapeService.barIndexes(kind, series);
41
- const lineIndexes = PsChartShapeService.lineIndexes(kind, series);
42
- const barSeries = barIndexes.map((position) => series[position]);
43
56
  const barColors = barIndexes.map((position) => colors[position]);
44
- const lineSeries = lineIndexes.map((position) => series[position]);
45
- const domain = PsChartScaleService.domain(isStacked
46
- ? [
47
- ...PsChartSeriesService.stackedValues(data, barSeries),
48
- ...PsChartSeriesService.values(data, lineSeries),
49
- ]
50
- : PsChartSeriesService.values(data, series));
57
+ const xLabels = PsChartAxisService.xLabels(data.map((row) => row.label), plot.right - plot.left, isBars);
58
+ const readoutLines = PsChartReadoutService.maxLines(data.map((row) => PsChartReadoutService.items(row, series, colors, formatValue)), width);
51
59
  const selected = index === null ? data.length - 1 : index;
52
60
  const datum = data[selected];
53
61
  const items = PsChartReadoutService.items(datum, series, colors, formatValue);
@@ -57,10 +65,10 @@ export const PsCartesianChart = ({ data, emptyLabel, formatTick, formatValue, he
57
65
  : isStacked
58
66
  ? PsChartBarService.stacked(data, barSeries, barColors, domain, plot)
59
67
  : PsChartBarService.grouped(data, barSeries, barColors, domain, plot);
60
- return (_jsxs(View, { style: { gap: 8 }, children: [_jsx(PsChartReadout, { items: items, title: datum.label }), _jsx(View, { accessible: true, accessibilityLabel: PsChartReadoutService.summary(datum.label, items), accessibilityRole: 'image', onLayout: onLayout, style: { height }, children: width === 0 ? null : (_jsxs(_Fragment, { children: [_jsxs(Svg, { height: height, pointerEvents: 'none', width: width, children: [PsChartScaleService.ticks(domain).map((tick) => {
68
+ return (_jsxs(View, { style: { gap: 8 }, children: [_jsx(PsChartReadout, { items: items, lines: readoutLines, title: datum.label }), _jsx(View, { accessible: true, accessibilityLabel: PsChartReadoutService.summary(datum.label, items), accessibilityRole: 'image', onLayout: onLayout, style: { height }, children: width === 0 ? null : (_jsxs(_Fragment, { children: [_jsxs(Svg, { height: height, pointerEvents: 'none', width: width, children: [PsChartScaleService.ticks(domain).map((tick, tickIndex) => {
61
69
  const y = PsChartScaleService.y(tick, domain, plot);
62
- return (_jsxs(G, { children: [_jsx(Line, { stroke: theme.line, strokeWidth: PsChartConfig.gridLineWidth, x1: plot.left, x2: plot.right, y1: y, y2: y }), _jsx(SvgText, { fill: theme.muted, fontFamily: theme.fonts.medium, fontSize: PsChartConfig.axisLabelSize, textAnchor: 'end', x: plot.left - 6, y: y + 3, children: formatTick(tick) })] }, tick));
63
- }), PsChartScaleService.labelIndexes(data.length).map((position) => (_jsx(SvgText, { fill: theme.muted, fontFamily: theme.fonts.medium, fontSize: PsChartConfig.axisLabelSize, textAnchor: PsChartScaleService.labelAnchor(position, data.length, isBars), x: xAt(position), y: height - 6, children: data[position].label }, position))), rects.map((rect) => (_jsx(PsChartBar, { progress: progress, rect: rect }, rect.id))), lineSeries.map((entry, lineIndex) => {
70
+ return (_jsxs(G, { children: [_jsx(Line, { stroke: theme.line, strokeWidth: PsChartConfig.gridLineWidth, x1: plot.left, x2: plot.right, y1: y, y2: y }), _jsx(SvgText, { fill: theme.muted, fontFamily: theme.fonts.medium, fontSize: PsChartConfig.axisLabelSize, textAnchor: 'end', x: plot.left - PsChartConfig.axisTickGap, y: y + PsChartConfig.axisLabelSize / 3, children: PsChartTextService.fit(tickLabels[tickIndex], plot.left - PsChartConfig.axisTickGap, PsChartConfig.axisLabelSize) })] }, tick));
71
+ }), xLabels.indexes.map((position) => (_jsx(SvgText, { fill: theme.muted, fontFamily: theme.fonts.medium, fontSize: PsChartConfig.axisLabelSize, textAnchor: PsChartScaleService.labelAnchor(position, data.length, isBars), x: xAt(position), y: height - 6, children: PsChartTextService.fit(data[position].label, xLabels.maxWidth, PsChartConfig.axisLabelSize) }, position))), rects.map((rect) => (_jsx(PsChartBar, { progress: progress, rect: rect }, rect.id))), lineSeries.map((entry, lineIndex) => {
64
72
  const position = lineIndexes[lineIndex];
65
73
  const points = data.map((row, rowIndex) => ({
66
74
  x: xAt(rowIndex),
@@ -1,5 +1,9 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { View } from 'react-native';
3
3
  import { PsChartConfig } from '../../constants/ps-chart-config';
4
+ import { usePsWidgetFill } from '../../hooks/use-ps-widget-fill';
4
5
  import { PsText } from '../ps-text/ps-text';
5
- export const PsChartEmptyState = ({ height = PsChartConfig.chartHeight, label, }) => (_jsx(View, { style: { alignItems: 'center', height, justifyContent: 'center' }, testID: 'ps-chart-empty-state', children: _jsx(PsText, { align: 'center', tone: 'muted', children: label }) }));
6
+ export const PsChartEmptyState = ({ height = PsChartConfig.chartHeight, label, }) => {
7
+ const fill = usePsWidgetFill();
8
+ return (_jsx(View, { style: { alignItems: 'center', height: height + fill, justifyContent: 'center' }, testID: 'ps-chart-empty-state', children: _jsx(PsText, { align: 'center', tone: 'muted', children: label }) }));
9
+ };
@@ -1,6 +1,15 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { View } from 'react-native';
3
+ import { PsChartConfig } from '../../constants/ps-chart-config';
4
+ import { usePsChartWidth } from '../../hooks/use-ps-chart-width';
5
+ import { PsChartTextService } from '../../services/ps-chart-text-service';
3
6
  import { PsCard } from '../ps-card/ps-card';
4
7
  import { PsChartDeltaBadge } from '../ps-chart-delta-badge/ps-chart-delta-badge';
5
8
  import { PsText } from '../ps-text/ps-text';
6
- export const PsChartFrame = ({ children, delta, period, title, value }) => (_jsx(PsCard, { style: { gap: 12 }, children: _jsxs(View, { style: { gap: 12 }, testID: 'ps-chart-frame', children: [title === undefined && value === undefined ? null : (_jsxs(View, { style: { gap: 4 }, children: [title === undefined ? null : (_jsx(PsText, { numberOfLines: 1, tone: 'muted', variant: 'label', children: title })), value === undefined ? null : (_jsx(PsText, { numberOfLines: 1, style: { fontSize: 24, lineHeight: 30 }, variant: 'numeric', weight: 'bold', children: value })), delta === undefined ? null : _jsx(PsChartDeltaBadge, { ...delta }), period === undefined ? null : (_jsx(PsText, { tone: 'muted', variant: 'caption', children: period }))] })), children] }) }));
9
+ export const PsChartFrame = ({ children, delta, period, title, value }) => {
10
+ const { onLayout, width } = usePsChartWidth();
11
+ const size = value === undefined
12
+ ? PsChartConfig.kpiValueFontMax
13
+ : PsChartTextService.fontSize(value, width, PsChartConfig.kpiValueFontMax, PsChartConfig.kpiValueFontMin);
14
+ return (_jsx(PsCard, { style: { gap: 12 }, children: _jsxs(View, { onLayout: onLayout, style: { gap: 12 }, testID: 'ps-chart-frame', children: [title === undefined && value === undefined ? null : (_jsxs(View, { style: { gap: 4 }, children: [title === undefined ? null : (_jsx(PsText, { numberOfLines: 1, tone: 'muted', variant: 'label', children: title })), value === undefined ? null : (_jsx(PsText, { numberOfLines: 1, style: { fontSize: size, lineHeight: Math.round(size * 1.25) }, variant: 'numeric', weight: 'bold', children: value })), delta === undefined ? null : _jsx(PsChartDeltaBadge, { ...delta }), period === undefined ? null : (_jsx(PsText, { tone: 'muted', variant: 'caption', children: period }))] })), children] }) }));
15
+ };
@@ -3,15 +3,24 @@ import { Pressable, View } from 'react-native';
3
3
  import { PsChartConfig } from '../../constants/ps-chart-config';
4
4
  import { PsText } from '../ps-text/ps-text';
5
5
  export const PsChartLegend = ({ activeIndex = null, items, onPressItem }) => {
6
- return (_jsx(View, { style: { gap: 6 }, testID: 'ps-chart-legend', children: items.map((item, index) => (_jsxs(Pressable, { disabled: onPressItem === undefined, onPress: () => (onPressItem === undefined ? undefined : onPressItem(index)), style: {
6
+ const isWrapped = items.every((item) => item.value === undefined);
7
+ return (_jsx(View, { style: isWrapped
8
+ ? {
9
+ columnGap: PsChartConfig.readoutItemGap,
10
+ flexDirection: 'row',
11
+ flexWrap: 'wrap',
12
+ rowGap: 6,
13
+ }
14
+ : { gap: 6 }, testID: 'ps-chart-legend', children: items.map((item, index) => (_jsxs(Pressable, { hitSlop: PsChartConfig.legendHitSlop, disabled: onPressItem === undefined, onPress: () => (onPressItem === undefined ? undefined : onPressItem(index)), style: {
7
15
  alignItems: 'center',
8
16
  flexDirection: 'row',
9
17
  gap: 8,
18
+ maxWidth: '100%',
10
19
  opacity: activeIndex === null || activeIndex === index ? 1 : 0.5,
11
20
  }, children: [_jsx(View, { style: {
12
21
  backgroundColor: item.color,
13
22
  borderRadius: PsChartConfig.legendDot,
14
23
  height: PsChartConfig.legendDot,
15
24
  width: PsChartConfig.legendDot,
16
- } }), _jsx(PsText, { numberOfLines: 1, style: { flex: 1 }, variant: 'label', children: item.label }), item.value === undefined ? null : (_jsx(PsText, { tone: 'muted', variant: 'numeric', weight: 'semibold', children: item.value }))] }, item.label))) }));
25
+ } }), _jsx(PsText, { numberOfLines: 1, style: isWrapped ? { flexShrink: 1 } : { flex: 1 }, variant: 'label', children: item.label }), item.value === undefined ? null : (_jsx(PsText, { tone: 'muted', variant: 'numeric', weight: 'semibold', children: item.value }))] }, item.label))) }));
17
26
  };
@@ -1,5 +1,6 @@
1
1
  import type { PsChartReadoutItem } from '../../interfaces/ps-chart-readout-item';
2
2
  export interface PsChartReadoutProps {
3
3
  items: PsChartReadoutItem[];
4
+ lines?: number;
4
5
  title: string;
5
6
  }
@@ -1,2 +1,2 @@
1
1
  import type { PsChartReadoutProps } from './ps-chart-readout-props';
2
- export declare const PsChartReadout: ({ items, title }: PsChartReadoutProps) => import("react").JSX.Element;
2
+ export declare const PsChartReadout: ({ items, lines, title }: PsChartReadoutProps) => import("react").JSX.Element;
@@ -1,9 +1,15 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { View } from 'react-native';
3
3
  import { PsChartConfig } from '../../constants/ps-chart-config';
4
+ import { PsChartReadoutService } from '../../services/ps-chart-readout-service';
4
5
  import { PsText } from '../ps-text/ps-text';
5
- export const PsChartReadout = ({ items, title }) => {
6
- return (_jsxs(View, { style: { height: PsChartConfig.readoutHeight, justifyContent: 'center' }, children: [_jsx(PsText, { tone: 'muted', variant: 'caption', children: title }), _jsx(View, { style: { flexDirection: 'row', flexWrap: 'wrap', gap: 12 }, children: items.map((item) => (_jsxs(View, { style: { alignItems: 'center', flexDirection: 'row', gap: 6 }, children: [_jsx(View, { style: {
6
+ export const PsChartReadout = ({ items, lines = 1, title }) => {
7
+ return (_jsxs(View, { style: { height: PsChartReadoutService.height(lines), justifyContent: 'center' }, children: [_jsx(PsText, { tone: 'muted', variant: 'caption', children: title }), _jsx(View, { style: {
8
+ columnGap: PsChartConfig.readoutItemGap,
9
+ flexDirection: 'row',
10
+ flexWrap: 'wrap',
11
+ rowGap: PsChartConfig.readoutRowGap,
12
+ }, children: items.map((item) => (_jsxs(View, { style: { alignItems: 'center', flexDirection: 'row', gap: 6 }, children: [_jsx(View, { style: {
7
13
  backgroundColor: item.color,
8
14
  borderRadius: PsChartConfig.legendDot,
9
15
  height: PsChartConfig.legendDot,
@@ -1,2 +1,2 @@
1
1
  import type { PsChartSkeletonProps } from './ps-chart-skeleton-props';
2
- export declare const PsChartSkeleton: ({ height, label, }: PsChartSkeletonProps) => import("react").JSX.Element;
2
+ export declare const PsChartSkeleton: ({ height: baseHeight, label, }: PsChartSkeletonProps) => import("react").JSX.Element;
@@ -2,5 +2,9 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { View } from 'react-native';
3
3
  import { PsChartConfig } from '../../constants/ps-chart-config';
4
4
  import { PsSkeletonShape } from '../../constants/ps-skeleton-shape';
5
+ import { usePsWidgetFill } from '../../hooks/use-ps-widget-fill';
5
6
  import { PsSkeleton } from '../ps-skeleton/ps-skeleton';
6
- export const PsChartSkeleton = ({ height = PsChartConfig.chartHeight, label, }) => (_jsx(View, { accessibilityLabel: label, accessibilityRole: 'progressbar', accessibilityState: { busy: true }, style: { height }, testID: 'ps-chart-skeleton', children: _jsx(PsSkeleton, { height: height, shape: PsSkeletonShape.Block }) }));
7
+ export const PsChartSkeleton = ({ height: baseHeight = PsChartConfig.chartHeight, label, }) => {
8
+ const height = baseHeight + usePsWidgetFill();
9
+ return (_jsx(View, { accessibilityLabel: label, accessibilityRole: 'progressbar', accessibilityState: { busy: true }, style: { height }, testID: 'ps-chart-skeleton', children: _jsx(PsSkeleton, { height: height, shape: PsSkeletonShape.Block }) }));
10
+ };
@@ -5,7 +5,9 @@ import Svg from 'react-native-svg';
5
5
  import { PsChartConfig } from '../../constants/ps-chart-config';
6
6
  import { PsChartSkeletonVariant } from '../../constants/ps-chart-skeleton-variant';
7
7
  import { usePsChartReveal } from '../../hooks/use-ps-chart-reveal';
8
+ import { usePsChartWidth } from '../../hooks/use-ps-chart-width';
8
9
  import { usePsMobileTheme } from '../../hooks/use-ps-mobile-theme';
10
+ import { usePsWidgetFill } from '../../hooks/use-ps-widget-fill';
9
11
  import { PsChartDonutService } from '../../services/ps-chart-donut-service';
10
12
  import { PsChartEmptyState } from '../ps-chart-empty-state/ps-chart-empty-state';
11
13
  import { PsChartLegend } from '../ps-chart-legend/ps-chart-legend';
@@ -14,14 +16,18 @@ import { PsDonutSlice } from '../ps-donut-slice/ps-donut-slice';
14
16
  import { PsText } from '../ps-text/ps-text';
15
17
  export const PsDonutChart = ({ centerLabel, centerValue, data, emptyLabel, formatShare, height = PsChartConfig.donutHeight, isLoading = false, }) => {
16
18
  const theme = usePsMobileTheme();
19
+ const { onLayout, width } = usePsChartWidth();
20
+ const fill = usePsWidgetFill();
17
21
  const [selected, setSelected] = useState(null);
18
22
  const progress = usePsChartReveal(data.map((datum) => `${datum.id}:${datum.share}`).join(','));
19
23
  if (isLoading)
20
24
  return _jsx(PsChartSkeleton, { height: height, variant: PsChartSkeletonVariant.Donut });
21
- const slices = PsChartDonutService.slices(data, theme.chart, height);
25
+ const layout = PsChartDonutService.layout(width, height);
26
+ const size = layout.size;
27
+ const slices = PsChartDonutService.slices(data, theme.chart, size);
22
28
  if (slices.length === 0)
23
29
  return _jsx(PsChartEmptyState, { height: height, label: emptyLabel });
24
- const circumference = PsChartDonutService.circumference(height);
30
+ const circumference = PsChartDonutService.circumference(size);
25
31
  const chosen = selected === null ? null : data[selected];
26
32
  const readValue = chosen === null
27
33
  ? centerValue
@@ -29,16 +35,28 @@ export const PsDonutChart = ({ centerLabel, centerValue, data, emptyLabel, forma
29
35
  ? formatShare(chosen.share)
30
36
  : chosen.amountLabel;
31
37
  const readLabel = chosen === null ? centerLabel : chosen.label;
32
- return (_jsxs(View, { style: { alignItems: 'center', flexDirection: 'row', gap: 16 }, children: [_jsxs(View, { style: { height, width: height }, children: [_jsx(Svg, { height: height, width: height, children: slices.map((slice, index) => (_jsx(PsDonutSlice, { circumference: circumference, isDimmed: selected !== null && selected !== index, onPress: () => setSelected(selected === index ? null : index), progress: progress, size: height, slice: slice }, slice.id))) }), _jsxs(View, { pointerEvents: 'none', style: {
38
+ if (width === 0)
39
+ return _jsx(View, { onLayout: onLayout, style: { minHeight: height }, testID: 'ps-donut-chart' });
40
+ const centerSize = readValue === undefined
41
+ ? PsChartConfig.donutCenterFontMax
42
+ : PsChartDonutService.centerFontSize(readValue, size);
43
+ return (_jsxs(View, { onLayout: onLayout, style: {
44
+ alignItems: 'center',
45
+ columnGap: PsChartConfig.donutGap,
46
+ flexDirection: layout.isStacked ? 'column' : 'row',
47
+ justifyContent: 'center',
48
+ minHeight: height + fill,
49
+ rowGap: PsChartConfig.donutGap,
50
+ }, testID: 'ps-donut-chart', children: [_jsxs(View, { style: { height: size, width: size }, children: [_jsx(Svg, { height: size, width: size, children: slices.map((slice, index) => (_jsx(PsDonutSlice, { circumference: circumference, isDimmed: selected !== null && selected !== index, onPress: () => setSelected(selected === index ? null : index), progress: progress, size: size, slice: slice }, slice.id))) }), _jsxs(View, { pointerEvents: 'none', style: {
33
51
  alignItems: 'center',
34
52
  bottom: 0,
35
53
  justifyContent: 'center',
36
54
  left: 0,
37
- padding: PsChartConfig.donutThickness + 8,
55
+ padding: PsChartConfig.donutThickness + PsChartConfig.donutCenterPadding,
38
56
  position: 'absolute',
39
57
  right: 0,
40
58
  top: 0,
41
- }, children: [readValue === undefined ? null : (_jsx(PsText, { numberOfLines: 1, style: { fontSize: 18, lineHeight: 24 }, variant: 'numeric', weight: 'bold', children: readValue })), readLabel === undefined ? null : (_jsx(PsText, { align: 'center', numberOfLines: 2, tone: 'muted', variant: 'caption', children: readLabel }))] })] }), _jsx(View, { style: { flex: 1 }, children: _jsx(PsChartLegend, { activeIndex: selected, items: data.map((datum, index) => ({
59
+ }, children: [readValue === undefined ? null : (_jsx(PsText, { numberOfLines: 1, style: { fontSize: centerSize, lineHeight: Math.round((centerSize * 4) / 3) }, variant: 'numeric', weight: 'bold', children: readValue })), readLabel === undefined ? null : (_jsx(PsText, { align: 'center', numberOfLines: 2, tone: 'muted', variant: 'caption', children: readLabel }))] })] }), _jsx(View, { style: layout.isStacked ? { alignSelf: 'stretch' } : { flex: 1 }, children: _jsx(PsChartLegend, { activeIndex: selected, items: data.map((datum, index) => ({
42
60
  color: slices[index].color,
43
61
  label: datum.label,
44
62
  value: datum.amountLabel === undefined ? formatShare(datum.share) : datum.amountLabel,
@@ -1,11 +1,14 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { View } from 'react-native';
2
3
  import { PsChartConfig } from '../../constants/ps-chart-config';
3
4
  import { PsChartSkeletonVariant } from '../../constants/ps-chart-skeleton-variant';
5
+ import { usePsWidgetFill } from '../../hooks/use-ps-widget-fill';
4
6
  import { PsChartFrame } from '../ps-chart-frame/ps-chart-frame';
5
7
  import { PsChartSkeleton } from '../ps-chart-skeleton/ps-chart-skeleton';
6
8
  import { PsSparkline } from '../ps-sparkline/ps-sparkline';
7
9
  export const PsKpiCard = ({ delta, isLoading = false, period, title, value, values, }) => {
10
+ const fill = usePsWidgetFill();
8
11
  if (isLoading)
9
12
  return (_jsx(PsChartFrame, { children: _jsx(PsChartSkeleton, { height: PsChartConfig.sparklineHeight * 2, variant: PsChartSkeletonVariant.Line }) }));
10
- return (_jsx(PsChartFrame, { delta: delta, period: period, title: title, value: value, children: values === undefined ? null : _jsx(PsSparkline, { values: values }) }));
13
+ return (_jsx(PsChartFrame, { delta: delta, period: period, title: title, value: value, children: values === undefined ? (fill > 0 ? (_jsx(View, { style: { height: fill } })) : null) : (_jsx(PsSparkline, { values: values })) }));
11
14
  };
@@ -1,4 +1,5 @@
1
1
  import type { ReactNode } from 'react';
2
2
  export interface PsPrivacyCoverProps {
3
3
  children?: ReactNode;
4
+ shouldTakeFocus?: boolean;
4
5
  }
@@ -1,2 +1,2 @@
1
1
  import type { PsPrivacyCoverProps } from './ps-privacy-cover-props';
2
- export declare const PsPrivacyCover: ({ children }: PsPrivacyCoverProps) => import("react").JSX.Element;
2
+ export declare const PsPrivacyCover: ({ children, shouldTakeFocus }: PsPrivacyCoverProps) => import("react").JSX.Element;
@@ -1,11 +1,20 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useRef } from 'react';
2
3
  import { PallasoftZIndex } from '@pallasoft/ps-design-system';
3
- import { StyleSheet, View } from 'react-native';
4
+ import { AccessibilityInfo, StyleSheet, View } from 'react-native';
5
+ import { PsAccessibilityConfig } from '../../constants/ps-accessibility-config';
4
6
  import { usePsMobileTheme } from '../../hooks/use-ps-mobile-theme';
5
7
  import { PsPageBackdrop } from '../ps-page-backdrop/ps-page-backdrop';
6
- export const PsPrivacyCover = ({ children }) => {
8
+ export const PsPrivacyCover = ({ children, shouldTakeFocus = false }) => {
7
9
  const theme = usePsMobileTheme();
8
- return (_jsxs(View, { accessibilityViewIsModal: true, style: [
10
+ const ref = useRef(null);
11
+ useEffect(() => {
12
+ if (!shouldTakeFocus)
13
+ return;
14
+ if (ref.current !== null)
15
+ AccessibilityInfo.sendAccessibilityEvent(ref.current, PsAccessibilityConfig.focusEvent);
16
+ }, [shouldTakeFocus]);
17
+ return (_jsxs(View, { accessibilityViewIsModal: true, importantForAccessibility: 'yes', ref: ref, style: [
9
18
  StyleSheet.absoluteFill,
10
19
  {
11
20
  alignItems: 'center',
@@ -31,7 +31,10 @@ export const PsSortableGrid = ({ getItemSpan, isDisabled = false, items, labels,
31
31
  });
32
32
  const ids = useMemo(() => PsSortableGridService.ids(order), [order]);
33
33
  const rects = useMemo(() => PsSortableGridService.layout(order.map((item) => getItemSpan(item)), PsSortableGridService.heights(ids, measured), width), [getItemSpan, ids, measured, order, width]);
34
+ const extras = useMemo(() => PsSortableGridService.extras(rects, PsSortableGridService.heights(ids, measured)), [ids, measured, rects]);
34
35
  const isReady = PsSortableGridService.isMeasured(ids, measured, width);
36
+ const applied = useRef({});
37
+ applied.current = Object.fromEntries(ids.map((id, index) => [id, isReady ? extras[index] : 0]));
35
38
  const latest = useRef({ items, onReorder, order, rects, scroll, windowHeight, insets });
36
39
  latest.current = { insets, items, onReorder, order, rects, scroll, windowHeight };
37
40
  useEffect(() => {
@@ -131,10 +134,11 @@ export const PsSortableGrid = ({ getItemSpan, isDisabled = false, items, labels,
131
134
  notify(next);
132
135
  PsHapticService.play('selection', hasHaptics);
133
136
  }, [hasHaptics]);
134
- const measure = useCallback((id, height) => {
135
- setMeasured((current) => current[id] !== undefined && Math.abs(current[id] - height) < 0.5
137
+ const measure = useCallback((id, total) => {
138
+ const natural = PsSortableGridService.natural(total, applied.current[id] === undefined ? 0 : applied.current[id]);
139
+ setMeasured((current) => current[id] !== undefined && Math.abs(current[id] - natural) < 0.5
136
140
  ? current
137
- : { ...current, [id]: height });
141
+ : { ...current, [id]: natural });
138
142
  }, []);
139
- return (_jsx(View, { onLayout: (event) => setWidth(event.nativeEvent.layout.width), style: { height: PsSortableGridService.contentHeight(rects) }, children: order.map((item, index) => (_jsx(PsSortableItem, { canMoveDown: index < order.length - 1, canMoveUp: index > 0, dragX: dragX, dragY: dragY, id: item.id, isActive: item.id === activeId, isDisabled: isDisabled, isReady: isReady, label: item.label, labels: labels, onEnd: end, onMeasure: measure, onMove: moveBy, onStart: start, onUpdate: update, rect: rects[index], children: renderItem({ isActive: item.id === activeId, item }) }, item.id))) }));
143
+ return (_jsx(View, { onLayout: (event) => setWidth(event.nativeEvent.layout.width), style: { height: PsSortableGridService.contentHeight(rects) }, children: order.map((item, index) => (_jsx(PsSortableItem, { canMoveDown: index < order.length - 1, canMoveUp: index > 0, dragX: dragX, dragY: dragY, extra: extras[index], id: item.id, isActive: item.id === activeId, isDisabled: isDisabled, isReady: isReady, label: item.label, labels: labels, onEnd: end, onMeasure: measure, onMove: moveBy, onStart: start, onUpdate: update, rect: rects[index], children: renderItem({ isActive: item.id === activeId, item }) }, item.id))) }));
140
144
  };
@@ -8,6 +8,7 @@ export interface PsSortableItemProps {
8
8
  children: ReactNode;
9
9
  dragX: SharedValue<number>;
10
10
  dragY: SharedValue<number>;
11
+ extra: number;
11
12
  id: string;
12
13
  isActive: boolean;
13
14
  isDisabled: boolean;
@@ -1,2 +1,2 @@
1
1
  import type { PsSortableItemProps } from './ps-sortable-item-props';
2
- export declare const PsSortableItem: ({ canMoveDown, canMoveUp, children, dragX, dragY, id, isActive, isDisabled, isReady, label, labels, onEnd, onMeasure, onMove, onStart, onUpdate, rect, }: PsSortableItemProps) => import("react").JSX.Element;
2
+ export declare const PsSortableItem: ({ canMoveDown, canMoveUp, children, dragX, dragY, extra, id, isActive, isDisabled, isReady, label, labels, onEnd, onMeasure, onMove, onStart, onUpdate, rect, }: PsSortableItemProps) => import("react").JSX.Element;
@@ -3,8 +3,9 @@ import { useEffect, useRef } from 'react';
3
3
  import { GestureDetector, usePanGesture } from 'react-native-gesture-handler';
4
4
  import Animated, { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
5
5
  import { PsSortableGridConfig } from '../../constants/ps-sortable-grid-config';
6
+ import { PsWidgetFillContext } from '../../contexts/ps-widget-fill-context';
6
7
  import { usePsMobileTheme } from '../../hooks/use-ps-mobile-theme';
7
- export const PsSortableItem = ({ canMoveDown, canMoveUp, children, dragX, dragY, id, isActive, isDisabled, isReady, label, labels, onEnd, onMeasure, onMove, onStart, onUpdate, rect, }) => {
8
+ export const PsSortableItem = ({ canMoveDown, canMoveUp, children, dragX, dragY, extra, id, isActive, isDisabled, isReady, label, labels, onEnd, onMeasure, onMove, onStart, onUpdate, rect, }) => {
8
9
  const theme = usePsMobileTheme();
9
10
  const left = useSharedValue(rect.x);
10
11
  const top = useSharedValue(rect.y);
@@ -70,5 +71,5 @@ export const PsSortableItem = ({ canMoveDown, canMoveUp, children, dragX, dragY,
70
71
  }
71
72
  : undefined,
72
73
  animatedStyle,
73
- ], children: children }) }));
74
+ ], children: _jsx(PsWidgetFillContext.Provider, { value: isReady ? extra : 0, children: children }) }) }));
74
75
  };
@@ -1,2 +1,2 @@
1
1
  import type { PsSparklineProps } from './ps-sparkline-props';
2
- export declare const PsSparkline: ({ color, height, isLoading, showArea, values, }: PsSparklineProps) => import("react").JSX.Element;
2
+ export declare const PsSparkline: ({ color, height: baseHeight, isLoading, showArea, values, }: PsSparklineProps) => import("react").JSX.Element;
@@ -6,11 +6,13 @@ import { PsChartSkeletonVariant } from '../../constants/ps-chart-skeleton-varian
6
6
  import { usePsChartReveal } from '../../hooks/use-ps-chart-reveal';
7
7
  import { usePsChartWidth } from '../../hooks/use-ps-chart-width';
8
8
  import { usePsMobileTheme } from '../../hooks/use-ps-mobile-theme';
9
+ import { usePsWidgetFill } from '../../hooks/use-ps-widget-fill';
9
10
  import { PsChartScaleService } from '../../services/ps-chart-scale-service';
10
11
  import { PsChartLine } from '../ps-chart-line/ps-chart-line';
11
12
  import { PsChartSkeleton } from '../ps-chart-skeleton/ps-chart-skeleton';
12
- export const PsSparkline = ({ color, height = PsChartConfig.sparklineHeight, isLoading = false, showArea = true, values, }) => {
13
+ export const PsSparkline = ({ color, height: baseHeight = PsChartConfig.sparklineHeight, isLoading = false, showArea = true, values, }) => {
13
14
  const theme = usePsMobileTheme();
15
+ const height = baseHeight + usePsWidgetFill();
14
16
  const { onLayout, width } = usePsChartWidth();
15
17
  const progress = usePsChartReveal(values.join(','));
16
18
  if (isLoading)
@@ -1,2 +1,2 @@
1
1
  import type { PsWaterfallChartProps } from './ps-waterfall-chart-props';
2
- export declare const PsWaterfallChart: ({ data, emptyLabel, formatTick, formatValue, height, isLoading, }: PsWaterfallChartProps) => import("react").JSX.Element;
2
+ export declare const PsWaterfallChart: ({ data, emptyLabel, formatTick, formatValue, height: baseHeight, isLoading, }: PsWaterfallChartProps) => import("react").JSX.Element;
@@ -7,31 +7,37 @@ import { usePsChartReveal } from '../../hooks/use-ps-chart-reveal';
7
7
  import { usePsChartScrub } from '../../hooks/use-ps-chart-scrub';
8
8
  import { usePsChartWidth } from '../../hooks/use-ps-chart-width';
9
9
  import { usePsMobileTheme } from '../../hooks/use-ps-mobile-theme';
10
+ import { usePsWidgetFill } from '../../hooks/use-ps-widget-fill';
11
+ import { PsChartAxisService } from '../../services/ps-chart-axis-service';
10
12
  import { PsChartScaleService } from '../../services/ps-chart-scale-service';
13
+ import { PsChartTextService } from '../../services/ps-chart-text-service';
11
14
  import { PsWaterfallService } from '../../services/ps-waterfall-service';
12
15
  import { PsChartBar } from '../ps-chart-bar/ps-chart-bar';
13
16
  import { PsChartEmptyState } from '../ps-chart-empty-state/ps-chart-empty-state';
14
17
  import { PsChartReadout } from '../ps-chart-readout/ps-chart-readout';
15
18
  import { PsChartSkeleton } from '../ps-chart-skeleton/ps-chart-skeleton';
16
- export const PsWaterfallChart = ({ data, emptyLabel, formatTick, formatValue, height = PsChartConfig.chartHeight, isLoading = false, }) => {
19
+ export const PsWaterfallChart = ({ data, emptyLabel, formatTick, formatValue, height: baseHeight = PsChartConfig.chartHeight, isLoading = false, }) => {
17
20
  const theme = usePsMobileTheme();
18
21
  const { onLayout, width } = usePsChartWidth();
19
- const plot = PsChartScaleService.plot(width, height);
20
- const { index, panHandlers } = usePsChartScrub(data.length, true, plot);
22
+ const height = baseHeight + usePsWidgetFill();
21
23
  const steps = PsWaterfallService.steps(data);
24
+ const domain = PsChartScaleService.domain(PsWaterfallService.values(steps));
25
+ const tickLabels = PsChartScaleService.ticks(domain).map((tick) => formatTick(tick));
26
+ const plot = PsChartScaleService.plot(width, height, PsChartAxisService.yAxisWidth(tickLabels, width));
27
+ const { index, panHandlers } = usePsChartScrub(data.length, true, plot);
22
28
  const progress = usePsChartReveal(`waterfall:${PsWaterfallService.values(steps).join(',')}`);
23
29
  if (isLoading)
24
- return _jsx(PsChartSkeleton, { height: height, variant: PsChartSkeletonVariant.Bars });
30
+ return _jsx(PsChartSkeleton, { height: baseHeight, variant: PsChartSkeletonVariant.Bars });
25
31
  if (steps.length === 0 || PsWaterfallService.values(steps).every((value) => value === 0))
26
- return _jsx(PsChartEmptyState, { height: height, label: emptyLabel });
32
+ return _jsx(PsChartEmptyState, { height: baseHeight, label: emptyLabel });
27
33
  const colors = [theme.chart[0], theme.danger, theme.primary700];
28
- const domain = PsChartScaleService.domain(PsWaterfallService.values(steps));
34
+ const xLabels = PsChartAxisService.xLabels(steps.map((entry) => entry.label), plot.right - plot.left, true);
29
35
  const selected = index === null ? steps.length - 1 : index;
30
36
  const step = steps[selected];
31
37
  const rects = PsWaterfallService.rects(steps, colors, domain, plot);
32
38
  const color = step.isTotal ? colors[2] : step.value < 0 ? colors[1] : colors[0];
33
- return (_jsxs(View, { style: { gap: 8 }, children: [_jsx(PsChartReadout, { items: [{ color, label: step.label, value: formatValue(step.value) }], title: step.label }), _jsx(View, { accessible: true, accessibilityLabel: `${step.label}, ${formatValue(step.value)}`, accessibilityRole: 'image', onLayout: onLayout, style: { height }, children: width === 0 ? null : (_jsxs(_Fragment, { children: [_jsxs(Svg, { height: height, pointerEvents: 'none', width: width, children: [PsChartScaleService.ticks(domain).map((tick) => {
39
+ return (_jsxs(View, { style: { gap: 8 }, children: [_jsx(PsChartReadout, { items: [{ color, label: step.label, value: formatValue(step.value) }], title: step.label }), _jsx(View, { accessible: true, accessibilityLabel: `${step.label}, ${formatValue(step.value)}`, accessibilityRole: 'image', onLayout: onLayout, style: { height }, children: width === 0 ? null : (_jsxs(_Fragment, { children: [_jsxs(Svg, { height: height, pointerEvents: 'none', width: width, children: [PsChartScaleService.ticks(domain).map((tick, tickIndex) => {
34
40
  const y = PsChartScaleService.y(tick, domain, plot);
35
- return (_jsxs(G, { children: [_jsx(Line, { stroke: theme.line, strokeWidth: PsChartConfig.gridLineWidth, x1: plot.left, x2: plot.right, y1: y, y2: y }), _jsx(SvgText, { fill: theme.muted, fontFamily: theme.fonts.medium, fontSize: PsChartConfig.axisLabelSize, textAnchor: 'end', x: plot.left - 6, y: y + 3, children: formatTick(tick) })] }, tick));
36
- }), steps.map((entry, position) => (_jsx(SvgText, { fill: theme.muted, fontFamily: theme.fonts.medium, fontSize: PsChartConfig.axisLabelSize, textAnchor: 'middle', x: PsChartScaleService.categoryX(position, steps.length, plot, true), y: height - 6, children: entry.label }, entry.label))), rects.map((rect) => (_jsx(PsChartBar, { progress: progress, rect: rect }, rect.id)))] }), _jsx(View, { ...panHandlers, style: StyleSheet.absoluteFill, testID: 'ps-chart-touch' })] })) })] }));
41
+ return (_jsxs(G, { children: [_jsx(Line, { stroke: theme.line, strokeWidth: PsChartConfig.gridLineWidth, x1: plot.left, x2: plot.right, y1: y, y2: y }), _jsx(SvgText, { fill: theme.muted, fontFamily: theme.fonts.medium, fontSize: PsChartConfig.axisLabelSize, textAnchor: 'end', x: plot.left - PsChartConfig.axisTickGap, y: y + PsChartConfig.axisLabelSize / 3, children: PsChartTextService.fit(tickLabels[tickIndex], plot.left - PsChartConfig.axisTickGap, PsChartConfig.axisLabelSize) })] }, tick));
42
+ }), xLabels.indexes.map((position) => (_jsx(SvgText, { fill: theme.muted, fontFamily: theme.fonts.medium, fontSize: PsChartConfig.axisLabelSize, textAnchor: 'middle', x: PsChartScaleService.categoryX(position, steps.length, plot, true), y: height - 6, children: PsChartTextService.fit(steps[position].label, xLabels.maxWidth, PsChartConfig.axisLabelSize) }, steps[position].label))), rects.map((rect) => (_jsx(PsChartBar, { progress: progress, rect: rect }, rect.id)))] }), _jsx(View, { ...panHandlers, style: StyleSheet.absoluteFill, testID: 'ps-chart-touch' })] })) })] }));
37
43
  };
@@ -0,0 +1,5 @@
1
+ export declare const PsAccessibilityConfig: {
2
+ readonly focusEvent: "focus";
3
+ readonly hiddenImportance: "no-hide-descendants";
4
+ readonly visibleImportance: "auto";
5
+ };
@@ -0,0 +1,5 @@
1
+ export const PsAccessibilityConfig = {
2
+ focusEvent: 'focus',
3
+ hiddenImportance: 'no-hide-descendants',
4
+ visibleImportance: 'auto',
5
+ };
@@ -1,31 +1,56 @@
1
1
  export declare const PsChartConfig: {
2
2
  readonly areaOpacity: 0.18;
3
- readonly axisLabelSize: 10;
3
+ readonly axisLabelGap: 8;
4
+ readonly axisLabelMaxWidth: 48;
5
+ readonly axisLabelSize: 11;
6
+ readonly axisTickGap: 6;
4
7
  readonly barGapRatio: 0.3;
5
8
  readonly barRadius: 4;
9
+ readonly charWidthRatio: 0.62;
10
+ readonly compactBarGapRatio: 0.15;
11
+ readonly compactSlot: 24;
6
12
  readonly cardPadding: 16;
7
13
  readonly cardRadius: 16;
8
14
  readonly chartHeight: 180;
9
15
  readonly deltaIconSize: 10;
10
16
  readonly donutHeight: 160;
11
17
  readonly donutThickness: 22;
18
+ readonly donutCenterFontMax: 18;
19
+ readonly donutCenterFontMin: 11;
20
+ readonly donutCenterPadding: 8;
21
+ readonly donutGap: 16;
22
+ readonly donutMinLegendWidth: 120;
12
23
  readonly donutSliceGap: 2;
13
24
  readonly drawMs: 700;
25
+ readonly ellipsis: "…";
14
26
  readonly gridLineCount: 3;
15
27
  readonly gridLineWidth: 1;
28
+ readonly kpiDeltaHeight: 20;
16
29
  readonly kpiGap: 12;
30
+ readonly kpiPeriodHeight: 16;
31
+ readonly kpiValueFontMax: 24;
32
+ readonly kpiValueFontMin: 16;
33
+ readonly legendHitSlop: 8;
17
34
  readonly legendDot: 8;
18
35
  readonly lineWidth: 2.5;
19
36
  readonly markerRadius: 4;
37
+ readonly minBarWidth: 4;
20
38
  readonly maxXLabels: 4;
39
+ readonly minXLabels: 2;
21
40
  readonly paddingBottom: 22;
22
41
  readonly paddingRight: 8;
23
42
  readonly paddingTop: 8;
24
43
  readonly readoutHeight: 40;
44
+ readonly readoutItemGap: 12;
45
+ readonly readoutLineHeight: 22;
46
+ readonly readoutRowGap: 2;
47
+ readonly readoutValueSize: 15;
25
48
  readonly scrubLineWidth: 1;
26
49
  readonly skeletonBarHeights: readonly [0.45, 0.7, 0.55, 0.85, 0.65, 0.95, 0.75];
27
50
  readonly skeletonPulseMs: 900;
28
51
  readonly sparklineHeight: 40;
29
52
  readonly sparklineWidth: 2;
53
+ readonly yAxisMaxRatio: 0.35;
54
+ readonly yAxisMinWidth: 28;
30
55
  readonly yAxisWidth: 52;
31
56
  };