pixel-react 1.5.9 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/.yarn/install-state.gz +0 -0
  2. package/lib/components/AppHeader/AppHeader.d.ts +1 -0
  3. package/lib/components/AppHeader/types.d.ts +18 -6
  4. package/lib/components/Charts/BarChart/BarChart.d.ts +1 -0
  5. package/lib/components/Charts/DashboardDonutChart/types.d.ts +2 -0
  6. package/lib/components/Excel/ExcelToolBar/ExcelToolBar.d.ts +0 -1
  7. package/lib/components/FieldSet/FieldSet.d.ts +5 -0
  8. package/lib/components/FieldSet/index.d.ts +1 -0
  9. package/lib/components/FieldSet/types.d.ts +7 -0
  10. package/lib/components/FileDropzone/types.d.ts +8 -0
  11. package/lib/components/MachineInputField/types.d.ts +1 -1
  12. package/lib/components/MultiSelect/MultiSelect.d.ts +1 -1
  13. package/lib/components/MultiSelect/MultiSelectTypes.d.ts +1 -0
  14. package/lib/components/PopUpModal/PopUpModal.d.ts +5 -0
  15. package/lib/components/PopUpModal/types.d.ts +14 -0
  16. package/lib/components/RadioGroup/radioGroupTypes.d.ts +20 -0
  17. package/lib/components/SequentialConnectingBranch/SequentialConnectingBranch.d.ts +2 -1
  18. package/lib/components/SequentialConnectingBranch/components/Branches/Branches.d.ts +1 -1
  19. package/lib/components/SequentialConnectingBranch/components/Branches/types.d.ts +3 -2
  20. package/lib/components/SequentialConnectingBranch/components/ConnectingBranches/ConnectingBranches.d.ts +1 -1
  21. package/lib/components/SequentialConnectingBranch/components/ConnectingBranches/types.d.ts +3 -2
  22. package/lib/components/SequentialConnectingBranch/types.d.ts +11 -3
  23. package/lib/components/TableTree/TableTree.d.ts +4 -24
  24. package/lib/components/TableTree/data.d.ts +112 -273
  25. package/lib/components/TableTree/types.d.ts +28 -0
  26. package/lib/index.d.ts +149 -32
  27. package/lib/index.esm.js +1104 -742
  28. package/lib/index.esm.js.map +1 -1
  29. package/lib/index.js +1109 -742
  30. package/lib/index.js.map +1 -1
  31. package/lib/tsconfig.tsbuildinfo +1 -1
  32. package/package.json +2 -2
  33. package/src/assets/Themes/BaseTheme.scss +5 -14
  34. package/src/assets/Themes/DarkTheme.scss +5 -2
  35. package/src/assets/icons/arrow_up.svg +1 -1
  36. package/src/assets/icons/export.svg +5 -0
  37. package/src/assets/icons/import.svg +5 -0
  38. package/src/assets/icons/info_icon.svg +4 -16
  39. package/src/assets/icons/replace_file.svg +14 -0
  40. package/src/assets/icons/web_service_icon.svg +3 -0
  41. package/src/assets/styles/_fonts.scss +4 -2
  42. package/src/components/AppHeader/AppHeader.stories.tsx +242 -39
  43. package/src/components/AppHeader/AppHeader.tsx +158 -139
  44. package/src/components/AppHeader/types.ts +19 -6
  45. package/src/components/Charts/BarChart/BarChart.scss +34 -34
  46. package/src/components/Charts/BarChart/BarChart.stories.tsx +3 -2
  47. package/src/components/Charts/BarChart/BarChart.tsx +79 -55
  48. package/src/components/Charts/DashboardDonutChart/DashboardDonutChart.scss +25 -18
  49. package/src/components/Charts/DashboardDonutChart/DashboardDonutChart.tsx +31 -11
  50. package/src/components/Charts/DashboardDonutChart/types.ts +2 -0
  51. package/src/components/Charts/IconRadialChart/IconRadialChart.tsx +3 -0
  52. package/src/components/Charts/LineChart/LineChart.scss +13 -4
  53. package/src/components/Charts/LineChart/LineChart.stories.tsx +100 -102
  54. package/src/components/Charts/LineChart/LineChart.tsx +143 -131
  55. package/src/components/Charts/MultiRadialChart/MultiRadialChart.scss +23 -2
  56. package/src/components/Charts/MultiRadialChart/MultiRadialChart.tsx +109 -24
  57. package/src/components/Charts/PieChart/PieChart.scss +5 -3
  58. package/src/components/Charts/PieChart/PieChart.tsx +1 -2
  59. package/src/components/Checkbox/Checkbox.tsx +1 -7
  60. package/src/components/DatePicker/DatePicker.scss +15 -1
  61. package/src/components/DragAndDrop/DragAndDropList.tsx +5 -4
  62. package/src/components/Excel/ExcelFile/ExcelFile.scss +1 -1
  63. package/src/components/Excel/ExcelFile/ExcelFile.tsx +34 -20
  64. package/src/components/Excel/ExcelFile/ExcelFileComponents/Spreadsheet.tsx +0 -1
  65. package/src/components/Excel/ExcelFile/ExcelFileComponents/reducerFunctions.ts +44 -15
  66. package/src/components/Excel/ExcelToolBar/ExcelToolBar.tsx +47 -4
  67. package/src/components/FieldSet/FieldSet.scss +9 -0
  68. package/src/components/FieldSet/FieldSet.stories.tsx +103 -0
  69. package/src/components/FieldSet/FieldSet.tsx +29 -0
  70. package/src/components/FieldSet/index.ts +1 -0
  71. package/src/components/FieldSet/types.ts +8 -0
  72. package/src/components/FileDropzone/FileDropzone.scss +1 -1
  73. package/src/components/FileDropzone/FileDropzone.stories.tsx +15 -3
  74. package/src/components/FileDropzone/FileDropzone.tsx +5 -0
  75. package/src/components/FileDropzone/FilePreview.tsx +1 -1
  76. package/src/components/FileDropzone/types.ts +8 -0
  77. package/src/components/Icon/Icons.scss +1 -1
  78. package/src/components/Icon/iconList.ts +11 -7
  79. package/src/components/MachineInputField/MachineInputField.scss +15 -2
  80. package/src/components/MachineInputField/MachineInputField.tsx +17 -3
  81. package/src/components/MachineInputField/types.ts +1 -1
  82. package/src/components/MultiSelect/Dropdown.tsx +7 -3
  83. package/src/components/MultiSelect/MultiSelect.stories.tsx +6 -1
  84. package/src/components/MultiSelect/MultiSelect.tsx +4 -20
  85. package/src/components/MultiSelect/MultiSelectTypes.ts +2 -0
  86. package/src/components/PopUpModal/PopUpModal.scss +36 -0
  87. package/src/components/PopUpModal/PopUpModal.stories.tsx +61 -0
  88. package/src/components/PopUpModal/PopUpModal.tsx +85 -0
  89. package/src/components/PopUpModal/types.ts +14 -0
  90. package/src/components/RadioGroup/RadioGroup.scss +7 -0
  91. package/src/components/RadioGroup/RadioGroup.stories.tsx +26 -0
  92. package/src/components/RadioGroup/RadioGroup.tsx +16 -0
  93. package/src/components/RadioGroup/radioGroupTypes.tsx +24 -0
  94. package/src/components/Select/Select.tsx +3 -4
  95. package/src/components/Select/components/Dropdown.tsx +34 -34
  96. package/src/components/SequentialConnectingBranch/SequentialConnectingBranch.scss +9 -0
  97. package/src/components/SequentialConnectingBranch/SequentialConnectingBranch.tsx +74 -43
  98. package/src/components/SequentialConnectingBranch/components/Branches/Branches.scss +9 -3
  99. package/src/components/SequentialConnectingBranch/components/Branches/Branches.tsx +45 -14
  100. package/src/components/SequentialConnectingBranch/components/Branches/types.ts +9 -2
  101. package/src/components/SequentialConnectingBranch/components/ConnectingBranches/ConnectingBranches.tsx +3 -1
  102. package/src/components/SequentialConnectingBranch/components/ConnectingBranches/types.ts +9 -2
  103. package/src/components/SequentialConnectingBranch/types.ts +18 -3
  104. package/src/components/TableTree/TableTree.scss +154 -123
  105. package/src/components/TableTree/TableTree.stories.tsx +148 -96
  106. package/src/components/TableTree/TableTree.tsx +250 -282
  107. package/src/components/TableTree/data.ts +318 -569
  108. package/src/components/TableTree/types.ts +30 -0
  109. package/src/components/Toast/Toast.tsx +1 -1
  110. package/src/index.ts +11 -0
