@alfalab/core-components-circular-progress-bar 3.6.8 → 3.7.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 (104) hide show
  1. package/@alfalab/core-components-shared/package.json +26 -0
  2. package/Component.d.ts +36 -5
  3. package/Component.js +42 -7
  4. package/consts.d.ts +9 -1
  5. package/consts.js +11 -0
  6. package/cssm/Component.d.ts +36 -5
  7. package/cssm/Component.js +41 -6
  8. package/cssm/consts.d.ts +9 -1
  9. package/cssm/consts.js +11 -0
  10. package/cssm/index.d.ts +1 -0
  11. package/cssm/index.module.css +10 -0
  12. package/cssm/shared/index.d.ts +1 -0
  13. package/cssm/shared/index.js +9 -0
  14. package/cssm/types/component-size.d.ts +2 -0
  15. package/cssm/types/component-size.js +2 -0
  16. package/cssm/types/typography-color.d.ts +2 -0
  17. package/cssm/types/typography-color.js +2 -0
  18. package/cssm/use-timer.d.ts +2 -0
  19. package/cssm/use-timer.js +31 -0
  20. package/cssm/utils/get-circular-progress-bar-test-ids.d.ts +8 -0
  21. package/cssm/utils/get-circular-progress-bar-test-ids.js +17 -0
  22. package/cssm/utils/is-typography-color.d.ts +3 -0
  23. package/cssm/utils/is-typography-color.js +11 -0
  24. package/esm/Component.d.ts +36 -5
  25. package/esm/Component.js +43 -8
  26. package/esm/consts.d.ts +9 -1
  27. package/esm/consts.js +9 -1
  28. package/esm/index.css +59 -49
  29. package/esm/index.d.ts +1 -0
  30. package/esm/shared/index.d.ts +1 -0
  31. package/esm/shared/index.js +1 -0
  32. package/esm/types/component-size.d.ts +2 -0
  33. package/esm/types/component-size.js +1 -0
  34. package/esm/types/typography-color.d.ts +2 -0
  35. package/esm/types/typography-color.js +1 -0
  36. package/esm/use-timer.d.ts +2 -0
  37. package/esm/use-timer.js +27 -0
  38. package/esm/utils/get-circular-progress-bar-test-ids.d.ts +8 -0
  39. package/esm/utils/get-circular-progress-bar-test-ids.js +13 -0
  40. package/esm/utils/is-typography-color.d.ts +3 -0
  41. package/esm/utils/is-typography-color.js +7 -0
  42. package/index.css +59 -49
  43. package/index.d.ts +1 -0
  44. package/modern/Component.d.ts +36 -5
  45. package/modern/Component.js +49 -12
  46. package/modern/consts.d.ts +9 -1
  47. package/modern/consts.js +9 -1
  48. package/modern/index.css +59 -49
  49. package/modern/index.d.ts +1 -0
  50. package/modern/shared/index.d.ts +1 -0
  51. package/modern/shared/index.js +1 -0
  52. package/modern/types/component-size.d.ts +2 -0
  53. package/modern/types/component-size.js +1 -0
  54. package/modern/types/typography-color.d.ts +2 -0
  55. package/modern/types/typography-color.js +1 -0
  56. package/modern/use-timer.d.ts +2 -0
  57. package/modern/use-timer.js +24 -0
  58. package/modern/utils/get-circular-progress-bar-test-ids.d.ts +8 -0
  59. package/modern/utils/get-circular-progress-bar-test-ids.js +13 -0
  60. package/modern/utils/is-typography-color.d.ts +3 -0
  61. package/modern/utils/is-typography-color.js +5 -0
  62. package/moderncssm/Component.d.ts +36 -5
  63. package/moderncssm/Component.js +48 -11
  64. package/moderncssm/consts.d.ts +9 -1
  65. package/moderncssm/consts.js +9 -1
  66. package/moderncssm/index.d.ts +1 -0
  67. package/moderncssm/index.module.css +18 -0
  68. package/moderncssm/shared/index.d.ts +1 -0
  69. package/moderncssm/shared/index.js +1 -0
  70. package/moderncssm/types/component-size.d.ts +2 -0
  71. package/moderncssm/types/component-size.js +1 -0
  72. package/moderncssm/types/typography-color.d.ts +2 -0
  73. package/moderncssm/types/typography-color.js +1 -0
  74. package/moderncssm/use-timer.d.ts +2 -0
  75. package/moderncssm/use-timer.js +24 -0
  76. package/moderncssm/utils/get-circular-progress-bar-test-ids.d.ts +8 -0
  77. package/moderncssm/utils/get-circular-progress-bar-test-ids.js +13 -0
  78. package/moderncssm/utils/is-typography-color.d.ts +3 -0
  79. package/moderncssm/utils/is-typography-color.js +5 -0
  80. package/package.json +3 -2
  81. package/shared/index.d.ts +1 -0
  82. package/shared/index.js +9 -0
  83. package/shared/package.json +3 -0
  84. package/src/Component.tsx +111 -14
  85. package/src/consts.ts +10 -0
  86. package/src/index.module.css +18 -0
  87. package/src/index.ts +1 -0
  88. package/src/shared/index.ts +1 -0
  89. package/src/shared/package.json +3 -0
  90. package/src/types/component-size.ts +1 -0
  91. package/src/types/typography-color.ts +1 -0
  92. package/src/use-timer.ts +35 -0
  93. package/src/utils/get-circular-progress-bar-test-ids.ts +11 -0
  94. package/src/utils/is-typography-color.ts +5 -0
  95. package/types/component-size.d.ts +2 -0
  96. package/types/component-size.js +2 -0
  97. package/types/typography-color.d.ts +2 -0
  98. package/types/typography-color.js +2 -0
  99. package/use-timer.d.ts +2 -0
  100. package/use-timer.js +31 -0
  101. package/utils/get-circular-progress-bar-test-ids.d.ts +8 -0
  102. package/utils/get-circular-progress-bar-test-ids.js +17 -0
  103. package/utils/is-typography-color.d.ts +3 -0
  104. package/utils/is-typography-color.js +11 -0
