@cdek-it/react-native-ui-kit 0.2.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 (261) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +151 -0
  3. package/dist/components/Accordion/Accordion.d.ts +39 -0
  4. package/dist/components/Accordion/Accordion.js +103 -0
  5. package/dist/components/Accordion/index.d.ts +1 -0
  6. package/dist/components/Accordion/index.js +1 -0
  7. package/dist/components/Avatar/Avatar.d.ts +96 -0
  8. package/dist/components/Avatar/Avatar.js +121 -0
  9. package/dist/components/Avatar/index.d.ts +1 -0
  10. package/dist/components/Avatar/index.js +1 -0
  11. package/dist/components/Badge/Badge.d.ts +35 -0
  12. package/dist/components/Badge/Badge.js +74 -0
  13. package/dist/components/Badge/index.d.ts +1 -0
  14. package/dist/components/Badge/index.js +1 -0
  15. package/dist/components/Button/BaseButton.d.ts +5 -0
  16. package/dist/components/Button/BaseButton.js +62 -0
  17. package/dist/components/Button/Button.d.ts +16 -0
  18. package/dist/components/Button/Button.js +21 -0
  19. package/dist/components/Button/ButtonBadge.d.ts +21 -0
  20. package/dist/components/Button/ButtonBadge.js +53 -0
  21. package/dist/components/Button/ButtonSeverity.d.ts +17 -0
  22. package/dist/components/Button/ButtonSeverity.js +22 -0
  23. package/dist/components/Button/index.d.ts +4 -0
  24. package/dist/components/Button/index.js +3 -0
  25. package/dist/components/Button/styles/index.d.ts +2 -0
  26. package/dist/components/Button/styles/index.js +2 -0
  27. package/dist/components/Button/styles/useBasicButtonStyles.d.ts +98 -0
  28. package/dist/components/Button/styles/useBasicButtonStyles.js +81 -0
  29. package/dist/components/Button/styles/useDangerButtonStyles.d.ts +63 -0
  30. package/dist/components/Button/styles/useDangerButtonStyles.js +57 -0
  31. package/dist/components/Button/styles/useInfoButtonStyles.d.ts +63 -0
  32. package/dist/components/Button/styles/useInfoButtonStyles.js +56 -0
  33. package/dist/components/Button/styles/useSeverityButtonStyles.d.ts +64 -0
  34. package/dist/components/Button/styles/useSeverityButtonStyles.js +29 -0
  35. package/dist/components/Button/styles/useSuccessButtonStyles.d.ts +63 -0
  36. package/dist/components/Button/styles/useSuccessButtonStyles.js +61 -0
  37. package/dist/components/Button/styles/useWarningButtonStyles.d.ts +63 -0
  38. package/dist/components/Button/styles/useWarningButtonStyles.js +61 -0
  39. package/dist/components/Button/types.d.ts +107 -0
  40. package/dist/components/Button/types.js +0 -0
  41. package/dist/components/Button/utils/ButtonActivityIndicator.d.ts +3 -0
  42. package/dist/components/Button/utils/ButtonActivityIndicator.js +17 -0
  43. package/dist/components/Button/utils/ButtonContainer.d.ts +7 -0
  44. package/dist/components/Button/utils/ButtonContainer.js +10 -0
  45. package/dist/components/Button/utils/ButtonIcon.d.ts +4 -0
  46. package/dist/components/Button/utils/ButtonIcon.js +11 -0
  47. package/dist/components/Button/utils/ButtonLabel.d.ts +4 -0
  48. package/dist/components/Button/utils/ButtonLabel.js +13 -0
  49. package/dist/components/Button/utils/ButtonLeftArea.d.ts +4 -0
  50. package/dist/components/Button/utils/ButtonLeftArea.js +13 -0
  51. package/dist/components/Button/utils/ButtonRightArea.d.ts +3 -0
  52. package/dist/components/Button/utils/ButtonRightArea.js +13 -0
  53. package/dist/components/Button/utils/index.d.ts +4 -0
  54. package/dist/components/Button/utils/index.js +4 -0
  55. package/dist/components/Button/utils/useButtonContainerCallbackStyle.d.ts +3 -0
  56. package/dist/components/Button/utils/useButtonContainerCallbackStyle.js +141 -0
  57. package/dist/components/Button/utils/useButtonLabelStyle.d.ts +3 -0
  58. package/dist/components/Button/utils/useButtonLabelStyle.js +40 -0
  59. package/dist/components/Button/utils/useIconStyle.d.ts +7 -0
  60. package/dist/components/Button/utils/useIconStyle.js +35 -0
  61. package/dist/components/Button/utils/useTypeBasedStyle.d.ts +2 -0
  62. package/dist/components/Button/utils/useTypeBasedStyle.js +4 -0
  63. package/dist/components/Checkbox/Checkbox.d.ts +31 -0
  64. package/dist/components/Checkbox/Checkbox.js +55 -0
  65. package/dist/components/Checkbox/hooks/usePressableStyles.d.ts +15 -0
  66. package/dist/components/Checkbox/hooks/usePressableStyles.js +91 -0
  67. package/dist/components/Checkbox/index.d.ts +1 -0
  68. package/dist/components/Checkbox/index.js +1 -0
  69. package/dist/components/Chip/Chip.d.ts +30 -0
  70. package/dist/components/Chip/Chip.js +70 -0
  71. package/dist/components/Chip/index.d.ts +1 -0
  72. package/dist/components/Chip/index.js +1 -0
  73. package/dist/components/Dialog/Dialog.d.ts +14 -0
  74. package/dist/components/Dialog/Dialog.js +96 -0
  75. package/dist/components/Dialog/DialogComponent.d.ts +7 -0
  76. package/dist/components/Dialog/DialogComponent.js +34 -0
  77. package/dist/components/Dialog/DialogHeader.d.ts +12 -0
  78. package/dist/components/Dialog/DialogHeader.js +68 -0
  79. package/dist/components/Dialog/index.d.ts +3 -0
  80. package/dist/components/Dialog/index.js +3 -0
  81. package/dist/components/Divider/Divider.d.ts +42 -0
  82. package/dist/components/Divider/Divider.js +95 -0
  83. package/dist/components/Divider/index.d.ts +1 -0
  84. package/dist/components/Divider/index.js +1 -0
  85. package/dist/components/Input/FloatLabel.d.ts +22 -0
  86. package/dist/components/Input/FloatLabel.js +19 -0
  87. package/dist/components/Input/InputGroup.d.ts +21 -0
  88. package/dist/components/Input/InputGroup.js +52 -0
  89. package/dist/components/Input/InputGroupAddon.d.ts +17 -0
  90. package/dist/components/Input/InputGroupAddon.js +57 -0
  91. package/dist/components/Input/InputSwitch/InputSwitch.d.ts +8 -0
  92. package/dist/components/Input/InputSwitch/InputSwitch.js +16 -0
  93. package/dist/components/Input/InputSwitch/index.d.ts +1 -0
  94. package/dist/components/Input/InputSwitch/index.js +1 -0
  95. package/dist/components/Input/InputSwitch/styles/index.d.ts +2 -0
  96. package/dist/components/Input/InputSwitch/styles/index.js +2 -0
  97. package/dist/components/Input/InputSwitch/styles/useHandleStyles.d.ts +13 -0
  98. package/dist/components/Input/InputSwitch/styles/useHandleStyles.js +47 -0
  99. package/dist/components/Input/InputSwitch/styles/useSliderStyles.d.ts +17 -0
  100. package/dist/components/Input/InputSwitch/styles/useSliderStyles.js +95 -0
  101. package/dist/components/Input/InputText.d.ts +13 -0
  102. package/dist/components/Input/InputText.js +14 -0
  103. package/dist/components/Input/InputTextBase/InputTextBase.d.ts +13 -0
  104. package/dist/components/Input/InputTextBase/InputTextBase.js +124 -0
  105. package/dist/components/Input/InputTextBase/testIds.d.ts +11 -0
  106. package/dist/components/Input/InputTextBase/testIds.js +11 -0
  107. package/dist/components/Input/InputTextBase/types.d.ts +41 -0
  108. package/dist/components/Input/InputTextBase/types.js +0 -0
  109. package/dist/components/Input/InputTextBase/useStyles.d.ts +86 -0
  110. package/dist/components/Input/InputTextBase/useStyles.js +78 -0
  111. package/dist/components/Input/index.d.ts +5 -0
  112. package/dist/components/Input/index.js +4 -0
  113. package/dist/components/List/Base/ListBase.d.ts +32 -0
  114. package/dist/components/List/Base/ListBase.js +88 -0
  115. package/dist/components/List/Base/index.d.ts +1 -0
  116. package/dist/components/List/Base/index.js +1 -0
  117. package/dist/components/MenuItem/MenuItemAccessory.d.ts +11 -0
  118. package/dist/components/MenuItem/MenuItemAccessory.js +23 -0
  119. package/dist/components/MenuItem/MenuItemIcon.d.ts +36 -0
  120. package/dist/components/MenuItem/MenuItemIcon.js +33 -0
  121. package/dist/components/MenuItem/Template/MenuItemTemplate.d.ts +42 -0
  122. package/dist/components/MenuItem/Template/MenuItemTemplate.js +79 -0
  123. package/dist/components/MenuItem/index.d.ts +1 -0
  124. package/dist/components/MenuItem/index.js +1 -0
  125. package/dist/components/Message/Message.d.ts +65 -0
  126. package/dist/components/Message/Message.js +126 -0
  127. package/dist/components/Message/index.d.ts +1 -0
  128. package/dist/components/Message/index.js +1 -0
  129. package/dist/components/ProgressBar/ProgressBar.d.ts +33 -0
  130. package/dist/components/ProgressBar/ProgressBar.js +62 -0
  131. package/dist/components/ProgressBar/index.d.ts +1 -0
  132. package/dist/components/ProgressBar/index.js +1 -0
  133. package/dist/components/ProgressSpinner/ProgressSpinner.d.ts +17 -0
  134. package/dist/components/ProgressSpinner/ProgressSpinner.js +68 -0
  135. package/dist/components/ProgressSpinner/index.d.ts +1 -0
  136. package/dist/components/ProgressSpinner/index.js +1 -0
  137. package/dist/components/RadioButton/RadioButton.d.ts +18 -0
  138. package/dist/components/RadioButton/RadioButton.js +134 -0
  139. package/dist/components/RadioButton/index.d.ts +1 -0
  140. package/dist/components/RadioButton/index.js +1 -0
  141. package/dist/components/Rating/Rating.d.ts +48 -0
  142. package/dist/components/Rating/Rating.js +37 -0
  143. package/dist/components/Rating/RatingClear.d.ts +14 -0
  144. package/dist/components/Rating/RatingClear.js +28 -0
  145. package/dist/components/Rating/RatingItem.d.ts +19 -0
  146. package/dist/components/Rating/RatingItem.js +44 -0
  147. package/dist/components/Rating/RatingItemContainer.d.ts +37 -0
  148. package/dist/components/Rating/RatingItemContainer.js +30 -0
  149. package/dist/components/Rating/index.d.ts +1 -0
  150. package/dist/components/Rating/index.js +1 -0
  151. package/dist/components/SelectButton/SelectButton.d.ts +32 -0
  152. package/dist/components/SelectButton/SelectButton.js +75 -0
  153. package/dist/components/SelectButton/SelectButtonItem.d.ts +35 -0
  154. package/dist/components/SelectButton/SelectButtonItem.js +133 -0
  155. package/dist/components/SelectButton/index.d.ts +1 -0
  156. package/dist/components/SelectButton/index.js +1 -0
  157. package/dist/components/Skeleton/Skeleton.d.ts +15 -0
  158. package/dist/components/Skeleton/Skeleton.js +53 -0
  159. package/dist/components/Skeleton/index.d.ts +1 -0
  160. package/dist/components/Skeleton/index.js +1 -0
  161. package/dist/components/Slider/Slider.d.ts +36 -0
  162. package/dist/components/Slider/Slider.js +153 -0
  163. package/dist/components/Slider/index.d.ts +1 -0
  164. package/dist/components/Slider/index.js +1 -0
  165. package/dist/components/Tabs/TabItem/TabItem.d.ts +24 -0
  166. package/dist/components/Tabs/TabItem/TabItem.js +82 -0
  167. package/dist/components/Tabs/TabItem/index.d.ts +1 -0
  168. package/dist/components/Tabs/TabItem/index.js +1 -0
  169. package/dist/components/Tabs/TabPanel/TabPanel.d.ts +9 -0
  170. package/dist/components/Tabs/TabPanel/TabPanel.js +11 -0
  171. package/dist/components/Tabs/TabPanel/index.d.ts +1 -0
  172. package/dist/components/Tabs/TabPanel/index.js +1 -0
  173. package/dist/components/Tabs/Tabs.d.ts +15 -0
  174. package/dist/components/Tabs/Tabs.js +48 -0
  175. package/dist/components/Tabs/index.d.ts +2 -0
  176. package/dist/components/Tabs/index.js +2 -0
  177. package/dist/components/Tag/Tag.d.ts +33 -0
  178. package/dist/components/Tag/Tag.js +71 -0
  179. package/dist/components/Tag/index.d.ts +1 -0
  180. package/dist/components/Tag/index.js +1 -0
  181. package/dist/components/Timer/Timer.d.ts +18 -0
  182. package/dist/components/Timer/Timer.js +74 -0
  183. package/dist/components/Timer/TimerFlip.d.ts +7 -0
  184. package/dist/components/Timer/TimerFlip.js +69 -0
  185. package/dist/components/Timer/constants.d.ts +1 -0
  186. package/dist/components/Timer/constants.js +1 -0
  187. package/dist/components/ToggleButton/ToggleButton.d.ts +45 -0
  188. package/dist/components/ToggleButton/ToggleButton.js +85 -0
  189. package/dist/components/ToggleButton/hooks/useIconSize.d.ts +14 -0
  190. package/dist/components/ToggleButton/hooks/useIconSize.js +26 -0
  191. package/dist/components/ToggleButton/hooks/useLabelSize.d.ts +8 -0
  192. package/dist/components/ToggleButton/hooks/useLabelSize.js +19 -0
  193. package/dist/components/ToggleButton/hooks/useStateStyles.d.ts +11 -0
  194. package/dist/components/ToggleButton/hooks/useStateStyles.js +92 -0
  195. package/dist/components/ToggleButton/index.d.ts +1 -0
  196. package/dist/components/ToggleButton/index.js +1 -0
  197. package/dist/components/Typography/Anchor.d.ts +31 -0
  198. package/dist/components/Typography/Anchor.js +75 -0
  199. package/dist/components/Typography/Body.d.ts +9 -0
  200. package/dist/components/Typography/Body.js +32 -0
  201. package/dist/components/Typography/Caption.d.ts +9 -0
  202. package/dist/components/Typography/Caption.js +38 -0
  203. package/dist/components/Typography/Service.d.ts +25 -0
  204. package/dist/components/Typography/Service.js +63 -0
  205. package/dist/components/Typography/Subtitle.d.ts +18 -0
  206. package/dist/components/Typography/Subtitle.js +23 -0
  207. package/dist/components/Typography/Title.d.ts +5 -0
  208. package/dist/components/Typography/Title.js +24 -0
  209. package/dist/components/Typography/index.d.ts +6 -0
  210. package/dist/components/Typography/index.js +6 -0
  211. package/dist/components/index.d.ts +23 -0
  212. package/dist/components/index.js +23 -0
  213. package/dist/hooks/useChangeTheme.d.ts +1 -0
  214. package/dist/hooks/useChangeTheme.js +5 -0
  215. package/dist/hooks/useFonts.d.ts +1 -0
  216. package/dist/hooks/useFonts.js +5 -0
  217. package/dist/hooks/useLoadingRotationAnimation.d.ts +5 -0
  218. package/dist/hooks/useLoadingRotationAnimation.js +19 -0
  219. package/dist/hooks/useMakeTestId.d.ts +3 -0
  220. package/dist/hooks/useMakeTestId.js +7 -0
  221. package/dist/hooks/useTheme.d.ts +1 -0
  222. package/dist/hooks/useTheme.js +5 -0
  223. package/dist/index.d.ts +6 -0
  224. package/dist/index.js +6 -0
  225. package/dist/theme/ThemeContext.d.ts +15 -0
  226. package/dist/theme/ThemeContext.js +20 -0
  227. package/dist/theme/assets/background.json +149 -0
  228. package/dist/theme/assets/border.json +103 -0
  229. package/dist/theme/assets/customCommon.d.ts +4 -0
  230. package/dist/theme/assets/customCommon.js +4 -0
  231. package/dist/theme/assets/customDark.d.ts +5 -0
  232. package/dist/theme/assets/customDark.js +15 -0
  233. package/dist/theme/assets/customLight.d.ts +15 -0
  234. package/dist/theme/assets/customLight.js +15 -0
  235. package/dist/theme/assets/effects.json +15 -0
  236. package/dist/theme/assets/global.json +114 -0
  237. package/dist/theme/assets/primaryColors.json +14 -0
  238. package/dist/theme/assets/shadow.d.ts +6 -0
  239. package/dist/theme/assets/shadow.js +6 -0
  240. package/dist/theme/assets/sizing.json +78 -0
  241. package/dist/theme/assets/spacing.json +48 -0
  242. package/dist/theme/assets/themeDark.json +1141 -0
  243. package/dist/theme/assets/themeLight.json +1141 -0
  244. package/dist/theme/assets/typography.json +45 -0
  245. package/dist/theme/commonTheme.d.ts +582 -0
  246. package/dist/theme/commonTheme.js +22 -0
  247. package/dist/theme/darkTheme.d.ts +2 -0
  248. package/dist/theme/darkTheme.js +7 -0
  249. package/dist/theme/index.d.ts +4 -0
  250. package/dist/theme/index.js +4 -0
  251. package/dist/theme/lightTheme.d.ts +2 -0
  252. package/dist/theme/lightTheme.js +7 -0
  253. package/dist/theme/types.d.ts +40 -0
  254. package/dist/theme/types.js +5 -0
  255. package/dist/utils/SvgUniversal.d.ts +29 -0
  256. package/dist/utils/SvgUniversal.js +28 -0
  257. package/dist/utils/genericMemo.d.ts +1 -0
  258. package/dist/utils/genericMemo.js +2 -0
  259. package/dist/utils/makeStyles.d.ts +11 -0
  260. package/dist/utils/makeStyles.js +19 -0
  261. package/package.json +159 -0
