@lunit/oui 2.3.4 → 2.3.5

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.
@@ -1,12 +1,13 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Box } from '@mui/material';
3
3
  import { AnalysisBarSegmentContainer, AnalysisBarOuter, AxisLabels, GraphAxisLabel, GraphScoreIndicator, GraphSegment, } from './AnalysisBar.styled';
4
- import { adjustBarSegmentWidth, parseStringValToNumber } from './AnalysisBar.utils';
4
+ import { parseStringValToNumber } from './AnalysisBar.utils';
5
5
  import HeatmapGraphSVG from './HeatmapGraphIcon/HeatmapGraphSVG';
6
6
  const Segments = ({ segments, adjustForOnePercent }) => {
7
7
  if (!segments) {
8
8
  return null;
9
9
  }
10
+ const combinedWidth = segments.length > 1 ? segments[0].width + segments[1].width : 0;
10
11
  if (segments?.length === 1 && segments[0].color === 'jet') {
11
12
  return (_jsx(Box, { sx: { width: '100%', height: '14px', transform: 'scaleY(0.8)' }, children: _jsx(HeatmapGraphSVG, {}) }));
12
13
  }
@@ -14,7 +15,7 @@ const Segments = ({ segments, adjustForOnePercent }) => {
14
15
  if (segment.color === 'jet') {
15
16
  return _jsx(HeatmapGraphSVG, { width: `${segment.width}%` });
16
17
  }
17
- return (_jsx(GraphSegment, { color: segment.color, width: adjustForOnePercent ? adjustBarSegmentWidth(segment.width) : segment.width }, i));
18
+ return (_jsx(GraphSegment, { color: segment.color, hasAdjustedOnePercentSegment: adjustForOnePercent, isOnePercentSegment: segment.width <= 1, combinedWidth: combinedWidth, width: segment.width, isNextSegment: i === 1 }, i));
18
19
  }) }));
19
20
  };