package/modern/index.css CHANGED
@@ -1,4 +1,4 @@
1
- /* hash: 11ahd */
1
+ /* hash: 14q8x */
2
2
  :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */
3
3
  } /* deprecated */ :root {
4
4
  --color-light-neutral-500: #babbc2;
@@ -45,135 +45,145 @@
45
45
  /* theme */
46
46
  --circular-progress-bar-font-family: var(--font-family-system);
47
47
  --circular-progress-bar-font-weight: 600;
48
- } .circular-progress-bar__component_1bxdv {
48
+ } .circular-progress-bar__component_1cf8i {
49
49
  position: relative;
50
50
  display: flex;
51
51
  justify-content: center;
52
52
  align-items: center;
53
53
  border-radius: var(--border-radius-pill)
54
- } .circular-progress-bar__component_1bxdv.circular-progress-bar__bg-positive_1bxdv {
54
+ } .circular-progress-bar__component_1cf8i.circular-progress-bar__bg-positive_1cf8i {
55
55
  background: var(--circular-progress-bar-positive-color);
56
- } .circular-progress-bar__component_1bxdv.circular-progress-bar__bg-negative_1bxdv {
56
+ } .circular-progress-bar__component_1cf8i.circular-progress-bar__bg-negative_1cf8i {
57
57
  background: var(--circular-progress-bar-negative-color);
58
- } .circular-progress-bar__svg_1bxdv {
58
+ } .circular-progress-bar__svg_1cf8i {
59
59
  display: block;
60
60
  width: 100%;
61
- } .circular-progress-bar__title_1bxdv,
62
- .circular-progress-bar__subtitle_1bxdv {
61
+ } .circular-progress-bar__title_1cf8i,
62
+ .circular-progress-bar__subtitle_1cf8i {
63
63
  overflow: hidden;
64
64
  word-break: break-word;
65
65
  white-space: nowrap;
66
66
  text-overflow: ellipsis;
67
67
  margin: var(--gap-0) 6px;
68
- } .circular-progress-bar__subtitle_1bxdv {
68
+ } .circular-progress-bar__subtitle_1cf8i {
69
69
  max-height: 40px;
70
- } .circular-progress-bar__labelWrapper_1bxdv {
70
+ } .circular-progress-bar__labelWrapper_1cf8i {
71
71
  text-align: center;
72
72
  position: absolute;
73
73
  top: 50%;
74
74
  left: 50%;
75
75
  width: 100%;
76
76
  transform: translate(-50%, -50%)
77
- } .circular-progress-bar__labelWrapper_1bxdv.circular-progress-bar__label_1bxdv {
77
+ } .circular-progress-bar__labelWrapper_1cf8i.circular-progress-bar__label_1cf8i {
78
78
  display: flex;
79
79
  align-items: center;
80
80
  justify-content: center;
81
- } .circular-progress-bar__typography_1bxdv {
81
+ } .circular-progress-bar__typography_1cf8i {
82
82
  font-feature-settings: 'ss01';
83
83
  font-weight: var(--circular-progress-bar-font-weight);
84
84
  font-family: var(--circular-progress-bar-font-family);
85
- } .circular-progress-bar__size-144_1bxdv {
85
+ } .circular-progress-bar__size-144_1cf8i {
86
86
  width: 144px;
87
87
  height: 144px
88
- } .circular-progress-bar__size-144_1bxdv .circular-progress-bar__labelWrapper_1bxdv {
88
+ } .circular-progress-bar__size-144_1cf8i .circular-progress-bar__labelWrapper_1cf8i {
89
89
  max-width: 128px;
90
- } .circular-progress-bar__size-144_1bxdv .circular-progress-bar__title_1bxdv {
90
+ } .circular-progress-bar__size-144_1cf8i .circular-progress-bar__title_1cf8i {
91
91
  max-height: 32px;
92
- } .circular-progress-bar__size-128_1bxdv {
92
+ } .circular-progress-bar__size-128_1cf8i {
93
93
  width: 128px;
94
94
  height: 128px
95
- } .circular-progress-bar__size-128_1bxdv .circular-progress-bar__labelWrapper_1bxdv {
95
+ } .circular-progress-bar__size-128_1cf8i .circular-progress-bar__labelWrapper_1cf8i {
96
96
  max-width: 108px;
97
- } .circular-progress-bar__size-128_1bxdv .circular-progress-bar__title_1bxdv {
97
+ } .circular-progress-bar__size-128_1cf8i .circular-progress-bar__title_1cf8i {
98
98
  max-height: 32px;
99
- } .circular-progress-bar__size-80_1bxdv {
99
+ } .circular-progress-bar__size-96_1cf8i {
100
+ width: 96px;
101
+ height: 96px
102
+ } .circular-progress-bar__size-96_1cf8i .circular-progress-bar__labelWrapper_1cf8i {
103
+ max-width: 64px;
104
+ } .circular-progress-bar__size-96_1cf8i .circular-progress-bar__title_1cf8i {
105
+ max-height: 20px;
106
+ } .circular-progress-bar__size-80_1cf8i {
100
107
  width: 80px;
101
108
  height: 80px
102
- } .circular-progress-bar__size-80_1bxdv .circular-progress-bar__labelWrapper_1bxdv {
109
+ } .circular-progress-bar__size-80_1cf8i .circular-progress-bar__labelWrapper_1cf8i {
103
110
  max-width: 64px;
104
- } .circular-progress-bar__size-80_1bxdv .circular-progress-bar__title_1bxdv {
111
+ } .circular-progress-bar__size-80_1cf8i .circular-progress-bar__title_1cf8i {
105
112
  max-height: 24px;
106
- } .circular-progress-bar__size-64_1bxdv {
113
+ } .circular-progress-bar__size-64_1cf8i {
107
114
  width: 64px;
108
115
  height: 64px
109
- } .circular-progress-bar__size-64_1bxdv .circular-progress-bar__labelWrapper_1bxdv {
116
+ } .circular-progress-bar__size-64_1cf8i .circular-progress-bar__labelWrapper_1cf8i {
110
117
  max-width: 48px;
111
- } .circular-progress-bar__size-64_1bxdv .circular-progress-bar__title_1bxdv {
118
+ } .circular-progress-bar__size-64_1cf8i .circular-progress-bar__title_1cf8i {
112
119
  max-height: 16px;
113
120
  margin: var(--gap-0);
114
- } .circular-progress-bar__size-48_1bxdv {
121
+ } .circular-progress-bar__size-48_1cf8i {
115
122
  width: 48px;
116
123
  height: 48px
117
- } .circular-progress-bar__size-48_1bxdv .circular-progress-bar__labelWrapper_1bxdv {
124
+ } .circular-progress-bar__size-48_1cf8i .circular-progress-bar__labelWrapper_1cf8i {
118
125
  max-width: 40px;
119
- } .circular-progress-bar__size-48_1bxdv .circular-progress-bar__title_1bxdv {
126
+ } .circular-progress-bar__size-48_1cf8i .circular-progress-bar__title_1cf8i {
120
127
  max-height: 16px;
121
128
  margin: var(--gap-0);
122
- } .circular-progress-bar__size-24_1bxdv {
129
+ } .circular-progress-bar__size-24_1cf8i {
123
130
  width: 24px;
124
131
  height: 24px
125
- } .circular-progress-bar__size-24_1bxdv .circular-progress-bar__labelWrapper_1bxdv {
132
+ } .circular-progress-bar__size-24_1cf8i .circular-progress-bar__labelWrapper_1cf8i {
126
133
  max-width: 24px;
127
- } .circular-progress-bar__backgroundCircle_1bxdv,
128
- .circular-progress-bar__progressCircle_1bxdv {
134
+ } .circular-progress-bar__backgroundCircle_1cf8i,
135
+ .circular-progress-bar__progressCircle_1cf8i {
129
136
  width: 100%;
130
137
  height: 100%;
131
138
  fill: transparent;
132
- } .circular-progress-bar__positive_1bxdv {
139
+ } .circular-progress-bar__positive_1cf8i {
133
140
  stroke: var(--circular-progress-bar-positive-color);
134
- } .circular-progress-bar__negative_1bxdv {
141
+ } .circular-progress-bar__negative_1cf8i {
135
142
  stroke: var(--circular-progress-bar-negative-color);
136
- } .circular-progress-bar__backgroundCircle_1bxdv {
143
+ } .circular-progress-bar__backgroundCircle_1cf8i {
137
144
  stroke: var(--circular-progress-bar-stroke-color)
138
- } .circular-progress-bar__backgroundCircle_1bxdv.circular-progress-bar__stroke_1bxdv {
145
+ } .circular-progress-bar__backgroundCircle_1cf8i.circular-progress-bar__stroke_1cf8i {
139
146
  stroke: transparent;
140
- } .circular-progress-bar__progressCircle_1bxdv {
147
+ } .circular-progress-bar__progressCircle_1cf8i {
141
148
  stroke-linecap: round;
142
- } .circular-progress-bar__iconWrapper_1bxdv {
149
+ } .circular-progress-bar__iconWrapper_1cf8i {
143
150
  display: flex;
144
151
  align-items: center;
145
152
  justify-content: center
146
- } .circular-progress-bar__iconWrapper_1bxdv.circular-progress-bar__size-144_1bxdv {
153
+ } .circular-progress-bar__iconWrapper_1cf8i.circular-progress-bar__size-144_1cf8i {
147
154
  max-width: 64px;
148
155
  max-height: 64px;
149
- } .circular-progress-bar__iconWrapper_1bxdv.circular-progress-bar__size-128_1bxdv {
156
+ } .circular-progress-bar__iconWrapper_1cf8i.circular-progress-bar__size-128_1cf8i {
150
157
  max-width: 64px;
151
158
  max-height: 64px;
152
- } .circular-progress-bar__iconWrapper_1bxdv.circular-progress-bar__size-80_1bxdv {
159
+ } .circular-progress-bar__iconWrapper_1cf8i.circular-progress-bar__size-96_1cf8i {
160
+ max-width: 48px;
161
+ max-height: 48px;
162
+ } .circular-progress-bar__iconWrapper_1cf8i.circular-progress-bar__size-80_1cf8i {
153
163
  max-width: 48px;
154
164
  max-height: 48px;
155
- } .circular-progress-bar__iconWrapper_1bxdv.circular-progress-bar__size-64_1bxdv {
165
+ } .circular-progress-bar__iconWrapper_1cf8i.circular-progress-bar__size-64_1cf8i {
156
166
  max-width: 36px;
157
167
  max-height: 36px;
158
- } .circular-progress-bar__iconWrapper_1bxdv.circular-progress-bar__size-48_1bxdv {
168
+ } .circular-progress-bar__iconWrapper_1cf8i.circular-progress-bar__size-48_1cf8i {
159
169
  max-width: 24px;
160
170
  max-height: 24px;
161
- } .circular-progress-bar__iconWrapper_1bxdv.circular-progress-bar__size-24_1bxdv {
171
+ } .circular-progress-bar__iconWrapper_1cf8i.circular-progress-bar__size-24_1cf8i {
162
172
  max-width: 16px;
163
173
  max-height: 16px;
164
- } .circular-progress-bar__iconWrapper_1bxdv.circular-progress-bar__icon-tertiary_1bxdv {
174
+ } .circular-progress-bar__iconWrapper_1cf8i.circular-progress-bar__icon-tertiary_1cf8i {
165
175
  color: var(--color-light-neutral-500);
166
- } .circular-progress-bar__iconWrapper_1bxdv.circular-progress-bar__icon-positive_1bxdv {
176
+ } .circular-progress-bar__iconWrapper_1cf8i.circular-progress-bar__icon-positive_1cf8i {
167
177
  color: var(--color-light-status-positive);
168
- } .circular-progress-bar__iconWrapper_1bxdv.circular-progress-bar__icon-negative_1bxdv {
178
+ } .circular-progress-bar__iconWrapper_1cf8i.circular-progress-bar__icon-negative_1cf8i {
169
179
  color: var(--color-light-status-negative);
170
- } .circular-progress-bar__iconWrapper_1bxdv.circular-progress-bar__icon-primary-inverted_1bxdv {
180
+ } .circular-progress-bar__iconWrapper_1cf8i.circular-progress-bar__icon-primary-inverted_1cf8i {
171
181
  color: var(--color-light-neutral-translucent-1300-inverted);
172
- } .circular-progress-bar__iconWrapper_1bxdv.circular-progress-bar__icon-primary_1bxdv {
182
+ } .circular-progress-bar__iconWrapper_1cf8i.circular-progress-bar__icon-primary_1cf8i {
173
183
  color: var(--color-light-neutral-translucent-1300);
174
- } .circular-progress-bar__iconWrapper_1bxdv.circular-progress-bar__icon-secondary_1bxdv {
184
+ } .circular-progress-bar__iconWrapper_1cf8i.circular-progress-bar__icon-secondary_1cf8i {
175
185
  color: var(--color-light-neutral-700);
176
- } .circular-progress-bar__icon_1bxdv {
186
+ } .circular-progress-bar__icon_1cf8i {
177
187
  width: 100%;
178
188
  height: 100%;
179
189
  }
