@himakarinv/nativex 1.0.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 (170) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +105 -0
  3. package/images.d.ts +14 -0
  4. package/index.js +8 -0
  5. package/nativewind-preset.js +18 -0
  6. package/package.json +120 -0
  7. package/src/assets/branding/logo.jpg +0 -0
  8. package/src/assets/branding/softech-logo.png +0 -0
  9. package/src/assets/icons/2-layers.svg +3 -0
  10. package/src/assets/icons/Forbidden.svg +211 -0
  11. package/src/assets/icons/Internal-server-error.svg +119 -0
  12. package/src/assets/icons/Log-out-nav.svg +4 -0
  13. package/src/assets/icons/Not-Found.svg +282 -0
  14. package/src/assets/icons/Unauthorized.svg +314 -0
  15. package/src/assets/icons/User-Frame.svg +5 -0
  16. package/src/assets/icons/alert.svg +4 -0
  17. package/src/assets/icons/arrow-right.svg +3 -0
  18. package/src/assets/icons/avatar-female.svg +10 -0
  19. package/src/assets/icons/avatar-male.svg +10 -0
  20. package/src/assets/icons/bell.svg +3 -0
  21. package/src/assets/icons/calendar-event.svg +11 -0
  22. package/src/assets/icons/calendar.svg +6 -0
  23. package/src/assets/icons/card.svg +4 -0
  24. package/src/assets/icons/caret-right.svg +3 -0
  25. package/src/assets/icons/chat.svg +11 -0
  26. package/src/assets/icons/check.svg +3 -0
  27. package/src/assets/icons/checkbox-minus.svg +3 -0
  28. package/src/assets/icons/checkmark.svg +3 -0
  29. package/src/assets/icons/chevron-down.svg +3 -0
  30. package/src/assets/icons/chevron-left.svg +9 -0
  31. package/src/assets/icons/chevron-right.svg +9 -0
  32. package/src/assets/icons/circle-radio-active.svg +10 -0
  33. package/src/assets/icons/circle-radio.svg +10 -0
  34. package/src/assets/icons/clock.svg +3 -0
  35. package/src/assets/icons/close.svg +3 -0
  36. package/src/assets/icons/code.svg +3 -0
  37. package/src/assets/icons/country.svg +20 -0
  38. package/src/assets/icons/dot.svg +3 -0
  39. package/src/assets/icons/download.svg +1 -0
  40. package/src/assets/icons/dropdown-arrow.svg +3 -0
  41. package/src/assets/icons/dropdown-avatar.svg +3 -0
  42. package/src/assets/icons/email.svg +3 -0
  43. package/src/assets/icons/error.svg +3 -0
  44. package/src/assets/icons/eye-off.svg +1 -0
  45. package/src/assets/icons/eye.svg +1 -0
  46. package/src/assets/icons/hashtag-icon.svg +3 -0
  47. package/src/assets/icons/help-circle.svg +10 -0
  48. package/src/assets/icons/help.svg +4 -0
  49. package/src/assets/icons/hide-checkbox.svg +3 -0
  50. package/src/assets/icons/home-smile.svg +3 -0
  51. package/src/assets/icons/home.svg +3 -0
  52. package/src/assets/icons/info.svg +5 -0
  53. package/src/assets/icons/left-arrow.svg +3 -0
  54. package/src/assets/icons/log-out.svg +3 -0
  55. package/src/assets/icons/notification-box.svg +4 -0
  56. package/src/assets/icons/pencil.svg +1 -0
  57. package/src/assets/icons/plus.svg +3 -0
  58. package/src/assets/icons/radio-dot.svg +3 -0
  59. package/src/assets/icons/right-arrow.svg +3 -0
  60. package/src/assets/icons/search.svg +3 -0
  61. package/src/assets/icons/settings.svg +11 -0
  62. package/src/assets/icons/slack.svg +17 -0
  63. package/src/assets/icons/slash.svg +3 -0
  64. package/src/assets/icons/success.svg +3 -0
  65. package/src/assets/icons/successicon.svg +5 -0
  66. package/src/assets/icons/three-dot-vertical.svg +5 -0
  67. package/src/assets/icons/trash.svg +1 -0
  68. package/src/assets/icons/trend-down-01.svg +3 -0
  69. package/src/assets/icons/trend-up-01.svg +3 -0
  70. package/src/assets/icons/up-arrow.svg +3 -0
  71. package/src/assets/icons/user-plus.svg +10 -0
  72. package/src/assets/icons/user.svg +3 -0
  73. package/src/assets/icons/users.svg +3 -0
  74. package/src/assets/icons/vertical-dots-true-icon.svg +5 -0
  75. package/src/assets/icons/vertical-line.svg +3 -0
  76. package/src/assets/icons/vertical-three-dots-icon.svg +5 -0
  77. package/src/assets/icons/warning.svg +3 -0
  78. package/src/assets/icons/zap.svg +3 -0
  79. package/src/components/ActionsMenu/ActionsMenu.tsx +314 -0
  80. package/src/components/ActionsMenu/index.ts +2 -0
  81. package/src/components/Alert/Alert.tsx +291 -0
  82. package/src/components/Alert/index.ts +2 -0
  83. package/src/components/Badge/Badge.tsx +230 -0
  84. package/src/components/Badge/index.ts +2 -0
  85. package/src/components/Breadcrumb/Breadcrumb.tsx +364 -0
  86. package/src/components/Breadcrumb/index.ts +7 -0
  87. package/src/components/Button/Button.tsx +584 -0
  88. package/src/components/Button/index.ts +9 -0
  89. package/src/components/Checkbox/Checkbox.tsx +336 -0
  90. package/src/components/Checkbox/index.ts +2 -0
  91. package/src/components/CreatePassword/CreatePassword.tsx +161 -0
  92. package/src/components/CreatePassword/index.ts +2 -0
  93. package/src/components/DataTable/DataTable.tsx +822 -0
  94. package/src/components/DataTable/index.ts +10 -0
  95. package/src/components/Datepicker/Datepicker.tsx +797 -0
  96. package/src/components/Datepicker/index.ts +2 -0
  97. package/src/components/Dropdown/Dropdown.tsx +277 -0
  98. package/src/components/Dropdown/index.ts +7 -0
  99. package/src/components/DropdownMenu/DropdownMenu.tsx +471 -0
  100. package/src/components/DropdownMenu/index.ts +11 -0
  101. package/src/components/DynamicForm/DynamicForm.tsx +741 -0
  102. package/src/components/DynamicForm/index.ts +13 -0
  103. package/src/components/ErrorPages/ErrorPages.tsx +135 -0
  104. package/src/components/ErrorPages/index.ts +2 -0
  105. package/src/components/ForgotPassword/ForgotPassword.tsx +121 -0
  106. package/src/components/ForgotPassword/index.ts +2 -0
  107. package/src/components/HintError/HintError.tsx +37 -0
  108. package/src/components/HintError/index.ts +2 -0
  109. package/src/components/Icon/Icon.tsx +43 -0
  110. package/src/components/Icon/icon-registry.ts +227 -0
  111. package/src/components/Icon/index.ts +3 -0
  112. package/src/components/InputDropdown/InputDropdown.tsx +662 -0
  113. package/src/components/InputDropdown/index.ts +9 -0
  114. package/src/components/InputField/InputField.tsx +527 -0
  115. package/src/components/InputField/index.ts +2 -0
  116. package/src/components/Label/Label.tsx +88 -0
  117. package/src/components/Label/index.ts +2 -0
  118. package/src/components/LoginForm/LoginForm.tsx +158 -0
  119. package/src/components/LoginForm/index.ts +2 -0
  120. package/src/components/LoginShell/LoginShell.tsx +97 -0
  121. package/src/components/LoginShell/RoleCard.tsx +24 -0
  122. package/src/components/LoginShell/SoftechLogo.tsx +24 -0
  123. package/src/components/LoginShell/branding-assets.ts +2 -0
  124. package/src/components/LoginShell/index.ts +20 -0
  125. package/src/components/LoginShell/login-copy.ts +45 -0
  126. package/src/components/LoginShell/loginPageStyles.ts +210 -0
  127. package/src/components/Modals/Modals.tsx +313 -0
  128. package/src/components/Modals/index.ts +2 -0
  129. package/src/components/Offcanvas/Offcanvas.tsx +404 -0
  130. package/src/components/Offcanvas/index.ts +13 -0
  131. package/src/components/PageHeader/PageHeader.tsx +128 -0
  132. package/src/components/PageHeader/index.ts +2 -0
  133. package/src/components/Pagination/Pagination.tsx +540 -0
  134. package/src/components/Pagination/index.ts +8 -0
  135. package/src/components/ResetPassword/ResetPassword.tsx +172 -0
  136. package/src/components/ResetPassword/index.ts +2 -0
  137. package/src/components/RoleSelection/RoleSelection.tsx +111 -0
  138. package/src/components/RoleSelection/index.ts +2 -0
  139. package/src/components/SendOtp/SendOtp.tsx +149 -0
  140. package/src/components/SendOtp/index.ts +2 -0
  141. package/src/components/Sidenavbar/Sidenavbar.tsx +358 -0
  142. package/src/components/Sidenavbar/index.ts +2 -0
  143. package/src/components/StatCard/StatCard.tsx +393 -0
  144. package/src/components/StatCard/index.ts +6 -0
  145. package/src/components/Tabs/Tabs.tsx +239 -0
  146. package/src/components/Tabs/index.ts +2 -0
  147. package/src/components/Textarea/Textarea.tsx +217 -0
  148. package/src/components/Textarea/index.ts +2 -0
  149. package/src/components/Timepicker/Timepicker.tsx +384 -0
  150. package/src/components/Timepicker/index.ts +2 -0
  151. package/src/components/Toast/Toast.tsx +278 -0
  152. package/src/components/Toast/index.ts +2 -0
  153. package/src/components/Toggle/Toggle.tsx +296 -0
  154. package/src/components/Toggle/index.ts +2 -0
  155. package/src/components/Typeahead/Typeahead.tsx +521 -0
  156. package/src/components/Typeahead/index.ts +2 -0
  157. package/src/components/Verification/Verification.tsx +374 -0
  158. package/src/components/Verification/index.ts +2 -0
  159. package/src/index.ts +39 -0
  160. package/src/theme/borders.ts +19 -0
  161. package/src/theme/button.ts +41 -0
  162. package/src/theme/colors.ts +273 -0
  163. package/src/theme/index.ts +14 -0
  164. package/src/theme/nativewind-theme.js +182 -0
  165. package/src/theme/radius.ts +12 -0
  166. package/src/theme/shadows.ts +40 -0
  167. package/src/theme/spacing.ts +18 -0
  168. package/src/theme/typography.ts +35 -0
  169. package/src/utils/a11y.ts +21 -0
  170. package/svg.d.ts +7 -0