20
21
  const AnalysisBar = ({ componentType = 'analysisBar', expressionValue, caption, expressionLevels = [], expressionLabels = [], segments, isDimmed = false, }) => {
@@ -22,10 +23,11 @@ const AnalysisBar = ({ componentType = 'analysisBar', expressionValue, caption,
22
23
  throw new Error("The 'componentType' prop is required.");
23
24
  if (!expressionLevels.length)
24
25
  throw new Error("The 'expressionLevels' prop must contain at least one item.");
25
- const hasAdjustedOnePercentSegment = segments?.[0].width === 1;
26
+ const hasAdjustedOnePercentSegment = segments?.[0].width <= 1;
26
27
  return (_jsxs(AnalysisBarOuter, { className: "analysis-bar", isDimmed: isDimmed, children: [_jsxs(AnalysisBarSegmentContainer, { children: [expressionValue && (_jsx(GraphScoreIndicator, { adjustForOnePercent: hasAdjustedOnePercentSegment, value: expressionValue, isJet: segments?.[0].color === 'jet' })), _jsx(Segments, { segments: segments, adjustForOnePercent: hasAdjustedOnePercentSegment })] }), (expressionLevels.length > 0 || caption) && (_jsxs(AxisLabels, { children: [expressionLevels.length > 0 &&
27
28
  expressionLevels.map((val, i) => {
28
- return (_jsx(GraphAxisLabel, { label: expressionLabels[i] || val, adjustForOnePercent: hasAdjustedOnePercentSegment, leftPos: parseStringValToNumber(val) }, i));
29
+ const adjustedForOnePercent = +val <= 1 && +val > 0;
30
+ return (_jsx(GraphAxisLabel, { label: expressionLabels[i] || val, adjustForOnePercent: adjustedForOnePercent, leftPos: parseStringValToNumber(val) }, i));
29
31
  }), caption && (_jsx(GraphAxisLabel, { label: caption, adjustForOnePercent: hasAdjustedOnePercentSegment, leftPos: 50 }))] }))] }));
30
32
  };
31
33
  export default AnalysisBar;
@@ -27,6 +27,10 @@ interface GraphSegmentProps {
27
27
  color: string | undefined;
28
28
  width: number;
29
29
  square?: boolean;
30
+ hasAdjustedOnePercentSegment?: boolean;
31
+ combinedWidth?: number;
32
+ isNextSegment?: boolean;
33
+ isOnePercentSegment?: boolean;
30
34
  }
31
35
  export declare const GraphSegment: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme> & GraphSegmentProps, React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, {}>;
32
36
  export {};
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Box, styled, Typography } from '@mui/material';
3
- import { adjustBarLabelPosition, clampBarLabelPosition, parseStringValToNumber, } from './AnalysisBar.utils';
3
+ import { clampBarLabelPosition, parseStringValToNumber } from './AnalysisBar.utils';
4
4
  export const AnalysisBarOuter = styled(Box, {
5
5
  shouldForwardProp: (prop) => prop !== 'isDimmed',
6
6
  })(({ isDimmed }) => ({
@@ -42,12 +42,12 @@ const GraphScoreIndicatorPip = styled('span')(() => {
42
42
  };
43
43
  });
44
44
  export const GraphScoreIndicator = ({ value, adjustForOnePercent, isJet, }) => {
45
- let leftPos = parseStringValToNumber(value);
46
- if (adjustForOnePercent) {
47
- leftPos = adjustBarLabelPosition(leftPos);
45
+ let leftPos = `${parseStringValToNumber(value)}%`;
46
+ if (adjustForOnePercent && +value <= 1) {
47
+ leftPos = '12px';
48
48
  }
49
49
  return (_jsxs(GraphScoreIndicatorContainer, { className: "analysis-bar-score-indicator", sx: {
50
- left: `${leftPos}%`,
50
+ left: leftPos,
51
51
  transform: isJet ? 'translateX(-50%) translateY(8px)' : 'translateX(-50%)',
52
52
  }, isJet: isJet, children: [_jsx(Typography, { variant: "small_body_sb1", sx: { textAlign: 'center' }, children: value }), _jsx(GraphScoreIndicatorPip, {})] }));
53
53
  };
@@ -64,7 +64,7 @@ const GraphAxisLabelContainer = styled('span')(() => {
64
64
  export const GraphAxisLabel = ({ label, leftPos, adjustForOnePercent, }) => {
65
65
  const getLeft = (value, adjustForOnePercent) => {
66
66
  if (adjustForOnePercent) {
67
- return `${adjustBarLabelPosition(value)}%`;
67
+ return '12px';
68
68
  }
69
69
  return `${clampBarLabelPosition(value)}%`;
70
70
  };
@@ -89,20 +89,43 @@ export const AnalysisBarCaption = ({ label }) => {
89
89
  width: 'auto',
90
90
  }, className: "analysis-bar-caption", children: _jsx(Typography, { variant: "small_body_m5", sx: { textAlign: 'center' }, children: label }) }));
91
91
  };
92
- const segmentStyle = (color, width, square) => {
93
- return {
92
+ const segmentStyle = (color, width, square, hasAdjustedOnePercentSegment, combinedWidth, isNextSegment, isOnePercentSegment) => {
93
+ const baseStyle = {
94
94
  backgroundColor: color,
95
- width: `${width}%`,
96
95
  height: '8px',
97
96
  borderRadius: square ? '0px' : '12px',
98
97
  };
98
+ if (isOnePercentSegment) {
99
+ return {
100
+ ...baseStyle,
101
+ width: '12px',
102
+ minWidth: '12px',
103
+ maxWidth: '12px',
104
+ };
105
+ }
106
+ else {
107
+ return {
108
+ ...baseStyle,
109
+ width: hasAdjustedOnePercentSegment && isNextSegment
110
+ ? `calc(${combinedWidth}% - 12px)`
111
+ : `${width}%`,
112
+ };
113
+ }
99
114
  };
100
115
  export const GraphSegment = styled('span', {
101
- shouldForwardProp: (prop) => !['color', 'width', 'square'].includes(prop.toString()),
102
- })(({ color, width, square }) => {
116
+ shouldForwardProp: (prop) => ![
117
+ 'color',
118
+ 'width',
119
+ 'square',
120
+ 'hasAdjustedOnePercentSegment',
121
+ 'combinedWidth',
122
+ 'isNextSegment',
123
+ 'isOnePercentSegment',
124
+ ].includes(prop.toString()),
125
+ })(({ color, width, square, hasAdjustedOnePercentSegment, combinedWidth, isNextSegment, isOnePercentSegment, }) => {
103
126
  // cover undefined and empty string
104
127
  const barColor = color && color.length ? color : 'red';
105
128
  return {
106
- ...segmentStyle(barColor, width, square ?? false), // fallback color
129
+ ...segmentStyle(barColor, width, square ?? false, hasAdjustedOnePercentSegment ?? false, combinedWidth ?? 0, isNextSegment ?? false, isOnePercentSegment ?? false), // fallback color
107
130
  };
108
131
  });
@@ -1,5 +1,3 @@
1
1
  export declare function parseStringValToNumber(val: string): number;
2
- export declare function adjustBarSegmentWidth(value: number): number;
3
- export declare function adjustBarLabelPosition(value: number): number;
4
2
  export declare function clampNumericalPercentage(value: number): number;
5
3
  export declare function clampBarLabelPosition(value: number): number;
@@ -2,22 +2,6 @@ export function parseStringValToNumber(val) {
2
2
  const value = val.endsWith('%') ? val.slice(0, -1) : val;
3
3
  return parseInt(value, 10);
4
4
  }
5
- export function adjustBarSegmentWidth(value) {
6
- if (value === 0)
7
- return 0;
8
- const adjusted = Math.floor((value / 100) * 97);
9
- return adjusted + 4;
10
- }
11
- export function adjustBarLabelPosition(value) {
12
- if (value === 0)
13
- return 1;
14
- if (value === 1)
15
- return 4;
16
- if (value === 100)
17
- return 98;
18
- const adjusted = Math.floor((value / 100) * 93);
19
- return adjusted + 6;
20
- }
21
5
  export function clampNumericalPercentage(value) {
22
6
  if (value >= 100)
23
7
  return 100;
@@ -20,6 +20,11 @@ const ModelType = ({ componentType = 'modelType', title, optionTitle, scoreItems
20
20
  throw new Error("The 'currentSpecificity' prop is required.");
21
21
  if (!options.length)
22
22
  throw new Error("The 'options' prop must contain at least one item.");
23
+ options.forEach((option) => {
24
+ if (typeof option.sensitivity !== 'number' || typeof option.specificity !== 'number') {
25
+ throw new Error('The sensitivity and specificity must be numbers.');
26
+ }
27
+ });
23
28
  const [selectedItem, setSelectedItem] = useState(userModelType);
24
29
  const [isModelTypeChanged, setIsModelTypeChanged] = useState(false);
25
30
  const handleDropdownChange = (event) => {
@@ -14,8 +14,9 @@ const ModelTypeControl = (modelType) => {
14
14
  const [memberExtraProperties, setMemberExtraProperties] = useState(initialMemberExtraProperties);
15
15
  const updateModelType = useCallback((type) => {
16
16
  const currentModelType = { ...modelType };
17
- const currentSensitivity = currentModelType.options.find((option) => option.target.annotation.dimension === type)?.sensitivity;
18
- const currentSpecificity = currentModelType.options.find((option) => option.target.annotation.dimension === type)?.specificity;
17
+ const currentModel = currentModelType.options.find((option) => option.target.annotation.dimension === type);
18
+ const currentSensitivity = currentModel?.sensitivity;
19
+ const currentSpecificity = currentModel?.specificity;
19
20
  currentModelType.currentSensitivity.metrics.value = currentSensitivity?.toString() || '0.0';
20
21
  currentModelType.currentSpecificity.metrics.value = currentSpecificity?.toString() || '0.0';
21
22
  setModelTypeState(currentModelType);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunit/oui",
3
- "version": "2.3.4",
3
+ "version": "2.3.5",
4
4
  "validate-branch-name": {
5
5
  "pattern": "^(main|develop)|(feature|fix|release|hotfix|qe)/.+$",
6
6
  "errorMsg": "The branch name is not correct. Please check the pattern. (ex. feature/add-something)"