jp-composter 0.1.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 (194) hide show
  1. package/dist/index.d.mts +997 -0
  2. package/dist/index.d.ts +997 -0
  3. package/dist/index.js +36837 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/index.mjs +36778 -0
  6. package/dist/index.mjs.map +1 -0
  7. package/package.json +66 -0
  8. package/src/SliceUI/IconMoon.tsx +33 -0
  9. package/src/SliceUI/assets/Anatomy diagram copy.svg +19 -0
  10. package/src/SliceUI/assets/Anatomy diagram.svg +19 -0
  11. package/src/SliceUI/assets/Anatomycheck.svg +15 -0
  12. package/src/SliceUI/assets/Anatomyinput.svg +32 -0
  13. package/src/SliceUI/assets/Checkbox.jpg +0 -0
  14. package/src/SliceUI/assets/Diagram copy.svg +15 -0
  15. package/src/SliceUI/assets/Diagram.jpg +0 -0
  16. package/src/SliceUI/assets/Diagram.svg +15 -0
  17. package/src/SliceUI/assets/Frame 5 copy.png +0 -0
  18. package/src/SliceUI/assets/Frame 5.png +0 -0
  19. package/src/SliceUI/assets/Frame 65.png +0 -0
  20. package/src/SliceUI/assets/Frame_65.png +0 -0
  21. package/src/SliceUI/assets/Icon copy.svg +3 -0
  22. package/src/SliceUI/assets/Icon.svg +3 -0
  23. package/src/SliceUI/assets/Icon_Bridging copy.svg +39 -0
  24. package/src/SliceUI/assets/Icon_Bridging.svg +39 -0
  25. package/src/SliceUI/assets/Icon_Consistent copy.svg +39 -0
  26. package/src/SliceUI/assets/Icon_Consistent.svg +39 -0
  27. package/src/SliceUI/assets/Icon_Plug copy.svg +38 -0
  28. package/src/SliceUI/assets/Icon_Plug.svg +38 -0
  29. package/src/SliceUI/assets/Icon_Reusable copy.svg +39 -0
  30. package/src/SliceUI/assets/Icon_Reusable.svg +39 -0
  31. package/src/SliceUI/assets/Layer_1.png +0 -0
  32. package/src/SliceUI/assets/accessibility.png +0 -0
  33. package/src/SliceUI/assets/accessibility.svg +1 -0
  34. package/src/SliceUI/assets/addon-library.png +0 -0
  35. package/src/SliceUI/assets/assets.png +0 -0
  36. package/src/SliceUI/assets/avif-test-image.avif +0 -0
  37. package/src/SliceUI/assets/bridging.svg +13 -0
  38. package/src/SliceUI/assets/consistent.svg +11 -0
  39. package/src/SliceUI/assets/context.png +0 -0
  40. package/src/SliceUI/assets/discord.svg +1 -0
  41. package/src/SliceUI/assets/docs.png +0 -0
  42. package/src/SliceUI/assets/figma-plugin.png +0 -0
  43. package/src/SliceUI/assets/github.svg +1 -0
  44. package/src/SliceUI/assets/resources/Anatomy diagram.svg +19 -0
  45. package/src/SliceUI/assets/resources/Anatomycheck.svg +15 -0
  46. package/src/SliceUI/assets/resources/Anatomyinput.svg +32 -0
  47. package/src/SliceUI/assets/resources/Diagram.svg +15 -0
  48. package/src/SliceUI/assets/resources/Frame 5.png +0 -0
  49. package/src/SliceUI/assets/resources/Frame 65.png +0 -0
  50. package/src/SliceUI/assets/resources/Icon.svg +3 -0
  51. package/src/SliceUI/assets/resources/Icon_Bridging.svg +39 -0
  52. package/src/SliceUI/assets/resources/Icon_Consistent.svg +39 -0
  53. package/src/SliceUI/assets/resources/Icon_Plug.svg +38 -0
  54. package/src/SliceUI/assets/resources/Icon_Reusable.svg +39 -0
  55. package/src/SliceUI/assets/resources/fonts/FontIcon.json +150 -0
  56. package/src/SliceUI/assets/resources/fonts/Lato-Black.ttf +0 -0
  57. package/src/SliceUI/assets/resources/fonts/Lato-Bold.ttf +0 -0
  58. package/src/SliceUI/assets/resources/fonts/Lato-Heavy.ttf +0 -0
  59. package/src/SliceUI/assets/resources/fonts/Lato-Medium.ttf +0 -0
  60. package/src/SliceUI/assets/resources/fonts/Lato-Regular.ttf +0 -0
  61. package/src/SliceUI/assets/resources/fonts/Lato.woff2 +0 -0
  62. package/src/SliceUI/assets/resources/fonts/icomoon.eot +0 -0
  63. package/src/SliceUI/assets/resources/fonts/icomoon.svg +601 -0
  64. package/src/SliceUI/assets/resources/fonts/icomoon.ttf +0 -0
  65. package/src/SliceUI/assets/resources/fonts/icomoon.woff +0 -0
  66. package/src/SliceUI/assets/resources/fonts/selection.json +1 -0
  67. package/src/SliceUI/assets/share.png +0 -0
  68. package/src/SliceUI/assets/styling.png +0 -0
  69. package/src/SliceUI/assets/testing.png +0 -0
  70. package/src/SliceUI/assets/theming.png +0 -0
  71. package/src/SliceUI/assets/tutorials.svg +1 -0
  72. package/src/SliceUI/assets/youtube.svg +1 -0
  73. package/src/SliceUI/automation/helper.ts +29 -0
  74. package/src/SliceUI/avatar/Avatar.tsx +237 -0
  75. package/src/SliceUI/avatar/Token.ts +116 -0
  76. package/src/SliceUI/avatar/Type.ts +36 -0
  77. package/src/SliceUI/avatar/helper.ts +53 -0
  78. package/src/SliceUI/badge/Badge.tsx +308 -0
  79. package/src/SliceUI/badge/Token.ts +202 -0
  80. package/src/SliceUI/badge/Type.ts +46 -0
  81. package/src/SliceUI/badge/helper.ts +39 -0
  82. package/src/SliceUI/button/Button.tsx +243 -0
  83. package/src/SliceUI/button/Token.ts +138 -0
  84. package/src/SliceUI/button/Type.ts +34 -0
  85. package/src/SliceUI/button/helper.ts +125 -0
  86. package/src/SliceUI/checkbox/Checkbox.tsx +176 -0
  87. package/src/SliceUI/checkbox/Token.ts +128 -0
  88. package/src/SliceUI/checkbox/Type.ts +35 -0
  89. package/src/SliceUI/chip/Chip.tsx +290 -0
  90. package/src/SliceUI/chip/Token.ts +151 -0
  91. package/src/SliceUI/chip/Type.ts +43 -0
  92. package/src/SliceUI/chip/helper.ts +40 -0
  93. package/src/SliceUI/colors/Pallete.ts +151 -0
  94. package/src/SliceUI/colors/Token.ts +110 -0
  95. package/src/SliceUI/colors/Type.ts +56 -0
  96. package/src/SliceUI/contextProvider/context.tsx +108 -0
  97. package/src/SliceUI/divider/Divider.tsx +109 -0
  98. package/src/SliceUI/divider/Token.ts +18 -0
  99. package/src/SliceUI/divider/Type.ts +26 -0
  100. package/src/SliceUI/icon/CustomIcon.ts +4 -0
  101. package/src/SliceUI/icon/IcoMoonIcon.tsx +11 -0
  102. package/src/SliceUI/icon/Icon.tsx +38 -0
  103. package/src/SliceUI/icon/Token.ts +14 -0
  104. package/src/SliceUI/icon/Type.ts +13 -0
  105. package/src/SliceUI/icon/selection.json +1 -0
  106. package/src/SliceUI/input/Input.tsx +573 -0
  107. package/src/SliceUI/input/ToDo.md +99 -0
  108. package/src/SliceUI/input/Token.ts +372 -0
  109. package/src/SliceUI/input/Type.ts +109 -0
  110. package/src/SliceUI/input/components/InputPortal.tsx +211 -0
  111. package/src/SliceUI/input/components/NativeBottomSheet.tsx +296 -0
  112. package/src/SliceUI/input/components/SelectChip.tsx +185 -0
  113. package/src/SliceUI/input/components/SelectList.tsx +173 -0
  114. package/src/SliceUI/input/components/SelectListItem.tsx +377 -0
  115. package/src/SliceUI/input/components/SelectScrollbarStyle.ts +44 -0
  116. package/src/SliceUI/input/hooks/useCustomScrollbar.ts +17 -0
  117. package/src/SliceUI/input/hooks/useInputState.ts +41 -0
  118. package/src/SliceUI/input/hooks/useLabelAnimation.ts +132 -0
  119. package/src/SliceUI/input/hooks/useOutsideClick.ts +38 -0
  120. package/src/SliceUI/input/hooks/useSelectLogic.ts +338 -0
  121. package/src/SliceUI/input/utils/inputUtils.ts +120 -0
  122. package/src/SliceUI/input/utils/selectUtils.ts +85 -0
  123. package/src/SliceUI/input/utils/styleUtils.ts +50 -0
  124. package/src/SliceUI/input/variants/CurrencyInput/CurrencyInput.tsx +16 -0
  125. package/src/SliceUI/input/variants/CurrencyInput/NativeCurrencyInput.tsx +181 -0
  126. package/src/SliceUI/input/variants/CurrencyInput/WebCurrencyInput.tsx +163 -0
  127. package/src/SliceUI/input/variants/CurrencyInput/types.ts +17 -0
  128. package/src/SliceUI/input/variants/PhoneInput/NativePhoneInput.tsx +189 -0
  129. package/src/SliceUI/input/variants/PhoneInput/PhoneInput.tsx +16 -0
  130. package/src/SliceUI/input/variants/PhoneInput/WebPhoneInput.tsx +291 -0
  131. package/src/SliceUI/input/variants/PhoneInput/types.ts +22 -0
  132. package/src/SliceUI/input/variants/SelectInput/SelectInput.tsx +407 -0
  133. package/src/SliceUI/input/variants/SelectInput/types.ts +34 -0
  134. package/src/SliceUI/input/variants/TextInput.tsx +68 -0
  135. package/src/SliceUI/layout/Box.tsx +38 -0
  136. package/src/SliceUI/layout/Center.tsx +38 -0
  137. package/src/SliceUI/layout/Divider.tsx +37 -0
  138. package/src/SliceUI/layout/Grid.tsx +75 -0
  139. package/src/SliceUI/layout/PageContainer.tsx +60 -0
  140. package/src/SliceUI/layout/ScrollContainer.tsx +72 -0
  141. package/src/SliceUI/layout/Spacer.tsx +54 -0
  142. package/src/SliceUI/layout/Stack.tsx +97 -0
  143. package/src/SliceUI/layout/StickyHeader.tsx +71 -0
  144. package/src/SliceUI/radio/RadioButton.tsx +130 -0
  145. package/src/SliceUI/radio/Token.ts +197 -0
  146. package/src/SliceUI/radio/Type.ts +35 -0
  147. package/src/SliceUI/react-native.config.js +3 -0
  148. package/src/SliceUI/responsive/Type.ts +7 -0
  149. package/src/SliceUI/responsive/helper.ts +53 -0
  150. package/src/SliceUI/switch/Switch.tsx +119 -0
  151. package/src/SliceUI/switch/Token.ts +205 -0
  152. package/src/SliceUI/switch/Type.ts +26 -0
  153. package/src/SliceUI/tab/TabItem.tsx +204 -0
  154. package/src/SliceUI/tab/Tabs.tsx +110 -0
  155. package/src/SliceUI/tab/Token.ts +282 -0
  156. package/src/SliceUI/tab/Type.ts +66 -0
  157. package/src/SliceUI/tab/helper.ts +53 -0
  158. package/src/SliceUI/table/Table.tsx +388 -0
  159. package/src/SliceUI/table/TableCell.tsx +158 -0
  160. package/src/SliceUI/table/TableFooter.tsx +353 -0
  161. package/src/SliceUI/table/TableHeader.tsx +247 -0
  162. package/src/SliceUI/table/TableRow.tsx +218 -0
  163. package/src/SliceUI/table/Token.ts +252 -0
  164. package/src/SliceUI/table/Type.ts +213 -0
  165. package/src/SliceUI/table/helper.ts +376 -0
  166. package/src/SliceUI/table/index.ts +53 -0
  167. package/src/SliceUI/theme/dummyColors.tsx +7 -0
  168. package/src/SliceUI/theme/theme.ts +107 -0
  169. package/src/SliceUI/typography/BaseTypographyToken.ts +62 -0
  170. package/src/SliceUI/typography/FoundationToken.ts +48 -0
  171. package/src/SliceUI/typography/Token.ts +228 -0
  172. package/src/SliceUI/typography/Type.ts +20 -0
  173. package/src/SliceUI/typography/Typography.tsx +99 -0
  174. package/src/SliceUI/values/BorderRadius.ts +17 -0
  175. package/src/SliceUI/values/BorderWidth.ts +7 -0
  176. package/src/SliceUI/values/Dimension.ts +35 -0
  177. package/src/SliceUI/values/IconSizes.ts +13 -0
  178. package/src/SliceUI/values/Spacing.ts +22 -0
  179. package/src/declarations.d.ts +8 -0
  180. package/src/index.tsx +119 -0
  181. package/src/stories/Colors.mdx +1418 -0
  182. package/src/stories/Dimensions.mdx +60 -0
  183. package/src/stories/GetStarted.mdx +90 -0
  184. package/src/stories/Introduction.mdx +136 -0
  185. package/src/stories/Shape.mdx +126 -0
  186. package/src/stories/Spacing.mdx +104 -0
  187. package/src/stories/Typography.mdx +454 -0
  188. package/src/stories/Utils.mdx +277 -0
  189. package/src/stories/story-components/AddIcon.js +13 -0
  190. package/src/stories/story-components/RectangleWithBox.jsx +51 -0
  191. package/src/stories/story-components/RoundedRectangle.jsx +18 -0
  192. package/src/stories/story-components/RoundedWithWhiteInside.jsx +33 -0
  193. package/src/stories/story-components/WhiteRoundedRectangle.jsx +107 -0
  194. package/src/stories/story-components/svgPaths.js +126 -0