@@ -2,6 +2,7 @@ import React, { useState } from 'react';
2
2
  import { MultiRadialChartProps, ChartItem, LegendType } from './types';
3
3
  import './MultiRadialChart.scss';
4
4
  import Typography from '../../Typography';
5
+ import { truncateText } from '../../../utils/truncateText/truncateText';
5
6
 
6
7
  const calculateArc = (
7
8
  centerX: number,
@@ -30,7 +31,17 @@ const MultiRadialChart: React.FC<MultiRadialChartProps> = ({
30
31
  legendType = 'numberLegend',
31
32
  isLegendDetails = true,
32
33
  }) => {
33
- const [hoveredIndex, setHoveredIndex] = useState<number | null>(null);
34
+ const [tooltip, setTooltip] = useState<{
35
+ visible: boolean;
36
+ x: number;
37
+ y: number;
38
+ content: string;
39
+ }>({
40
+ visible: false,
41
+ x: 0,
42
+ y: 0,
43
+ content: '',
44
+ });
34
45
 
35
46
  const totalBarValue = barValues.reduce(
36
47
  (acc, status) => acc + status.value,
@@ -59,7 +70,11 @@ const MultiRadialChart: React.FC<MultiRadialChartProps> = ({
59
70
  >
60
71
  {item.value}
61
72
  </Typography>
62
- <Typography fontSize={10} className="ff-legend-key">
73
+ <Typography
74
+ fontSize={10}
75
+ className="ff-legend-key"
76
+ color=" var(--text-color)"
77
+ >
63
78
  {item.label}
64
79
  </Typography>
65
80
  </div>
@@ -80,7 +95,12 @@ const MultiRadialChart: React.FC<MultiRadialChartProps> = ({
80
95
  >
81
96
  <Typography fontSize={10}>{item.value}</Typography>
82
97
  </span>
83
- <Typography className="ff-legend-key">{item.label}</Typography>
98
+ <Typography
99
+ className="ff-legend-key"
100
+ color=" var(--text-color)"
101
+ >
102
+ {item.label}
103
+ </Typography>
84
104
  </div>
85
105
  ))}
86
106
  </div>
@@ -91,6 +111,38 @@ const MultiRadialChart: React.FC<MultiRadialChartProps> = ({
91
111
  }
92
112
  };
93
113
 
114
+ const handleMouseEnter = (e: React.MouseEvent, content: string) => {
115
+ const { clientX, clientY } = e;
116
+ setTooltip({
117
+ visible: true,
118
+ x: clientX,
119
+ y: clientY,
120
+ content: content,
121
+ });
122
+ };
123
+
124
+ const handleMouseMove = (e: React.MouseEvent) => {
125
+ const { clientX, clientY } = e;
126
+ setTooltip((prev) => ({
127
+ ...prev,
128
+ x: clientX,
129
+ y: clientY,
130
+ }));
131
+ };
132
+
133
+ const handleMouseLeave = () => {
134
+ setTooltip({ visible: false, x: 0, y: 0, content: '' });
135
+ };
136
+
137
+ const textData = (text: string, maxLength: number) => {
138
+ return text.length > maxLength ? text.slice(0, maxLength) + '...' : text;
139
+ };
140
+ const getArcColorFromTooltip = () => {
141
+ if (!tooltip.visible) return '';
142
+ const value = tooltip.content.split(':')[1]?.trim();
143
+ const matchingBar = barValues.find((val) => `${val.value}` === value);
144
+ return matchingBar?.arcColor || '';
145
+ };
94
146
  return (
95
147
  <div
96
148
  className={`ff-multi-radial-chart-container ${
@@ -148,8 +200,14 @@ const MultiRadialChart: React.FC<MultiRadialChartProps> = ({
148
200
  stroke={values.arcColor}
149
201
  strokeWidth={lineWidth}
150
202
  strokeLinecap={lineCap === 'square' ? 'butt' : 'round'}
151
- onMouseEnter={() => setHoveredIndex(originalIndex)}
152
- onMouseLeave={() => setHoveredIndex(null)}
203
+ onMouseEnter={(e) =>
204
+ handleMouseEnter(
205
+ e,
206
+ `${values.barLabel || 'Data'}: ${values.value}`
207
+ )
208
+ }
209
+ onMouseMove={handleMouseMove}
210
+ onMouseLeave={handleMouseLeave}
153
211
  style={{
154
212
  pointerEvents: 'stroke',
155
213
  }}
@@ -160,42 +218,69 @@ const MultiRadialChart: React.FC<MultiRadialChartProps> = ({
160
218
  <text
161
219
  x="0"
162
220
  y="-20"
163
- fill={
164
- hoveredIndex !== null ? barValues[hoveredIndex]?.arcColor : ''
165
- }
221
+ fill={getArcColorFromTooltip()}
166
222
  textAnchor="middle"
167
223
  dominantBaseline="central"
168
224
  >
169
- {hoveredIndex !== null ? (
225
+ {tooltip.visible ? (
170
226
  <>
171
- <tspan x="0" dy={0} className="ff-center-text">
172
- {barValues[hoveredIndex]?.value}
227
+ <tspan x="0" dy={10} className="ff-center-text-tooltip">
228
+ {textData(tooltip.content.split(':')[1]?.trim() || '', 5)}
173
229
  </tspan>
174
- <tspan x="0" dy={18} className="ff-center-text">
175
- {barValues[hoveredIndex]?.barLabel}
230
+ <tspan x="0" dy={18} className="ff-center-text-tooltip">
231
+ {textData(tooltip.content.split(':')[0] ?? '', 8)}
176
232
  </tspan>
177
233
  </>
178
234
  ) : (
179
- labelLines.map((line, index) => (
180
- <tspan
181
- key={index}
182
- x="0"
183
- dy={index === 0 ? 0 : 18}
184
- className="ff-center-text"
185
- >
186
- {line}
187
- </tspan>
188
- ))
235
+ <>
236
+ {labelLines.map((line, index) => {
237
+ if (index === 0) {
238
+ const [firstWord, ...restWords] = line.split(' ');
239
+ return (
240
+ <tspan key={index}>
241
+ <tspan x="0" dy="0" className="ff-center-first-text">
242
+ {firstWord}
243
+ </tspan>
244
+ <tspan x="0" dy={18} className="ff-center-text">
245
+ {restWords.join(' ')}
246
+ </tspan>
247
+ </tspan>
248
+ );
249
+ }
250
+ return (
251
+ <tspan
252
+ key={index}
253
+ x="0"
254
+ dy={index === 0 ? 0 : 18}
255
+ className="ff-center-text"
256
+ >
257
+ {line}
258
+ </tspan>
259
+ );
260
+ })}
261
+ </>
189
262
  )}
190
263
  </text>
191
264
  </g>
192
265
  </svg>
266
+ {tooltip.visible && (
267
+ <div
268
+ className="ff-multi-radial-tooltip"
269
+ style={{
270
+ top: tooltip.y + 10,
271
+ left: tooltip.x + 10,
272
+ zIndex: 1000,
273
+ }}
274
+ >
275
+ {tooltip.content}
276
+ </div>
277
+ )}
193
278
  </div>
194
279
  {isLegendDetails &&
195
280
  renderLegend(
196
281
  barValues.map((value) => ({
197
282
  ...value,
198
- label: value.barLabel || '',
283
+ label: truncateText(value?.barLabel, 8),
199
284
  key: value.value.toString(),
200
285
  })),
201
286
  legendType
@@ -1,3 +1,4 @@
1
+ @use '../../../assets/styles/fonts';
1
2
  .ff-pie-chart-container {
2
3
  display: flex;
3
4
  flex-direction: column;
@@ -18,11 +19,9 @@
18
19
  border-radius: 4px;
19
20
  background-color: var(--tooltip-bg-color);
20
21
  color: var(--primary-icon-color);
21
- border: 10px solid;
22
- font-size: 14px;
22
+ @extend .fontSm;
23
23
  font-weight: 400;
24
24
  pointer-events: none;
25
- opacity: 0.8;
26
25
  }
27
26
 
28
27
  .ff-pie-chart-legend {
@@ -35,5 +34,8 @@
35
34
  align-items: center;
36
35
  text-align: center;
37
36
  }
37
+ .ff-pie-chart-legend-value {
38
+ color: var(--drawer-title-color);
39
+ }
38
40
  }
39
41
  }
@@ -119,7 +119,7 @@ const PieChart: React.FC<PieChartProps> = ({
119
119
  fontSize={10}
120
120
  fontWeight="regular"
121
121
  lineHeight="18px"
122
- className="ff-Pie-chart-legend-value"
122
+ className="ff-pie-chart-legend-value"
123
123
  >
124
124
  {item.label}
125
125
  </Typography>
@@ -178,7 +178,6 @@ const PieChart: React.FC<PieChartProps> = ({
178
178
  style={{
179
179
  top: tooltipPosition.y,
180
180
  left: tooltipPosition.x,
181
- border: `2px solid ${tooltip.color}`,
182
181
  }}
183
182
  >
184
183
  {tooltip.label} : {tooltip.value}
@@ -21,12 +21,6 @@ const Checkbox: React.FC<CheckboxProps> = ({
21
21
  setChecked(initialChecked);
22
22
  }, [initialChecked]);
23
23
 
24
- const handleCheckboxChange = (event: React.ChangeEvent<HTMLInputElement>) => {
25
- if (!disabled) {
26
- setChecked((prev) => !prev), onChange?.(event);
27
- }
28
- };
29
-
30
24
  return (
31
25
  <label className="ff-checkbox--overlay" htmlFor={id}>
32
26
  <input
@@ -35,7 +29,7 @@ const Checkbox: React.FC<CheckboxProps> = ({
35
29
  id={id}
36
30
  name={name}
37
31
  checked={checked}
38
- onChange={handleCheckboxChange}
32
+ onChange={onChange}
39
33
  disabled={disabled}
40
34
  />
41
35
  <span
@@ -118,7 +118,7 @@
118
118
  margin: 0 5px;
119
119
  border: 1px solid var(--border-color);
120
120
  background-color: var(--toggle-button-bg-color);
121
- box-shadow: 0 -2px 2px 0 var(--ff-mini-modal-box-shadow);
121
+ box-shadow: 0 -1px 2px 0 var(--ff-mini-modal-box-shadow);
122
122
  padding: 0px;
123
123
  border-radius: 30%;
124
124
  cursor: pointer;
@@ -231,6 +231,7 @@
231
231
  width: 100%;
232
232
  text-align: center;
233
233
  border-radius: 4px 0 0 4px;
234
+ font-weight: 400;
234
235
  @extend .fontSm;
235
236
 
236
237
  &::placeholder {
@@ -325,10 +326,23 @@
325
326
  }
326
327
 
327
328
  .ff-time-period-icon {
329
+ svg {
330
+ path {
331
+ fill: var(--default-icon-color);
332
+ }
333
+ }
328
334
  margin-left: auto;
329
335
  pointer-events: none;
330
336
  }
331
337
 
338
+ &:hover {
339
+ svg {
340
+ path {
341
+ fill: var(--brand-color);
342
+ }
343
+ }
344
+ }
345
+
332
346
  .ff-time-period-options {
333
347
  position: fixed;
334
348
  z-index: 100;
@@ -21,6 +21,7 @@ const {
21
21
  import Typography from '../Typography';
22
22
 
23
23
  import './DragAndDropList.scss';
24
+ import { DragEndEvent } from '@dnd-kit/core';
24
25
 
25
26
  interface TaskProps {
26
27
  id: number;
@@ -117,14 +118,14 @@ const DragAndDropList = () => {
117
118
  const getTaskPos = (id: number): number =>
118
119
  tasks.findIndex((task) => task.id === id);
119
120
 
120
- const handleDragEnd = (event: any) => {
121
+ const handleDragEnd = (event: DragEndEvent) => {
121
122
  const { active, over } = event;
122
123
 
123
- if (active.id === over.id) return;
124
+ if (active.id === over?.id) return;
124
125
 
125
126
  setTasks((tasks) => {
126
- const originalPos = getTaskPos(active.id);
127
- const newPos = getTaskPos(over.id);
127
+ const originalPos = getTaskPos(Number(active?.id));
128
+ const newPos = getTaskPos(Number(over?.id));
128
129
 
129
130
  return arrayMove(tasks, originalPos, newPos);
130
131
  });
@@ -18,7 +18,7 @@
18
18
  // }
19
19
 
20
20
  .ff-excel-sheet-bar {
21
- margin-left: 83px;
21
+ margin-left: 60px;
22
22
  display: flex;
23
23
  height: 36px;
24
24
  align-items: center;
@@ -34,9 +34,7 @@ interface ExcelFileProps {
34
34
 
35
35
  const ExcelFile: React.FC<ExcelFileProps> = ({
36
36
  excelData,
37
- onSave = (saveData) => {
38
- saveData();
39
- },
37
+ onSave = (saveData) => {saveData()},
40
38
  }) => {
41
39
  const [sheetNames, setSheetNames] = useState<string[]>([]);
42
40
  const [contextMenu, setContextMenu] = React.useState<ContextMenuState>({
@@ -51,6 +49,8 @@ const ExcelFile: React.FC<ExcelFileProps> = ({
51
49
  color: 'var(--text-color)',
52
50
  backgroundColor: 'var(--drawer-footer-bg)',
53
51
  borderColor: 'var(--toggle-strip-color)',
52
+ textDecoration: 'none',
53
+ textDecorationStyle: 'solid',
54
54
  },
55
55
  };
56
56
 
@@ -128,7 +128,7 @@ const ExcelFile: React.FC<ExcelFileProps> = ({
128
128
  }
129
129
  spreadsheetData[rowIndex][colIndex] = {
130
130
  value: checkVal(cell.value),
131
- style: convertStyleToFrontend(cell?.style),
131
+ style: convertStyleToFrontend(cell?.style) ,
132
132
  type: true,
133
133
  };
134
134
  }
@@ -143,6 +143,23 @@ const ExcelFile: React.FC<ExcelFileProps> = ({
143
143
  setSelectedSheetData(newWorksheetsData[firstSheetName]);
144
144
  }
145
145
  }, []);
146
+ const handleSave = React.useCallback(
147
+ (event: KeyboardEvent) => {
148
+ if (event.ctrlKey && event.key === 's') {
149
+ event.preventDefault();
150
+ event.stopPropagation();
151
+ onSaveWorksheetData();
152
+ }
153
+ },
154
+ [onSave]
155
+ );
156
+
157
+ React.useEffect(() => {
158
+ document.addEventListener('keydown', handleSave);
159
+ return () => {
160
+ document.removeEventListener('keydown', handleSave);
161
+ };
162
+ }, [handleSave]);
146
163
 
147
164
  const onSaveWorksheetData = () => {
148
165
  const savedData = {
@@ -159,21 +176,18 @@ const ExcelFile: React.FC<ExcelFileProps> = ({
159
176
  }, -1);
160
177
 
161
178
  const filteredRow = row
162
- .map((cell, index) => {
163
- if (cell && cell.value !== null) {
164
- return {
165
- value: cell.value,
166
- styles: convertStyleToBackend(cell.style ?? {}),
167
- };
168
- } else if ((cell && cell.type) || index <= lastIndex) {
169
- return {
170
- value: '',
171
- styles: convertStyleToBackend(cell?.style ?? {}),
172
- };
173
- }
174
- return null;
175
- })
176
- .filter((cell) => cell !== null);
179
+ .map((cell, index) => {
180
+ if (cell && cell.value !== null) {
181
+ return {
182
+ value: cell.value,
183
+ styles: convertStyleToBackend(cell.style ?? {}),
184
+ };
185
+ } else if (cell && cell.type || index <= lastIndex) {
186
+ return { value: '', styles: convertStyleToBackend(cell?.style ?? {}) };
187
+ }
188
+ return null;
189
+ })
190
+ .filter((cell) => cell !== null);
177
191
 
178
192
  return filteredRow.length > 0 ? filteredRow : [];
179
193
  }) || [];
@@ -194,7 +208,7 @@ const ExcelFile: React.FC<ExcelFileProps> = ({
194
208
  onSave(savedData);
195
209
  toast.success('File saved successfully!');
196
210
  };
197
-
211
+
198
212
  const onEvaluateChange = (data: Matrix.Matrix<CellBase>) => {
199
213
  setWorksheetsData((prev) => ({ ...prev, [pageRef.current]: data }));
200
214
  onSaveWorksheetData();
@@ -444,7 +444,6 @@ const Spreadsheet = <CellType extends Types.CellBase>(
444
444
  () => (
445
445
  <div className="ff-excel">
446
446
  <ExcelToolBar
447
- data={props.data}
448
447
  onBold={onBold}
449
448
  onItalic={onItalic}
450
449
  setUnderlineType={setUnderlineType}
@@ -12,7 +12,7 @@ import {
12
12
 
13
13
  export function applyBoldToCells(
14
14
  currentData: Matrix.Matrix<Types.CellBase<any>>,
15
- selectedRange: PointRange
15
+ selectedRange: PointRange,
16
16
  ): Matrix.Matrix<Types.CellBase<any>> {
17
17
  if (!selectedRange) {
18
18
  return currentData;
@@ -21,24 +21,33 @@ export function applyBoldToCells(
21
21
  const { start, end } = selectedRange;
22
22
 
23
23
  let updatedData = currentData;
24
+ let anyBold = false;
24
25
 
25
26
  for (let row = start.row; row <= end.row; row++) {
26
27
  for (let col = start.column; col <= end.column; col++) {
27
28
  const currentCell = Matrix.get({ row, column: col }, updatedData);
29
+ if (!currentCell) continue;
28
30
 
29
- if (!currentCell) {
30
- continue;
31
+ if (currentCell.style?.fontWeight === 'bold') {
32
+ anyBold = true;
33
+ break;
31
34
  }
35
+ }
36
+ if (anyBold) break;
37
+ }
38
+
39
+ for (let row = start.row; row <= end.row; row++) {
40
+ for (let col = start.column; col <= end.column; col++) {
41
+ const currentCell = Matrix.get({ row, column: col }, updatedData);
42
+ if (!currentCell) continue;
32
43
 
33
44
  const updatedCell = {
34
45
  ...currentCell,
35
46
  style: {
36
47
  ...currentCell.style,
37
- fontWeight:
38
- currentCell.style?.fontWeight !== 'bold' ? 'bold' : 'normal',
48
+ fontWeight: anyBold ? 'normal' : 'bold',
39
49
  },
40
50
  };
41
-
42
51
  updatedData = Matrix.set({ row, column: col }, updatedCell, updatedData);
43
52
  }
44
53
  }
@@ -57,24 +66,33 @@ export function applyItalicToCells(
57
66
  const { start, end } = selectedRange;
58
67
 
59
68
  let updatedData = currentData;
69
+ let anyItalic = false;
60
70
 
61
71
  for (let row = start.row; row <= end.row; row++) {
62
72
  for (let col = start.column; col <= end.column; col++) {
63
73
  const currentCell = Matrix.get({ row, column: col }, updatedData);
74
+ if (!currentCell) continue;
64
75
 
65
- if (!currentCell) {
66
- continue;
76
+ if (currentCell.style?.fontStyle === 'italic') {
77
+ anyItalic = true;
78
+ break;
67
79
  }
80
+ }
81
+ if (anyItalic) break;
82
+ }
83
+
84
+ for (let row = start.row; row <= end.row; row++) {
85
+ for (let col = start.column; col <= end.column; col++) {
86
+ const currentCell = Matrix.get({ row, column: col }, updatedData);
87
+ if (!currentCell) continue;
68
88
 
69
89
  const updatedCell = {
70
90
  ...currentCell,
71
91
  style: {
72
92
  ...currentCell.style,
73
- fontStyle:
74
- currentCell.style?.fontStyle !== 'italic' ? 'italic' : 'normal',
93
+ fontStyle: anyItalic ? 'normal' : 'italic',
75
94
  },
76
95
  };
77
-
78
96
  updatedData = Matrix.set({ row, column: col }, updatedCell, updatedData);
79
97
  }
80
98
  }
@@ -289,23 +307,34 @@ export function applyUnderlineToCells(
289
307
  const { start, end } = selectedRange;
290
308
 
291
309
  let updatedData = currentData;
310
+ let anyUnderlined = false;
292
311
 
293
312
  for (let row = start.row; row <= end.row; row++) {
294
313
  for (let col = start.column; col <= end.column; col++) {
295
314
  const currentCell = Matrix.get({ row, column: col }, updatedData);
315
+ if (!currentCell) continue;
296
316
 
297
- if (!currentCell) {
298
- continue;
317
+ if (currentCell.style?.textDecoration === 'underline') {
318
+ anyUnderlined = true;
319
+ break;
299
320
  }
321
+ }
322
+ if (anyUnderlined) break;
323
+ }
324
+
325
+ for (let row = start.row; row <= end.row; row++) {
326
+ for (let col = start.column; col <= end.column; col++) {
327
+ const currentCell = Matrix.get({ row, column: col }, updatedData);
328
+ if (!currentCell) continue;
300
329
 
301
330
  let updatedCell;
302
- if (!active) {
331
+ if (!active || anyUnderlined) {
303
332
  updatedCell = {
304
333
  ...currentCell,
305
334
  style: {
306
335
  ...currentCell.style,
307
336
  textDecoration: 'none',
308
- textDecorationStyle: 'none' as TextDecorationStyle,
337
+ textDecorationStyle: 'solid' as TextDecorationStyle,
309
338
  },
310
339
  };
311
340
  } else {