@@ -0,0 +1,358 @@
1
+ import { useEffect, useState } from 'react';
2
+ import {
3
+ Image,
4
+ Pressable,
5
+ ScrollView,
6
+ StyleSheet,
7
+ Text,
8
+ View,
9
+ useWindowDimensions,
10
+ type StyleProp,
11
+ type ViewStyle,
12
+ } from 'react-native';
13
+
14
+ import { borders, colors, radius, spacing, typography } from '../../theme';
15
+ import { Button, ButtonSize, ButtonVariant, IconPosition, dismissButtonFocus } from '../Button';
16
+ import { Icon, IconName } from '../Icon';
17
+
18
+ export type SidenavSubItem = {
19
+ id: string;
20
+ label: string;
21
+ icon: string;
22
+ };
23
+
24
+ export type SidenavItem = {
25
+ id: string;
26
+ label: string;
27
+ icon: string;
28
+ danger?: boolean;
29
+ children?: SidenavSubItem[];
30
+ };
31
+
32
+ export type SidenavSection = {
33
+ title: string;
34
+ items: SidenavItem[];
35
+ scrollable?: boolean;
36
+ };
37
+
38
+ export type SidenavbarProps = {
39
+ logoSrc?: string;
40
+ logoAlt?: string;
41
+ activeItemId?: string;
42
+ bodySections?: SidenavSection[];
43
+ footerSection?: SidenavSection;
44
+ onActiveItemChange?: (id: string) => void;
45
+ onToggleCollapse?: (collapsed: boolean) => void;
46
+ style?: StyleProp<ViewStyle>;
47
+ };
48
+
49
+ function parentOf(sections: SidenavSection[], selectedId: string) {
50
+ for (const section of sections) {
51
+ for (const item of section.items) {
52
+ if (item.children?.some((child) => child.id === selectedId)) {
53
+ return item.id;
54
+ }
55
+ }
56
+ }
57
+ return null;
58
+ }
59
+
60
+ export function Sidenavbar({
61
+ logoSrc = '',
62
+ logoAlt = '',
63
+ activeItemId = 'dashboard',
64
+ bodySections = [],
65
+ footerSection = { title: '', items: [] },
66
+ onActiveItemChange,
67
+ onToggleCollapse,
68
+ style,
69
+ }: SidenavbarProps) {
70
+ const { width } = useWindowDimensions();
71
+ const [selectedId, setSelectedId] = useState(activeItemId);
72
+ const [expandedItemId, setExpandedItemId] = useState<string | null>(() => parentOf(bodySections, activeItemId));
73
+ const [collapsed, setCollapsed] = useState(false);
74
+
75
+ useEffect(() => {
76
+ setSelectedId(activeItemId);
77
+ setExpandedItemId(parentOf(bodySections, activeItemId));
78
+ }, [activeItemId]);
79
+
80
+ const expandedWidth = Math.min(spacing['6xl'] * 6, Math.round(width * 0.82));
81
+ const railWidth = collapsed ? spacing['4xl'] + spacing['6xl'] : expandedWidth;
82
+
83
+ function select(id: string) {
84
+ setSelectedId(id);
85
+ setExpandedItemId(parentOf(bodySections, id));
86
+ onActiveItemChange?.(id);
87
+ }
88
+
89
+ function toggleParent(id: string) {
90
+ setExpandedItemId((current) => (current === id ? null : id));
91
+ }
92
+
93
+ function toggleCollapse() {
94
+ const next = !collapsed;
95
+ setCollapsed(next);
96
+ if (next) {
97
+ setExpandedItemId(null);
98
+ }
99
+ dismissButtonFocus();
100
+ onToggleCollapse?.(next);
101
+ }
102
+
103
+ function renderItem(item: SidenavItem, nested = false) {
104
+ const hasChildren = Boolean(item.children?.length);
105
+ const isSelected = selectedId === item.id;
106
+ const isParentActive = hasChildren && item.children?.some((child) => child.id === selectedId);
107
+ const isActive = isSelected || Boolean(isParentActive);
108
+ const isExpanded = expandedItemId === item.id;
109
+ const iconColor = item.danger
110
+ ? colors.danger.dark
111
+ : isActive
112
+ ? colors.sidenavbar.activeText
113
+ : colors.sidenavbar.text;
114
+
115
+ return (
116
+ <View key={item.id}>
117
+ <Pressable
118
+ accessibilityRole="button"
119
+ accessibilityState={{ selected: isActive, expanded: hasChildren ? isExpanded : undefined }}
120
+ accessibilityLabel={item.label}
121
+ android_ripple={{ color: colors.sidenavbar.hoverBackground, borderless: false }}
122
+ onPress={() => (hasChildren ? toggleParent(item.id) : select(item.id))}
123
+ style={[styles.itemHit, nested && styles.itemNested]}>
124
+ <View
125
+ style={[
126
+ styles.itemInner,
127
+ collapsed && styles.itemInnerCollapsed,
128
+ isActive && !item.danger && styles.itemInnerActive,
129
+ isActive && item.danger && styles.itemInnerDangerActive,
130
+ ]}>
131
+ <Icon name={item.icon} size={spacing.lg} color={iconColor} decorative />
132
+ {collapsed ? null : (
133
+ <Text
134
+ numberOfLines={1}
135
+ style={[
136
+ styles.itemLabel,
137
+ isActive && styles.itemLabelActive,
138
+ item.danger && styles.itemLabelDanger,
139
+ ]}>
140
+ {item.label}
141
+ </Text>
142
+ )}
143
+ {hasChildren && !collapsed ? (
144
+ <Icon
145
+ name={isExpanded ? IconName.ChevronDown : IconName.ChevronRight}
146
+ size={spacing.base}
147
+ color={isActive ? colors.sidenavbar.activeText : colors.sidenavbar.text}
148
+ decorative
149
+ />
150
+ ) : null}
151
+ </View>
152
+ </Pressable>
153
+
154
+ {hasChildren && isExpanded && !collapsed ? (
155
+ <View style={styles.submenu}>
156
+ {item.children?.map((child) =>
157
+ renderItem({ id: child.id, label: child.label, icon: child.icon }, true),
158
+ )}
159
+ </View>
160
+ ) : null}
161
+ </View>
162
+ );
163
+ }
164
+
165
+ function renderSection(section: SidenavSection, footer = false) {
166
+ const list = (
167
+ <View style={styles.navList}>
168
+ {section.items.map((item) => renderItem(item))}
169
+ </View>
170
+ );
171
+
172
+ return (
173
+ <View key={section.title} style={styles.section}>
174
+ {collapsed || !section.title ? null : (
175
+ <Text style={styles.sectionTitle}>{section.title}</Text>
176
+ )}
177
+ {section.scrollable && !footer ? (
178
+ <ScrollView
179
+ style={styles.scrollableList}
180
+ nestedScrollEnabled
181
+ showsVerticalScrollIndicator={false}
182
+ onScrollBeginDrag={() => setExpandedItemId(null)}>
183
+ {list}
184
+ </ScrollView>
185
+ ) : (
186
+ list
187
+ )}
188
+ </View>
189
+ );
190
+ }
191
+
192
+ return (
193
+ <View
194
+ accessibilityLabel="Main navigation"
195
+ style={[styles.host, { width: railWidth }, collapsed && styles.hostCollapsed, style]}>
196
+ <View style={[styles.header, collapsed && styles.headerCollapsed]}>
197
+ <View style={styles.brand}>
198
+ {logoSrc ? (
199
+ <Image accessibilityLabel={logoAlt} resizeMode="contain" source={{ uri: logoSrc }} style={styles.logo} />
200
+ ) : logoAlt ? (
201
+ <Text numberOfLines={1} style={styles.brandText}>
202
+ {logoAlt}
203
+ </Text>
204
+ ) : null}
205
+ </View>
206
+ <Button
207
+ variant={ButtonVariant.SecondaryGray}
208
+ size={ButtonSize.Small}
209
+ iconPosition={IconPosition.Only}
210
+ iconName={collapsed ? IconName.ChevronRight : IconName.ChevronLeft}
211
+ iconDecorative
212
+ accessibilityLabel={collapsed ? 'Expand sidebar' : 'Collapse sidebar'}
213
+ onPress={toggleCollapse}
214
+ contentStyle={styles.collapseBtn}
215
+ />
216
+ </View>
217
+
218
+ <View style={styles.middle}>
219
+ <View style={styles.body}>{bodySections.map((section) => renderSection(section))}</View>
220
+ <View style={styles.tail} />
221
+ <View style={styles.footer}>{renderSection(footerSection, true)}</View>
222
+ </View>
223
+ </View>
224
+ );
225
+ }
226
+
227
+ const styles = StyleSheet.create({
228
+ host: {
229
+ height: '100%',
230
+ maxWidth: '100%',
231
+ backgroundColor: colors.sidenavbar.background,
232
+ borderRightWidth: borders.width.thin,
233
+ borderRightColor: colors.sidenavbar.border,
234
+ },
235
+ hostCollapsed: {
236
+ overflow: 'hidden',
237
+ },
238
+ header: {
239
+ flexDirection: 'row',
240
+ alignItems: 'center',
241
+ gap: spacing.sm,
242
+ paddingVertical: spacing.sm,
243
+ paddingLeft: spacing.base,
244
+ paddingRight: spacing.sm,
245
+ },
246
+ headerCollapsed: {
247
+ flexDirection: 'column',
248
+ paddingHorizontal: spacing.xs,
249
+ },
250
+ brand: {
251
+ flex: 1,
252
+ minWidth: 0,
253
+ },
254
+ logo: {
255
+ width: '100%',
256
+ maxWidth: spacing['6xl'] * 4,
257
+ height: spacing['6xl'],
258
+ },
259
+ brandText: {
260
+ fontFamily: typography.fontFamily.base,
261
+ fontSize: typography.fontSize.md,
262
+ fontWeight: typography.fontWeight.bold,
263
+ color: colors.text.strong,
264
+ },
265
+ collapseBtn: {
266
+ width: spacing['3xl'],
267
+ height: spacing['3xl'],
268
+ minHeight: spacing['3xl'],
269
+ padding: spacing.none,
270
+ backgroundColor: colors.white,
271
+ borderWidth: borders.width.thin,
272
+ borderColor: colors.sidenavbar.border,
273
+ borderRadius: radius.lg,
274
+ },
275
+ middle: {
276
+ flex: 1,
277
+ minHeight: 0,
278
+ },
279
+ body: {
280
+ gap: spacing.sm,
281
+ },
282
+ tail: {
283
+ flex: 1,
284
+ minHeight: spacing.base,
285
+ },
286
+ footer: {
287
+ paddingBottom: spacing.md,
288
+ },
289
+ section: {
290
+ minHeight: 0,
291
+ },
292
+ sectionTitle: {
293
+ paddingVertical: spacing.xs,
294
+ paddingHorizontal: spacing.md,
295
+ fontFamily: typography.fontFamily.base,
296
+ fontSize: typography.fontSize.sm,
297
+ fontWeight: typography.fontWeight.medium,
298
+ textTransform: 'uppercase',
299
+ color: colors.text.muted,
300
+ },
301
+ navList: {
302
+ paddingHorizontal: spacing.sm,
303
+ gap: spacing.xs,
304
+ },
305
+ scrollableList: {
306
+ maxHeight: spacing['5xl'] * 6 + spacing.xs * 5,
307
+ },
308
+ itemHit: {
309
+ width: '100%',
310
+ borderRadius: radius.md,
311
+ overflow: 'hidden',
312
+ },
313
+ submenu: {
314
+ paddingTop: spacing.sm,
315
+ gap: spacing.xs,
316
+ },
317
+ itemNested: {
318
+ paddingLeft: spacing.lg,
319
+ },
320
+ itemInner: {
321
+ minHeight: spacing['5xl'],
322
+ flexDirection: 'row',
323
+ alignItems: 'center',
324
+ gap: spacing.md,
325
+ paddingVertical: spacing.sm,
326
+ paddingHorizontal: spacing.md,
327
+ borderRadius: radius.md,
328
+ overflow: 'hidden',
329
+ },
330
+ itemInnerCollapsed: {
331
+ justifyContent: 'center',
332
+ paddingHorizontal: spacing.sm,
333
+ gap: spacing.none,
334
+ },
335
+ itemInnerActive: {
336
+ backgroundColor: colors.sidenavbar.activeBackground,
337
+ borderRadius: radius.md,
338
+ },
339
+ itemInnerDangerActive: {
340
+ backgroundColor: colors.danger.lighter,
341
+ borderRadius: radius.md,
342
+ },
343
+ itemLabel: {
344
+ flex: 1,
345
+ minWidth: 0,
346
+ fontFamily: typography.fontFamily.base,
347
+ fontSize: typography.fontSize.sm,
348
+ fontWeight: typography.fontWeight.regular,
349
+ color: colors.sidenavbar.text,
350
+ },
351
+ itemLabelActive: {
352
+ fontWeight: typography.fontWeight.bold,
353
+ color: colors.sidenavbar.activeText,
354
+ },
355
+ itemLabelDanger: {
356
+ color: colors.danger.dark,
357
+ },
358
+ });
@@ -0,0 +1,2 @@
1
+ export { Sidenavbar } from './Sidenavbar';
2
+ export type { SidenavbarProps, SidenavSection, SidenavItem, SidenavSubItem } from './Sidenavbar';