package/modern/index.d.ts CHANGED
@@ -1 +1,2 @@
1
1
  export * from "./Component";
2
+ export * from "./types/typography-color";
@@ -0,0 +1 @@
1
+ export { getCircularProgressBarTestIds } from "../utils/get-circular-progress-bar-test-ids";
@@ -0,0 +1 @@
1
+ export { getCircularProgressBarTestIds } from '../utils/get-circular-progress-bar-test-ids.js';
@@ -0,0 +1,2 @@
1
+ type ComponentSize = 'xxl' | 'xl' | 'l' | 'm' | 's' | 'xs' | 24 | 48 | 64 | 80 | 128 | 144;
2
+ export { ComponentSize };
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,2 @@
1
+ type TypographyColor = 'primary' | 'secondary' | 'tertiary' | 'positive' | 'negative';
2
+ export { TypographyColor };
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,2 @@
1
+ declare function useTimer(time: number, active: boolean | undefined, counting: 'forward' | 'backward', interval?: number, step?: number): [value: number, title: string];
2
+ export { useTimer };
@@ -0,0 +1,24 @@
1
+ import { useState, useEffect } from 'react';
2
+ import { noop } from '@alfalab/core-components-shared/modern';
3
+
4
+ const MAX_PERSENT_VALUE = 100;
5
+ function makeTitle(time) {
6
+ return `${Math.trunc(time / 60)}:${`${time % 60}`.padStart(2, '0')}`;
7
+ }
8
+ function useTimer(time, active = true, counting, interval = 1000, step = 1) {
9
+ const [passedTime, setPassedTime] = useState(0);
10
+ const isCompleted = passedTime === time;
11
+ const persentValue = Math.trunc((passedTime / time) * MAX_PERSENT_VALUE);
12
+ useEffect(() => {
13
+ if (!active || isCompleted) {
14
+ return noop;
15
+ }
16
+ const timer = setInterval(() => {
17
+ setPassedTime((prevPassed) => prevPassed + step);
18
+ }, interval);
19
+ return () => clearInterval(timer);
20
+ }, [interval, isCompleted, active, step]);
21
+ return [persentValue, makeTitle(counting === 'backward' ? time - passedTime : passedTime)];
22
+ }
23
+
24
+ export { useTimer };
@@ -0,0 +1,8 @@
1
+ declare function getCircularProgressBarTestIds(dataTestId: string): {
2
+ progressBar: string;
3
+ title: string;
4
+ subtitle: string;
5
+ circleProgressBar: string;
6
+ circleProgressValue: string;
7
+ };
8
+ export { getCircularProgressBarTestIds };
@@ -0,0 +1,13 @@
1
+ import { getDataTestId } from '@alfalab/core-components-shared/modern';
2
+
3
+ function getCircularProgressBarTestIds(dataTestId) {
4
+ return {
5
+ progressBar: dataTestId,
6
+ title: getDataTestId(dataTestId, 'title'),
7
+ subtitle: getDataTestId(dataTestId, 'subtitle'),
8
+ circleProgressBar: getDataTestId(dataTestId, 'circle-progress-bar'),
9
+ circleProgressValue: getDataTestId(dataTestId, 'circle-progress-value'),
10
+ };
11
+ }
12
+
13
+ export { getCircularProgressBarTestIds };
@@ -0,0 +1,3 @@
1
+ import { TypographyColor } from "../types/typography-color";
2
+ declare const isTypographyColor: (color: TypographyColor | string) => color is TypographyColor;
3
+ export { isTypographyColor };
@@ -0,0 +1,5 @@
1
+ import { TYPOGRAPHY_COLOR } from '../consts.js';
2
+
3
+ const isTypographyColor = (color) => TYPOGRAPHY_COLOR.includes(color);
4
+
5
+ export { isTypographyColor };
@@ -1,12 +1,27 @@
1
1
  /// <reference types="react" />