@@ -0,0 +1,205 @@
1
+ import {dimensions} from '../values/Dimension';
2
+ import {borderRadius} from '../values/BorderRadius';
3
+ import {spacing} from '../values/Spacing';
4
+ import type {ExtendedTheme} from '../colors/Type';
5
+ import type {SwitchThemeSize} from './Type';
6
+
7
+ export const SWITCH_THEME: SwitchThemeSize = {
8
+ large: {
9
+ default: (theme: ExtendedTheme) => ({
10
+ track: {
11
+ width: dimensions.dimension20,
12
+ height: dimensions.dimension16,
13
+ borderRadius: borderRadius.borderRadiusFull,
14
+ paddingTop: spacing.space50,
15
+ paddingRight: spacing.space50,
16
+ paddingBottom: spacing.space50,
17
+ borderWidth: 0.5,
18
+ borderColor: theme.colors.colorBorderLight,
19
+ backgroundColor: theme.colors.colorBackgroundLight,
20
+ justifyContent: 'flex-end',
21
+ alignItems: 'center',
22
+ },
23
+ thumb: {
24
+ width: dimensions.dimension14,
25
+ height: dimensions.dimension14,
26
+ borderRadius: borderRadius.borderRadiusFull,
27
+ backgroundColor: theme.colors.colorBackgroundTertiary,
28
+ aspectRatio: 1,
29
+ },
30
+ }),
31
+ checked: (theme: ExtendedTheme, brand: 'CO' | 'CM' | 'OTHER') => ({
32
+ track: {
33
+ width: dimensions.dimension20,
34
+ height: dimensions.dimension16,
35
+ borderRadius: borderRadius.borderRadiusFull,
36
+ backgroundColor: theme.colors.colorBackgroundAccent,
37
+ paddingTop: spacing.space50,
38
+ paddingRight: spacing.space50,
39
+ paddingBottom: spacing.space50,
40
+ paddingLeft: dimensions.dimension09,
41
+ justifyContent: 'flex-end',
42
+ alignItems: 'center',
43
+ },
44
+ thumb: {
45
+ width: dimensions.dimension14,
46
+ height: dimensions.dimension14,
47
+ borderRadius: borderRadius.borderRadiusFull,
48
+ backgroundColor: theme.colors.colorForegroundInvariable,
49
+ aspectRatio: 1,
50
+ },
51
+ }),
52
+ disabled: (theme: ExtendedTheme) => ({
53
+ track: {
54
+ width: dimensions.dimension20,
55
+ height: dimensions.dimension16,
56
+ borderRadius: borderRadius.borderRadiusFull,
57
+ backgroundColor: theme.colors.colorStatePrimaryDisabled2,
58
+ paddingTop: spacing.space50,
59
+ paddingRight: spacing.space50,
60
+ paddingBottom: spacing.space50,
61
+ justifyContent: 'flex-end',
62
+ alignItems: 'center',
63
+ borderWidth: 0.5,
64
+ borderColor: theme.colors.colorStatePrimaryDisabled,
65
+ },
66
+ thumb: {
67
+ width: dimensions.dimension14,
68
+ height: dimensions.dimension14,
69
+ borderRadius: borderRadius.borderRadiusFull,
70
+ backgroundColor: theme.colors.colorStateContrastWhiteDisabled,
71
+ aspectRatio: 1,
72
+ },
73
+ }),
74
+ },
75
+ medium: {
76
+ default: (theme: ExtendedTheme) => ({
77
+ track: {
78
+ width: dimensions.dimension18,
79
+ height: dimensions.dimension12,
80
+ borderRadius: borderRadius.borderRadiusFull,
81
+ borderWidth: 0.3,
82
+ borderColor: theme.colors.colorBorderLight,
83
+ backgroundColor: theme.colors.colorBackgroundLight,
84
+ paddingTop: spacing.space50,
85
+ paddingRight: spacing.space50,
86
+ paddingBottom: spacing.space50,
87
+ justifyContent: 'flex-end',
88
+ alignItems: 'center',
89
+ },
90
+ thumb: {
91
+ width: dimensions.dimension10,
92
+ height: dimensions.dimension10,
93
+ borderRadius: borderRadius.borderRadiusFull,
94
+ backgroundColor: theme.colors.colorBackgroundTertiary,
95
+ aspectRatio: 1,
96
+ },
97
+ }),
98
+ checked: (theme: ExtendedTheme, brand: 'CO' | 'CM') => ({
99
+ track: {
100
+ width: dimensions.dimension18,
101
+ height: dimensions.dimension12,
102
+ borderRadius: borderRadius.borderRadiusFull,
103
+ backgroundColor: theme.colors.colorBackgroundAccent,
104
+ paddingTop: spacing.space50,
105
+ paddingRight: spacing.space50,
106
+ paddingBottom: spacing.space50,
107
+ paddingLeft: dimensions.dimension07,
108
+ justifyContent: 'flex-end',
109
+ alignItems: 'center',
110
+ },
111
+ thumb: {
112
+ width: dimensions.dimension10,
113
+ height: dimensions.dimension10,
114
+ borderRadius: borderRadius.borderRadiusFull,
115
+ backgroundColor: theme.colors.colorForegroundInvariable,
116
+ aspectRatio: 1,
117
+ },
118
+ }),
119
+ disabled: (theme: ExtendedTheme) => ({
120
+ track: {
121
+ width: dimensions.dimension18,
122
+ height: dimensions.dimension12,
123
+ borderRadius: borderRadius.borderRadiusFull,
124
+ backgroundColor: theme.colors.colorStateAccentDisabled,
125
+ paddingTop: spacing.space50,
126
+ paddingRight: spacing.space50,
127
+ paddingBottom: spacing.space50,
128
+ justifyContent: 'flex-end',
129
+ alignItems: 'center',
130
+ },
131
+ thumb: {
132
+ width: dimensions.dimension10,
133
+ height: dimensions.dimension10,
134
+ borderRadius: borderRadius.borderRadiusFull,
135
+ backgroundColor: theme.colors.colorStateContrastWhiteDisabled,
136
+ aspectRatio: 1,
137
+ },
138
+ }),
139
+ },
140
+ small: {
141
+ default: (theme: ExtendedTheme) => ({
142
+ track: {
143
+ width: dimensions.dimension16,
144
+ height: dimensions.dimension10,
145
+ borderRadius: borderRadius.borderRadiusFull,
146
+ borderWidth: 0.2,
147
+ borderColor: theme.colors.colorBorderLight,
148
+ backgroundColor: theme.colors.colorBackgroundLight,
149
+ paddingTop: spacing.space50,
150
+ paddingRight: spacing.space50,
151
+ paddingBottom: spacing.space50,
152
+ justifyContent: 'flex-end',
153
+ alignItems: 'center',
154
+ },
155
+ thumb: {
156
+ width: dimensions.dimension08,
157
+ height: dimensions.dimension08,
158
+ borderRadius: borderRadius.borderRadiusFull,
159
+ backgroundColor: theme.colors.colorBackgroundTertiary,
160
+ aspectRatio: 1,
161
+ },
162
+ }),
163
+ checked: (theme: ExtendedTheme, brand: 'CO' | 'CM') => ({
164
+ track: {
165
+ width: dimensions.dimension16,
166
+ height: dimensions.dimension10,
167
+ borderRadius: borderRadius.borderRadiusFull,
168
+ backgroundColor: theme.colors.colorBackgroundAccent,
169
+ paddingTop: spacing.space50,
170
+ paddingRight: spacing.space50,
171
+ paddingBottom: spacing.space50,
172
+ paddingLeft: dimensions.dimension03,
173
+ justifyContent: 'flex-end',
174
+ alignItems: 'center',
175
+ },
176
+ thumb: {
177
+ width: dimensions.dimension08,
178
+ height: dimensions.dimension08,
179
+ borderRadius: borderRadius.borderRadiusFull,
180
+ backgroundColor: theme.colors.colorForegroundInvariable,
181
+ aspectRatio: 1,
182
+ },
183
+ }),
184
+ disabled: (theme: ExtendedTheme) => ({
185
+ track: {
186
+ width: dimensions.dimension16,
187
+ height: dimensions.dimension10,
188
+ borderRadius: borderRadius.borderRadiusFull,
189
+ backgroundColor: theme.colors.colorStatePrimaryDisabled,
190
+ paddingTop: spacing.space50,
191
+ paddingRight: spacing.space50,
192
+ paddingBottom: spacing.space50,
193
+ justifyContent: 'flex-end',
194
+ alignItems: 'center',
195
+ },
196
+ thumb: {
197
+ width: dimensions.dimension08,
198
+ height: dimensions.dimension08,
199
+ borderRadius: borderRadius.borderRadiusFull,
200
+ backgroundColor: theme.colors.colorStatePrimaryDisabled,
201
+ aspectRatio: 1,
202
+ },
203
+ }),
204
+ },
205
+ };
@@ -0,0 +1,26 @@
1
+ import type {ViewStyle} from 'react-native';
2
+ import type {ExtendedTheme} from '../colors/Type';
3
+
4
+ export type SwitchSize = 'small' | 'medium' | 'large';
5
+ export type SwitchState = 'default' | 'checked' | 'disabled';
6
+ export type SwitchBrand = 'CO' | 'CM';
7
+
8
+ export interface SwitchTheme {
9
+ track: ViewStyle;
10
+ thumb: ViewStyle;
11
+ }
12
+
13
+ export type SwitchThemeVariant = {
14
+ [key in SwitchState]: (
15
+ theme: ExtendedTheme,
16
+ brand?: SwitchBrand,
17
+ ) => SwitchTheme;
18
+ };
19
+
20
+ export type SwitchThemeSize = {
21
+ [key in SwitchSize]: {
22
+ default: (theme: ExtendedTheme) => SwitchTheme;
23
+ checked: (theme: ExtendedTheme, brand: SwitchBrand) => SwitchTheme;
24
+ disabled: (theme: ExtendedTheme) => SwitchTheme;
25
+ };
26
+ };
@@ -0,0 +1,204 @@
1
+ import React, {useMemo} from 'react';
2
+ import {
3
+ View,
4
+ Text,
5
+ StyleSheet,
6
+ type ViewStyle,
7
+ type TextStyle,
8
+ TouchableOpacity,
9
+ } from 'react-native';
10
+ import {useSliceTheme} from '../contextProvider/context';
11
+ import {resolveVariant} from '../responsive/helper';
12
+ import type {
13
+ TabSizeType,
14
+ TabVariantType,
15
+ TabStateType,
16
+ TabBrandType,
17
+ } from './Type';
18
+ import {TAB_SIZES, TAB_VARIANTS, TAB_STATES, TAB_BRANDS} from './Type';
19
+ import {setTestId} from '../automation/helper';
20
+ import type {ExtendedTheme} from '../colors/Type';
21
+ import Typography from '../typography/Typography';
22
+ import {getTextColor, getBackgroundColor, getUnderlineColor} from './helper';
23
+ import {TAB_ITEM_STYLE, TAB_ITEM_TXT_STYLE} from './Token';
24
+
25
+ interface TabItemProps {
26
+ screenName?: string;
27
+ id?: number | string;
28
+ label: string;
29
+ size?: TabSizeType;
30
+ variant?: TabVariantType;
31
+ brand?: TabBrandType;
32
+ state?: TabStateType;
33
+ isActive?: boolean;
34
+ disabled?: boolean;
35
+ onPress?: () => void;
36
+ tabItemStyle?: ViewStyle;
37
+ textStyle?: TextStyle;
38
+ }
39
+
40
+ const TabItem: React.FC<TabItemProps> = ({
41
+ screenName,
42
+ id,
43
+ label,
44
+ size = 'medium',
45
+ variant = 'bordered',
46
+ brand = 'cm',
47
+ state = 'default',
48
+ isActive = false,
49
+ disabled = false,
50
+ onPress,
51
+ tabItemStyle,
52
+ textStyle,
53
+ }) => {
54
+ const {theme, deviceBreakpoint} = useSliceTheme();
55
+ const {isDebugBuildType, automationBaseid} = theme;
56
+
57
+ const responsiveSize = useMemo(
58
+ () => resolveVariant(size, deviceBreakpoint),
59
+ [size, deviceBreakpoint],
60
+ );
61
+
62
+ const tabTheme = useMemo(
63
+ () =>
64
+ theme.tabItemStyles?.[responsiveSize as TabSizeType] ||
65
+ TAB_ITEM_STYLE[responsiveSize as TabSizeType],
66
+ [responsiveSize, theme.tabItemStyles],
67
+ );
68
+
69
+ const textTheme = useMemo(
70
+ () =>
71
+ theme.tabItemTextStyles?.[responsiveSize as TabSizeType] ||
72
+ TAB_ITEM_TXT_STYLE[responsiveSize as TabSizeType],
73
+ [responsiveSize, theme.tabItemTextStyles],
74
+ );
75
+
76
+ // Determine actual state based on disabled prop
77
+ const actualState = disabled ? 'disabled' : state;
78
+
79
+ const textColor = useMemo(
80
+ () =>
81
+ getTextColor(
82
+ variant,
83
+ brand,
84
+ actualState as TabStateType,
85
+ isActive,
86
+ theme as ExtendedTheme,
87
+ ),
88
+ [variant, brand, actualState, isActive, theme],
89
+ );
90
+
91
+ const backgroundColor = useMemo(
92
+ () =>
93
+ getBackgroundColor(
94
+ variant,
95
+ brand,
96
+ actualState as TabStateType,
97
+ isActive,
98
+ theme as ExtendedTheme,
99
+ ),
100
+ [variant, brand, actualState, isActive, theme],
101
+ );
102
+
103
+ const underlineColor = useMemo(
104
+ () =>
105
+ getUnderlineColor(
106
+ variant,
107
+ brand,
108
+ actualState as TabStateType,
109
+ isActive,
110
+ theme as ExtendedTheme,
111
+ ),
112
+ [variant, brand, actualState, isActive, theme],
113
+ );
114
+
115
+ const typographyVariant = useMemo(() => {
116
+ switch (responsiveSize) {
117
+ case 'small':
118
+ return 'captionBold';
119
+ case 'medium':
120
+ return 'body2Bold';
121
+ case 'large':
122
+ return 'body1Bold';
123
+ default:
124
+ return 'body2Bold';
125
+ }
126
+ }, [responsiveSize]);
127
+
128
+ const combinedTabStyle = useMemo(
129
+ () =>
130
+ StyleSheet.flatten([
131
+ styles.baseTab,
132
+ tabTheme,
133
+ {
134
+ backgroundColor,
135
+ borderRadius:
136
+ variant === 'filledRounded'
137
+ ? tabTheme.height / 2
138
+ : variant === 'bordered'
139
+ ? 0
140
+ : tabTheme.borderRadius,
141
+ // Add bottom border for bordered variant
142
+ ...(variant === 'bordered' && {
143
+ borderBottomWidth: 2,
144
+ borderBottomColor: isActive ? underlineColor : 'transparent',
145
+ borderBottomLeftRadius: 0,
146
+ borderBottomRightRadius: 0,
147
+ }),
148
+ },
149
+ tabItemStyle,
150
+ ]),
151
+ [
152
+ tabTheme,
153
+ backgroundColor,
154
+ variant,
155
+ tabItemStyle,
156
+ isActive,
157
+ underlineColor,
158
+ ],
159
+ );
160
+
161
+ const combinedTextStyle = useMemo(
162
+ () =>
163
+ StyleSheet.flatten([
164
+ textTheme,
165
+ {
166
+ color: textColor,
167
+ // Reduce weight when inactive as per spec
168
+ ...(isActive ? {} : {fontWeight: '500'}),
169
+ },
170
+ textStyle,
171
+ ]),
172
+ [textTheme, textColor, textStyle, isActive],
173
+ );
174
+
175
+ const renderContent = () => {
176
+ return (
177
+ <Typography style={combinedTextStyle} variant={typographyVariant}>
178
+ {label}
179
+ </Typography>
180
+ );
181
+ };
182
+
183
+ return (
184
+ <TouchableOpacity
185
+ style={combinedTabStyle}
186
+ onPress={disabled ? undefined : onPress}
187
+ disabled={disabled}
188
+ {...(isDebugBuildType && automationBaseid
189
+ ? setTestId(automationBaseid, screenName || 'TabItem', id || 'default')
190
+ : {})}>
191
+ {renderContent()}
192
+ </TouchableOpacity>
193
+ );
194
+ };
195
+
196
+ const styles = StyleSheet.create({
197
+ baseTab: {
198
+ alignItems: 'center',
199
+ justifyContent: 'center',
200
+ flexDirection: 'row',
201
+ },
202
+ });
203
+
204
+ export default TabItem;
@@ -0,0 +1,110 @@
1
+ import React, {useState, useMemo} from 'react';
2
+ import {View, StyleSheet, type ViewStyle} from 'react-native';
3
+ import {useSliceTheme} from '../contextProvider/context';
4
+ import {setTestId} from '../automation/helper';
5
+ import type {TabSizeType, TabVariantType, TabBrandType} from './Type';
6
+ import TabItem from './TabItem';
7
+
8
+ interface TabOption {
9
+ id: string;
10
+ label: string;
11
+ disabled?: boolean;
12
+ }
13
+
14
+ interface TabsProps {
15
+ screenName?: string;
16
+ id?: number | string;
17
+ options: TabOption[];
18
+ activeTabId?: string;
19
+ size?: TabSizeType;
20
+ variant?: TabVariantType;
21
+ brand?: TabBrandType;
22
+ onTabChange?: (tabId: string) => void;
23
+ tabsStyle?: ViewStyle;
24
+ tabItemStyle?: ViewStyle;
25
+ }
26
+
27
+ const Tabs: React.FC<TabsProps> = ({
28
+ screenName,
29
+ id,
30
+ options,
31
+ activeTabId,
32
+ size = 'medium',
33
+ variant = 'bordered',
34
+ brand = 'cm',
35
+ onTabChange,
36
+ tabsStyle,
37
+ tabItemStyle,
38
+ }) => {
39
+ const {theme, deviceBreakpoint} = useSliceTheme();
40
+ const {isDebugBuildType, automationBaseid} = theme;
41
+
42
+ const [internalActiveTab, setInternalActiveTab] = useState<string>(
43
+ activeTabId || options[0]?.id || '',
44
+ );
45
+
46
+ const currentActiveTab = activeTabId || internalActiveTab;
47
+
48
+ const handleTabPress = (tabId: string) => {
49
+ if (onTabChange) {
50
+ onTabChange(tabId);
51
+ } else {
52
+ setInternalActiveTab(tabId);
53
+ }
54
+ };
55
+
56
+ const combinedTabsStyle = useMemo(
57
+ () =>
58
+ StyleSheet.flatten([
59
+ styles.baseTabs,
60
+ // Show a rounded group background only for filledRounded
61
+ variant === 'filledRounded'
62
+ ? {
63
+ backgroundColor: theme.colors.colorBackgroundLight,
64
+ borderRadius: 999,
65
+ padding: 4,
66
+ gap: 4,
67
+ }
68
+ : {},
69
+ tabsStyle,
70
+ ]),
71
+ [variant, theme.colors.colorBackgroundLight, tabsStyle],
72
+ );
73
+
74
+ const renderTabItems = () => {
75
+ return options.map(option => (
76
+ <TabItem
77
+ key={option.id}
78
+ id={`${id}-${option.id}`}
79
+ label={option.label}
80
+ size={size}
81
+ variant={variant}
82
+ brand={brand}
83
+ isActive={currentActiveTab === option.id}
84
+ disabled={option.disabled}
85
+ onPress={() => handleTabPress(option.id)}
86
+ tabItemStyle={tabItemStyle}
87
+ />
88
+ ));
89
+ };
90
+
91
+ return (
92
+ <View
93
+ style={combinedTabsStyle}
94
+ {...(isDebugBuildType && automationBaseid
95
+ ? setTestId(automationBaseid, screenName || 'Tabs', id || 'default')
96
+ : {})}>
97
+ {renderTabItems()}
98
+ </View>
99
+ );
100
+ };
101
+
102
+ const styles = StyleSheet.create({
103
+ baseTabs: {
104
+ flexDirection: 'row',
105
+ alignItems: 'center',
106
+ gap: 8, // Add gap between tab items
107
+ },
108
+ });
109
+
110
+ export default Tabs;