@@ -0,0 +1,71 @@
1
+ import { memo } from 'react';
2
+ import { View, Text, } from 'react-native';
3
+ import { SvgUniversal } from '../../utils/SvgUniversal';
4
+ import { makeStyles } from '../../utils/makeStyles';
5
+ /**
6
+ * Используется для маркировки элементов интерфейса
7
+ * @see https://www.figma.com/design/4TYeki0MDLhfPGJstbIicf/UI-kit-PrimeFace-(DS)?node-id=484-4921
8
+ */
9
+ export const Tag = memo(({ text, rounded, severity = 'basic', showIcon = true, style, Icon, testID, ...rest }) => {
10
+ const styles = useStyles();
11
+ return (<View style={style} testID={testID || TagTestId.root} {...rest}>
12
+ <View style={[
13
+ styles.container,
14
+ styles[severity],
15
+ rounded && styles.roundedContainer,
16
+ ]} testID={TagTestId.innerContainer}>
17
+ {showIcon && Icon ? (<SvgUniversal color={styles[`text${severity}`].color} height={styles.icon.height} source={Icon} testID={TagTestId.icon} width={styles.icon.width}/>) : null}
18
+ <Text numberOfLines={1} style={[styles.text, styles[`text${severity}`]]} testID={TagTestId.text}>
19
+ {text}
20
+ </Text>
21
+ </View>
22
+ </View>);
23
+ });
24
+ const useStyles = makeStyles(({ theme, border, spacing, typography, fonts }) => ({
25
+ container: {
26
+ alignSelf: 'flex-start',
27
+ flexDirection: 'row',
28
+ alignItems: 'center',
29
+ gap: spacing.Gap['gap-1'],
30
+ paddingHorizontal: theme.Misc.Tag.tagPadding,
31
+ height: theme.Misc.Tag.tagHeight,
32
+ borderRadius: border.Radius['rounded-lg'],
33
+ },
34
+ roundedContainer: { borderRadius: border.Radius['rounded-full'] },
35
+ icon: {
36
+ width: theme.Misc.Tag.tagFontSize,
37
+ height: theme.Misc.Tag.tagFontSize,
38
+ color: theme.Misc.Badge.badgeTextColor,
39
+ },
40
+ text: {
41
+ flexShrink: 1,
42
+ fontSize: typography.Size['text-xs'],
43
+ includeFontPadding: false,
44
+ verticalAlign: 'middle',
45
+ fontFamily: fonts.primary,
46
+ },
47
+ textbasic: { color: theme.Misc.Badge.badgeTextColor },
48
+ textinfo: { color: theme.Misc.Badge.badgeInfoTextColor },
49
+ textwarning: { color: theme.Misc.Badge.badgeWarningTextColor },
50
+ textsuccess: { color: theme.Misc.Badge.badgeSuccessTextColor },
51
+ textdanger: { color: theme.Misc.Badge.badgeDangerTextColor },
52
+ textsecondary: { color: theme.Misc.Badge.badgeTextColor },
53
+ basic: { backgroundColor: theme.Misc.Badge.badgeBg },
54
+ info: { backgroundColor: theme.Button.Severity.Info.Basic.infoButtonBg },
55
+ success: {
56
+ backgroundColor: theme.Button.Severity.Success.Basic.successButtonBg,
57
+ },
58
+ warning: {
59
+ backgroundColor: theme.Button.Severity.Warning.Basic.warningButtonBg,
60
+ },
61
+ danger: {
62
+ backgroundColor: theme.Button.Severity.Danger.Basic.dangerButtonBg,
63
+ },
64
+ secondary: { backgroundColor: theme.Surface['surface-border'] },
65
+ }));
66
+ export const TagTestId = {
67
+ root: 'Tag',
68
+ innerContainer: 'Tag.innerContainer',
69
+ icon: 'Tag.icon',
70
+ text: 'Tag.text',
71
+ };
@@ -0,0 +1 @@
1
+ export { Tag, type TagProps } from './Tag';
@@ -0,0 +1 @@
1
+ export { Tag } from './Tag';
@@ -0,0 +1,18 @@
1
+ interface TimerProps {
2
+ /**
3
+ * Время в секундах, которое нужно отсчитать.
4
+ * Min - 1, Max - 99
5
+ */
6
+ countFrom: number;
7
+ /** Функция, которая будет вызвана по завершению отсчета */
8
+ onFinish?: () => void;
9
+ }
10
+ /**
11
+ * Таймер для использования внутри ui kit, не экспортируется для внешнего использования
12
+ * @see https://www.figma.com/design/2ZnL6XPKEpxAHvrlbRvnMu/Template-Tailwind-CSS-(DS)?node-id=270-1514
13
+ */
14
+ export declare const Timer: import("react").NamedExoticComponent<TimerProps>;
15
+ export declare enum TestId {
16
+ Container = "TimerContainer"
17
+ }
18
+ export {};
@@ -0,0 +1,74 @@
1
+ import { memo, useEffect, useState } from 'react';
2
+ import { View } from 'react-native';
3
+ import Animated, { cancelAnimation, Easing, useAnimatedProps, useSharedValue, withTiming, } from 'react-native-reanimated';
4
+ import Svg, { Circle } from 'react-native-svg';
5
+ import { makeStyles } from '../../utils/makeStyles';
6
+ import { TimerFlip } from './TimerFlip';
7
+ import { COUNTER_SIZE } from './constants';
8
+ // eslint-disable-next-line import-x/no-deprecated
9
+ const AnimatedCircle = Animated.createAnimatedComponent(Circle);
10
+ const BORDER_WIDTH = 2;
11
+ /**
12
+ * Таймер для использования внутри ui kit, не экспортируется для внешнего использования
13
+ * @see https://www.figma.com/design/2ZnL6XPKEpxAHvrlbRvnMu/Template-Tailwind-CSS-(DS)?node-id=270-1514
14
+ */
15
+ export const Timer = memo(({ countFrom, onFinish }) => {
16
+ const styles = useStyles();
17
+ const circleAnimation = useSharedValue(0);
18
+ const [currentTimerValue, setCurrentTimerValue] = useState(countFrom);
19
+ const circumferenceRadius = COUNTER_SIZE / 2 - BORDER_WIDTH;
20
+ const circumferenceLength = 2 * Math.PI * circumferenceRadius;
21
+ const center = COUNTER_SIZE / 2;
22
+ const circleAnimatedProps = useAnimatedProps(() => ({
23
+ strokeDashoffset: -circleAnimation.value * circumferenceLength,
24
+ }));
25
+ useEffect(() => {
26
+ setCurrentTimerValue(countFrom);
27
+ circleAnimation.value = 0;
28
+ circleAnimation.value = withTiming(1, {
29
+ duration: countFrom * 1000,
30
+ easing: Easing.linear,
31
+ });
32
+ return () => cancelAnimation(circleAnimation);
33
+ }, [circleAnimation, countFrom]);
34
+ useEffect(() => {
35
+ let timeoutId;
36
+ if (currentTimerValue > 0) {
37
+ timeoutId = setTimeout(() => setCurrentTimerValue((prev) => prev - 1), 1000);
38
+ }
39
+ return () => clearTimeout(timeoutId);
40
+ }, [currentTimerValue, onFinish]);
41
+ useEffect(() => {
42
+ if (currentTimerValue === 0) {
43
+ onFinish?.();
44
+ }
45
+ }, [currentTimerValue, onFinish]);
46
+ return (<View style={styles.container} testID={TestId.Container}>
47
+ <Svg style={styles.svgContainer}>
48
+ <AnimatedCircle animatedProps={circleAnimatedProps} cx={center} cy={center} fill='none' origin={[center, center]} r={circumferenceRadius} rotation={-90} stroke={styles.circle.color} strokeDasharray={circumferenceLength} strokeLinecap='round' strokeWidth={BORDER_WIDTH}/>
49
+ </Svg>
50
+
51
+ <TimerFlip value={currentTimerValue}/>
52
+ </View>);
53
+ });
54
+ const useStyles = makeStyles(({ typography }) => ({
55
+ container: {
56
+ overflow: 'hidden',
57
+ width: COUNTER_SIZE,
58
+ height: COUNTER_SIZE,
59
+ alignItems: 'center',
60
+ justifyContent: 'center',
61
+ },
62
+ svgContainer: {
63
+ position: 'absolute',
64
+ top: 0,
65
+ left: 0,
66
+ width: COUNTER_SIZE,
67
+ height: COUNTER_SIZE,
68
+ },
69
+ circle: { color: typography.Color.Surface['text-surface-0'] },
70
+ }));
71
+ export var TestId;
72
+ (function (TestId) {
73
+ TestId["Container"] = "TimerContainer";
74
+ })(TestId || (TestId = {}));
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ interface TimerFlipProps {
3
+ readonly value: number;
4
+ readonly duration?: number;
5
+ }
6
+ export declare const TimerFlip: React.NamedExoticComponent<TimerFlipProps>;
7
+ export {};
@@ -0,0 +1,69 @@
1
+ import React, { memo, useEffect, useState } from 'react';
2
+ import { View, Text } from 'react-native';
3
+ import Animated, { useSharedValue, useAnimatedStyle, withTiming, runOnJS, } from 'react-native-reanimated';
4
+ import { makeStyles } from '../../utils/makeStyles';
5
+ import { COUNTER_SIZE } from './constants';
6
+ export const TimerFlip = memo(({ value, duration = 300 }) => {
7
+ const styles = useStyles();
8
+ const [currentValue, setCurrentValue] = useState(value);
9
+ const [nextValue, setNextValue] = useState(value);
10
+ const progress = useSharedValue(0);
11
+ const currentStyle = useAnimatedStyle(() => ({
12
+ transform: [{ translateY: progress.value * COUNTER_SIZE }],
13
+ opacity: 1 - progress.value,
14
+ }));
15
+ const nextStyle = useAnimatedStyle(() => ({
16
+ transform: [{ translateY: progress.value * COUNTER_SIZE }],
17
+ opacity: progress.value,
18
+ bottom: COUNTER_SIZE,
19
+ }));
20
+ useEffect(() => {
21
+ if (nextValue === currentValue && value !== currentValue) {
22
+ setNextValue(null);
23
+ progress.value = 0;
24
+ }
25
+ }, [currentValue, nextValue, progress, value]);
26
+ useEffect(() => {
27
+ if (value === currentValue || nextValue !== null)
28
+ return;
29
+ setNextValue(value);
30
+ progress.value = withTiming(1, { duration }, (finished) => {
31
+ if (finished) {
32
+ runOnJS(setCurrentValue)(value);
33
+ }
34
+ });
35
+ }, [value, currentValue, duration, progress, nextValue]);
36
+ return (<View style={styles.container}>
37
+ {nextValue !== null && (<Animated.View style={[styles.textWrapper, nextStyle]}>
38
+ <Text style={styles.text}>{nextValue}</Text>
39
+ </Animated.View>)}
40
+ <Animated.View style={[styles.textWrapper, currentStyle]}>
41
+ <Text style={styles.text}>{currentValue}</Text>
42
+ </Animated.View>
43
+ </View>);
44
+ });
45
+ const useStyles = makeStyles(({ typography, fonts }) => ({
46
+ container: {
47
+ overflow: 'hidden',
48
+ width: COUNTER_SIZE,
49
+ height: COUNTER_SIZE,
50
+ alignItems: 'center',
51
+ justifyContent: 'center',
52
+ position: 'relative',
53
+ },
54
+ textWrapper: {
55
+ height: COUNTER_SIZE,
56
+ width: COUNTER_SIZE,
57
+ justifyContent: 'center',
58
+ alignItems: 'center',
59
+ position: 'absolute',
60
+ },
61
+ text: {
62
+ fontSize: typography.Size['text-base'],
63
+ fontWeight: 700,
64
+ includeFontPadding: false,
65
+ verticalAlign: 'middle',
66
+ color: typography.Color.Surface['text-surface-0'],
67
+ fontFamily: fonts.secondary,
68
+ },
69
+ }));
@@ -0,0 +1 @@
1
+ export declare const COUNTER_SIZE = 28;
@@ -0,0 +1 @@
1
+ export const COUNTER_SIZE = 28;
@@ -0,0 +1,45 @@
1
+ import { type AccessibilityProps, type ViewProps, type ViewStyle } from 'react-native';
2
+ import { type SvgSource } from '../../utils/SvgUniversal';
3
+ export interface ToggleButtonProps extends AccessibilityProps, Pick<ViewProps, 'testID'> {
4
+ /** Обработчик нажатия на кнопку */
5
+ onPress: () => void;
6
+ /**
7
+ * true, если необходим компонент в активном состоянии
8
+ * @default false
9
+ */
10
+ checked?: boolean;
11
+ /**
12
+ * Управление доступностью компонента
13
+ * @default false
14
+ */
15
+ disabled?: boolean;
16
+ /** Отображение только иконки без текста */
17
+ iconOnly?: boolean;
18
+ /**
19
+ * Выбор позиции иконки. 'left' - иконка слева, 'right' - иконка справа, null - иконка скрыта
20
+ * @default 'left'
21
+ */
22
+ iconPos?: 'left' | 'right' | null;
23
+ /** Текст на кнопке */
24
+ label?: string;
25
+ /**
26
+ * Выбор размера элемента
27
+ * @default 'base'
28
+ */
29
+ size?: 'xlarge' | 'large' | 'base' | 'small';
30
+ /** Дополнительная стилизация для контейнера компонента */
31
+ style?: ViewStyle;
32
+ /** SVG-иконка */
33
+ Icon?: SvgSource;
34
+ }
35
+ /**
36
+ * Используется для выбора нескольких значений с помощью кнопки
37
+ * @see https://www.figma.com/design/4TYeki0MDLhfPGJstbIicf/UI-kit-PrimeFace-(DS)?node-id=484-4821
38
+ */
39
+ export declare const ToggleButton: import("react").NamedExoticComponent<ToggleButtonProps>;
40
+ export declare const ToggleButtonTestId: {
41
+ root: string;
42
+ container: string;
43
+ text: string;
44
+ icon: string;
45
+ };
@@ -0,0 +1,85 @@
1
+ import { memo, useCallback, useMemo, useState } from 'react';
2
+ import { Pressable, Text, View, } from 'react-native';
3
+ import { SvgUniversal } from '../../utils/SvgUniversal';
4
+ import { makeStyles } from '../../utils/makeStyles';
5
+ import { useIconSize } from './hooks/useIconSize';
6
+ import { useLabelSize } from './hooks/useLabelSize';
7
+ import { useStateStyles } from './hooks/useStateStyles';
8
+ /**
9
+ * Используется для выбора нескольких значений с помощью кнопки
10
+ * @see https://www.figma.com/design/4TYeki0MDLhfPGJstbIicf/UI-kit-PrimeFace-(DS)?node-id=484-4821
11
+ */
12
+ export const ToggleButton = memo(({ onPress, checked, disabled, iconOnly: iconOnlyProp, iconPos = 'left', label, size = 'base', style, Icon, testID, ...rest }) => {
13
+ const styles = useStyles();
14
+ const labelSize = useLabelSize(size);
15
+ const iconSize = useIconSize(size);
16
+ const [pressed, setPressed] = useState(false);
17
+ const stateStyles = useStateStyles(checked, disabled, pressed);
18
+ const iconOnly = useMemo(() => iconOnlyProp || !label, [iconOnlyProp, label]);
19
+ const icon = useMemo(() => {
20
+ if (!Icon) {
21
+ return null;
22
+ }
23
+ return (<SvgUniversal height={iconSize.height} source={Icon} style={stateStyles.label} testID={ToggleButtonTestId.icon} width={iconSize.width}/>);
24
+ }, [Icon, iconSize.height, iconSize.width, stateStyles.label]);
25
+ const onPressIn = useCallback(() => setPressed(true), []);
26
+ const onPressOut = useCallback(() => setPressed(false), []);
27
+ return (<Pressable disabled={disabled} style={[styles.container, style, stateStyles.borderContainer]} testID={testID || ToggleButtonTestId.root} onPress={onPress} onPressIn={onPressIn} onPressOut={onPressOut} {...rest}>
28
+ <View style={[
29
+ styles.contentContainer,
30
+ styles[size],
31
+ iconOnly && styles.iconOnly,
32
+ stateStyles.contentContainer,
33
+ ]} testID={ToggleButtonTestId.container}>
34
+ {iconOnly ? (icon) : (<>
35
+ {iconPos === 'left' && icon}
36
+ <Text style={[styles.label, labelSize, stateStyles.label]} testID={ToggleButtonTestId.text}>
37
+ {label}
38
+ </Text>
39
+ {Icon && iconPos === 'right' ? icon : null}
40
+ </>)}
41
+ </View>
42
+ </Pressable>);
43
+ });
44
+ const useStyles = makeStyles(({ theme, spacing, border, fonts }) => ({
45
+ container: {
46
+ alignSelf: 'flex-start',
47
+ borderRadius: border.Radius['rounded-full'],
48
+ borderWidth: border.Width.border,
49
+ overflow: 'hidden',
50
+ },
51
+ contentContainer: {
52
+ flexDirection: 'row',
53
+ alignItems: 'center',
54
+ alignSelf: 'flex-start',
55
+ borderRadius: border.Radius['rounded-full'],
56
+ paddingVertical: theme.Button.Common.buttonPaddingTopBottom,
57
+ paddingHorizontal: spacing.Padding['p-6'],
58
+ gap: spacing.Gap['gap-3'],
59
+ },
60
+ xlarge: { minHeight: theme.Button.Common.buttonHeightXL },
61
+ large: { minHeight: theme.Button.Common.buttonHeightLG },
62
+ base: {
63
+ minHeight: theme.Button.Common.buttonHeight,
64
+ paddingHorizontal: theme.Button.Common.buttonPaddingLeftRight,
65
+ gap: theme.General.inlineSpacing,
66
+ },
67
+ small: {
68
+ minHeight: theme.Button.Common.buttonHeightSM,
69
+ paddingHorizontal: spacing.Padding['p-3'],
70
+ gap: theme.General.inlineSpacing,
71
+ },
72
+ iconOnly: {
73
+ aspectRatio: 1,
74
+ paddingHorizontal: 0,
75
+ paddingVertical: 0,
76
+ justifyContent: 'center',
77
+ },
78
+ label: { flexShrink: 1, fontFamily: fonts.primary },
79
+ }));
80
+ export const ToggleButtonTestId = {
81
+ root: 'ToggleButton',
82
+ container: 'ToggleButton.container',
83
+ text: 'ToggleButton.text',
84
+ icon: 'ToggleButton.icon',
85
+ };
@@ -0,0 +1,14 @@
1
+ import type { ToggleButtonProps } from '../ToggleButton';
2
+ export declare const useIconSize: (size?: ToggleButtonProps["size"]) => {
3
+ width: number;
4
+ height: number;
5
+ } | {
6
+ width: number;
7
+ height: number;
8
+ } | {
9
+ width: number;
10
+ height: number;
11
+ } | {
12
+ width: number;
13
+ height: number;
14
+ };
@@ -0,0 +1,26 @@
1
+ import { useMemo } from 'react';
2
+ import { makeStyles } from '../../../utils/makeStyles';
3
+ export const useIconSize = (size = 'base') => {
4
+ const styles = useStyles();
5
+ return useMemo(() => {
6
+ return styles[size];
7
+ }, [size, styles]);
8
+ };
9
+ const useStyles = makeStyles(({ typography }) => ({
10
+ xlarge: {
11
+ width: typography.Size['text-4xl'],
12
+ height: typography.Size['text-4xl'],
13
+ },
14
+ large: {
15
+ width: typography.Size['text-2xl'],
16
+ height: typography.Size['text-2xl'],
17
+ },
18
+ base: {
19
+ width: typography.Size['text-xl'],
20
+ height: typography.Size['text-xl'],
21
+ },
22
+ small: {
23
+ width: typography.Size['text-base'],
24
+ height: typography.Size['text-base'],
25
+ },
26
+ }));
@@ -0,0 +1,8 @@
1
+ import type { ToggleButtonProps } from '../ToggleButton';
2
+ export declare const useLabelSize: (size?: ToggleButtonProps["size"]) => ({
3
+ fontWeight: "600";
4
+ includeFontPadding: false;
5
+ verticalAlign: "middle";
6
+ } | {
7
+ fontSize: number;
8
+ })[];
@@ -0,0 +1,19 @@
1
+ import { useMemo } from 'react';
2
+ import { makeStyles } from '../../../utils/makeStyles';
3
+ export const useLabelSize = (size = 'base') => {
4
+ const styles = useStyles();
5
+ return useMemo(() => {
6
+ return [styles.common, styles[size]];
7
+ }, [size, styles]);
8
+ };
9
+ const useStyles = makeStyles(({ typography }) => ({
10
+ common: {
11
+ fontWeight: '600',
12
+ includeFontPadding: false,
13
+ verticalAlign: 'middle',
14
+ },
15
+ xlarge: { fontSize: typography.Size['text-2xl'] },
16
+ large: { fontSize: typography.Size['text-xl'] },
17
+ base: { fontSize: typography.Size['text-base'] },
18
+ small: { fontSize: typography.Size['text-sm'] },
19
+ }));
@@ -0,0 +1,11 @@
1
+ export declare const useStateStyles: (checked?: boolean, disabled?: boolean, pressed?: boolean) => {
2
+ borderContainer: (false | {
3
+ borderColor: string;
4
+ })[];
5
+ contentContainer: (false | {
6
+ backgroundColor: string;
7
+ })[];
8
+ label: (false | {
9
+ color: string;
10
+ })[];
11
+ };
@@ -0,0 +1,92 @@
1
+ import { useMemo } from 'react';
2
+ import { makeStyles } from '../../../utils/makeStyles';
3
+ export const useStateStyles = (checked = false, disabled = false, pressed = false) => {
4
+ const styles = useStyles();
5
+ const borderContainer = useMemo(() => [
6
+ styles.borderContainer,
7
+ pressed && styles.pressedBorderContainer,
8
+ checked && styles.checkedBorderContainer,
9
+ checked && pressed && styles.checkedPressedBorderContainer,
10
+ disabled && styles.disabledBorderContainer,
11
+ ], [
12
+ checked,
13
+ disabled,
14
+ pressed,
15
+ styles.borderContainer,
16
+ styles.checkedBorderContainer,
17
+ styles.checkedPressedBorderContainer,
18
+ styles.disabledBorderContainer,
19
+ styles.pressedBorderContainer,
20
+ ]);
21
+ const contentContainer = useMemo(() => [
22
+ styles.contentContainer,
23
+ pressed && styles.pressedContentContainer,
24
+ checked && styles.checkedContentContainer,
25
+ checked && pressed && styles.checkedPressedContentContainer,
26
+ disabled && styles.disabledContentContainer,
27
+ ], [
28
+ checked,
29
+ disabled,
30
+ pressed,
31
+ styles.checkedContentContainer,
32
+ styles.checkedPressedContentContainer,
33
+ styles.contentContainer,
34
+ styles.disabledContentContainer,
35
+ styles.pressedContentContainer,
36
+ ]);
37
+ const label = useMemo(() => [
38
+ styles.label,
39
+ pressed && styles.pressedLabel,
40
+ checked && styles.checkedLabel,
41
+ checked && pressed && styles.checkedPressedLabel,
42
+ disabled && styles.disabledLabel,
43
+ ], [
44
+ checked,
45
+ disabled,
46
+ pressed,
47
+ styles.checkedLabel,
48
+ styles.checkedPressedLabel,
49
+ styles.disabledLabel,
50
+ styles.label,
51
+ styles.pressedLabel,
52
+ ]);
53
+ return useMemo(() => ({ borderContainer, contentContainer, label }), [borderContainer, contentContainer, label]);
54
+ };
55
+ const useStyles = makeStyles(({ theme }) => ({
56
+ borderContainer: {
57
+ borderColor: theme.Form.ToggleButton.toggleButtonBorderColor,
58
+ },
59
+ pressedBorderContainer: {
60
+ borderColor: theme.Form.ToggleButton.toggleButtonHoverBg,
61
+ },
62
+ checkedBorderContainer: {
63
+ borderColor: theme.Form.ToggleButton.toggleButtonActiveBorderColor,
64
+ },
65
+ checkedPressedBorderContainer: {
66
+ borderColor: theme.Form.ToggleButton.toggleButtonActiveHoverBorderColor,
67
+ },
68
+ disabledBorderContainer: {
69
+ borderColor: theme.Button.Disabled.disabledButtonBorderColor,
70
+ opacity: 0.6,
71
+ },
72
+ contentContainer: { backgroundColor: theme.Form.ToggleButton.toggleButtonBg },
73
+ pressedContentContainer: {
74
+ backgroundColor: theme.Form.ToggleButton.toggleButtonHoverBg,
75
+ },
76
+ checkedContentContainer: {
77
+ backgroundColor: theme.Form.ToggleButton.toggleButtonActiveBg,
78
+ },
79
+ checkedPressedContentContainer: {
80
+ backgroundColor: theme.Form.ToggleButton.toggleButtonActiveHoverBg,
81
+ },
82
+ disabledContentContainer: {
83
+ backgroundColor: theme.Button.Disabled.disabledButtonBg,
84
+ },
85
+ label: { color: theme.Form.ToggleButton.toggleButtonTextColor },
86
+ pressedLabel: { color: theme.Form.ToggleButton.toggleButtonHoverTextColor },
87
+ checkedLabel: { color: theme.Form.ToggleButton.toggleButtonActiveTextColor },
88
+ checkedPressedLabel: {
89
+ color: theme.Form.ToggleButton.toggleButtonTextActiveHoverColor,
90
+ },
91
+ disabledLabel: { color: theme.Button.Disabled.disabledButtonTextColor },
92
+ }));
@@ -0,0 +1 @@
1
+ export { ToggleButton, type ToggleButtonProps } from './ToggleButton';
@@ -0,0 +1 @@
1
+ export { ToggleButton } from './ToggleButton';
@@ -0,0 +1,31 @@
1
+ import { type StyleProp, type TextProps, type TextStyle } from 'react-native';
2
+ import { type SvgSource } from '../../utils/SvgUniversal';
3
+ export interface AnchorProps extends Omit<TextProps, 'onPressIn' | 'onPressOut'> {
4
+ readonly onPress: () => void;
5
+ /** true, если необходим базовый размер текста ссылки, равный 14 */
6
+ readonly base?: boolean;
7
+ /** true, если необходимо состояние посещенной ссылки. Меняет цвет */
8
+ readonly visited?: boolean;
9
+ /**
10
+ * Используется для рендера ссылки в составе другого текста.
11
+ * Если true, компонент оборачивается во фрагмент вместо обычного View
12
+ */
13
+ readonly noWrapper?: boolean;
14
+ /** Кастомные стили, применяемые к тексту */
15
+ readonly style?: StyleProp<TextStyle>;
16
+ readonly LeftIcon?: SvgSource;
17
+ readonly RightIcon?: SvgSource;
18
+ }
19
+ /**
20
+ * Используется для ссылок и якорей
21
+ * @see https://www.figma.com/design/2ZnL6XPKEpxAHvrlbRvnMu/Template-Tailwind-CSS--DS-?node-id=1-271
22
+ */
23
+ export declare const Anchor: import("react").MemoExoticComponent<({ onPress, base, visited, children, noWrapper, LeftIcon, RightIcon, testID, style, ...other }: AnchorProps) => import("react").JSX.Element>;
24
+ export declare const AnchorTestId: {
25
+ root: string;
26
+ leftPressable: string;
27
+ rightPressable: string;
28
+ leftIcon: string;
29
+ rightIcon: string;
30
+ text: string;
31
+ };