2
2
  import React from 'react';
3
3
  import { ElementType, ReactNode } from "react";
4
- type TypographyColor = 'primary' | 'secondary' | 'tertiary' | 'positive' | 'negative';
4
+ import { ComponentSize } from "./types/component-size";
5
+ import { TypographyColor } from "./types/typography-color";
5
6
  type CircularProgressBarProps = {
6
7
  /**
7
8
  * Уровень прогресса, %
8
9
  */
9
- value: number;
10
+ value: number | {
11
+ /**
12
+ * Время таймера в секундах
13
+ * Минимальное значение 0
14
+ * Максимальное значение 3600
15
+ */
16
+ timer: number;
17
+ /**
18
+ * Направлние отсчета таймера
19
+ * forward: считаем от 0 до указанного значения
20
+ * backward: считаем от указанного значения до 0
21
+ * @default backward
22
+ */
23
+ counting?: 'forward' | 'backward';
24
+ };
10
25
  /**
11
26
  * Дополнительный класс
12
27
  */
@@ -19,6 +34,16 @@ type CircularProgressBarProps = {
19
34
  * Цвет контента
20
35
  */
21
36
  contentColor?: TypographyColor | string;
37
+ /**
38
+ * Цвет заголовка
39
+ * Приоритет выше чем у `contentColor`
40
+ */
41
+ titleColor?: TypographyColor | string;
42
+ /**
43
+ * Цвет подзаголовка
44
+ * Приоритет выше чем у `contentColor`
45
+ */
46
+ subtitleColor?: TypographyColor | string;
22
47
  /**
23
48
  * Дополнительный текст
24
49
  */
@@ -37,9 +62,10 @@ type CircularProgressBarProps = {
37
62
  view?: 'positive' | 'negative';
38
63
  /**
39
64
  * Размер (xxl — 144×144px, xl — 128×128px, l — 80×80px, m — 64×64px, s — 48×48px, xs — 24×24px)
40
- * @description xs, s, m, l, xl, xxl deprecated, используйте вместо них 24, 48, 64 , 80, 128, 144 соответственно
65
+ * @description xs, s, m, l, xl, xxl deprecated, используйте вместо них 24, 48, 64, 80, 128, 144 соответственно
66
+ * @default 64
41
67
  */
42
- size?: 'xxl' | 'xl' | 'l' | 'm' | 's' | 'xs' | 24 | 48 | 64 | 80 | 128 | 144;
68
+ size?: ComponentSize;
43
69
  /**
44
70
  * Наличие желоба
45
71
  */
@@ -103,9 +129,14 @@ type CircularProgressBarProps = {
103
129
  * Цвет желоба
104
130
  */
105
131
  strokeColor?: string;
132
+ /**
133
+ * Направление заполнения круга
134
+ * @default desc
135
+ */
136
+ directionType?: 'asc' | 'desc';
106
137
  };
107
138
  /**
108
139
  * Компонент круглого прогресс бара.
109
140
  */
110
141
  declare const CircularProgressBar: React.FC<CircularProgressBarProps>;
111
- export { TypographyColor, CircularProgressBarProps, CircularProgressBar };
142
+ export { CircularProgressBarProps, CircularProgressBar };
@@ -1,13 +1,30 @@
1
1
  import React, { useMemo } from 'react';
2
2
  import cn from 'classnames';
3
+ import { isObject, getDataTestId } from '@alfalab/core-components-shared/moderncssm';
3
4
  import { Text, TitleMobile } from '@alfalab/core-components-typography/moderncssm';
4
- import { STROKE, SIZES, TYPOGRAPHY_COLOR, SIZE_TO_CLASSNAME_MAP, VIEW_TITLE, VIEW_TEXT } from './consts.js';
5
+ import { isTypographyColor } from './utils/is-typography-color.js';
6
+ import { MIN_TIMER_VALUE, MAX_TIMER_VALUE, STROKE, SIZES, TYPOGRAPHY_COLOR, SIZE_TO_CLASSNAME_MAP, MAX_PROGRESS_VALUE, VIEW_TITLE, VIEW_TEXT } from './consts.js';
7
+ import { useTimer } from './use-timer.js';
5
8
  import styles from './index.module.css';
6
9
 
10
+ /* eslint-disable complexity */
7
11
  /**
8
12
  * Компонент круглого прогресс бара.
9
13
  */
10
- const CircularProgressBar = ({ value, view = 'positive', size = 64, className, dataTestId, title = value ? value.toString() : '0', titleComplete, subtitle, contentColor = 'secondary', subtitleComplete, stroke = true, fillComplete, icon: Icon, iconComplete: IconComplete, completeTextColor, completeIconColor = 'tertiary', direction = 'clockwise', height, children, progressStrokeColor, circleColor, strokeColor, }) => {
14
+ const CircularProgressBar = ({ value: valueFromProps, view = 'positive', size = 64, className, dataTestId, title: titleFromProps = isObject(valueFromProps) ? null : `${valueFromProps}`, titleComplete, subtitle, contentColor = 'secondary', subtitleComplete, stroke = true, fillComplete, icon: Icon, iconComplete: IconComplete, completeTextColor, completeIconColor = 'tertiary', direction = 'clockwise', height, children, progressStrokeColor, circleColor, strokeColor, directionType = 'asc', titleColor, subtitleColor, }) => {
15
+ const isTimer = isObject(valueFromProps);
16
+ const [timerValue, timerTitle] = useTimer(isTimer ? Math.min(Math.max(valueFromProps.timer, MIN_TIMER_VALUE), MAX_TIMER_VALUE) : -1, isTimer, isTimer ? valueFromProps.counting ?? 'backward' : 'backward');
17
+ let value;
18
+ let title;
19
+ if (isTimer) {
20
+ value = timerValue;
21
+ title = timerTitle;
22
+ }
23
+ else {
24
+ value = valueFromProps;
25
+ title = titleFromProps;
26
+ }
27
+ value = directionType === 'desc' ? MAX_PROGRESS_VALUE - value : value;
11
28
  const memorized = useMemo(() => {
12
29
  const strokeWidth = STROKE[size];
13
30
  const maxProgress = 100;
@@ -28,7 +45,7 @@ const CircularProgressBar = ({ value, view = 'positive', size = 64, className, d
28
45
  strokeDasharray,
29
46
  strokeDashoffset,
30
47
  };
31
- }, [value, size]);
48
+ }, [size, value]);
32
49
  const isComplete = value === 100;
33
50
  const isCompleteTextColor = isComplete && completeTextColor;
34
51
  const titleContent = titleComplete && isComplete ? titleComplete : title;
@@ -37,14 +54,34 @@ const CircularProgressBar = ({ value, view = 'positive', size = 64, className, d
37
54
  const typographyContentColor = TYPOGRAPHY_COLOR.includes(contentColor)
38
55
  ? contentColor
39
56
  : undefined;
40
- const renderTitleString = () => SIZES[size] > 64 ? (React.createElement(TitleMobile, { className: cn(styles.typography, styles.title), color: isCompleteTextColor ? completeTextColor : typographyContentColor, tag: 'div', font: 'system', view: VIEW_TITLE[size], style: {
41
- ...(!typographyContentColor && { color: contentColor }),
42
- } }, titleContent)) : (React.createElement(Text, { className: styles.title, color: isCompleteTextColor ? completeTextColor : typographyContentColor, tag: 'div', weight: 'bold', view: VIEW_TEXT[size], style: {
57
+ const getTextColor = (color) => {
58
+ if (isCompleteTextColor) {
59
+ return completeTextColor;
60
+ }
61
+ if (color) {
62
+ return isTypographyColor(color) ? color : undefined;
63
+ }
64
+ return typographyContentColor;
65
+ };
66
+ const getTextStyleColor = (color) => {
67
+ if (color) {
68
+ if (!isTypographyColor(color)) {
69
+ return { color };
70
+ }
71
+ return {};
72
+ }
73
+ return {
43
74
  ...(!typographyContentColor && { color: contentColor }),
44
- } }, titleContent));
75
+ };
76
+ };
77
+ const renderTitleString = () => SIZES[size] > 64 ? (React.createElement(TitleMobile, { className: cn(styles.typography, styles.title), color: getTextColor(titleColor), tag: 'div', font: 'system', view: VIEW_TITLE[size], style: {
78
+ ...getTextStyleColor(titleColor),
79
+ }, dataTestId: getDataTestId(dataTestId, 'title') }, titleContent)) : (React.createElement(Text, { className: styles.title, color: getTextColor(titleColor), tag: 'div', weight: 'bold', view: VIEW_TEXT[size], style: {
80
+ ...getTextStyleColor(titleColor),
81
+ }, dataTestId: getDataTestId(dataTestId, 'title') }, titleContent));
45
82
  const renderTitle = () => (typeof title === 'string' ? renderTitleString() : titleContent);
46
- const renderSubTitle = () => typeof subtitle === 'string' ? (React.createElement(Text, { tag: 'div', className: styles.subtitle, color: isCompleteTextColor ? completeTextColor : typographyContentColor, view: 'primary-small', style: {
47
- ...(!typographyContentColor && { color: contentColor }),
83
+ const renderSubTitle = () => typeof subtitle === 'string' ? (React.createElement(Text, { tag: 'div', className: styles.subtitle, color: getTextColor(subtitleColor), view: 'primary-small', dataTestId: getDataTestId(dataTestId, 'subtitle'), style: {
84
+ ...getTextStyleColor(subtitleColor),
48
85
  } }, subtitleContent)) : (subtitleContent);
49
86
  const renderIcon = () => (React.createElement("span", { className: cn(styles.iconWrapper, styles[SIZE_TO_CLASSNAME_MAP[size]], styles.tertiary, styles[`icon-${contentColor}`], {
50
87
  [styles[`icon-${completeIconColor}`]]: completeIconColor,
@@ -63,12 +100,12 @@ const CircularProgressBar = ({ value, view = 'positive', size = 64, className, d
63
100
  [styles.stroke]: !stroke,
64
101
  }), style: {
65
102
  ...(strokeColor && stroke && { stroke: strokeColor }),
66
- }, cx: memorized.center, cy: memorized.center, r: memorized.radius, strokeWidth: STROKE[size] }),
103
+ }, cx: memorized.center, cy: memorized.center, r: memorized.radius, strokeWidth: STROKE[size], "data-test-id": getDataTestId(dataTestId, 'circle-progress-bar') }),
67
104
  React.createElement("circle", { className: cn(styles.progressCircle, styles[view], styles[SIZE_TO_CLASSNAME_MAP[size]]), style: {
68
105
  ...(progressStrokeColor && { stroke: progressStrokeColor }),
69
106
  }, cx: memorized.center, cy: memorized.center, r: memorized.radius, strokeWidth: STROKE[size], strokeDasharray: memorized.strokeDasharray, strokeDashoffset: direction === 'counter-clockwise'
70
107
  ? -memorized.strokeDashoffset
71
- : memorized.strokeDashoffset, transform: `rotate(${-90} ${memorized.center} ${memorized.center})` })),
108
+ : memorized.strokeDashoffset, transform: `rotate(${-90} ${memorized.center} ${memorized.center})`, "data-test-id": getDataTestId(dataTestId, 'circle-progress-value') })),
72
109
  React.createElement("div", { className: cn(styles.labelWrapper, {
73
110
  [styles.label]: Icon || IconComplete,
74
111
  }) }, children || renderContent())));
@@ -9,6 +9,7 @@ declare const SIZES: {
9
9
  48: number;
10
10
  64: number;
11
11
  80: number;
12
+ 96: number;
12
13
  128: number;
13
14
  144: number;
14
15
  };
@@ -23,6 +24,7 @@ declare const STROKE: {
23
24
  48: number;
24
25
  64: number;
25
26
  80: number;
27
+ 96: number;
26
28
  128: number;
27
29
  144: number;
28
30
  };
@@ -37,6 +39,7 @@ declare const VIEW_TITLE: {
37
39
  readonly 48: "small";
38
40
  readonly 64: "small";
39
41
  readonly 80: "xsmall";
42
+ readonly 96: "xsmall";
40
43
  readonly 128: "medium";
41
44
  readonly 144: "medium";
42
45
  };
@@ -51,6 +54,7 @@ declare const VIEW_TEXT: {
51
54
  readonly 48: "secondary-small";
52
55
  readonly 64: "secondary-large";
53
56
  readonly 80: "secondary-large";
57
+ readonly 96: "secondary-large";
54
58
  readonly 128: "secondary-large";
55
59
  readonly 144: "secondary-large";
56
60
  };
@@ -66,7 +70,11 @@ declare const SIZE_TO_CLASSNAME_MAP: {
66
70
  48: string;
67
71
  64: string;
68
72
  80: string;
73
+ 96: string;
69
74
  128: string;
70
75
  144: string;
71
76
  };
72
- export { SIZES, STROKE, VIEW_TITLE, VIEW_TEXT, TYPOGRAPHY_COLOR, SIZE_TO_CLASSNAME_MAP };
77
+ declare const MAX_PROGRESS_VALUE = 100;
78
+ declare const MIN_TIMER_VALUE = 0;
79
+ declare const MAX_TIMER_VALUE = 3599;
80
+ export { SIZES, STROKE, VIEW_TITLE, VIEW_TEXT, TYPOGRAPHY_COLOR, SIZE_TO_CLASSNAME_MAP, MAX_PROGRESS_VALUE, MIN_TIMER_VALUE, MAX_TIMER_VALUE };
@@ -9,6 +9,7 @@ const SIZES = {
9
9
  48: 48,
10
10
  64: 64,
11
11
  80: 80,
12
+ 96: 96,
12
13
  128: 128,
13
14
  144: 144,
14
15
  };
@@ -23,6 +24,7 @@ const STROKE = {
23
24
  48: 4,
24
25
  64: 6,
25
26
  80: 8,
27
+ 96: 8,
26
28
  128: 10,
27
29
  144: 12,
28
30
  };
@@ -37,6 +39,7 @@ const VIEW_TITLE = {
37
39
  48: 'small',
38
40
  64: 'small',
39
41
  80: 'xsmall',
42
+ 96: 'xsmall',
40
43
  128: 'medium',
41
44
  144: 'medium',
42
45
  };
@@ -51,6 +54,7 @@ const VIEW_TEXT = {
51
54
  48: 'secondary-small',
52
55
  64: 'secondary-large',
53
56
  80: 'secondary-large',
57
+ 96: 'secondary-large',
54
58
  128: 'secondary-large',
55
59
  144: 'secondary-large',
56
60
  };
@@ -66,8 +70,12 @@ const SIZE_TO_CLASSNAME_MAP = {
66
70
  48: 'size-48',
67
71
  64: 'size-64',
68
72
  80: 'size-80',
73
+ 96: 'size-96',
69
74
  128: 'size-128',
70
75
  144: 'size-144',
71
76
  };
77
+ const MAX_PROGRESS_VALUE = 100;
78
+ const MIN_TIMER_VALUE = 0;
79
+ const MAX_TIMER_VALUE = 3599;
72
80
 
73
- export { SIZES, SIZE_TO_CLASSNAME_MAP, STROKE, TYPOGRAPHY_COLOR, VIEW_TEXT, VIEW_TITLE };
81
+ export { MAX_PROGRESS_VALUE, MAX_TIMER_VALUE, MIN_TIMER_VALUE, SIZES, SIZE_TO_CLASSNAME_MAP, STROKE, TYPOGRAPHY_COLOR, VIEW_TEXT, VIEW_TITLE };
@@ -1 +1,2 @@
1
1
  export * from "./Component";
2
+ export * from "./types/typography-color";
@@ -96,6 +96,19 @@
96
96
  max-height: 32px;
97
97
  }
98
98
 
99
+ .size-96 {
100
+ width: 96px;
101
+ height: 96px
102
+ }
103
+
104
+ .size-96 .labelWrapper {
105
+ max-width: 64px;
106
+ }
107
+
108
+ .size-96 .title {
109
+ max-height: 20px;
110
+ }
111
+
99
112
  .size-80 {
100
113
  width: 80px;
101
114
  height: 80px
@@ -189,6 +202,11 @@
189
202
  max-height: 64px;
190
203
  }
191
204
 
205
+ .iconWrapper.size-96 {
206
+ max-width: 48px;
207
+ max-height: 48px;
208
+ }
209
+
192
210
  .iconWrapper.size-80 {
193
211
  max-width: 48px;
194
212
  max-height: 48px;
@@ -0,0 +1 @@
1
+ export { getCircularProgressBarTestIds } from "../utils/get-circular-progress-bar-test-ids";
@@ -0,0 +1 @@
1
+ export { getCircularProgressBarTestIds } from '../utils/get-circular-progress-bar-test-ids.js';
@@ -0,0 +1,2 @@
1
+ type ComponentSize = 'xxl' | 'xl' | 'l' | 'm' | 's' | 'xs' | 24 | 48 | 64 | 80 | 128 | 144;
2
+ export { ComponentSize };
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,2 @@
1
+ type TypographyColor = 'primary' | 'secondary' | 'tertiary' | 'positive' | 'negative';
2
+ export { TypographyColor };
@@ -0,0 +1,2 @@
1
+ declare function useTimer(time: number, active: boolean | undefined, counting: 'forward' | 'backward', interval?: number, step?: number): [value: number, title: string];
2
+ export { useTimer };
@@ -0,0 +1,24 @@
1
+ import { useState, useEffect } from 'react';
2
+ import { noop } from '@alfalab/core-components-shared/moderncssm';
3
+
4
+ const MAX_PERSENT_VALUE = 100;
5
+ function makeTitle(time) {
6
+ return `${Math.trunc(time / 60)}:${`${time % 60}`.padStart(2, '0')}`;
7
+ }
8
+ function useTimer(time, active = true, counting, interval = 1000, step = 1) {
9
+ const [passedTime, setPassedTime] = useState(0);
10
+ const isCompleted = passedTime === time;
11
+ const persentValue = Math.trunc((passedTime / time) * MAX_PERSENT_VALUE);
12
+ useEffect(() => {
13
+ if (!active || isCompleted) {
14
+ return noop;
15
+ }
16
+ const timer = setInterval(() => {
17
+ setPassedTime((prevPassed) => prevPassed + step);
18
+ }, interval);
19
+ return () => clearInterval(timer);
20
+ }, [interval, isCompleted, active, step]);
21
+ return [persentValue, makeTitle(counting === 'backward' ? time - passedTime : passedTime)];
22
+ }
23
+
24
+ export { useTimer };