@boostdev/design-system-components 2.4.2 → 2.5.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 (201) hide show
  1. package/AGENTS.md +4 -20
  2. package/README.md +3 -23
  3. package/dist/client.cjs +115 -61
  4. package/dist/client.css +537 -537
  5. package/dist/client.d.cts +11 -1
  6. package/dist/client.d.ts +11 -1
  7. package/dist/client.js +115 -61
  8. package/dist/index.cjs +115 -61
  9. package/dist/index.css +537 -537
  10. package/dist/index.d.cts +11 -1
  11. package/dist/index.d.ts +11 -1
  12. package/dist/index.js +115 -61
  13. package/dist/web-components/index.js +23 -3
  14. package/package.json +2 -10
  15. package/src/components/layout/Grid/Grid.mdx +20 -2
  16. package/src/components/layout/Grid/Grid.spec.tsx +175 -4
  17. package/src/components/layout/Grid/Grid.tsx +15 -1
  18. package/src/components/layout/Grid/masonry.ts +120 -9
  19. package/dist/native/index.cjs +0 -4337
  20. package/dist/native/index.d.cts +0 -574
  21. package/dist/native/index.d.ts +0 -574
  22. package/dist/native/index.js +0 -4421
  23. package/src/components/interaction/Button/Button.native.mdx +0 -91
  24. package/src/components/interaction/Button/Button.native.spec.tsx +0 -55
  25. package/src/components/interaction/Button/Button.native.stories.tsx +0 -141
  26. package/src/components/interaction/Button/Button.native.tsx +0 -105
  27. package/src/components/interaction/Dialog/Dialog.native.mdx +0 -61
  28. package/src/components/interaction/Dialog/Dialog.native.spec.tsx +0 -73
  29. package/src/components/interaction/Dialog/Dialog.native.stories.tsx +0 -53
  30. package/src/components/interaction/Dialog/Dialog.native.tsx +0 -128
  31. package/src/components/interaction/Drawer/Drawer.native.mdx +0 -58
  32. package/src/components/interaction/Drawer/Drawer.native.spec.tsx +0 -81
  33. package/src/components/interaction/Drawer/Drawer.native.stories.tsx +0 -33
  34. package/src/components/interaction/Drawer/Drawer.native.tsx +0 -175
  35. package/src/components/interaction/DropdownMenu/DropdownMenu.native.mdx +0 -74
  36. package/src/components/interaction/DropdownMenu/DropdownMenu.native.spec.tsx +0 -78
  37. package/src/components/interaction/DropdownMenu/DropdownMenu.native.stories.tsx +0 -51
  38. package/src/components/interaction/DropdownMenu/DropdownMenu.native.tsx +0 -254
  39. package/src/components/interaction/Popover/Popover.native.mdx +0 -61
  40. package/src/components/interaction/Popover/Popover.native.spec.tsx +0 -73
  41. package/src/components/interaction/Popover/Popover.native.stories.tsx +0 -44
  42. package/src/components/interaction/Popover/Popover.native.tsx +0 -87
  43. package/src/components/interaction/Rating/Rating.native.mdx +0 -55
  44. package/src/components/interaction/Rating/Rating.native.spec.tsx +0 -38
  45. package/src/components/interaction/Rating/Rating.native.stories.tsx +0 -37
  46. package/src/components/interaction/Rating/Rating.native.tsx +0 -50
  47. package/src/components/interaction/Toast/Toast.native.mdx +0 -81
  48. package/src/components/interaction/Toast/Toast.native.spec.tsx +0 -80
  49. package/src/components/interaction/Toast/Toast.native.stories.tsx +0 -47
  50. package/src/components/interaction/Toast/Toast.native.tsx +0 -202
  51. package/src/components/interaction/form/Checkbox/Checkbox.native.mdx +0 -74
  52. package/src/components/interaction/form/Checkbox/Checkbox.native.spec.tsx +0 -42
  53. package/src/components/interaction/form/Checkbox/Checkbox.native.stories.tsx +0 -34
  54. package/src/components/interaction/form/Checkbox/Checkbox.native.tsx +0 -80
  55. package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.native.mdx +0 -78
  56. package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.native.spec.tsx +0 -57
  57. package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.native.stories.tsx +0 -96
  58. package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.native.tsx +0 -61
  59. package/src/components/interaction/form/Combobox/Combobox.native.mdx +0 -86
  60. package/src/components/interaction/form/Combobox/Combobox.native.spec.tsx +0 -60
  61. package/src/components/interaction/form/Combobox/Combobox.native.stories.tsx +0 -99
  62. package/src/components/interaction/form/Combobox/Combobox.native.tsx +0 -211
  63. package/src/components/interaction/form/FileInput/FileInput.native.mdx +0 -86
  64. package/src/components/interaction/form/FileInput/FileInput.native.spec.tsx +0 -73
  65. package/src/components/interaction/form/FileInput/FileInput.native.stories.tsx +0 -69
  66. package/src/components/interaction/form/FileInput/FileInput.native.tsx +0 -129
  67. package/src/components/interaction/form/FormInput/FormInput.native.mdx +0 -81
  68. package/src/components/interaction/form/FormInput/FormInput.native.spec.tsx +0 -51
  69. package/src/components/interaction/form/FormInput/FormInput.native.stories.tsx +0 -54
  70. package/src/components/interaction/form/FormInput/FormInput.native.tsx +0 -122
  71. package/src/components/interaction/form/NumberInput/NumberInput.native.mdx +0 -87
  72. package/src/components/interaction/form/NumberInput/NumberInput.native.spec.tsx +0 -63
  73. package/src/components/interaction/form/NumberInput/NumberInput.native.stories.tsx +0 -63
  74. package/src/components/interaction/form/NumberInput/NumberInput.native.tsx +0 -198
  75. package/src/components/interaction/form/Radio/Radio.native.spec.tsx +0 -79
  76. package/src/components/interaction/form/Radio/Radio.native.stories.tsx +0 -44
  77. package/src/components/interaction/form/Radio/Radio.native.tsx +0 -79
  78. package/src/components/interaction/form/RadioGroup/RadioGroup.native.mdx +0 -79
  79. package/src/components/interaction/form/RadioGroup/RadioGroup.native.spec.tsx +0 -66
  80. package/src/components/interaction/form/RadioGroup/RadioGroup.native.stories.tsx +0 -96
  81. package/src/components/interaction/form/RadioGroup/RadioGroup.native.tsx +0 -61
  82. package/src/components/interaction/form/SegmentedControl/SegmentedControl.native.mdx +0 -78
  83. package/src/components/interaction/form/SegmentedControl/SegmentedControl.native.spec.tsx +0 -82
  84. package/src/components/interaction/form/SegmentedControl/SegmentedControl.native.stories.tsx +0 -99
  85. package/src/components/interaction/form/SegmentedControl/SegmentedControl.native.tsx +0 -121
  86. package/src/components/interaction/form/Select/Select.native.mdx +0 -85
  87. package/src/components/interaction/form/Select/Select.native.spec.tsx +0 -64
  88. package/src/components/interaction/form/Select/Select.native.stories.tsx +0 -75
  89. package/src/components/interaction/form/Select/Select.native.tsx +0 -252
  90. package/src/components/interaction/form/Slider/Slider.native.mdx +0 -83
  91. package/src/components/interaction/form/Slider/Slider.native.spec.tsx +0 -51
  92. package/src/components/interaction/form/Slider/Slider.native.stories.tsx +0 -58
  93. package/src/components/interaction/form/Slider/Slider.native.tsx +0 -188
  94. package/src/components/interaction/form/Switch/Switch.native.spec.tsx +0 -60
  95. package/src/components/interaction/form/Switch/Switch.native.stories.tsx +0 -33
  96. package/src/components/interaction/form/Switch/Switch.native.tsx +0 -59
  97. package/src/components/interaction/form/Textarea/Textarea.native.mdx +0 -76
  98. package/src/components/interaction/form/Textarea/Textarea.native.spec.tsx +0 -50
  99. package/src/components/interaction/form/Textarea/Textarea.native.stories.tsx +0 -50
  100. package/src/components/interaction/form/Textarea/Textarea.native.tsx +0 -108
  101. package/src/components/interaction/form/atoms/Label.native.spec.tsx +0 -39
  102. package/src/components/interaction/form/atoms/Label.native.stories.tsx +0 -18
  103. package/src/components/interaction/form/atoms/Label.native.tsx +0 -29
  104. package/src/components/interaction/form/atoms/Message.native.spec.tsx +0 -30
  105. package/src/components/interaction/form/atoms/Message.native.stories.tsx +0 -22
  106. package/src/components/interaction/form/atoms/Message.native.tsx +0 -34
  107. package/src/components/layout/ButtonGroup/ButtonGroup.native.spec.tsx +0 -83
  108. package/src/components/layout/ButtonGroup/ButtonGroup.native.stories.tsx +0 -44
  109. package/src/components/layout/ButtonGroup/ButtonGroup.native.tsx +0 -44
  110. package/src/components/layout/Card/Card.native.spec.tsx +0 -102
  111. package/src/components/layout/Card/Card.native.stories.tsx +0 -51
  112. package/src/components/layout/Card/Card.native.tsx +0 -89
  113. package/src/components/layout/IconWrapper/IconWrapper.native.spec.tsx +0 -39
  114. package/src/components/layout/IconWrapper/IconWrapper.native.stories.tsx +0 -37
  115. package/src/components/layout/IconWrapper/IconWrapper.native.tsx +0 -20
  116. package/src/components/layout/SectionHeader/SectionHeader.native.spec.tsx +0 -51
  117. package/src/components/layout/SectionHeader/SectionHeader.native.stories.tsx +0 -36
  118. package/src/components/layout/SectionHeader/SectionHeader.native.tsx +0 -79
  119. package/src/components/ui/Accordion/Accordion.native.mdx +0 -65
  120. package/src/components/ui/Accordion/Accordion.native.spec.tsx +0 -69
  121. package/src/components/ui/Accordion/Accordion.native.stories.tsx +0 -52
  122. package/src/components/ui/Accordion/Accordion.native.tsx +0 -141
  123. package/src/components/ui/Alert/Alert.native.mdx +0 -62
  124. package/src/components/ui/Alert/Alert.native.spec.tsx +0 -76
  125. package/src/components/ui/Alert/Alert.native.stories.tsx +0 -41
  126. package/src/components/ui/Alert/Alert.native.tsx +0 -94
  127. package/src/components/ui/Avatar/Avatar.native.mdx +0 -50
  128. package/src/components/ui/Avatar/Avatar.native.spec.tsx +0 -47
  129. package/src/components/ui/Avatar/Avatar.native.stories.tsx +0 -32
  130. package/src/components/ui/Avatar/Avatar.native.tsx +0 -85
  131. package/src/components/ui/Badge/Badge.native.mdx +0 -54
  132. package/src/components/ui/Badge/Badge.native.spec.tsx +0 -45
  133. package/src/components/ui/Badge/Badge.native.stories.tsx +0 -34
  134. package/src/components/ui/Badge/Badge.native.tsx +0 -50
  135. package/src/components/ui/Breadcrumb/Breadcrumb.native.mdx +0 -52
  136. package/src/components/ui/Breadcrumb/Breadcrumb.native.spec.tsx +0 -49
  137. package/src/components/ui/Breadcrumb/Breadcrumb.native.stories.tsx +0 -46
  138. package/src/components/ui/Breadcrumb/Breadcrumb.native.tsx +0 -83
  139. package/src/components/ui/Calendar/Calendar.native.mdx +0 -58
  140. package/src/components/ui/Calendar/Calendar.native.spec.tsx +0 -92
  141. package/src/components/ui/Calendar/Calendar.native.stories.tsx +0 -45
  142. package/src/components/ui/Calendar/Calendar.native.tsx +0 -294
  143. package/src/components/ui/Carousel/Carousel.native.mdx +0 -55
  144. package/src/components/ui/Carousel/Carousel.native.spec.tsx +0 -55
  145. package/src/components/ui/Carousel/Carousel.native.stories.tsx +0 -59
  146. package/src/components/ui/Carousel/Carousel.native.tsx +0 -184
  147. package/src/components/ui/Collapsible/Collapsible.native.mdx +0 -53
  148. package/src/components/ui/Collapsible/Collapsible.native.spec.tsx +0 -68
  149. package/src/components/ui/Collapsible/Collapsible.native.stories.tsx +0 -48
  150. package/src/components/ui/Collapsible/Collapsible.native.tsx +0 -139
  151. package/src/components/ui/DescriptionList/DescriptionList.native.mdx +0 -50
  152. package/src/components/ui/DescriptionList/DescriptionList.native.spec.tsx +0 -37
  153. package/src/components/ui/DescriptionList/DescriptionList.native.stories.tsx +0 -48
  154. package/src/components/ui/DescriptionList/DescriptionList.native.tsx +0 -54
  155. package/src/components/ui/Link/Link.native.mdx +0 -53
  156. package/src/components/ui/Link/Link.native.spec.tsx +0 -35
  157. package/src/components/ui/Link/Link.native.stories.tsx +0 -46
  158. package/src/components/ui/Link/Link.native.tsx +0 -48
  159. package/src/components/ui/Loading/Loading.native.spec.tsx +0 -24
  160. package/src/components/ui/Loading/Loading.native.stories.tsx +0 -31
  161. package/src/components/ui/Loading/Loading.native.tsx +0 -29
  162. package/src/components/ui/NotificationBanner/NotificationBanner.native.spec.tsx +0 -85
  163. package/src/components/ui/NotificationBanner/NotificationBanner.native.stories.tsx +0 -37
  164. package/src/components/ui/NotificationBanner/NotificationBanner.native.tsx +0 -76
  165. package/src/components/ui/Pagination/Pagination.native.mdx +0 -62
  166. package/src/components/ui/Pagination/Pagination.native.spec.tsx +0 -86
  167. package/src/components/ui/Pagination/Pagination.native.stories.tsx +0 -47
  168. package/src/components/ui/Pagination/Pagination.native.tsx +0 -157
  169. package/src/components/ui/Progress/Progress.native.spec.tsx +0 -56
  170. package/src/components/ui/Progress/Progress.native.stories.tsx +0 -34
  171. package/src/components/ui/Progress/Progress.native.tsx +0 -84
  172. package/src/components/ui/ProgressCircle/ProgressCircle.native.mdx +0 -63
  173. package/src/components/ui/ProgressCircle/ProgressCircle.native.spec.tsx +0 -39
  174. package/src/components/ui/ProgressCircle/ProgressCircle.native.stories.tsx +0 -36
  175. package/src/components/ui/ProgressCircle/ProgressCircle.native.tsx +0 -176
  176. package/src/components/ui/Separator/Separator.native.spec.tsx +0 -39
  177. package/src/components/ui/Separator/Separator.native.stories.tsx +0 -38
  178. package/src/components/ui/Separator/Separator.native.tsx +0 -32
  179. package/src/components/ui/Skeleton/Skeleton.native.spec.tsx +0 -39
  180. package/src/components/ui/Skeleton/Skeleton.native.stories.tsx +0 -31
  181. package/src/components/ui/Skeleton/Skeleton.native.tsx +0 -42
  182. package/src/components/ui/Table/Table.native.mdx +0 -72
  183. package/src/components/ui/Table/Table.native.spec.tsx +0 -83
  184. package/src/components/ui/Table/Table.native.stories.tsx +0 -55
  185. package/src/components/ui/Table/Table.native.tsx +0 -196
  186. package/src/components/ui/Tabs/Tabs.native.mdx +0 -65
  187. package/src/components/ui/Tabs/Tabs.native.spec.tsx +0 -65
  188. package/src/components/ui/Tabs/Tabs.native.stories.tsx +0 -57
  189. package/src/components/ui/Tabs/Tabs.native.tsx +0 -133
  190. package/src/components/ui/Tooltip/Tooltip.native.mdx +0 -47
  191. package/src/components/ui/Tooltip/Tooltip.native.spec.tsx +0 -37
  192. package/src/components/ui/Tooltip/Tooltip.native.stories.tsx +0 -38
  193. package/src/components/ui/Tooltip/Tooltip.native.tsx +0 -57
  194. package/src/components/ui/Typography/Typography.native.mdx +0 -56
  195. package/src/components/ui/Typography/Typography.native.spec.tsx +0 -49
  196. package/src/components/ui/Typography/Typography.native.stories.tsx +0 -36
  197. package/src/components/ui/Typography/Typography.native.tsx +0 -65
  198. package/src/native/ThemeContext.tsx +0 -28
  199. package/src/native/tokens.ts +0 -13
  200. package/src/native.ts +0 -76
  201. package/src/stories/ReactNative.mdx +0 -156
@@ -1,4421 +0,0 @@
1
- // src/native/ThemeContext.tsx
2
- import { createContext, useContext, useMemo } from "react";
3
- import { useColorScheme } from "react-native";
4
-
5
- // src/native/tokens.ts
6
- import { colors, spacing, font, border, zIndex, animation } from "@boostdev/design-system-foundation/native";
7
- var lineHeight = {
8
- display: Math.round(font.size.display * font.lineHeight.display),
9
- heading1: Math.round(font.size.heading1 * font.lineHeight.heading),
10
- heading2: Math.round(font.size.heading2 * font.lineHeight.heading),
11
- heading3: Math.round(font.size.heading3 * font.lineHeight.heading),
12
- body: Math.round(font.size.body * font.lineHeight.body),
13
- bodyS: Math.round(font.size.bodyS * font.lineHeight.body)
14
- };
15
-
16
- // src/native/ThemeContext.tsx
17
- import { jsx } from "react/jsx-runtime";
18
- var ThemeContext = createContext(null);
19
- function ThemeProvider({ children, colorScheme }) {
20
- const systemScheme = useColorScheme();
21
- const isDark = (colorScheme ?? systemScheme) === "dark";
22
- const value = useMemo(
23
- () => ({ colors: isDark ? colors.dark : colors.light, isDark }),
24
- [isDark]
25
- );
26
- return /* @__PURE__ */ jsx(ThemeContext.Provider, { value, children });
27
- }
28
- function useTheme() {
29
- const ctx = useContext(ThemeContext);
30
- if (!ctx) throw new Error("useTheme must be used within ThemeProvider");
31
- return ctx;
32
- }
33
-
34
- // src/components/ui/Typography/Typography.native.tsx
35
- import { StyleSheet, Text } from "react-native";
36
- import { jsx as jsx2 } from "react/jsx-runtime";
37
- var styles = StyleSheet.create({
38
- base: {
39
- fontFamily: font.family.body,
40
- fontWeight: font.weight.body
41
- },
42
- h1: {
43
- fontSize: font.size.heading1,
44
- fontFamily: font.family.heading,
45
- fontWeight: font.weight.heading,
46
- lineHeight: lineHeight.heading1
47
- },
48
- h2: {
49
- fontSize: font.size.heading2,
50
- fontFamily: font.family.heading,
51
- fontWeight: font.weight.heading,
52
- lineHeight: lineHeight.heading2
53
- },
54
- h3: {
55
- fontSize: font.size.heading3,
56
- fontFamily: font.family.heading,
57
- fontWeight: font.weight.heading,
58
- lineHeight: lineHeight.heading3
59
- },
60
- body: {
61
- fontSize: font.size.body,
62
- lineHeight: lineHeight.body
63
- },
64
- body_s: {
65
- fontSize: font.size.bodyS,
66
- lineHeight: lineHeight.bodyS
67
- }
68
- });
69
- var accessibilityRoles = {
70
- h1: "header",
71
- h2: "header",
72
- h3: "header",
73
- body: "text",
74
- body_s: "text"
75
- };
76
- function Typography({ variant = "body", children, style }) {
77
- const { colors: colors2 } = useTheme();
78
- return /* @__PURE__ */ jsx2(
79
- Text,
80
- {
81
- accessibilityRole: accessibilityRoles[variant],
82
- style: [styles.base, styles[variant], { color: colors2.colorOnBg }, style],
83
- children
84
- }
85
- );
86
- }
87
-
88
- // src/components/ui/Badge/Badge.native.tsx
89
- import { StyleSheet as StyleSheet2, View, Text as Text2 } from "react-native";
90
- import { jsx as jsx3 } from "react/jsx-runtime";
91
- var styles2 = StyleSheet2.create({
92
- badge: {
93
- alignSelf: "flex-start",
94
- flexDirection: "row",
95
- alignItems: "center",
96
- justifyContent: "center",
97
- paddingVertical: spacing.xxs,
98
- paddingHorizontal: spacing.xs,
99
- borderRadius: border.radius.full
100
- },
101
- text: {
102
- fontSize: font.size.bodyS,
103
- fontFamily: font.family.body,
104
- fontWeight: font.weight.semibold,
105
- lineHeight: font.size.bodyS
106
- }
107
- });
108
- function Badge({ children, variant = "primary", style }) {
109
- const { colors: colors2 } = useTheme();
110
- const variantColors = {
111
- primary: { bg: colors2.colorInteractive, text: colors2.colorOnInteractive },
112
- secondary: { bg: colors2.colorBgSubtle, text: colors2.colorOnBgSubtle },
113
- success: { bg: colors2.colorSuccess, text: colors2.colorOnSuccess },
114
- error: { bg: colors2.colorError, text: colors2.colorOnError },
115
- warning: { bg: colors2.colorWarning, text: colors2.colorOnWarning }
116
- };
117
- const { bg, text } = variantColors[variant];
118
- return /* @__PURE__ */ jsx3(View, { style: [styles2.badge, { backgroundColor: bg }, style], children: /* @__PURE__ */ jsx3(Text2, { style: [styles2.text, { color: text }], children }) });
119
- }
120
-
121
- // src/components/ui/Avatar/Avatar.native.tsx
122
- import { StyleSheet as StyleSheet3, View as View2, Text as Text3, Image } from "react-native";
123
- import { jsx as jsx4 } from "react/jsx-runtime";
124
- var sizeMap = {
125
- small: { container: 32, fontSize: font.size.bodyS },
126
- medium: { container: 48, fontSize: font.size.body },
127
- large: { container: 72, fontSize: font.size.heading3 }
128
- };
129
- function getInitials(name) {
130
- return name.split(" ").filter(Boolean).slice(0, 2).map((word) => word[0].toUpperCase()).join("");
131
- }
132
- var styles3 = StyleSheet3.create({
133
- container: {
134
- borderRadius: border.radius.full,
135
- overflow: "hidden",
136
- alignItems: "center",
137
- justifyContent: "center"
138
- },
139
- image: {
140
- width: "100%",
141
- height: "100%"
142
- },
143
- initials: {
144
- fontFamily: font.family.body,
145
- fontWeight: font.weight.semibold
146
- }
147
- });
148
- function Avatar({ src, alt, name, size = "medium", style }) {
149
- const { colors: colors2 } = useTheme();
150
- const { container, fontSize } = sizeMap[size];
151
- const label = alt ?? name ?? "User avatar";
152
- if (src) {
153
- return /* @__PURE__ */ jsx4(
154
- View2,
155
- {
156
- style: [styles3.container, { width: container, height: container }, style],
157
- accessibilityLabel: label,
158
- accessibilityRole: "image",
159
- children: /* @__PURE__ */ jsx4(Image, { source: { uri: src }, style: styles3.image })
160
- }
161
- );
162
- }
163
- const initials = name ? getInitials(name) : "";
164
- return /* @__PURE__ */ jsx4(
165
- View2,
166
- {
167
- style: [
168
- styles3.container,
169
- { width: container, height: container, backgroundColor: colors2.colorBlue },
170
- style
171
- ],
172
- accessibilityLabel: label,
173
- accessibilityRole: "image",
174
- children: /* @__PURE__ */ jsx4(
175
- Text3,
176
- {
177
- style: [styles3.initials, { fontSize, color: colors2.colorOnBlue }],
178
- importantForAccessibility: "no",
179
- accessibilityElementsHidden: true,
180
- children: initials
181
- }
182
- )
183
- }
184
- );
185
- }
186
-
187
- // src/components/ui/Separator/Separator.native.tsx
188
- import { StyleSheet as StyleSheet4, View as View3 } from "react-native";
189
- import { jsx as jsx5 } from "react/jsx-runtime";
190
- var styles4 = StyleSheet4.create({
191
- horizontal: {
192
- height: StyleSheet4.hairlineWidth,
193
- width: "100%"
194
- },
195
- vertical: {
196
- width: StyleSheet4.hairlineWidth,
197
- alignSelf: "stretch"
198
- }
199
- });
200
- function Separator({ orientation = "horizontal", style }) {
201
- const { colors: colors2 } = useTheme();
202
- return /* @__PURE__ */ jsx5(
203
- View3,
204
- {
205
- accessibilityRole: "none",
206
- style: [
207
- orientation === "vertical" ? styles4.vertical : styles4.horizontal,
208
- { backgroundColor: colors2.colorBgSubtle },
209
- style
210
- ]
211
- }
212
- );
213
- }
214
-
215
- // src/components/ui/Loading/Loading.native.tsx
216
- import { ActivityIndicator } from "react-native";
217
- import { jsx as jsx6 } from "react/jsx-runtime";
218
- var rnSize = {
219
- small: "small",
220
- medium: "large",
221
- large: "large"
222
- };
223
- function Loading({ size = "medium", accessibilityLabel = "Loading", style }) {
224
- const { colors: colors2 } = useTheme();
225
- return /* @__PURE__ */ jsx6(
226
- ActivityIndicator,
227
- {
228
- size: rnSize[size],
229
- color: colors2.colorInteractive,
230
- style,
231
- accessibilityRole: "progressbar",
232
- accessibilityLabel
233
- }
234
- );
235
- }
236
-
237
- // src/components/ui/Progress/Progress.native.tsx
238
- import { StyleSheet as StyleSheet5, View as View4, Text as Text4 } from "react-native";
239
- import { jsx as jsx7, jsxs } from "react/jsx-runtime";
240
- var trackHeight = {
241
- small: 4,
242
- medium: 8,
243
- large: 12
244
- };
245
- var styles5 = StyleSheet5.create({
246
- container: {
247
- width: "100%"
248
- },
249
- labelRow: {
250
- flexDirection: "row",
251
- justifyContent: "space-between",
252
- marginBottom: spacing.xxs
253
- },
254
- labelText: {
255
- fontSize: font.size.bodyS,
256
- fontFamily: font.family.body,
257
- lineHeight: lineHeight.bodyS
258
- },
259
- track: {
260
- width: "100%",
261
- borderRadius: border.radius.full,
262
- overflow: "hidden"
263
- },
264
- fill: {
265
- height: "100%",
266
- borderRadius: border.radius.full
267
- }
268
- });
269
- function Progress({
270
- value,
271
- max = 100,
272
- label,
273
- showLabel = false,
274
- size = "medium",
275
- style
276
- }) {
277
- const { colors: colors2 } = useTheme();
278
- const percentage = Math.min(100, Math.max(0, value / max * 100));
279
- const height = trackHeight[size];
280
- return /* @__PURE__ */ jsxs(View4, { style: [styles5.container, style], children: [
281
- showLabel && /* @__PURE__ */ jsxs(View4, { style: styles5.labelRow, children: [
282
- /* @__PURE__ */ jsx7(Text4, { style: [styles5.labelText, { color: colors2.colorOnBg }], children: label }),
283
- /* @__PURE__ */ jsxs(Text4, { style: [styles5.labelText, { color: colors2.colorOnBgSubtle }], children: [
284
- Math.round(percentage),
285
- "%"
286
- ] })
287
- ] }),
288
- /* @__PURE__ */ jsx7(
289
- View4,
290
- {
291
- style: [styles5.track, { height, backgroundColor: colors2.colorBgSubtle }],
292
- accessibilityRole: "progressbar",
293
- accessibilityLabel: label,
294
- accessibilityValue: { min: 0, max, now: value },
295
- children: /* @__PURE__ */ jsx7(
296
- View4,
297
- {
298
- style: [
299
- styles5.fill,
300
- { width: `${percentage}%`, backgroundColor: colors2.colorInteractive }
301
- ]
302
- }
303
- )
304
- }
305
- )
306
- ] });
307
- }
308
-
309
- // src/components/ui/Skeleton/Skeleton.native.tsx
310
- import { useEffect, useRef } from "react";
311
- import { Animated, StyleSheet as StyleSheet6 } from "react-native";
312
- import { jsx as jsx8 } from "react/jsx-runtime";
313
- var styles6 = StyleSheet6.create({
314
- skeleton: {
315
- borderRadius: border.radius.xs,
316
- overflow: "hidden"
317
- }
318
- });
319
- function Skeleton({ style }) {
320
- const { colors: colors2 } = useTheme();
321
- const opacity = useRef(new Animated.Value(1)).current;
322
- useEffect(() => {
323
- const anim = Animated.loop(
324
- Animated.sequence([
325
- Animated.timing(opacity, { toValue: 0.4, duration: 700, useNativeDriver: true }),
326
- Animated.timing(opacity, { toValue: 1, duration: 700, useNativeDriver: true })
327
- ])
328
- );
329
- anim.start();
330
- return () => anim.stop();
331
- }, [opacity]);
332
- return /* @__PURE__ */ jsx8(
333
- Animated.View,
334
- {
335
- importantForAccessibility: "no-hide-descendants",
336
- style: [
337
- styles6.skeleton,
338
- { backgroundColor: colors2.colorBgSubtle, opacity },
339
- style
340
- ]
341
- }
342
- );
343
- }
344
-
345
- // src/components/ui/Alert/Alert.native.tsx
346
- import { StyleSheet as StyleSheet7, View as View5, Text as Text5, Pressable } from "react-native";
347
- import { jsx as jsx9, jsxs as jsxs2 } from "react/jsx-runtime";
348
- var styles7 = StyleSheet7.create({
349
- alert: {
350
- flexDirection: "row",
351
- alignItems: "flex-start",
352
- padding: spacing.m,
353
- borderRadius: border.radius.s,
354
- gap: spacing.xs
355
- },
356
- icon: {
357
- flexShrink: 0,
358
- marginTop: 2
359
- },
360
- content: {
361
- flex: 1,
362
- gap: spacing.xxs
363
- },
364
- title: {
365
- fontSize: font.size.body,
366
- fontFamily: font.family.body,
367
- fontWeight: font.weight.semibold,
368
- lineHeight: lineHeight.body
369
- },
370
- body: {
371
- fontSize: font.size.bodyS,
372
- fontFamily: font.family.body,
373
- lineHeight: lineHeight.bodyS
374
- },
375
- dismiss: {
376
- padding: spacing.xxs,
377
- flexShrink: 0
378
- }
379
- });
380
- function Alert({
381
- variant = "info",
382
- icon,
383
- title,
384
- children,
385
- onDismiss,
386
- style
387
- }) {
388
- const { colors: colors2 } = useTheme();
389
- const isUrgent = variant === "error" || variant === "warning";
390
- const variantColors = {
391
- info: { bg: colors2.colorBlueSubtle, text: colors2.colorOnBlueSubtle, border: colors2.colorBlue },
392
- success: { bg: colors2.colorSuccessSubtle, text: colors2.colorOnSuccessSubtle, border: colors2.colorSuccess },
393
- warning: { bg: colors2.colorOrangeSubtle, text: colors2.colorOnOrangeSubtle, border: colors2.colorWarning },
394
- error: { bg: colors2.colorRedSubtle, text: colors2.colorOnBg, border: colors2.colorError }
395
- };
396
- const { bg, text, border: borderColor } = variantColors[variant];
397
- return /* @__PURE__ */ jsxs2(
398
- View5,
399
- {
400
- accessibilityRole: isUrgent ? "alert" : "none",
401
- accessibilityLiveRegion: isUrgent ? "assertive" : "polite",
402
- style: [styles7.alert, { backgroundColor: bg, borderStartWidth: spacing.s, borderStartColor: borderColor }, style],
403
- children: [
404
- icon && /* @__PURE__ */ jsx9(View5, { style: styles7.icon, children: icon }),
405
- /* @__PURE__ */ jsxs2(View5, { style: styles7.content, children: [
406
- title && /* @__PURE__ */ jsx9(Text5, { style: [styles7.title, { color: text }], children: title }),
407
- /* @__PURE__ */ jsx9(Text5, { style: [styles7.body, { color: text }], children })
408
- ] }),
409
- onDismiss && /* @__PURE__ */ jsx9(
410
- Pressable,
411
- {
412
- onPress: onDismiss,
413
- style: styles7.dismiss,
414
- accessibilityLabel: "Dismiss alert",
415
- accessibilityRole: "button",
416
- hitSlop: 8,
417
- children: /* @__PURE__ */ jsx9(Text5, { style: { color: text, fontSize: 16 }, children: "\u2715" })
418
- }
419
- )
420
- ]
421
- }
422
- );
423
- }
424
-
425
- // src/components/ui/NotificationBanner/NotificationBanner.native.tsx
426
- import { StyleSheet as StyleSheet8, View as View6, Text as Text6, Pressable as Pressable2 } from "react-native";
427
- import { jsx as jsx10, jsxs as jsxs3 } from "react/jsx-runtime";
428
- var styles8 = StyleSheet8.create({
429
- banner: {
430
- flexDirection: "row",
431
- alignItems: "center",
432
- paddingVertical: spacing.s,
433
- paddingHorizontal: spacing.m,
434
- gap: spacing.xs
435
- },
436
- content: {
437
- flex: 1,
438
- fontSize: font.size.bodyS,
439
- fontFamily: font.family.body,
440
- lineHeight: lineHeight.bodyS
441
- },
442
- dismiss: {
443
- padding: spacing.xxs,
444
- flexShrink: 0
445
- }
446
- });
447
- function NotificationBanner({
448
- variant = "info",
449
- children,
450
- action,
451
- onDismiss,
452
- style
453
- }) {
454
- const { colors: colors2 } = useTheme();
455
- const isUrgent = variant === "error" || variant === "warning";
456
- const variantColors = {
457
- info: { bg: colors2.colorBlueSubtle, text: colors2.colorOnBlueSubtle, border: colors2.colorBlue },
458
- success: { bg: colors2.colorSuccessSubtle, text: colors2.colorOnSuccessSubtle, border: colors2.colorSuccess },
459
- warning: { bg: colors2.colorOrangeSubtle, text: colors2.colorOnOrangeSubtle, border: colors2.colorWarning },
460
- error: { bg: colors2.colorRedSubtle, text: colors2.colorOnBg, border: colors2.colorError }
461
- };
462
- const { bg, text, border: borderColor } = variantColors[variant];
463
- return /* @__PURE__ */ jsxs3(
464
- View6,
465
- {
466
- accessibilityRole: isUrgent ? "alert" : "none",
467
- accessibilityLiveRegion: isUrgent ? "assertive" : "polite",
468
- style: [styles8.banner, { backgroundColor: bg, borderBottomWidth: 3, borderBottomColor: borderColor }, style],
469
- children: [
470
- /* @__PURE__ */ jsx10(Text6, { style: [styles8.content, { color: text }], children }),
471
- action,
472
- onDismiss && /* @__PURE__ */ jsx10(
473
- Pressable2,
474
- {
475
- onPress: onDismiss,
476
- style: styles8.dismiss,
477
- accessibilityLabel: "Dismiss notification",
478
- accessibilityRole: "button",
479
- hitSlop: 8,
480
- children: /* @__PURE__ */ jsx10(Text6, { style: { color: text, fontSize: 16 }, children: "\u2715" })
481
- }
482
- )
483
- ]
484
- }
485
- );
486
- }
487
-
488
- // src/components/ui/Link/Link.native.tsx
489
- import { StyleSheet as StyleSheet9, Text as Text7, Pressable as Pressable3, Linking } from "react-native";
490
- import { jsx as jsx11 } from "react/jsx-runtime";
491
- var styles9 = StyleSheet9.create({
492
- text: {
493
- fontSize: font.size.body,
494
- fontFamily: font.family.body,
495
- textDecorationLine: "underline"
496
- },
497
- pressed: {
498
- opacity: 0.75
499
- }
500
- });
501
- function Link({ href, children, accessibilityLabel, style, onPress }) {
502
- const { colors: colors2 } = useTheme();
503
- const handlePress = () => {
504
- if (onPress) {
505
- onPress();
506
- } else if (href) {
507
- Linking.openURL(href);
508
- }
509
- };
510
- return /* @__PURE__ */ jsx11(
511
- Pressable3,
512
- {
513
- onPress: handlePress,
514
- accessibilityRole: "link",
515
- accessibilityLabel,
516
- style: ({ pressed }) => pressed && styles9.pressed,
517
- children: /* @__PURE__ */ jsx11(Text7, { style: [styles9.text, { color: colors2.colorInteractiveOnBg }, style], children })
518
- }
519
- );
520
- }
521
-
522
- // src/components/ui/DescriptionList/DescriptionList.native.tsx
523
- import { StyleSheet as StyleSheet10, View as View7, Text as Text8 } from "react-native";
524
- import { jsx as jsx12, jsxs as jsxs4 } from "react/jsx-runtime";
525
- var styles10 = StyleSheet10.create({
526
- list: {
527
- gap: spacing.m
528
- },
529
- group: {
530
- gap: spacing.xxs
531
- },
532
- term: {
533
- fontSize: font.size.bodyS,
534
- fontFamily: font.family.body,
535
- fontWeight: font.weight.semibold,
536
- lineHeight: lineHeight.bodyS
537
- },
538
- description: {
539
- fontSize: font.size.body,
540
- fontFamily: font.family.body,
541
- fontWeight: font.weight.body,
542
- lineHeight: lineHeight.body
543
- }
544
- });
545
- function DescriptionList({ items, style }) {
546
- const { colors: colors2 } = useTheme();
547
- return /* @__PURE__ */ jsx12(View7, { style: [styles10.list, style], accessibilityRole: "list", children: items.map((item, i) => /* @__PURE__ */ jsxs4(View7, { style: styles10.group, accessibilityRole: "listitem", children: [
548
- /* @__PURE__ */ jsx12(Text8, { style: [styles10.term, { color: colors2.colorOnBgSubtle }], children: item.term }),
549
- typeof item.description === "string" ? /* @__PURE__ */ jsx12(Text8, { style: [styles10.description, { color: colors2.colorOnBg }], children: item.description }) : /* @__PURE__ */ jsx12(View7, { children: item.description })
550
- ] }, i)) });
551
- }
552
-
553
- // src/components/ui/Breadcrumb/Breadcrumb.native.tsx
554
- import { StyleSheet as StyleSheet11, View as View8, Text as Text9, Pressable as Pressable4 } from "react-native";
555
- import { Fragment, jsx as jsx13, jsxs as jsxs5 } from "react/jsx-runtime";
556
- var styles11 = StyleSheet11.create({
557
- container: {
558
- flexDirection: "row",
559
- flexWrap: "wrap",
560
- alignItems: "center"
561
- },
562
- separator: {
563
- marginHorizontal: spacing.xs,
564
- fontSize: font.size.body,
565
- fontFamily: font.family.body,
566
- lineHeight: lineHeight.body
567
- },
568
- itemText: {
569
- fontSize: font.size.body,
570
- fontFamily: font.family.body,
571
- lineHeight: lineHeight.body
572
- },
573
- pressed: {
574
- opacity: 0.75
575
- }
576
- });
577
- function Breadcrumb({ items, style }) {
578
- const { colors: colors2 } = useTheme();
579
- return /* @__PURE__ */ jsx13(
580
- View8,
581
- {
582
- style: [styles11.container, style],
583
- accessibilityRole: "navigation",
584
- accessibilityLabel: "Breadcrumb",
585
- children: items.map((item, index) => {
586
- const isLast = index === items.length - 1;
587
- return /* @__PURE__ */ jsx13(View8, { style: { flexDirection: "row", alignItems: "center", minHeight: 44 }, children: isLast ? /* @__PURE__ */ jsx13(
588
- Text9,
589
- {
590
- style: [styles11.itemText, { color: colors2.colorOnBg }],
591
- accessibilityRole: "text",
592
- children: item.label
593
- }
594
- ) : /* @__PURE__ */ jsxs5(Fragment, { children: [
595
- /* @__PURE__ */ jsx13(
596
- Pressable4,
597
- {
598
- onPress: item.onPress,
599
- accessibilityRole: "link",
600
- style: ({ pressed }) => pressed && styles11.pressed,
601
- children: /* @__PURE__ */ jsx13(Text9, { style: [styles11.itemText, { color: colors2.colorInteractiveOnBg }], children: item.label })
602
- }
603
- ),
604
- /* @__PURE__ */ jsx13(
605
- Text9,
606
- {
607
- style: [styles11.separator, { color: colors2.colorOnBgSubtle }],
608
- importantForAccessibility: "no",
609
- accessibilityElementsHidden: true,
610
- children: "/"
611
- }
612
- )
613
- ] }) }, index);
614
- })
615
- }
616
- );
617
- }
618
-
619
- // src/components/ui/ProgressCircle/ProgressCircle.native.tsx
620
- import { StyleSheet as StyleSheet12, View as View9, Text as Text10 } from "react-native";
621
- import { jsx as jsx14, jsxs as jsxs6 } from "react/jsx-runtime";
622
- var SIZE_PX = {
623
- small: 40,
624
- medium: 64,
625
- large: 96
626
- };
627
- var STROKE_WIDTH = {
628
- small: 3,
629
- medium: 4,
630
- large: 5
631
- };
632
- var FONT_SIZE = {
633
- small: font.size.bodyS - 2,
634
- medium: font.size.bodyS,
635
- large: font.size.body
636
- };
637
- var styles12 = StyleSheet12.create({
638
- wrapper: {
639
- alignItems: "center",
640
- justifyContent: "center"
641
- },
642
- valueText: {
643
- position: "absolute",
644
- fontFamily: font.family.body,
645
- fontWeight: font.weight.semibold
646
- }
647
- });
648
- function HalfCircle({
649
- size,
650
- stroke,
651
- color,
652
- rotation
653
- }) {
654
- return /* @__PURE__ */ jsx14(
655
- View9,
656
- {
657
- style: {
658
- width: size / 2,
659
- height: size,
660
- overflow: "hidden"
661
- },
662
- children: /* @__PURE__ */ jsx14(
663
- View9,
664
- {
665
- style: {
666
- width: size,
667
- height: size,
668
- borderRadius: size / 2,
669
- borderWidth: stroke,
670
- borderColor: color,
671
- transform: [{ rotate: `${rotation}deg` }]
672
- }
673
- }
674
- )
675
- }
676
- );
677
- }
678
- function ProgressCircle({
679
- value,
680
- max = 100,
681
- size = "medium",
682
- label,
683
- showValue = false,
684
- style
685
- }) {
686
- const { colors: colors2 } = useTheme();
687
- const percentage = Math.min(100, Math.max(0, value / max * 100));
688
- const px = SIZE_PX[size];
689
- const stroke = STROKE_WIDTH[size];
690
- const fillColor = colors2.colorInteractive;
691
- const trackColor = colors2.colorBgSubtle;
692
- const degrees = percentage / 100 * 360;
693
- return /* @__PURE__ */ jsxs6(
694
- View9,
695
- {
696
- style: [
697
- styles12.wrapper,
698
- { width: px, height: px },
699
- style
700
- ],
701
- accessibilityRole: "progressbar",
702
- accessibilityLabel: label,
703
- accessibilityValue: { min: 0, max, now: value },
704
- children: [
705
- /* @__PURE__ */ jsx14(
706
- View9,
707
- {
708
- style: {
709
- position: "absolute",
710
- width: px,
711
- height: px,
712
- borderRadius: px / 2,
713
- borderWidth: stroke,
714
- borderColor: trackColor
715
- }
716
- }
717
- ),
718
- /* @__PURE__ */ jsx14(
719
- View9,
720
- {
721
- style: {
722
- position: "absolute",
723
- width: px / 2,
724
- height: px,
725
- start: px / 2,
726
- overflow: "hidden"
727
- },
728
- children: /* @__PURE__ */ jsx14(
729
- HalfCircle,
730
- {
731
- size: px,
732
- stroke,
733
- color: percentage > 0 ? fillColor : "transparent",
734
- rotation: Math.min(degrees, 180) - 180
735
- }
736
- )
737
- }
738
- ),
739
- degrees > 180 && /* @__PURE__ */ jsx14(
740
- View9,
741
- {
742
- style: {
743
- position: "absolute",
744
- width: px / 2,
745
- height: px,
746
- start: 0,
747
- overflow: "hidden"
748
- },
749
- children: /* @__PURE__ */ jsx14(
750
- View9,
751
- {
752
- style: {
753
- position: "absolute",
754
- end: 0
755
- },
756
- children: /* @__PURE__ */ jsx14(
757
- HalfCircle,
758
- {
759
- size: px,
760
- stroke,
761
- color: fillColor,
762
- rotation: Math.min(degrees - 180, 180)
763
- }
764
- )
765
- }
766
- )
767
- }
768
- ),
769
- showValue && /* @__PURE__ */ jsxs6(
770
- Text10,
771
- {
772
- style: [styles12.valueText, { fontSize: FONT_SIZE[size], color: colors2.colorOnBg }],
773
- importantForAccessibility: "no",
774
- accessibilityElementsHidden: true,
775
- children: [
776
- Math.round(percentage),
777
- "%"
778
- ]
779
- }
780
- )
781
- ]
782
- }
783
- );
784
- }
785
-
786
- // src/components/ui/Tooltip/Tooltip.native.tsx
787
- import { useState } from "react";
788
- import { StyleSheet as StyleSheet13, View as View10, Text as Text11, Pressable as Pressable5 } from "react-native";
789
- import { jsx as jsx15, jsxs as jsxs7 } from "react/jsx-runtime";
790
- var styles13 = StyleSheet13.create({
791
- wrapper: {
792
- position: "relative"
793
- },
794
- tooltip: {
795
- position: "absolute",
796
- bottom: "100%",
797
- start: 0,
798
- marginBottom: spacing.xxs,
799
- paddingVertical: spacing.xxs,
800
- paddingHorizontal: spacing.xs,
801
- borderRadius: border.radius.full,
802
- zIndex: 10,
803
- alignSelf: "flex-start"
804
- },
805
- text: {
806
- fontSize: font.size.bodyS,
807
- fontFamily: font.family.body
808
- }
809
- });
810
- function Tooltip({ content, children, style }) {
811
- const { colors: colors2 } = useTheme();
812
- const [visible, setVisible] = useState(false);
813
- return /* @__PURE__ */ jsxs7(View10, { style: [styles13.wrapper, style], children: [
814
- /* @__PURE__ */ jsx15(
815
- Pressable5,
816
- {
817
- onLongPress: () => setVisible(true),
818
- onPressOut: () => setVisible(false),
819
- accessibilityHint: content,
820
- children
821
- }
822
- ),
823
- visible && /* @__PURE__ */ jsx15(
824
- View10,
825
- {
826
- style: [styles13.tooltip, { backgroundColor: colors2.colorOnBg }],
827
- accessibilityRole: "text",
828
- accessibilityLabel: content,
829
- children: /* @__PURE__ */ jsx15(Text11, { style: [styles13.text, { color: colors2.colorBg }], children: content })
830
- }
831
- )
832
- ] });
833
- }
834
-
835
- // src/components/ui/Pagination/Pagination.native.tsx
836
- import { StyleSheet as StyleSheet14, View as View11, Text as Text12, Pressable as Pressable6 } from "react-native";
837
- import { jsx as jsx16, jsxs as jsxs8 } from "react/jsx-runtime";
838
- function getPageRange(current, total) {
839
- const delta = 1;
840
- const range = [];
841
- for (let i = 1; i <= total; i++) {
842
- if (i === 1 || i === total || i >= current - delta && i <= current + delta) {
843
- range.push(i);
844
- } else if (range[range.length - 1] !== "...") {
845
- range.push("...");
846
- }
847
- }
848
- return range;
849
- }
850
- var styles14 = StyleSheet14.create({
851
- container: {
852
- flexDirection: "row",
853
- alignItems: "center",
854
- gap: spacing.xxs
855
- },
856
- button: {
857
- minWidth: 44,
858
- minHeight: 44,
859
- alignItems: "center",
860
- justifyContent: "center",
861
- borderRadius: border.radius.full,
862
- paddingHorizontal: spacing.xs,
863
- paddingVertical: spacing.xxs
864
- },
865
- buttonText: {
866
- fontSize: font.size.body,
867
- fontFamily: font.family.body,
868
- lineHeight: lineHeight.body,
869
- fontWeight: font.weight.body
870
- },
871
- navText: {
872
- fontSize: font.size.body,
873
- fontFamily: font.family.body,
874
- lineHeight: lineHeight.body,
875
- fontWeight: font.weight.semibold
876
- },
877
- ellipsis: {
878
- fontSize: font.size.body,
879
- fontFamily: font.family.body,
880
- lineHeight: lineHeight.body,
881
- minWidth: 44,
882
- minHeight: 44,
883
- textAlign: "center",
884
- textAlignVertical: "center"
885
- },
886
- pressed: {
887
- opacity: 0.75
888
- },
889
- disabled: {
890
- opacity: 0.4
891
- }
892
- });
893
- function Pagination({
894
- currentPage,
895
- totalPages,
896
- onPageChange,
897
- style
898
- }) {
899
- const { colors: colors2 } = useTheme();
900
- const pages = getPageRange(currentPage, totalPages);
901
- return /* @__PURE__ */ jsxs8(
902
- View11,
903
- {
904
- style: [styles14.container, style],
905
- accessibilityRole: "navigation",
906
- accessibilityLabel: "Pagination",
907
- children: [
908
- /* @__PURE__ */ jsx16(
909
- Pressable6,
910
- {
911
- onPress: () => onPageChange(currentPage - 1),
912
- disabled: currentPage <= 1,
913
- accessibilityRole: "button",
914
- accessibilityLabel: "Previous page",
915
- accessibilityState: { disabled: currentPage <= 1 },
916
- style: ({ pressed }) => [
917
- styles14.button,
918
- currentPage <= 1 && styles14.disabled,
919
- pressed && !currentPage && styles14.pressed
920
- ],
921
- children: /* @__PURE__ */ jsx16(Text12, { style: [styles14.navText, { color: colors2.colorOnBg }], children: "\u2039" })
922
- }
923
- ),
924
- pages.map(
925
- (page, index) => page === "..." ? /* @__PURE__ */ jsx16(
926
- Text12,
927
- {
928
- style: [styles14.ellipsis, { color: colors2.colorOnBgSubtle }],
929
- importantForAccessibility: "no",
930
- accessibilityElementsHidden: true,
931
- children: "..."
932
- },
933
- `ellipsis-${index}`
934
- ) : /* @__PURE__ */ jsx16(
935
- Pressable6,
936
- {
937
- onPress: () => onPageChange(page),
938
- accessibilityRole: "button",
939
- accessibilityLabel: `Page ${page}`,
940
- accessibilityState: { selected: currentPage === page },
941
- style: ({ pressed }) => [
942
- styles14.button,
943
- currentPage === page && { backgroundColor: colors2.colorInteractive },
944
- pressed && styles14.pressed
945
- ],
946
- children: /* @__PURE__ */ jsx16(
947
- Text12,
948
- {
949
- style: [
950
- styles14.buttonText,
951
- {
952
- color: currentPage === page ? colors2.colorOnInteractive : colors2.colorOnBg
953
- },
954
- currentPage === page && { fontWeight: font.weight.semibold }
955
- ],
956
- children: page
957
- }
958
- )
959
- },
960
- page
961
- )
962
- ),
963
- /* @__PURE__ */ jsx16(
964
- Pressable6,
965
- {
966
- onPress: () => onPageChange(currentPage + 1),
967
- disabled: currentPage >= totalPages,
968
- accessibilityRole: "button",
969
- accessibilityLabel: "Next page",
970
- accessibilityState: { disabled: currentPage >= totalPages },
971
- style: ({ pressed }) => [
972
- styles14.button,
973
- currentPage >= totalPages && styles14.disabled,
974
- pressed && styles14.pressed
975
- ],
976
- children: /* @__PURE__ */ jsx16(Text12, { style: [styles14.navText, { color: colors2.colorOnBg }], children: "\u203A" })
977
- }
978
- )
979
- ]
980
- }
981
- );
982
- }
983
-
984
- // src/components/ui/Collapsible/Collapsible.native.tsx
985
- import { useCallback, useRef as useRef2, useState as useState2 } from "react";
986
- import {
987
- StyleSheet as StyleSheet15,
988
- View as View12,
989
- Text as Text13,
990
- Pressable as Pressable7,
991
- Animated as Animated2,
992
- LayoutAnimation,
993
- Platform,
994
- UIManager
995
- } from "react-native";
996
- import { jsx as jsx17, jsxs as jsxs9 } from "react/jsx-runtime";
997
- if (Platform.OS === "android" && UIManager.setLayoutAnimationEnabledExperimental) {
998
- UIManager.setLayoutAnimationEnabledExperimental(true);
999
- }
1000
- var styles15 = StyleSheet15.create({
1001
- container: {
1002
- borderRadius: border.radius.m,
1003
- overflow: "hidden"
1004
- },
1005
- header: {
1006
- flexDirection: "row",
1007
- alignItems: "center",
1008
- justifyContent: "space-between",
1009
- minHeight: 44,
1010
- paddingVertical: spacing.s,
1011
- paddingHorizontal: spacing.m
1012
- },
1013
- summaryText: {
1014
- flex: 1,
1015
- fontSize: font.size.body,
1016
- fontFamily: font.family.body,
1017
- fontWeight: font.weight.semibold,
1018
- lineHeight: lineHeight.body
1019
- },
1020
- chevron: {
1021
- fontSize: font.size.body,
1022
- marginStart: spacing.xs
1023
- },
1024
- content: {
1025
- paddingHorizontal: spacing.m,
1026
- paddingBottom: spacing.m
1027
- },
1028
- pressed: {
1029
- opacity: 0.75
1030
- }
1031
- });
1032
- function Collapsible({
1033
- summary,
1034
- children,
1035
- open: controlledOpen,
1036
- defaultOpen = false,
1037
- onToggle,
1038
- name: _name,
1039
- // eslint-disable-line @typescript-eslint/no-unused-vars
1040
- style
1041
- }) {
1042
- const { colors: colors2 } = useTheme();
1043
- const [internalOpen, setInternalOpen] = useState2(defaultOpen);
1044
- const isControlled = controlledOpen !== void 0;
1045
- const isOpen = isControlled ? controlledOpen : internalOpen;
1046
- const rotation = useRef2(new Animated2.Value(isOpen ? 1 : 0)).current;
1047
- const toggle = useCallback(() => {
1048
- const next = !isOpen;
1049
- LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
1050
- Animated2.timing(rotation, {
1051
- toValue: next ? 1 : 0,
1052
- duration: 200,
1053
- useNativeDriver: true
1054
- }).start();
1055
- if (!isControlled) {
1056
- setInternalOpen(next);
1057
- }
1058
- onToggle?.(next);
1059
- }, [isOpen, isControlled, onToggle, rotation]);
1060
- const rotateZ = rotation.interpolate({
1061
- inputRange: [0, 1],
1062
- outputRange: ["0deg", "90deg"]
1063
- });
1064
- return /* @__PURE__ */ jsxs9(
1065
- View12,
1066
- {
1067
- style: [styles15.container, { borderBottomWidth: 1, borderBottomColor: colors2.colorBgSubtle }, style],
1068
- accessibilityRole: "summary",
1069
- children: [
1070
- /* @__PURE__ */ jsxs9(
1071
- Pressable7,
1072
- {
1073
- onPress: toggle,
1074
- accessibilityRole: "button",
1075
- accessibilityLabel: summary,
1076
- accessibilityState: { expanded: isOpen },
1077
- style: ({ pressed }) => [styles15.header, pressed && styles15.pressed],
1078
- children: [
1079
- /* @__PURE__ */ jsx17(Text13, { style: [styles15.summaryText, { color: colors2.colorOnBg }], children: summary }),
1080
- /* @__PURE__ */ jsx17(
1081
- Animated2.Text,
1082
- {
1083
- style: [styles15.chevron, { color: colors2.colorOnBgSubtle, transform: [{ rotateZ }] }],
1084
- importantForAccessibility: "no",
1085
- accessibilityElementsHidden: true,
1086
- children: "\u25B8"
1087
- }
1088
- )
1089
- ]
1090
- }
1091
- ),
1092
- isOpen && /* @__PURE__ */ jsx17(View12, { style: styles15.content, children })
1093
- ]
1094
- }
1095
- );
1096
- }
1097
-
1098
- // src/components/ui/Accordion/Accordion.native.tsx
1099
- import { useState as useState3 } from "react";
1100
- import {
1101
- StyleSheet as StyleSheet16,
1102
- View as View13,
1103
- Text as Text14,
1104
- Pressable as Pressable8,
1105
- LayoutAnimation as LayoutAnimation2,
1106
- Platform as Platform2,
1107
- UIManager as UIManager2
1108
- } from "react-native";
1109
- import { jsx as jsx18, jsxs as jsxs10 } from "react/jsx-runtime";
1110
- if (Platform2.OS === "android" && UIManager2.setLayoutAnimationEnabledExperimental) {
1111
- UIManager2.setLayoutAnimationEnabledExperimental(true);
1112
- }
1113
- var styles16 = StyleSheet16.create({
1114
- container: {
1115
- overflow: "hidden",
1116
- borderRadius: border.radius.s
1117
- },
1118
- item: {
1119
- borderBottomWidth: 1
1120
- },
1121
- header: {
1122
- flexDirection: "row",
1123
- alignItems: "center",
1124
- justifyContent: "space-between",
1125
- minHeight: 44,
1126
- paddingVertical: spacing.s,
1127
- paddingHorizontal: spacing.m
1128
- },
1129
- titleText: {
1130
- flex: 1,
1131
- fontSize: font.size.body,
1132
- fontFamily: font.family.body,
1133
- fontWeight: font.weight.semibold,
1134
- lineHeight: lineHeight.body
1135
- },
1136
- chevron: {
1137
- fontSize: font.size.bodyS,
1138
- marginStart: spacing.xs
1139
- },
1140
- panel: {
1141
- paddingHorizontal: spacing.m,
1142
- paddingBottom: spacing.m
1143
- },
1144
- pressed: {
1145
- opacity: 0.75
1146
- },
1147
- disabled: {
1148
- opacity: 0.4
1149
- }
1150
- });
1151
- function Accordion({
1152
- items,
1153
- allowMultiple = false,
1154
- defaultOpen = [],
1155
- style
1156
- }) {
1157
- const { colors: colors2 } = useTheme();
1158
- const [openIds, setOpenIds] = useState3(defaultOpen);
1159
- const toggle = (id) => {
1160
- LayoutAnimation2.configureNext(LayoutAnimation2.Presets.easeInEaseOut);
1161
- setOpenIds((prev) => {
1162
- const isOpen = prev.includes(id);
1163
- if (isOpen) return prev.filter((i) => i !== id);
1164
- return allowMultiple ? [...prev, id] : [id];
1165
- });
1166
- };
1167
- return /* @__PURE__ */ jsx18(View13, { style: [styles16.container, style], children: items.map((item, index) => {
1168
- const isOpen = openIds.includes(item.id);
1169
- const isLast = index === items.length - 1;
1170
- return /* @__PURE__ */ jsxs10(
1171
- View13,
1172
- {
1173
- style: [
1174
- styles16.item,
1175
- { borderBottomColor: colors2.colorBgSubtle },
1176
- isLast && { borderBottomWidth: 0 }
1177
- ],
1178
- children: [
1179
- /* @__PURE__ */ jsxs10(
1180
- Pressable8,
1181
- {
1182
- onPress: () => toggle(item.id),
1183
- disabled: item.disabled,
1184
- accessibilityRole: "button",
1185
- accessibilityState: { expanded: isOpen, disabled: item.disabled },
1186
- style: ({ pressed }) => [
1187
- styles16.header,
1188
- item.disabled && styles16.disabled,
1189
- pressed && !item.disabled && styles16.pressed
1190
- ],
1191
- children: [
1192
- /* @__PURE__ */ jsx18(Text14, { style: [styles16.titleText, { color: colors2.colorOnBg }], children: typeof item.title === "string" ? item.title : item.title }),
1193
- /* @__PURE__ */ jsx18(
1194
- Text14,
1195
- {
1196
- style: [styles16.chevron, { color: colors2.colorOnBgSubtle }],
1197
- importantForAccessibility: "no",
1198
- accessibilityElementsHidden: true,
1199
- children: isOpen ? "\u25BE" : "\u25B8"
1200
- }
1201
- )
1202
- ]
1203
- }
1204
- ),
1205
- isOpen && /* @__PURE__ */ jsx18(View13, { style: styles16.panel, accessibilityRole: "summary", children: item.content })
1206
- ]
1207
- },
1208
- item.id
1209
- );
1210
- }) });
1211
- }
1212
-
1213
- // src/components/ui/Tabs/Tabs.native.tsx
1214
- import { useState as useState4 } from "react";
1215
- import {
1216
- StyleSheet as StyleSheet17,
1217
- View as View14,
1218
- Text as Text15,
1219
- Pressable as Pressable9,
1220
- ScrollView
1221
- } from "react-native";
1222
- import { jsx as jsx19, jsxs as jsxs11 } from "react/jsx-runtime";
1223
- var styles17 = StyleSheet17.create({
1224
- container: {
1225
- overflow: "hidden"
1226
- },
1227
- tabList: {
1228
- flexDirection: "row",
1229
- borderBottomWidth: 2
1230
- },
1231
- tabButton: {
1232
- minHeight: 44,
1233
- paddingHorizontal: spacing.m,
1234
- paddingVertical: spacing.s,
1235
- alignItems: "center",
1236
- justifyContent: "center",
1237
- borderBottomWidth: 2,
1238
- marginBottom: -2
1239
- },
1240
- tabLabel: {
1241
- fontSize: font.size.body,
1242
- fontFamily: font.family.body,
1243
- lineHeight: lineHeight.body
1244
- },
1245
- panel: {
1246
- paddingVertical: spacing.m
1247
- },
1248
- pressed: {
1249
- opacity: 0.75
1250
- },
1251
- disabled: {
1252
- opacity: 0.4
1253
- }
1254
- });
1255
- function Tabs({
1256
- tabs,
1257
- defaultTab,
1258
- style
1259
- }) {
1260
- const { colors: colors2 } = useTheme();
1261
- const [activeTab, setActiveTab] = useState4(defaultTab ?? tabs[0]?.id);
1262
- return /* @__PURE__ */ jsxs11(View14, { style: [styles17.container, style], children: [
1263
- /* @__PURE__ */ jsx19(
1264
- ScrollView,
1265
- {
1266
- horizontal: true,
1267
- showsHorizontalScrollIndicator: false,
1268
- contentContainerStyle: [styles17.tabList, { borderBottomColor: colors2.colorBgSubtle }],
1269
- accessibilityRole: "tabbar",
1270
- children: tabs.map((tab) => {
1271
- const isActive = activeTab === tab.id;
1272
- return /* @__PURE__ */ jsx19(
1273
- Pressable9,
1274
- {
1275
- onPress: () => setActiveTab(tab.id),
1276
- disabled: tab.disabled,
1277
- accessibilityRole: "tab",
1278
- accessibilityState: {
1279
- selected: isActive,
1280
- disabled: tab.disabled
1281
- },
1282
- accessibilityLabel: typeof tab.label === "string" ? tab.label : void 0,
1283
- style: ({ pressed }) => [
1284
- styles17.tabButton,
1285
- {
1286
- borderBottomColor: isActive ? colors2.colorInteractive : "transparent"
1287
- },
1288
- tab.disabled && styles17.disabled,
1289
- pressed && !tab.disabled && styles17.pressed
1290
- ],
1291
- children: /* @__PURE__ */ jsx19(
1292
- Text15,
1293
- {
1294
- style: [
1295
- styles17.tabLabel,
1296
- {
1297
- color: isActive ? colors2.colorInteractive : colors2.colorOnBgSubtle,
1298
- fontWeight: isActive ? font.weight.semibold : font.weight.body
1299
- }
1300
- ],
1301
- children: tab.label
1302
- }
1303
- )
1304
- },
1305
- tab.id
1306
- );
1307
- })
1308
- }
1309
- ),
1310
- tabs.map((tab) => {
1311
- const isActive = activeTab === tab.id;
1312
- if (!isActive) return null;
1313
- return /* @__PURE__ */ jsx19(View14, { style: styles17.panel, accessibilityRole: "tabpanel", children: tab.content }, tab.id);
1314
- })
1315
- ] });
1316
- }
1317
-
1318
- // src/components/ui/Table/Table.native.tsx
1319
- import {
1320
- StyleSheet as StyleSheet18,
1321
- View as View15,
1322
- Text as Text16,
1323
- ScrollView as ScrollView2,
1324
- Pressable as Pressable10
1325
- } from "react-native";
1326
- import { jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
1327
- var styles18 = StyleSheet18.create({
1328
- wrapper: {
1329
- borderRadius: border.radius.s,
1330
- overflow: "hidden"
1331
- },
1332
- caption: {
1333
- fontSize: font.size.bodyS,
1334
- fontFamily: font.family.body,
1335
- fontWeight: font.weight.semibold,
1336
- lineHeight: lineHeight.bodyS,
1337
- paddingVertical: spacing.xs,
1338
- paddingHorizontal: spacing.m
1339
- },
1340
- headerRow: {
1341
- flexDirection: "row"
1342
- },
1343
- headerCell: {
1344
- flex: 1,
1345
- minWidth: 100,
1346
- paddingVertical: spacing.s,
1347
- paddingHorizontal: spacing.m,
1348
- flexDirection: "row",
1349
- alignItems: "center",
1350
- gap: spacing.xxs
1351
- },
1352
- headerText: {
1353
- fontSize: font.size.bodyS,
1354
- fontFamily: font.family.body,
1355
- fontWeight: font.weight.semibold,
1356
- lineHeight: lineHeight.bodyS
1357
- },
1358
- sortIndicator: {
1359
- fontSize: font.size.bodyS
1360
- },
1361
- row: {
1362
- flexDirection: "row",
1363
- borderTopWidth: 1,
1364
- minHeight: 44
1365
- },
1366
- cell: {
1367
- flex: 1,
1368
- minWidth: 100,
1369
- paddingVertical: spacing.s,
1370
- paddingHorizontal: spacing.m,
1371
- justifyContent: "center"
1372
- },
1373
- cellText: {
1374
- fontSize: font.size.body,
1375
- fontFamily: font.family.body,
1376
- fontWeight: font.weight.body,
1377
- lineHeight: lineHeight.body
1378
- },
1379
- pressed: {
1380
- opacity: 0.75
1381
- }
1382
- });
1383
- function Table({
1384
- columns,
1385
- rows,
1386
- caption,
1387
- sortKey,
1388
- sortDirection,
1389
- onSort,
1390
- style
1391
- }) {
1392
- const { colors: colors2 } = useTheme();
1393
- const handleSort = (key) => {
1394
- if (!onSort) return;
1395
- const nextDirection = sortKey === key && sortDirection === "asc" ? "desc" : "asc";
1396
- onSort(key, nextDirection);
1397
- };
1398
- const getSortLabel = (col) => {
1399
- const base = `Sort by ${String(col.header)}`;
1400
- if (sortKey !== col.key) return base;
1401
- return `${base}, currently ${sortDirection === "asc" ? "ascending" : "descending"}`;
1402
- };
1403
- return /* @__PURE__ */ jsx20(
1404
- ScrollView2,
1405
- {
1406
- horizontal: true,
1407
- showsHorizontalScrollIndicator: true,
1408
- style: [styles18.wrapper, { backgroundColor: colors2.colorBg }, style],
1409
- children: /* @__PURE__ */ jsxs12(View15, { children: [
1410
- caption && /* @__PURE__ */ jsx20(Text16, { style: [styles18.caption, { color: colors2.colorOnBgSubtle }], children: caption }),
1411
- /* @__PURE__ */ jsx20(View15, { style: [styles18.headerRow, { backgroundColor: colors2.colorBgSubtle }], children: columns.map(
1412
- (col) => col.sortable ? /* @__PURE__ */ jsxs12(
1413
- Pressable10,
1414
- {
1415
- onPress: () => handleSort(col.key),
1416
- accessibilityRole: "button",
1417
- accessibilityLabel: getSortLabel(col),
1418
- style: ({ pressed }) => [styles18.headerCell, pressed && styles18.pressed],
1419
- children: [
1420
- /* @__PURE__ */ jsx20(Text16, { style: [styles18.headerText, { color: colors2.colorOnBg }], children: col.header }),
1421
- /* @__PURE__ */ jsx20(
1422
- Text16,
1423
- {
1424
- style: [
1425
- styles18.sortIndicator,
1426
- {
1427
- color: sortKey === col.key ? colors2.colorInteractive : colors2.colorOnBgSubtle
1428
- }
1429
- ],
1430
- importantForAccessibility: "no",
1431
- accessibilityElementsHidden: true,
1432
- children: sortKey === col.key ? sortDirection === "asc" ? "\u25B2" : "\u25BC" : "\u25BD"
1433
- }
1434
- )
1435
- ]
1436
- },
1437
- col.key
1438
- ) : /* @__PURE__ */ jsx20(View15, { style: styles18.headerCell, children: /* @__PURE__ */ jsx20(Text16, { style: [styles18.headerText, { color: colors2.colorOnBg }], children: col.header }) }, col.key)
1439
- ) }),
1440
- rows.map((row, rowIndex) => /* @__PURE__ */ jsx20(
1441
- View15,
1442
- {
1443
- style: [
1444
- styles18.row,
1445
- { borderTopColor: colors2.colorBgSubtle },
1446
- rowIndex % 2 === 1 && { backgroundColor: colors2.colorBgSubtle }
1447
- ],
1448
- accessibilityRole: "none",
1449
- children: columns.map((col) => /* @__PURE__ */ jsx20(View15, { style: styles18.cell, children: col.render ? typeof col.render(row) === "string" ? /* @__PURE__ */ jsx20(Text16, { style: [styles18.cellText, { color: colors2.colorOnBg }], children: col.render(row) }) : col.render(row) : /* @__PURE__ */ jsx20(Text16, { style: [styles18.cellText, { color: colors2.colorOnBg }], children: String(row[col.key] ?? "") }) }, col.key))
1450
- },
1451
- rowIndex
1452
- ))
1453
- ] })
1454
- }
1455
- );
1456
- }
1457
-
1458
- // src/components/ui/Calendar/Calendar.native.tsx
1459
- import { useState as useState5 } from "react";
1460
- import {
1461
- StyleSheet as StyleSheet19,
1462
- View as View16,
1463
- Text as Text17,
1464
- Pressable as Pressable11
1465
- } from "react-native";
1466
- import { jsx as jsx21, jsxs as jsxs13 } from "react/jsx-runtime";
1467
- var DAYS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
1468
- var DAY_LABELS = {
1469
- Su: "Sunday",
1470
- Mo: "Monday",
1471
- Tu: "Tuesday",
1472
- We: "Wednesday",
1473
- Th: "Thursday",
1474
- Fr: "Friday",
1475
- Sa: "Saturday"
1476
- };
1477
- var MONTHS = [
1478
- "January",
1479
- "February",
1480
- "March",
1481
- "April",
1482
- "May",
1483
- "June",
1484
- "July",
1485
- "August",
1486
- "September",
1487
- "October",
1488
- "November",
1489
- "December"
1490
- ];
1491
- function isSameDay(a, b) {
1492
- return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
1493
- }
1494
- function toMidnight(date) {
1495
- return new Date(date.getFullYear(), date.getMonth(), date.getDate());
1496
- }
1497
- function isOutOfRange(date, min, max) {
1498
- const d = toMidnight(date);
1499
- if (min && d < toMidnight(min)) return true;
1500
- return !!(max && d > toMidnight(max));
1501
- }
1502
- function getDaysInMonth(year, month) {
1503
- return new Date(year, month + 1, 0).getDate();
1504
- }
1505
- function getFirstDayOfMonth(year, month) {
1506
- return new Date(year, month, 1).getDay();
1507
- }
1508
- var DAY_SIZE = 44;
1509
- var styles19 = StyleSheet19.create({
1510
- container: {
1511
- alignSelf: "flex-start"
1512
- },
1513
- header: {
1514
- flexDirection: "row",
1515
- alignItems: "center",
1516
- justifyContent: "space-between",
1517
- paddingVertical: spacing.xs,
1518
- paddingHorizontal: spacing.xxs
1519
- },
1520
- navButton: {
1521
- minWidth: DAY_SIZE,
1522
- minHeight: DAY_SIZE,
1523
- alignItems: "center",
1524
- justifyContent: "center",
1525
- borderRadius: border.radius.full
1526
- },
1527
- navText: {
1528
- fontSize: font.size.heading3,
1529
- fontWeight: font.weight.semibold
1530
- },
1531
- monthYear: {
1532
- fontSize: font.size.body,
1533
- fontFamily: font.family.body,
1534
- fontWeight: font.weight.semibold,
1535
- lineHeight: lineHeight.body
1536
- },
1537
- weekRow: {
1538
- flexDirection: "row"
1539
- },
1540
- weekday: {
1541
- width: DAY_SIZE,
1542
- height: DAY_SIZE,
1543
- alignItems: "center",
1544
- justifyContent: "center"
1545
- },
1546
- weekdayText: {
1547
- fontSize: font.size.bodyS,
1548
- fontFamily: font.family.body,
1549
- fontWeight: font.weight.semibold,
1550
- lineHeight: lineHeight.bodyS
1551
- },
1552
- grid: {
1553
- gap: spacing.xxxs
1554
- },
1555
- dayRow: {
1556
- flexDirection: "row"
1557
- },
1558
- dayCell: {
1559
- width: DAY_SIZE,
1560
- height: DAY_SIZE,
1561
- alignItems: "center",
1562
- justifyContent: "center",
1563
- borderRadius: border.radius.full
1564
- },
1565
- dayText: {
1566
- fontSize: font.size.body,
1567
- fontFamily: font.family.body,
1568
- lineHeight: lineHeight.body
1569
- },
1570
- today: {
1571
- borderWidth: 1
1572
- },
1573
- pressed: {
1574
- opacity: 0.75
1575
- },
1576
- disabled: {
1577
- opacity: 0.4
1578
- }
1579
- });
1580
- function Calendar({
1581
- value,
1582
- defaultValue,
1583
- min,
1584
- max,
1585
- onChange,
1586
- style
1587
- }) {
1588
- const { colors: colors2 } = useTheme();
1589
- const today = /* @__PURE__ */ new Date();
1590
- const controlled = value !== void 0;
1591
- const [internal, setInternal] = useState5(defaultValue);
1592
- const selected = controlled ? value : internal;
1593
- const [viewYear, setViewYear] = useState5(
1594
- selected?.getFullYear() ?? today.getFullYear()
1595
- );
1596
- const [viewMonth, setViewMonth] = useState5(
1597
- selected?.getMonth() ?? today.getMonth()
1598
- );
1599
- const daysInMonth = getDaysInMonth(viewYear, viewMonth);
1600
- const firstDay = getFirstDayOfMonth(viewYear, viewMonth);
1601
- const navigate = (delta) => {
1602
- const d = new Date(viewYear, viewMonth + delta, 1);
1603
- setViewYear(d.getFullYear());
1604
- setViewMonth(d.getMonth());
1605
- };
1606
- const selectDay = (day) => {
1607
- const date = new Date(viewYear, viewMonth, day);
1608
- if (isOutOfRange(date, min, max)) return;
1609
- if (!controlled) setInternal(date);
1610
- onChange?.(date);
1611
- };
1612
- const cells = [
1613
- ...Array.from({ length: firstDay }, () => null),
1614
- ...Array.from({ length: daysInMonth }, (_, i) => ({ day: i + 1 }))
1615
- ];
1616
- while (cells.length % 7 !== 0) cells.push(null);
1617
- const rows = Array.from(
1618
- { length: cells.length / 7 },
1619
- (_, i) => cells.slice(i * 7, i * 7 + 7)
1620
- );
1621
- return /* @__PURE__ */ jsxs13(
1622
- View16,
1623
- {
1624
- style: [styles19.container, style],
1625
- accessibilityRole: "none",
1626
- accessibilityLabel: `${MONTHS[viewMonth]} ${viewYear} calendar`,
1627
- children: [
1628
- /* @__PURE__ */ jsxs13(View16, { style: styles19.header, children: [
1629
- /* @__PURE__ */ jsx21(
1630
- Pressable11,
1631
- {
1632
- onPress: () => navigate(-1),
1633
- accessibilityRole: "button",
1634
- accessibilityLabel: "Previous month",
1635
- style: ({ pressed }) => [styles19.navButton, pressed && styles19.pressed],
1636
- children: /* @__PURE__ */ jsx21(Text17, { style: [styles19.navText, { color: colors2.colorOnBg }], children: "\u2039" })
1637
- }
1638
- ),
1639
- /* @__PURE__ */ jsxs13(
1640
- Text17,
1641
- {
1642
- style: [styles19.monthYear, { color: colors2.colorOnBg }],
1643
- accessibilityRole: "text",
1644
- accessibilityLiveRegion: "polite",
1645
- children: [
1646
- MONTHS[viewMonth],
1647
- " ",
1648
- viewYear
1649
- ]
1650
- }
1651
- ),
1652
- /* @__PURE__ */ jsx21(
1653
- Pressable11,
1654
- {
1655
- onPress: () => navigate(1),
1656
- accessibilityRole: "button",
1657
- accessibilityLabel: "Next month",
1658
- style: ({ pressed }) => [styles19.navButton, pressed && styles19.pressed],
1659
- children: /* @__PURE__ */ jsx21(Text17, { style: [styles19.navText, { color: colors2.colorOnBg }], children: "\u203A" })
1660
- }
1661
- )
1662
- ] }),
1663
- /* @__PURE__ */ jsx21(View16, { style: styles19.weekRow, children: DAYS.map((d) => /* @__PURE__ */ jsx21(View16, { style: styles19.weekday, children: /* @__PURE__ */ jsx21(
1664
- Text17,
1665
- {
1666
- style: [styles19.weekdayText, { color: colors2.colorOnBgSubtle }],
1667
- accessibilityLabel: DAY_LABELS[d],
1668
- children: d
1669
- }
1670
- ) }, d)) }),
1671
- /* @__PURE__ */ jsx21(View16, { style: styles19.grid, children: rows.map((row, rowIndex) => /* @__PURE__ */ jsx21(View16, { style: styles19.dayRow, children: row.map((cell, colIndex) => {
1672
- if (!cell) {
1673
- return /* @__PURE__ */ jsx21(View16, { style: styles19.dayCell }, colIndex);
1674
- }
1675
- const date = new Date(viewYear, viewMonth, cell.day);
1676
- const isSelected = selected ? isSameDay(date, selected) : false;
1677
- const isToday = isSameDay(date, today);
1678
- const disabled = isOutOfRange(date, min, max);
1679
- return /* @__PURE__ */ jsx21(
1680
- Pressable11,
1681
- {
1682
- onPress: () => selectDay(cell.day),
1683
- disabled,
1684
- accessibilityRole: "button",
1685
- accessibilityLabel: date.toLocaleDateString("en", {
1686
- month: "long",
1687
- day: "numeric",
1688
- year: "numeric"
1689
- }),
1690
- accessibilityState: {
1691
- selected: isSelected,
1692
- disabled
1693
- },
1694
- style: ({ pressed }) => [
1695
- styles19.dayCell,
1696
- isSelected && {
1697
- backgroundColor: colors2.colorInteractive
1698
- },
1699
- isToday && !isSelected && [
1700
- styles19.today,
1701
- { borderColor: colors2.colorInteractive }
1702
- ],
1703
- disabled && styles19.disabled,
1704
- pressed && !disabled && styles19.pressed
1705
- ],
1706
- children: /* @__PURE__ */ jsx21(
1707
- Text17,
1708
- {
1709
- style: [
1710
- styles19.dayText,
1711
- {
1712
- color: isSelected ? colors2.colorOnInteractive : colors2.colorOnBg,
1713
- fontWeight: isToday ? font.weight.semibold : font.weight.body
1714
- }
1715
- ],
1716
- children: cell.day
1717
- }
1718
- )
1719
- },
1720
- colIndex
1721
- );
1722
- }) }, rowIndex)) })
1723
- ]
1724
- }
1725
- );
1726
- }
1727
-
1728
- // src/components/ui/Carousel/Carousel.native.tsx
1729
- import { useCallback as useCallback2, useRef as useRef3, useState as useState6 } from "react";
1730
- import {
1731
- StyleSheet as StyleSheet20,
1732
- View as View17,
1733
- Text as Text18,
1734
- Pressable as Pressable12,
1735
- ScrollView as ScrollView3,
1736
- Dimensions
1737
- } from "react-native";
1738
- import { jsx as jsx22, jsxs as jsxs14 } from "react/jsx-runtime";
1739
- var DOT_SIZE = 8;
1740
- var DOT_HIT_SIZE = 44;
1741
- var styles20 = StyleSheet20.create({
1742
- container: {
1743
- width: "100%"
1744
- },
1745
- scrollView: {
1746
- flexGrow: 0
1747
- },
1748
- slide: {
1749
- justifyContent: "center",
1750
- alignItems: "center"
1751
- },
1752
- nav: {
1753
- flexDirection: "row",
1754
- alignItems: "center",
1755
- justifyContent: "center",
1756
- gap: spacing.xs,
1757
- paddingVertical: spacing.s
1758
- },
1759
- navButton: {
1760
- minWidth: 44,
1761
- minHeight: 44,
1762
- alignItems: "center",
1763
- justifyContent: "center",
1764
- borderRadius: border.radius.s
1765
- },
1766
- navText: {
1767
- fontSize: 20,
1768
- fontWeight: "600"
1769
- },
1770
- dots: {
1771
- flexDirection: "row",
1772
- alignItems: "center",
1773
- gap: spacing.xs
1774
- },
1775
- dotWrapper: {
1776
- minWidth: DOT_HIT_SIZE,
1777
- minHeight: DOT_HIT_SIZE,
1778
- alignItems: "center",
1779
- justifyContent: "center"
1780
- },
1781
- dot: {
1782
- width: DOT_SIZE,
1783
- height: DOT_SIZE,
1784
- borderRadius: DOT_SIZE / 2
1785
- },
1786
- pressed: {
1787
- opacity: 0.75
1788
- }
1789
- });
1790
- function Carousel({
1791
- items,
1792
- label,
1793
- style
1794
- }) {
1795
- const { colors: colors2 } = useTheme();
1796
- const scrollRef = useRef3(null);
1797
- const [activeIndex, setActiveIndex] = useState6(0);
1798
- const [slideWidth, setSlideWidth] = useState6(Dimensions.get("window").width);
1799
- const handleScroll = useCallback2(
1800
- (e) => {
1801
- const offset = e.nativeEvent.contentOffset.x;
1802
- const width = e.nativeEvent.layoutMeasurement.width;
1803
- if (width > 0) {
1804
- const index = Math.round(offset / width);
1805
- setActiveIndex(index);
1806
- }
1807
- },
1808
- []
1809
- );
1810
- const scrollTo = (index) => {
1811
- const clamped = Math.max(0, Math.min(index, items.length - 1));
1812
- scrollRef.current?.scrollTo({ x: clamped * slideWidth, animated: true });
1813
- };
1814
- return /* @__PURE__ */ jsxs14(
1815
- View17,
1816
- {
1817
- style: [styles20.container, style],
1818
- accessibilityRole: "none",
1819
- accessibilityLabel: label,
1820
- children: [
1821
- /* @__PURE__ */ jsx22(
1822
- ScrollView3,
1823
- {
1824
- ref: scrollRef,
1825
- horizontal: true,
1826
- pagingEnabled: true,
1827
- showsHorizontalScrollIndicator: false,
1828
- onScroll: handleScroll,
1829
- scrollEventThrottle: 16,
1830
- onLayout: (e) => setSlideWidth(e.nativeEvent.layout.width),
1831
- style: styles20.scrollView,
1832
- children: items.map((item, index) => /* @__PURE__ */ jsx22(View17, { style: [styles20.slide, { width: slideWidth }], children: item }, index))
1833
- }
1834
- ),
1835
- /* @__PURE__ */ jsxs14(View17, { style: styles20.nav, children: [
1836
- /* @__PURE__ */ jsx22(
1837
- Pressable12,
1838
- {
1839
- onPress: () => scrollTo(activeIndex - 1),
1840
- disabled: activeIndex <= 0,
1841
- accessibilityRole: "button",
1842
- accessibilityLabel: "Previous",
1843
- accessibilityState: { disabled: activeIndex <= 0 },
1844
- style: ({ pressed }) => [
1845
- styles20.navButton,
1846
- activeIndex <= 0 && { opacity: 0.4 },
1847
- pressed && styles20.pressed
1848
- ],
1849
- children: /* @__PURE__ */ jsx22(Text18, { style: [styles20.navText, { color: colors2.colorOnBg }], children: "\u2039" })
1850
- }
1851
- ),
1852
- /* @__PURE__ */ jsx22(View17, { style: styles20.dots, children: items.map((_, index) => /* @__PURE__ */ jsx22(
1853
- Pressable12,
1854
- {
1855
- onPress: () => scrollTo(index),
1856
- accessibilityRole: "button",
1857
- accessibilityLabel: `Go to slide ${index + 1}`,
1858
- accessibilityState: { selected: activeIndex === index },
1859
- style: styles20.dotWrapper,
1860
- children: /* @__PURE__ */ jsx22(
1861
- View17,
1862
- {
1863
- style: [
1864
- styles20.dot,
1865
- {
1866
- backgroundColor: activeIndex === index ? colors2.colorInteractive : colors2.colorBgSubtle
1867
- }
1868
- ]
1869
- }
1870
- )
1871
- },
1872
- index
1873
- )) }),
1874
- /* @__PURE__ */ jsx22(
1875
- Pressable12,
1876
- {
1877
- onPress: () => scrollTo(activeIndex + 1),
1878
- disabled: activeIndex >= items.length - 1,
1879
- accessibilityRole: "button",
1880
- accessibilityLabel: "Next",
1881
- accessibilityState: { disabled: activeIndex >= items.length - 1 },
1882
- style: ({ pressed }) => [
1883
- styles20.navButton,
1884
- activeIndex >= items.length - 1 && { opacity: 0.4 },
1885
- pressed && styles20.pressed
1886
- ],
1887
- children: /* @__PURE__ */ jsx22(Text18, { style: [styles20.navText, { color: colors2.colorOnBg }], children: "\u203A" })
1888
- }
1889
- )
1890
- ] })
1891
- ]
1892
- }
1893
- );
1894
- }
1895
-
1896
- // src/components/layout/Card/Card.native.tsx
1897
- import { StyleSheet as StyleSheet21, View as View18, Pressable as Pressable13 } from "react-native";
1898
- import { jsx as jsx23 } from "react/jsx-runtime";
1899
- var paddingMap = {
1900
- none: 0,
1901
- small: spacing.s,
1902
- medium: spacing.m,
1903
- large: spacing.xxl
1904
- };
1905
- var alignMap = {
1906
- start: "flex-start",
1907
- center: "center",
1908
- end: "flex-end"
1909
- };
1910
- var styles21 = StyleSheet21.create({
1911
- card: {
1912
- borderRadius: border.radius.m,
1913
- overflow: "hidden"
1914
- }
1915
- });
1916
- function Card({
1917
- children,
1918
- variant = "default",
1919
- padding = "medium",
1920
- textAlign = "start",
1921
- style,
1922
- onPress,
1923
- accessibilityLabel
1924
- }) {
1925
- const { colors: colors2 } = useTheme();
1926
- const variantStyle = {
1927
- backgroundColor: colors2.colorBg,
1928
- ...variant === "elevated" && {
1929
- shadowColor: "#000",
1930
- shadowOffset: { width: 0, height: 2 },
1931
- shadowOpacity: 0.1,
1932
- shadowRadius: 8,
1933
- elevation: 4
1934
- },
1935
- ...variant === "outlined" && {
1936
- borderWidth: 1,
1937
- borderColor: colors2.colorBgSubtle
1938
- }
1939
- };
1940
- const inner = {
1941
- padding: paddingMap[padding],
1942
- alignItems: alignMap[textAlign]
1943
- };
1944
- if (onPress) {
1945
- return /* @__PURE__ */ jsx23(
1946
- Pressable13,
1947
- {
1948
- onPress,
1949
- accessibilityRole: "button",
1950
- accessibilityLabel,
1951
- style: ({ pressed }) => [styles21.card, variantStyle, inner, pressed && { opacity: 0.8 }, style],
1952
- children
1953
- }
1954
- );
1955
- }
1956
- return /* @__PURE__ */ jsx23(View18, { style: [styles21.card, variantStyle, inner, style], children });
1957
- }
1958
-
1959
- // src/components/layout/SectionHeader/SectionHeader.native.tsx
1960
- import { StyleSheet as StyleSheet22, View as View19, Text as Text19 } from "react-native";
1961
- import { jsx as jsx24, jsxs as jsxs15 } from "react/jsx-runtime";
1962
- var alignMap2 = {
1963
- start: "flex-start",
1964
- center: "center",
1965
- end: "flex-end"
1966
- };
1967
- var titleStyles = StyleSheet22.create({
1968
- small: {
1969
- fontSize: font.size.heading3,
1970
- fontFamily: font.family.heading,
1971
- fontWeight: font.weight.heading,
1972
- lineHeight: lineHeight.heading3
1973
- },
1974
- medium: {
1975
- fontSize: font.size.heading2,
1976
- fontFamily: font.family.heading,
1977
- fontWeight: font.weight.heading,
1978
- lineHeight: lineHeight.heading2
1979
- },
1980
- large: {
1981
- fontSize: font.size.heading1,
1982
- fontFamily: font.family.heading,
1983
- fontWeight: font.weight.heading,
1984
- lineHeight: lineHeight.heading1
1985
- }
1986
- });
1987
- var styles22 = StyleSheet22.create({
1988
- container: {
1989
- gap: spacing.xxs
1990
- },
1991
- subtitle: {
1992
- fontSize: font.size.bodyS,
1993
- fontFamily: font.family.body,
1994
- lineHeight: lineHeight.bodyS
1995
- }
1996
- });
1997
- function SectionHeader({
1998
- title,
1999
- subtitle,
2000
- alignment = "start",
2001
- size = "medium",
2002
- style
2003
- }) {
2004
- const { colors: colors2 } = useTheme();
2005
- const align = alignMap2[alignment];
2006
- return /* @__PURE__ */ jsxs15(View19, { style: [styles22.container, { alignItems: align }, style], children: [
2007
- /* @__PURE__ */ jsx24(
2008
- Text19,
2009
- {
2010
- accessibilityRole: "header",
2011
- style: [titleStyles[size], { color: colors2.colorOnBg }],
2012
- children: title
2013
- }
2014
- ),
2015
- subtitle && /* @__PURE__ */ jsx24(Text19, { style: [styles22.subtitle, { color: colors2.colorOnBgSubtle }], children: subtitle })
2016
- ] });
2017
- }
2018
-
2019
- // src/components/layout/IconWrapper/IconWrapper.native.tsx
2020
- import { View as View20 } from "react-native";
2021
- import { jsx as jsx25 } from "react/jsx-runtime";
2022
- function IconWrapper({ children, style, accessibilityElementsHidden }) {
2023
- return /* @__PURE__ */ jsx25(
2024
- View20,
2025
- {
2026
- style: [{ alignItems: "center", justifyContent: "center" }, style],
2027
- importantForAccessibility: accessibilityElementsHidden ? "no-hide-descendants" : "auto",
2028
- accessibilityElementsHidden,
2029
- children
2030
- }
2031
- );
2032
- }
2033
-
2034
- // src/components/layout/ButtonGroup/ButtonGroup.native.tsx
2035
- import { StyleSheet as StyleSheet23, View as View21 } from "react-native";
2036
- import { jsx as jsx26 } from "react/jsx-runtime";
2037
- var styles23 = StyleSheet23.create({
2038
- group: {
2039
- flexDirection: "row",
2040
- flexWrap: "wrap",
2041
- gap: spacing.xs
2042
- },
2043
- column: {
2044
- flexDirection: "column",
2045
- gap: spacing.xs
2046
- }
2047
- });
2048
- function ButtonContainer({ children, variant, accessibilityLabel, style }) {
2049
- const isColumn = variant === "card" || variant === "modal";
2050
- return /* @__PURE__ */ jsx26(
2051
- View21,
2052
- {
2053
- accessibilityLabel,
2054
- style: [isColumn ? styles23.column : styles23.group, style],
2055
- children
2056
- }
2057
- );
2058
- }
2059
- var ButtonGroup = ButtonContainer;
2060
-
2061
- // src/components/interaction/Button/Button.native.tsx
2062
- import { StyleSheet as StyleSheet24, Pressable as Pressable14, Text as Text20, View as View22 } from "react-native";
2063
- import { jsx as jsx27, jsxs as jsxs16 } from "react/jsx-runtime";
2064
- var sizeTokens = {
2065
- small: { height: 36, px: spacing.m, fontSize: font.size.bodyS, radius: border.radius.full },
2066
- medium: { height: 48, px: spacing.m, fontSize: font.size.body, radius: border.radius.full },
2067
- large: { height: 56, px: spacing.xxl, fontSize: font.size.heading3, radius: border.radius.full }
2068
- };
2069
- var styles24 = StyleSheet24.create({
2070
- pressable: {
2071
- flexDirection: "row",
2072
- alignItems: "center",
2073
- justifyContent: "center",
2074
- gap: spacing.xs,
2075
- alignSelf: "flex-start"
2076
- },
2077
- label: {
2078
- fontFamily: font.family.body,
2079
- fontWeight: font.weight.semibold,
2080
- includeFontPadding: false
2081
- }
2082
- });
2083
- function Button({
2084
- children,
2085
- variant = "default",
2086
- size = "medium",
2087
- iconStart,
2088
- iconEnd,
2089
- disabled = false,
2090
- isIconOnly = false,
2091
- onPress,
2092
- accessibilityLabel,
2093
- style
2094
- }) {
2095
- const { colors: colors2 } = useTheme();
2096
- const { height, px, fontSize, radius } = sizeTokens[size];
2097
- const primaryColor = colors2.colorInteractive;
2098
- const onPrimaryColor = colors2.colorOnInteractive;
2099
- const outlineTextColor = colors2.colorInteractiveOnBg;
2100
- const isOutline = variant === "outline" || variant === "ghost";
2101
- const containerStyle = {
2102
- height,
2103
- paddingHorizontal: isIconOnly ? spacing.xs : px,
2104
- borderRadius: radius,
2105
- opacity: disabled ? 0.4 : 1,
2106
- // Icon-only: square with equal xs padding on both axes.
2107
- ...isIconOnly && { aspectRatio: 1, paddingVertical: spacing.xs },
2108
- ...variant === "default" && { backgroundColor: primaryColor },
2109
- ...isOutline && {
2110
- backgroundColor: "transparent",
2111
- borderWidth: 1,
2112
- borderColor: outlineTextColor
2113
- }
2114
- };
2115
- const textColor = variant === "default" ? onPrimaryColor : outlineTextColor;
2116
- return /* @__PURE__ */ jsxs16(
2117
- Pressable14,
2118
- {
2119
- onPress,
2120
- disabled,
2121
- accessibilityRole: "button",
2122
- accessibilityLabel,
2123
- accessibilityState: { disabled },
2124
- style: ({ pressed }) => [styles24.pressable, containerStyle, pressed && { opacity: 0.75 }, style],
2125
- children: [
2126
- iconStart && /* @__PURE__ */ jsx27(View22, { importantForAccessibility: "no-hide-descendants", accessibilityElementsHidden: true, children: iconStart }),
2127
- children && (isIconOnly ? children : /* @__PURE__ */ jsx27(Text20, { style: [styles24.label, { fontSize, color: textColor }], children })),
2128
- iconEnd && /* @__PURE__ */ jsx27(View22, { importantForAccessibility: "no-hide-descendants", children: iconEnd })
2129
- ]
2130
- }
2131
- );
2132
- }
2133
-
2134
- // src/components/interaction/Rating/Rating.native.tsx
2135
- import { StyleSheet as StyleSheet25, View as View23, Text as Text21 } from "react-native";
2136
- import { jsx as jsx28 } from "react/jsx-runtime";
2137
- var STAR_SIZE = 24;
2138
- var styles25 = StyleSheet25.create({
2139
- container: {
2140
- flexDirection: "row",
2141
- alignItems: "center"
2142
- },
2143
- star: {
2144
- fontSize: STAR_SIZE,
2145
- fontFamily: font.family.body
2146
- }
2147
- });
2148
- function Rating({ value, max = 5, style, accessibilityLabel }) {
2149
- const { colors: colors2 } = useTheme();
2150
- const label = accessibilityLabel ?? `${value} out of ${max} stars`;
2151
- return /* @__PURE__ */ jsx28(
2152
- View23,
2153
- {
2154
- style: [styles25.container, style],
2155
- accessibilityRole: "image",
2156
- accessibilityLabel: label,
2157
- children: Array.from({ length: max }).map((_, i) => /* @__PURE__ */ jsx28(
2158
- Text21,
2159
- {
2160
- style: [
2161
- styles25.star,
2162
- { color: i < value ? colors2.colorWarning : colors2.colorBgSubtle }
2163
- ],
2164
- importantForAccessibility: "no",
2165
- accessibilityElementsHidden: true,
2166
- children: "\u2605"
2167
- },
2168
- i
2169
- ))
2170
- }
2171
- );
2172
- }
2173
-
2174
- // src/components/interaction/form/Switch/Switch.native.tsx
2175
- import { Switch as RNSwitch, View as View24, StyleSheet as StyleSheet27 } from "react-native";
2176
-
2177
- // src/components/interaction/form/atoms/Label.native.tsx
2178
- import { Text as Text22 } from "react-native";
2179
- import { jsx as jsx29 } from "react/jsx-runtime";
2180
- function Label({ label, style }) {
2181
- const { colors: colors2 } = useTheme();
2182
- return /* @__PURE__ */ jsx29(
2183
- Text22,
2184
- {
2185
- style: [
2186
- {
2187
- fontFamily: font.family.body,
2188
- fontSize: font.size.body,
2189
- lineHeight: lineHeight.body,
2190
- fontWeight: font.weight.semibold,
2191
- color: colors2.colorOnBg
2192
- },
2193
- style
2194
- ],
2195
- children: label
2196
- }
2197
- );
2198
- }
2199
-
2200
- // src/components/interaction/form/atoms/Message.native.tsx
2201
- import { StyleSheet as StyleSheet26, Text as Text23 } from "react-native";
2202
- import { jsx as jsx30 } from "react/jsx-runtime";
2203
- var styles26 = StyleSheet26.create({
2204
- base: {
2205
- fontFamily: font.family.body,
2206
- fontSize: font.size.bodyS,
2207
- lineHeight: lineHeight.bodyS
2208
- }
2209
- });
2210
- function Message({ message, type, style }) {
2211
- const { colors: colors2 } = useTheme();
2212
- if (!message) return null;
2213
- const color = type === "error" ? colors2.colorError : colors2.colorOnBgSubtle;
2214
- return /* @__PURE__ */ jsx30(
2215
- Text23,
2216
- {
2217
- accessibilityRole: type === "error" ? "alert" : "none",
2218
- accessibilityLiveRegion: type === "error" ? "assertive" : "polite",
2219
- style: [styles26.base, { color }, style],
2220
- children: message
2221
- }
2222
- );
2223
- }
2224
-
2225
- // src/components/interaction/form/Switch/Switch.native.tsx
2226
- import { jsx as jsx31, jsxs as jsxs17 } from "react/jsx-runtime";
2227
- var styles27 = StyleSheet27.create({
2228
- container: {
2229
- gap: spacing.xxs
2230
- },
2231
- row: {
2232
- flexDirection: "row",
2233
- alignItems: "center",
2234
- gap: spacing.xs
2235
- }
2236
- });
2237
- function Switch({
2238
- label,
2239
- value = false,
2240
- onChange,
2241
- disabled = false,
2242
- error,
2243
- hint,
2244
- style
2245
- }) {
2246
- const { colors: colors2 } = useTheme();
2247
- return /* @__PURE__ */ jsxs17(View24, { style: [styles27.container, style], children: [
2248
- /* @__PURE__ */ jsxs17(View24, { style: styles27.row, children: [
2249
- /* @__PURE__ */ jsx31(
2250
- RNSwitch,
2251
- {
2252
- value,
2253
- onValueChange: onChange,
2254
- disabled,
2255
- accessibilityLabel: label,
2256
- accessibilityRole: "switch",
2257
- accessibilityState: { checked: value, disabled },
2258
- thumbColor: colors2.colorInteractive,
2259
- trackColor: { false: colors2.colorBgSubtle, true: colors2.colorBlueSubtle }
2260
- }
2261
- ),
2262
- /* @__PURE__ */ jsx31(Label, { label })
2263
- ] }),
2264
- /* @__PURE__ */ jsx31(Message, { type: "error", message: error }),
2265
- /* @__PURE__ */ jsx31(Message, { type: "hint", message: hint })
2266
- ] });
2267
- }
2268
-
2269
- // src/components/interaction/form/Checkbox/Checkbox.native.tsx
2270
- import { StyleSheet as StyleSheet28, View as View25, Pressable as Pressable15 } from "react-native";
2271
- import { jsx as jsx32, jsxs as jsxs18 } from "react/jsx-runtime";
2272
- var BOX = 22;
2273
- var styles28 = StyleSheet28.create({
2274
- container: {
2275
- gap: spacing.xxs
2276
- },
2277
- row: {
2278
- flexDirection: "row",
2279
- alignItems: "center",
2280
- gap: spacing.xs,
2281
- minHeight: 44
2282
- },
2283
- box: {
2284
- width: BOX,
2285
- height: BOX,
2286
- borderRadius: border.radius.xs,
2287
- borderWidth: 2,
2288
- alignItems: "center",
2289
- justifyContent: "center"
2290
- },
2291
- checkmark: {
2292
- fontSize: 14,
2293
- fontWeight: "700",
2294
- lineHeight: 16
2295
- }
2296
- });
2297
- function Checkbox({
2298
- label,
2299
- name,
2300
- checked = false,
2301
- onChange,
2302
- disabled = false,
2303
- error,
2304
- hint,
2305
- style
2306
- }) {
2307
- const { colors: colors2 } = useTheme();
2308
- const borderColor = error ? colors2.colorError : checked ? colors2.colorInteractive : colors2.colorOnBg;
2309
- const bgColor = checked ? colors2.colorInteractive : "transparent";
2310
- return /* @__PURE__ */ jsxs18(View25, { style: [styles28.container, style], children: [
2311
- /* @__PURE__ */ jsxs18(
2312
- Pressable15,
2313
- {
2314
- onPress: () => !disabled && onChange?.(!checked),
2315
- accessibilityRole: "checkbox",
2316
- accessibilityLabel: typeof label === "string" ? label : name,
2317
- accessibilityState: { checked, disabled },
2318
- disabled,
2319
- style: ({ pressed }) => [styles28.row, pressed && { opacity: 0.7 }, disabled && { opacity: 0.4 }],
2320
- children: [
2321
- /* @__PURE__ */ jsx32(View25, { style: [styles28.box, { borderColor, backgroundColor: bgColor }], children: checked && /* @__PURE__ */ jsx32(Label, { label: "\u2713", style: [styles28.checkmark, { color: colors2.colorOnInteractive }] }) }),
2322
- /* @__PURE__ */ jsx32(Label, { label })
2323
- ]
2324
- }
2325
- ),
2326
- /* @__PURE__ */ jsx32(Message, { type: "error", message: error }),
2327
- /* @__PURE__ */ jsx32(Message, { type: "hint", message: hint })
2328
- ] });
2329
- }
2330
-
2331
- // src/components/interaction/form/CheckboxGroup/CheckboxGroup.native.tsx
2332
- import { StyleSheet as StyleSheet29, View as View26, Text as Text24 } from "react-native";
2333
- import { jsx as jsx33, jsxs as jsxs19 } from "react/jsx-runtime";
2334
- var styles29 = StyleSheet29.create({
2335
- container: {
2336
- gap: spacing.xs
2337
- },
2338
- legend: {
2339
- fontFamily: font.family.body,
2340
- fontSize: font.size.body,
2341
- lineHeight: lineHeight.body,
2342
- fontWeight: font.weight.semibold
2343
- },
2344
- required: {
2345
- fontWeight: font.weight.body
2346
- },
2347
- items: {
2348
- gap: spacing.xxs
2349
- }
2350
- });
2351
- function CheckboxGroup({
2352
- legend,
2353
- children,
2354
- error,
2355
- hint,
2356
- required,
2357
- disabled = false,
2358
- style
2359
- }) {
2360
- const { colors: colors2 } = useTheme();
2361
- return /* @__PURE__ */ jsxs19(
2362
- View26,
2363
- {
2364
- style: [styles29.container, disabled && { opacity: 0.4 }, style],
2365
- accessibilityRole: "none",
2366
- accessibilityLabel: legend,
2367
- children: [
2368
- /* @__PURE__ */ jsxs19(Text24, { style: [styles29.legend, { color: colors2.colorOnBg }], children: [
2369
- legend,
2370
- required && /* @__PURE__ */ jsx33(Text24, { style: [styles29.required, { color: colors2.colorOnBgSubtle }], children: " *" })
2371
- ] }),
2372
- /* @__PURE__ */ jsx33(View26, { style: styles29.items, children }),
2373
- /* @__PURE__ */ jsx33(Message, { type: "error", message: error }),
2374
- /* @__PURE__ */ jsx33(Message, { type: "hint", message: hint })
2375
- ]
2376
- }
2377
- );
2378
- }
2379
-
2380
- // src/components/interaction/form/Radio/Radio.native.tsx
2381
- import { StyleSheet as StyleSheet30, View as View27, Pressable as Pressable16 } from "react-native";
2382
- import { jsx as jsx34, jsxs as jsxs20 } from "react/jsx-runtime";
2383
- var DOT = 22;
2384
- var INNER = 10;
2385
- var styles30 = StyleSheet30.create({
2386
- container: {
2387
- gap: spacing.xxs
2388
- },
2389
- row: {
2390
- flexDirection: "row",
2391
- alignItems: "center",
2392
- gap: spacing.xs,
2393
- minHeight: 44
2394
- },
2395
- outer: {
2396
- width: DOT,
2397
- height: DOT,
2398
- borderRadius: DOT / 2,
2399
- borderWidth: 2,
2400
- alignItems: "center",
2401
- justifyContent: "center"
2402
- },
2403
- inner: {
2404
- width: INNER,
2405
- height: INNER,
2406
- borderRadius: INNER / 2
2407
- }
2408
- });
2409
- function Radio({
2410
- label,
2411
- name,
2412
- checked = false,
2413
- onChange,
2414
- disabled = false,
2415
- error,
2416
- hint,
2417
- style
2418
- }) {
2419
- const { colors: colors2 } = useTheme();
2420
- const borderColor = error ? colors2.colorError : checked ? colors2.colorInteractive : colors2.colorOnBg;
2421
- return /* @__PURE__ */ jsxs20(View27, { style: [styles30.container, style], children: [
2422
- /* @__PURE__ */ jsxs20(
2423
- Pressable16,
2424
- {
2425
- onPress: () => !disabled && onChange?.(),
2426
- accessibilityRole: "radio",
2427
- accessibilityLabel: typeof label === "string" ? label : name,
2428
- accessibilityState: { checked, disabled },
2429
- disabled,
2430
- style: ({ pressed }) => [styles30.row, pressed && { opacity: 0.7 }, disabled && { opacity: 0.4 }],
2431
- children: [
2432
- /* @__PURE__ */ jsx34(View27, { style: [styles30.outer, { borderColor }], children: checked && /* @__PURE__ */ jsx34(View27, { style: [styles30.inner, { backgroundColor: colors2.colorInteractive }] }) }),
2433
- /* @__PURE__ */ jsx34(Label, { label })
2434
- ]
2435
- }
2436
- ),
2437
- /* @__PURE__ */ jsx34(Message, { type: "error", message: error }),
2438
- /* @__PURE__ */ jsx34(Message, { type: "hint", message: hint })
2439
- ] });
2440
- }
2441
-
2442
- // src/components/interaction/form/RadioGroup/RadioGroup.native.tsx
2443
- import { StyleSheet as StyleSheet31, View as View28, Text as Text25 } from "react-native";
2444
- import { jsx as jsx35, jsxs as jsxs21 } from "react/jsx-runtime";
2445
- var styles31 = StyleSheet31.create({
2446
- container: {
2447
- gap: spacing.xs
2448
- },
2449
- legend: {
2450
- fontFamily: font.family.body,
2451
- fontSize: font.size.body,
2452
- lineHeight: lineHeight.body,
2453
- fontWeight: font.weight.semibold
2454
- },
2455
- required: {
2456
- fontWeight: font.weight.body
2457
- },
2458
- items: {
2459
- gap: spacing.xxs
2460
- }
2461
- });
2462
- function RadioGroup({
2463
- legend,
2464
- children,
2465
- error,
2466
- hint,
2467
- required,
2468
- disabled = false,
2469
- style
2470
- }) {
2471
- const { colors: colors2 } = useTheme();
2472
- return /* @__PURE__ */ jsxs21(
2473
- View28,
2474
- {
2475
- style: [styles31.container, disabled && { opacity: 0.4 }, style],
2476
- accessibilityRole: "radiogroup",
2477
- accessibilityLabel: legend,
2478
- children: [
2479
- /* @__PURE__ */ jsxs21(Text25, { style: [styles31.legend, { color: colors2.colorOnBg }], children: [
2480
- legend,
2481
- required && /* @__PURE__ */ jsx35(Text25, { style: [styles31.required, { color: colors2.colorOnBgSubtle }], children: " *" })
2482
- ] }),
2483
- /* @__PURE__ */ jsx35(View28, { style: styles31.items, children }),
2484
- /* @__PURE__ */ jsx35(Message, { type: "error", message: error }),
2485
- /* @__PURE__ */ jsx35(Message, { type: "hint", message: hint })
2486
- ]
2487
- }
2488
- );
2489
- }
2490
-
2491
- // src/components/interaction/form/FileInput/FileInput.native.tsx
2492
- import { StyleSheet as StyleSheet32, View as View29, Pressable as Pressable17, Text as Text26 } from "react-native";
2493
- import { jsx as jsx36, jsxs as jsxs22 } from "react/jsx-runtime";
2494
- var styles32 = StyleSheet32.create({
2495
- container: {
2496
- gap: spacing.xxs
2497
- },
2498
- dropZone: {
2499
- alignItems: "center",
2500
- justifyContent: "center",
2501
- gap: spacing.xs,
2502
- paddingVertical: spacing.xl,
2503
- paddingHorizontal: spacing.m,
2504
- borderWidth: 2,
2505
- borderStyle: "dashed",
2506
- borderRadius: border.radius.s,
2507
- minHeight: 120
2508
- },
2509
- icon: {
2510
- fontSize: 28,
2511
- lineHeight: 32
2512
- },
2513
- prompt: {
2514
- fontFamily: font.family.body,
2515
- fontSize: font.size.body,
2516
- lineHeight: lineHeight.body,
2517
- textAlign: "center"
2518
- },
2519
- acceptHint: {
2520
- fontFamily: font.family.body,
2521
- fontSize: font.size.bodyS,
2522
- lineHeight: lineHeight.bodyS,
2523
- textAlign: "center"
2524
- },
2525
- fileList: {
2526
- gap: spacing.xxs,
2527
- alignItems: "center"
2528
- },
2529
- fileName: {
2530
- fontFamily: font.family.body,
2531
- fontSize: font.size.bodyS,
2532
- lineHeight: lineHeight.bodyS
2533
- }
2534
- });
2535
- function FileInput({
2536
- label,
2537
- name,
2538
- accept,
2539
- disabled = false,
2540
- required,
2541
- error,
2542
- hint,
2543
- onSelect,
2544
- fileNames = [],
2545
- style
2546
- }) {
2547
- const { colors: colors2 } = useTheme();
2548
- const borderColor = error ? colors2.colorError : colors2.colorBgSubtle;
2549
- return /* @__PURE__ */ jsxs22(View29, { style: [styles32.container, style], testID: name, children: [
2550
- /* @__PURE__ */ jsx36(
2551
- Label,
2552
- {
2553
- label: required ? `${label} *` : label
2554
- }
2555
- ),
2556
- /* @__PURE__ */ jsxs22(
2557
- Pressable17,
2558
- {
2559
- onPress: () => !disabled && onSelect?.(),
2560
- disabled,
2561
- accessibilityRole: "button",
2562
- accessibilityLabel: `${label}, tap to select file`,
2563
- accessibilityState: { disabled },
2564
- style: ({ pressed }) => [
2565
- styles32.dropZone,
2566
- {
2567
- borderColor,
2568
- backgroundColor: "transparent"
2569
- },
2570
- pressed && { opacity: 0.7 },
2571
- disabled && { opacity: 0.4 }
2572
- ],
2573
- children: [
2574
- /* @__PURE__ */ jsx36(Text26, { style: [styles32.icon, { color: colors2.colorInteractive }], children: "\u2191" }),
2575
- /* @__PURE__ */ jsx36(Text26, { style: [styles32.prompt, { color: colors2.colorOnBgSubtle }], children: fileNames.length > 0 ? "Selected files:" : "Tap to select file" }),
2576
- fileNames.length > 0 && /* @__PURE__ */ jsx36(View29, { style: styles32.fileList, children: fileNames.map((fileName) => /* @__PURE__ */ jsx36(Text26, { style: [styles32.fileName, { color: colors2.colorOnBg }], children: fileName }, fileName)) }),
2577
- accept && /* @__PURE__ */ jsx36(Text26, { style: [styles32.acceptHint, { color: colors2.colorOnBgSubtle }], children: accept })
2578
- ]
2579
- }
2580
- ),
2581
- /* @__PURE__ */ jsx36(Message, { type: "error", message: error }),
2582
- /* @__PURE__ */ jsx36(Message, { type: "hint", message: hint })
2583
- ] });
2584
- }
2585
-
2586
- // src/components/interaction/form/Combobox/Combobox.native.tsx
2587
- import { useState as useState7, useMemo as useMemo2 } from "react";
2588
- import {
2589
- StyleSheet as StyleSheet33,
2590
- View as View30,
2591
- TextInput,
2592
- Pressable as Pressable18,
2593
- Text as Text27,
2594
- ScrollView as ScrollView4
2595
- } from "react-native";
2596
- import { jsx as jsx37, jsxs as jsxs23 } from "react/jsx-runtime";
2597
- var MAX_DROPDOWN_HEIGHT = 200;
2598
- var styles33 = StyleSheet33.create({
2599
- container: {
2600
- gap: spacing.xxs
2601
- },
2602
- inputWrapper: {
2603
- position: "relative"
2604
- },
2605
- input: {
2606
- fontFamily: font.family.body,
2607
- fontSize: font.size.body,
2608
- lineHeight: lineHeight.body,
2609
- paddingVertical: spacing.xs,
2610
- paddingHorizontal: spacing.s,
2611
- borderWidth: 1,
2612
- borderRadius: border.radius.full,
2613
- minHeight: 44
2614
- },
2615
- dropdown: {
2616
- position: "absolute",
2617
- top: "100%",
2618
- start: 0,
2619
- end: 0,
2620
- maxHeight: MAX_DROPDOWN_HEIGHT,
2621
- borderWidth: 1,
2622
- borderTopWidth: 0,
2623
- borderBottomStartRadius: border.radius.xs,
2624
- borderBottomEndRadius: border.radius.xs,
2625
- zIndex: 10
2626
- },
2627
- option: {
2628
- paddingVertical: spacing.xs,
2629
- paddingHorizontal: spacing.s,
2630
- minHeight: 44,
2631
- justifyContent: "center"
2632
- },
2633
- optionText: {
2634
- fontFamily: font.family.body,
2635
- fontSize: font.size.body,
2636
- lineHeight: lineHeight.body
2637
- }
2638
- });
2639
- function Combobox({
2640
- label,
2641
- name,
2642
- options,
2643
- placeholder,
2644
- value,
2645
- onChange,
2646
- disabled = false,
2647
- error,
2648
- hint,
2649
- style
2650
- }) {
2651
- const { colors: colors2 } = useTheme();
2652
- const selectedOption = useMemo2(
2653
- () => options.find((o) => o.value === value),
2654
- [options, value]
2655
- );
2656
- const [inputValue, setInputValue] = useState7(selectedOption?.label ?? "");
2657
- const [isOpen, setIsOpen] = useState7(false);
2658
- const filtered = useMemo2(
2659
- () => options.filter(
2660
- (o) => o.label.toLowerCase().includes(inputValue.toLowerCase())
2661
- ),
2662
- [options, inputValue]
2663
- );
2664
- const selectOption = (option) => {
2665
- setInputValue(option.label);
2666
- setIsOpen(false);
2667
- onChange?.(option.value);
2668
- };
2669
- const handleChangeText = (text) => {
2670
- setInputValue(text);
2671
- setIsOpen(true);
2672
- };
2673
- const handleFocus = () => {
2674
- setIsOpen(true);
2675
- };
2676
- const handleBlur = () => {
2677
- setTimeout(() => setIsOpen(false), 150);
2678
- };
2679
- const borderColor = error ? colors2.colorError : colors2.colorOnBg;
2680
- return /* @__PURE__ */ jsxs23(View30, { style: [styles33.container, style], children: [
2681
- /* @__PURE__ */ jsx37(Label, { label }),
2682
- /* @__PURE__ */ jsxs23(View30, { style: styles33.inputWrapper, children: [
2683
- /* @__PURE__ */ jsx37(
2684
- TextInput,
2685
- {
2686
- value: inputValue,
2687
- onChangeText: handleChangeText,
2688
- onFocus: handleFocus,
2689
- onBlur: handleBlur,
2690
- placeholder,
2691
- placeholderTextColor: colors2.colorOnBgSubtle,
2692
- editable: !disabled,
2693
- accessibilityRole: "combobox",
2694
- accessibilityLabel: typeof label === "string" ? label : name,
2695
- accessibilityState: { disabled, expanded: isOpen },
2696
- style: [
2697
- styles33.input,
2698
- {
2699
- borderColor,
2700
- color: colors2.colorOnBg,
2701
- backgroundColor: colors2.colorBg
2702
- },
2703
- disabled && { opacity: 0.4 }
2704
- ]
2705
- }
2706
- ),
2707
- isOpen && filtered.length > 0 && /* @__PURE__ */ jsx37(
2708
- ScrollView4,
2709
- {
2710
- style: [
2711
- styles33.dropdown,
2712
- {
2713
- borderColor: colors2.colorBgSubtle,
2714
- backgroundColor: colors2.colorBg
2715
- }
2716
- ],
2717
- keyboardShouldPersistTaps: "handled",
2718
- nestedScrollEnabled: true,
2719
- children: filtered.map((option) => {
2720
- const isSelected = option.value === value;
2721
- const isDisabled = option.disabled;
2722
- return /* @__PURE__ */ jsx37(
2723
- Pressable18,
2724
- {
2725
- onPress: () => !isDisabled && selectOption(option),
2726
- disabled: isDisabled,
2727
- accessibilityRole: "menuitem",
2728
- accessibilityLabel: option.label,
2729
- accessibilityState: { selected: isSelected, disabled: isDisabled },
2730
- style: ({ pressed }) => [
2731
- styles33.option,
2732
- isSelected && { backgroundColor: colors2.colorBlueSubtle },
2733
- pressed && !isDisabled && { backgroundColor: colors2.colorBgSubtle },
2734
- isDisabled && { opacity: 0.4 }
2735
- ],
2736
- children: /* @__PURE__ */ jsx37(
2737
- Text27,
2738
- {
2739
- style: [
2740
- styles33.optionText,
2741
- {
2742
- color: isSelected ? colors2.colorInteractive : colors2.colorOnBg
2743
- },
2744
- isSelected && { fontWeight: font.weight.semibold }
2745
- ],
2746
- children: option.label
2747
- }
2748
- )
2749
- },
2750
- option.value
2751
- );
2752
- })
2753
- }
2754
- )
2755
- ] }),
2756
- /* @__PURE__ */ jsx37(Message, { type: "error", message: error }),
2757
- /* @__PURE__ */ jsx37(Message, { type: "hint", message: hint })
2758
- ] });
2759
- }
2760
-
2761
- // src/components/interaction/form/SegmentedControl/SegmentedControl.native.tsx
2762
- import { Children } from "react";
2763
- import { StyleSheet as StyleSheet34, View as View31, Pressable as Pressable19, Text as Text28 } from "react-native";
2764
- import { jsx as jsx38 } from "react/jsx-runtime";
2765
- var sizeTokens2 = {
2766
- small: { height: 32, fontSize: font.size.bodyS, px: spacing.s },
2767
- medium: { height: 40, fontSize: font.size.body, px: spacing.m },
2768
- large: { height: 48, fontSize: font.size.body, px: spacing.l }
2769
- };
2770
- var styles34 = StyleSheet34.create({
2771
- track: {
2772
- flexDirection: "row",
2773
- borderRadius: border.radius.full,
2774
- overflow: "hidden"
2775
- },
2776
- item: {
2777
- flex: 1,
2778
- alignItems: "center",
2779
- justifyContent: "center",
2780
- minHeight: 44
2781
- },
2782
- label: {
2783
- fontFamily: font.family.body,
2784
- fontWeight: font.weight.semibold,
2785
- textAlign: "center"
2786
- }
2787
- });
2788
- function SegmentedControl({
2789
- selectedIndex = 0,
2790
- disabled = false,
2791
- size = "medium",
2792
- variant = "outline",
2793
- children,
2794
- accessibilityLabel,
2795
- onValueChange,
2796
- style
2797
- }) {
2798
- const { colors: colors2 } = useTheme();
2799
- const { height, fontSize, px } = sizeTokens2[size];
2800
- const items = Children.toArray(children);
2801
- const trackStyle = variant === "filled" ? { backgroundColor: colors2.colorBgSubtle } : { backgroundColor: "transparent", borderWidth: 1, borderColor: colors2.colorBgSubtle };
2802
- return /* @__PURE__ */ jsx38(
2803
- View31,
2804
- {
2805
- style: [styles34.track, trackStyle, { borderRadius: border.radius.full }, style],
2806
- accessibilityRole: "tablist",
2807
- accessibilityLabel,
2808
- children: items.map((child, index) => {
2809
- const isActive = index === selectedIndex;
2810
- const activeStyle = variant === "filled" ? { backgroundColor: colors2.colorInteractive } : { borderWidth: 2, borderColor: colors2.colorInteractive };
2811
- const inactiveStyle = variant === "filled" ? {} : {};
2812
- const textColor = variant === "filled" && isActive ? colors2.colorOnInteractive : isActive ? colors2.colorInteractive : colors2.colorOnBgSubtle;
2813
- const label = typeof child === "string" || typeof child === "number" ? String(child) : null;
2814
- return /* @__PURE__ */ jsx38(
2815
- Pressable19,
2816
- {
2817
- onPress: () => !disabled && onValueChange?.(index),
2818
- disabled,
2819
- accessibilityRole: "tab",
2820
- accessibilityLabel: label ?? void 0,
2821
- accessibilityState: { selected: isActive, disabled },
2822
- style: ({ pressed }) => [
2823
- styles34.item,
2824
- { height, paddingHorizontal: px },
2825
- isActive ? activeStyle : inactiveStyle,
2826
- variant === "filled" && isActive && { borderRadius: border.radius.full },
2827
- pressed && !disabled && { opacity: 0.7 },
2828
- disabled && { opacity: 0.4 }
2829
- ],
2830
- children: label !== null ? /* @__PURE__ */ jsx38(Text28, { style: [styles34.label, { fontSize, color: textColor }], children: label }) : child
2831
- },
2832
- index
2833
- );
2834
- })
2835
- }
2836
- );
2837
- }
2838
-
2839
- // src/components/interaction/form/FormInput/FormInput.native.tsx
2840
- import { useState as useState8 } from "react";
2841
- import {
2842
- StyleSheet as StyleSheet35,
2843
- View as View32,
2844
- TextInput as TextInput2
2845
- } from "react-native";
2846
- import { jsx as jsx39, jsxs as jsxs24 } from "react/jsx-runtime";
2847
- var keyboardTypeMap = {
2848
- text: "default",
2849
- email: "email-address",
2850
- password: "default",
2851
- tel: "phone-pad",
2852
- url: "url",
2853
- number: "numeric",
2854
- search: "default"
2855
- };
2856
- var styles35 = StyleSheet35.create({
2857
- container: {
2858
- gap: spacing.xxs
2859
- },
2860
- input: {
2861
- fontFamily: font.family.body,
2862
- fontSize: font.size.body,
2863
- lineHeight: lineHeight.body,
2864
- paddingHorizontal: spacing.s,
2865
- paddingVertical: spacing.xs,
2866
- borderWidth: 1,
2867
- borderRadius: border.radius.full,
2868
- minHeight: 44
2869
- }
2870
- });
2871
- function FormInput({
2872
- label,
2873
- name,
2874
- type = "text",
2875
- value,
2876
- defaultValue,
2877
- placeholder,
2878
- error,
2879
- hint,
2880
- disabled = false,
2881
- onChange,
2882
- onBlur,
2883
- onFocus,
2884
- style
2885
- }) {
2886
- const { colors: colors2 } = useTheme();
2887
- const [focused, setFocused] = useState8(false);
2888
- const borderColor = error ? colors2.colorError : focused ? colors2.colorInteractive : colors2.colorOnBg;
2889
- return /* @__PURE__ */ jsxs24(View32, { style: [styles35.container, style], children: [
2890
- /* @__PURE__ */ jsx39(Label, { label }),
2891
- /* @__PURE__ */ jsx39(
2892
- TextInput2,
2893
- {
2894
- accessibilityLabel: typeof label === "string" ? label : name,
2895
- accessibilityState: { disabled },
2896
- accessibilityHint: hint,
2897
- value,
2898
- defaultValue,
2899
- placeholder,
2900
- placeholderTextColor: colors2.colorOnBgSubtle,
2901
- keyboardType: keyboardTypeMap[type],
2902
- secureTextEntry: type === "password",
2903
- autoCapitalize: type === "email" || type === "url" ? "none" : "sentences",
2904
- autoComplete: type === "email" ? "email" : type === "tel" ? "tel" : void 0,
2905
- editable: !disabled,
2906
- onChangeText: onChange,
2907
- onFocus: () => {
2908
- setFocused(true);
2909
- onFocus?.();
2910
- },
2911
- onBlur: () => {
2912
- setFocused(false);
2913
- onBlur?.();
2914
- },
2915
- style: [
2916
- styles35.input,
2917
- {
2918
- borderColor,
2919
- color: colors2.colorOnBg,
2920
- backgroundColor: colors2.colorBg
2921
- },
2922
- disabled && { opacity: 0.4 }
2923
- ]
2924
- }
2925
- ),
2926
- /* @__PURE__ */ jsx39(Message, { type: "error", message: error }),
2927
- /* @__PURE__ */ jsx39(Message, { type: "hint", message: hint })
2928
- ] });
2929
- }
2930
-
2931
- // src/components/interaction/form/Textarea/Textarea.native.tsx
2932
- import { useState as useState9 } from "react";
2933
- import {
2934
- StyleSheet as StyleSheet36,
2935
- View as View33,
2936
- TextInput as TextInput3
2937
- } from "react-native";
2938
- import { jsx as jsx40, jsxs as jsxs25 } from "react/jsx-runtime";
2939
- var styles36 = StyleSheet36.create({
2940
- container: {
2941
- gap: spacing.xxs
2942
- },
2943
- textarea: {
2944
- fontFamily: font.family.body,
2945
- fontSize: font.size.body,
2946
- lineHeight: lineHeight.body,
2947
- paddingHorizontal: spacing.s,
2948
- paddingVertical: spacing.xs,
2949
- borderWidth: 1,
2950
- borderRadius: border.radius.xs,
2951
- minHeight: 100,
2952
- textAlignVertical: "top"
2953
- }
2954
- });
2955
- function Textarea({
2956
- label,
2957
- name,
2958
- value,
2959
- defaultValue,
2960
- placeholder,
2961
- error,
2962
- hint,
2963
- disabled = false,
2964
- numberOfLines = 4,
2965
- onChange,
2966
- onBlur,
2967
- onFocus,
2968
- style
2969
- }) {
2970
- const { colors: colors2 } = useTheme();
2971
- const [focused, setFocused] = useState9(false);
2972
- const borderColor = error ? colors2.colorError : focused ? colors2.colorInteractive : colors2.colorOnBg;
2973
- return /* @__PURE__ */ jsxs25(View33, { style: [styles36.container, style], children: [
2974
- /* @__PURE__ */ jsx40(Label, { label }),
2975
- /* @__PURE__ */ jsx40(
2976
- TextInput3,
2977
- {
2978
- accessibilityLabel: typeof label === "string" ? label : name,
2979
- accessibilityState: { disabled },
2980
- accessibilityHint: hint,
2981
- multiline: true,
2982
- numberOfLines,
2983
- value,
2984
- defaultValue,
2985
- placeholder,
2986
- placeholderTextColor: colors2.colorOnBgSubtle,
2987
- editable: !disabled,
2988
- onChangeText: onChange,
2989
- onFocus: () => {
2990
- setFocused(true);
2991
- onFocus?.();
2992
- },
2993
- onBlur: () => {
2994
- setFocused(false);
2995
- onBlur?.();
2996
- },
2997
- style: [
2998
- styles36.textarea,
2999
- {
3000
- borderColor,
3001
- color: colors2.colorOnBg,
3002
- backgroundColor: colors2.colorBg
3003
- },
3004
- disabled && { opacity: 0.4 }
3005
- ]
3006
- }
3007
- ),
3008
- /* @__PURE__ */ jsx40(Message, { type: "error", message: error }),
3009
- /* @__PURE__ */ jsx40(Message, { type: "hint", message: hint })
3010
- ] });
3011
- }
3012
-
3013
- // src/components/interaction/form/Select/Select.native.tsx
3014
- import { useState as useState10 } from "react";
3015
- import {
3016
- StyleSheet as StyleSheet37,
3017
- View as View34,
3018
- Text as Text29,
3019
- Pressable as Pressable20,
3020
- Modal,
3021
- FlatList,
3022
- SafeAreaView
3023
- } from "react-native";
3024
- import { jsx as jsx41, jsxs as jsxs26 } from "react/jsx-runtime";
3025
- var styles37 = StyleSheet37.create({
3026
- container: {
3027
- gap: spacing.xxs
3028
- },
3029
- trigger: {
3030
- flexDirection: "row",
3031
- alignItems: "center",
3032
- justifyContent: "space-between",
3033
- paddingHorizontal: spacing.s,
3034
- paddingVertical: spacing.xs,
3035
- borderWidth: 1,
3036
- borderRadius: border.radius.full,
3037
- minHeight: 44
3038
- },
3039
- triggerText: {
3040
- fontFamily: font.family.body,
3041
- fontSize: font.size.body,
3042
- lineHeight: lineHeight.body,
3043
- flex: 1
3044
- },
3045
- chevron: {
3046
- fontFamily: font.family.body,
3047
- fontSize: font.size.body,
3048
- marginStart: spacing.xs
3049
- },
3050
- overlay: {
3051
- flex: 1,
3052
- justifyContent: "flex-end",
3053
- backgroundColor: "rgba(0, 0, 0, 0.5)"
3054
- },
3055
- sheet: {
3056
- maxHeight: "60%",
3057
- borderTopStartRadius: border.radius.m,
3058
- borderTopEndRadius: border.radius.m,
3059
- paddingTop: spacing.m,
3060
- paddingBottom: spacing.xxxl
3061
- },
3062
- sheetHeader: {
3063
- flexDirection: "row",
3064
- justifyContent: "space-between",
3065
- alignItems: "center",
3066
- paddingHorizontal: spacing.m,
3067
- paddingBottom: spacing.s
3068
- },
3069
- sheetTitle: {
3070
- fontFamily: font.family.body,
3071
- fontSize: font.size.heading3,
3072
- fontWeight: font.weight.semibold
3073
- },
3074
- closeText: {
3075
- fontFamily: font.family.body,
3076
- fontSize: font.size.body,
3077
- fontWeight: font.weight.semibold
3078
- },
3079
- optionItem: {
3080
- paddingHorizontal: spacing.m,
3081
- paddingVertical: spacing.s,
3082
- minHeight: 44,
3083
- justifyContent: "center"
3084
- },
3085
- optionText: {
3086
- fontFamily: font.family.body,
3087
- fontSize: font.size.body,
3088
- lineHeight: lineHeight.body
3089
- }
3090
- });
3091
- function Select({
3092
- label,
3093
- name,
3094
- options,
3095
- placeholder = "Select an option",
3096
- value,
3097
- error,
3098
- hint,
3099
- disabled = false,
3100
- onChange,
3101
- style
3102
- }) {
3103
- const { colors: colors2 } = useTheme();
3104
- const [open, setOpen] = useState10(false);
3105
- const selectedOption = options.find((o) => o.value === value);
3106
- const displayText = selectedOption?.label ?? placeholder;
3107
- const isPlaceholder = !selectedOption;
3108
- const borderColor = error ? colors2.colorError : open ? colors2.colorInteractive : colors2.colorOnBg;
3109
- const handleSelect = (optionValue) => {
3110
- onChange?.(optionValue);
3111
- setOpen(false);
3112
- };
3113
- return /* @__PURE__ */ jsxs26(View34, { style: [styles37.container, style], children: [
3114
- /* @__PURE__ */ jsx41(Label, { label }),
3115
- /* @__PURE__ */ jsxs26(
3116
- Pressable20,
3117
- {
3118
- accessibilityRole: "button",
3119
- accessibilityLabel: typeof label === "string" ? `${label}, ${displayText}` : name,
3120
- accessibilityState: { disabled, expanded: open },
3121
- accessibilityHint: "Double tap to open options",
3122
- disabled,
3123
- onPress: () => setOpen(true),
3124
- style: [
3125
- styles37.trigger,
3126
- {
3127
- borderColor,
3128
- backgroundColor: colors2.colorBg
3129
- },
3130
- disabled && { opacity: 0.4 }
3131
- ],
3132
- children: [
3133
- /* @__PURE__ */ jsx41(
3134
- Text29,
3135
- {
3136
- style: [
3137
- styles37.triggerText,
3138
- {
3139
- color: isPlaceholder ? colors2.colorOnBgSubtle : colors2.colorOnBg
3140
- }
3141
- ],
3142
- children: displayText
3143
- }
3144
- ),
3145
- /* @__PURE__ */ jsx41(Text29, { style: [styles37.chevron, { color: colors2.colorOnBgSubtle }], "aria-hidden": true, children: "\u25BE" })
3146
- ]
3147
- }
3148
- ),
3149
- /* @__PURE__ */ jsx41(
3150
- Modal,
3151
- {
3152
- visible: open,
3153
- transparent: true,
3154
- animationType: "slide",
3155
- onRequestClose: () => setOpen(false),
3156
- children: /* @__PURE__ */ jsx41(
3157
- Pressable20,
3158
- {
3159
- style: styles37.overlay,
3160
- onPress: () => setOpen(false),
3161
- accessibilityRole: "button",
3162
- accessibilityLabel: "Close options",
3163
- children: /* @__PURE__ */ jsx41(
3164
- Pressable20,
3165
- {
3166
- style: [styles37.sheet, { backgroundColor: colors2.colorBg }],
3167
- onPress: () => {
3168
- },
3169
- children: /* @__PURE__ */ jsxs26(SafeAreaView, { children: [
3170
- /* @__PURE__ */ jsxs26(View34, { style: styles37.sheetHeader, children: [
3171
- /* @__PURE__ */ jsx41(Text29, { style: [styles37.sheetTitle, { color: colors2.colorOnBg }], children: typeof label === "string" ? label : "Select" }),
3172
- /* @__PURE__ */ jsx41(
3173
- Pressable20,
3174
- {
3175
- accessibilityRole: "button",
3176
- accessibilityLabel: "Close",
3177
- onPress: () => setOpen(false),
3178
- hitSlop: 8,
3179
- children: /* @__PURE__ */ jsx41(Text29, { style: [styles37.closeText, { color: colors2.colorInteractive }], children: "Done" })
3180
- }
3181
- )
3182
- ] }),
3183
- /* @__PURE__ */ jsx41(
3184
- FlatList,
3185
- {
3186
- data: options,
3187
- keyExtractor: (item) => item.value,
3188
- renderItem: ({ item }) => {
3189
- const isSelected = item.value === value;
3190
- return /* @__PURE__ */ jsx41(
3191
- Pressable20,
3192
- {
3193
- accessibilityRole: "button",
3194
- accessibilityLabel: item.label,
3195
- accessibilityState: {
3196
- selected: isSelected,
3197
- disabled: item.disabled
3198
- },
3199
- disabled: item.disabled,
3200
- onPress: () => handleSelect(item.value),
3201
- style: ({ pressed }) => [
3202
- styles37.optionItem,
3203
- isSelected && { backgroundColor: colors2.colorBgSubtle },
3204
- pressed && { opacity: 0.7 },
3205
- item.disabled && { opacity: 0.4 }
3206
- ],
3207
- children: /* @__PURE__ */ jsx41(
3208
- Text29,
3209
- {
3210
- style: [
3211
- styles37.optionText,
3212
- {
3213
- color: isSelected ? colors2.colorInteractive : colors2.colorOnBg,
3214
- fontWeight: isSelected ? font.weight.semibold : font.weight.body
3215
- }
3216
- ],
3217
- children: item.label
3218
- }
3219
- )
3220
- }
3221
- );
3222
- }
3223
- }
3224
- )
3225
- ] })
3226
- }
3227
- )
3228
- }
3229
- )
3230
- }
3231
- ),
3232
- /* @__PURE__ */ jsx41(Message, { type: "error", message: error }),
3233
- /* @__PURE__ */ jsx41(Message, { type: "hint", message: hint })
3234
- ] });
3235
- }
3236
-
3237
- // src/components/interaction/form/Slider/Slider.native.tsx
3238
- import { useState as useState11 } from "react";
3239
- import {
3240
- StyleSheet as StyleSheet38,
3241
- View as View35,
3242
- Text as Text30
3243
- } from "react-native";
3244
- import { jsx as jsx42, jsxs as jsxs27 } from "react/jsx-runtime";
3245
- var TRACK_HEIGHT = 6;
3246
- var THUMB_SIZE = 24;
3247
- var styles38 = StyleSheet38.create({
3248
- container: {
3249
- gap: spacing.xxs
3250
- },
3251
- labelRow: {
3252
- flexDirection: "row",
3253
- justifyContent: "space-between",
3254
- alignItems: "center"
3255
- },
3256
- valueText: {
3257
- fontFamily: font.family.body,
3258
- fontSize: font.size.bodyS,
3259
- lineHeight: lineHeight.bodyS,
3260
- fontWeight: font.weight.semibold
3261
- },
3262
- trackContainer: {
3263
- height: THUMB_SIZE + spacing.xs * 2,
3264
- justifyContent: "center",
3265
- paddingHorizontal: THUMB_SIZE / 2
3266
- },
3267
- track: {
3268
- height: TRACK_HEIGHT,
3269
- borderRadius: TRACK_HEIGHT / 2,
3270
- overflow: "hidden"
3271
- },
3272
- fill: {
3273
- height: TRACK_HEIGHT,
3274
- borderRadius: TRACK_HEIGHT / 2
3275
- },
3276
- thumb: {
3277
- position: "absolute",
3278
- width: THUMB_SIZE,
3279
- height: THUMB_SIZE,
3280
- borderRadius: THUMB_SIZE / 2,
3281
- top: "50%",
3282
- marginTop: -(THUMB_SIZE / 2),
3283
- borderWidth: 2
3284
- }
3285
- });
3286
- function clampValue(v, min, max) {
3287
- return Math.min(max, Math.max(min, v));
3288
- }
3289
- function snapToStep(v, min, step) {
3290
- return Math.round((v - min) / step) * step + min;
3291
- }
3292
- function Slider({
3293
- label,
3294
- name: _name,
3295
- // eslint-disable-line @typescript-eslint/no-unused-vars
3296
- value,
3297
- defaultValue,
3298
- min = 0,
3299
- max = 100,
3300
- step = 1,
3301
- showValue = false,
3302
- disabled = false,
3303
- error,
3304
- hint,
3305
- onChange,
3306
- style
3307
- }) {
3308
- const { colors: colors2 } = useTheme();
3309
- const isControlled = value !== void 0;
3310
- const [internalValue, setInternalValue] = useState11(defaultValue ?? min);
3311
- const [trackWidth, setTrackWidth] = useState11(0);
3312
- const currentValue = isControlled ? value : internalValue;
3313
- const fillPct = max > min ? (currentValue - min) / (max - min) * 100 : 0;
3314
- const updateValue = (v) => {
3315
- const clamped = clampValue(v, min, max);
3316
- const snapped = snapToStep(clamped, min, step);
3317
- if (!isControlled) setInternalValue(snapped);
3318
- onChange?.(snapped);
3319
- };
3320
- const handleTrackLayout = (e) => {
3321
- setTrackWidth(e.nativeEvent.layout.width);
3322
- };
3323
- const valueFromTouch = (pageX, layoutX) => {
3324
- const x = pageX - layoutX;
3325
- const pct = clampValue(x / trackWidth, 0, 1);
3326
- return pct * (max - min) + min;
3327
- };
3328
- const handleStartShouldSetResponder = () => !disabled;
3329
- const handleResponderGrant = (e) => {
3330
- const target = e.currentTarget;
3331
- target.measure((_x, _y, _w, _h, pageX) => {
3332
- updateValue(valueFromTouch(e.nativeEvent.pageX, pageX));
3333
- });
3334
- };
3335
- const handleResponderMove = (e) => {
3336
- const target = e.currentTarget;
3337
- target.measure((_x, _y, _w, _h, pageX) => {
3338
- updateValue(valueFromTouch(e.nativeEvent.pageX, pageX));
3339
- });
3340
- };
3341
- return /* @__PURE__ */ jsxs27(
3342
- View35,
3343
- {
3344
- style: [styles38.container, style],
3345
- accessibilityRole: "adjustable",
3346
- accessibilityLabel: label,
3347
- accessibilityValue: { min, max, now: currentValue, text: String(currentValue) },
3348
- accessibilityState: { disabled },
3349
- children: [
3350
- /* @__PURE__ */ jsxs27(View35, { style: styles38.labelRow, children: [
3351
- /* @__PURE__ */ jsx42(Label, { label }),
3352
- showValue && /* @__PURE__ */ jsx42(Text30, { style: [styles38.valueText, { color: colors2.colorOnBg }], children: currentValue })
3353
- ] }),
3354
- /* @__PURE__ */ jsxs27(
3355
- View35,
3356
- {
3357
- style: [styles38.trackContainer, disabled && { opacity: 0.4 }],
3358
- onLayout: handleTrackLayout,
3359
- onStartShouldSetResponder: handleStartShouldSetResponder,
3360
- onMoveShouldSetResponder: handleStartShouldSetResponder,
3361
- onResponderGrant: handleResponderGrant,
3362
- onResponderMove: handleResponderMove,
3363
- children: [
3364
- /* @__PURE__ */ jsx42(View35, { style: [styles38.track, { backgroundColor: colors2.colorBgSubtle }], children: /* @__PURE__ */ jsx42(
3365
- View35,
3366
- {
3367
- style: [
3368
- styles38.fill,
3369
- {
3370
- width: `${fillPct}%`,
3371
- backgroundColor: error ? colors2.colorError : colors2.colorInteractive
3372
- }
3373
- ]
3374
- }
3375
- ) }),
3376
- /* @__PURE__ */ jsx42(
3377
- View35,
3378
- {
3379
- style: [
3380
- styles38.thumb,
3381
- {
3382
- start: `${fillPct}%`,
3383
- marginStart: -(THUMB_SIZE / 2),
3384
- backgroundColor: colors2.colorBg,
3385
- borderColor: error ? colors2.colorError : colors2.colorInteractive
3386
- }
3387
- ]
3388
- }
3389
- )
3390
- ]
3391
- }
3392
- ),
3393
- /* @__PURE__ */ jsx42(Message, { type: "error", message: error }),
3394
- /* @__PURE__ */ jsx42(Message, { type: "hint", message: hint })
3395
- ]
3396
- }
3397
- );
3398
- }
3399
-
3400
- // src/components/interaction/form/NumberInput/NumberInput.native.tsx
3401
- import { useState as useState12 } from "react";
3402
- import {
3403
- StyleSheet as StyleSheet39,
3404
- View as View36,
3405
- TextInput as TextInput4,
3406
- Text as Text31,
3407
- Pressable as Pressable21
3408
- } from "react-native";
3409
- import { jsx as jsx43, jsxs as jsxs28 } from "react/jsx-runtime";
3410
- var STEPPER_SIZE = 44;
3411
- var styles39 = StyleSheet39.create({
3412
- container: {
3413
- gap: spacing.xxs
3414
- },
3415
- inputRow: {
3416
- flexDirection: "row",
3417
- alignItems: "center"
3418
- },
3419
- stepper: {
3420
- width: STEPPER_SIZE,
3421
- height: STEPPER_SIZE,
3422
- alignItems: "center",
3423
- justifyContent: "center",
3424
- borderWidth: 1
3425
- },
3426
- stepperStart: {
3427
- borderTopStartRadius: border.radius.full,
3428
- borderBottomStartRadius: border.radius.full,
3429
- borderEndWidth: 0
3430
- },
3431
- stepperEnd: {
3432
- borderTopEndRadius: border.radius.full,
3433
- borderBottomEndRadius: border.radius.full,
3434
- borderStartWidth: 0
3435
- },
3436
- stepperText: {
3437
- fontSize: 20,
3438
- fontWeight: font.weight.semibold,
3439
- lineHeight: 24
3440
- },
3441
- input: {
3442
- flex: 1,
3443
- fontFamily: font.family.body,
3444
- fontSize: font.size.body,
3445
- lineHeight: lineHeight.body,
3446
- textAlign: "center",
3447
- paddingHorizontal: spacing.xs,
3448
- paddingVertical: spacing.xs,
3449
- borderTopWidth: 1,
3450
- borderBottomWidth: 1,
3451
- minHeight: STEPPER_SIZE
3452
- }
3453
- });
3454
- function NumberInput({
3455
- label,
3456
- name: _name,
3457
- // eslint-disable-line @typescript-eslint/no-unused-vars
3458
- value,
3459
- defaultValue,
3460
- min,
3461
- max,
3462
- step = 1,
3463
- disabled = false,
3464
- error,
3465
- hint,
3466
- onChange,
3467
- style
3468
- }) {
3469
- const { colors: colors2 } = useTheme();
3470
- const isControlled = value !== void 0;
3471
- const [internalValue, setInternalValue] = useState12(defaultValue ?? 0);
3472
- const currentValue = isControlled ? value : internalValue;
3473
- const clamp = (v) => {
3474
- const withMin = min !== void 0 ? Math.max(min, v) : v;
3475
- return max !== void 0 ? Math.min(max, withMin) : withMin;
3476
- };
3477
- const update = (next) => {
3478
- const clamped = clamp(next);
3479
- if (!isControlled) setInternalValue(clamped);
3480
- onChange?.(clamped);
3481
- };
3482
- const canDecrease = min === void 0 || currentValue > min;
3483
- const canIncrease = max === void 0 || currentValue < max;
3484
- const borderColor = error ? colors2.colorError : colors2.colorOnBg;
3485
- return /* @__PURE__ */ jsxs28(View36, { style: [styles39.container, style], children: [
3486
- /* @__PURE__ */ jsx43(Label, { label }),
3487
- /* @__PURE__ */ jsxs28(View36, { style: [styles39.inputRow, disabled && { opacity: 0.4 }], children: [
3488
- /* @__PURE__ */ jsx43(
3489
- Pressable21,
3490
- {
3491
- accessibilityRole: "button",
3492
- accessibilityLabel: "Decrease",
3493
- accessibilityState: { disabled: disabled || !canDecrease },
3494
- disabled: disabled || !canDecrease,
3495
- onPress: () => update(currentValue - step),
3496
- style: ({ pressed }) => [
3497
- styles39.stepper,
3498
- styles39.stepperStart,
3499
- {
3500
- borderColor,
3501
- backgroundColor: colors2.colorBgSubtle
3502
- },
3503
- pressed && { opacity: 0.7 },
3504
- (disabled || !canDecrease) && { opacity: 0.4 }
3505
- ],
3506
- children: /* @__PURE__ */ jsx43(
3507
- Text31,
3508
- {
3509
- style: [styles39.stepperText, { color: colors2.colorOnBg }],
3510
- "aria-hidden": true,
3511
- children: "\u2212"
3512
- }
3513
- )
3514
- }
3515
- ),
3516
- /* @__PURE__ */ jsx43(
3517
- TextInput4,
3518
- {
3519
- accessibilityLabel: label,
3520
- accessibilityState: { disabled },
3521
- accessibilityValue: {
3522
- min,
3523
- max,
3524
- now: currentValue,
3525
- text: String(currentValue)
3526
- },
3527
- keyboardType: "numeric",
3528
- value: String(currentValue),
3529
- editable: !disabled,
3530
- onChangeText: (text) => {
3531
- const parsed = parseFloat(text);
3532
- const safe = isNaN(parsed) ? 0 : parsed;
3533
- update(safe);
3534
- },
3535
- style: [
3536
- styles39.input,
3537
- {
3538
- borderColor,
3539
- color: colors2.colorOnBg,
3540
- backgroundColor: colors2.colorBg
3541
- }
3542
- ]
3543
- }
3544
- ),
3545
- /* @__PURE__ */ jsx43(
3546
- Pressable21,
3547
- {
3548
- accessibilityRole: "button",
3549
- accessibilityLabel: "Increase",
3550
- accessibilityState: { disabled: disabled || !canIncrease },
3551
- disabled: disabled || !canIncrease,
3552
- onPress: () => update(currentValue + step),
3553
- style: ({ pressed }) => [
3554
- styles39.stepper,
3555
- styles39.stepperEnd,
3556
- {
3557
- borderColor,
3558
- backgroundColor: colors2.colorBgSubtle
3559
- },
3560
- pressed && { opacity: 0.7 },
3561
- (disabled || !canIncrease) && { opacity: 0.4 }
3562
- ],
3563
- children: /* @__PURE__ */ jsx43(
3564
- Text31,
3565
- {
3566
- style: [styles39.stepperText, { color: colors2.colorOnBg }],
3567
- "aria-hidden": true,
3568
- children: "+"
3569
- }
3570
- )
3571
- }
3572
- )
3573
- ] }),
3574
- /* @__PURE__ */ jsx43(Message, { type: "error", message: error }),
3575
- /* @__PURE__ */ jsx43(Message, { type: "hint", message: hint })
3576
- ] });
3577
- }
3578
-
3579
- // src/components/interaction/Dialog/Dialog.native.tsx
3580
- import {
3581
- Modal as Modal2,
3582
- View as View37,
3583
- Pressable as Pressable22,
3584
- Text as Text32,
3585
- StyleSheet as StyleSheet40
3586
- } from "react-native";
3587
- import { jsx as jsx44, jsxs as jsxs29 } from "react/jsx-runtime";
3588
- var styles40 = StyleSheet40.create({
3589
- overlay: {
3590
- flex: 1,
3591
- justifyContent: "center",
3592
- alignItems: "center",
3593
- backgroundColor: "rgba(0, 0, 0, 0.5)",
3594
- padding: spacing.m
3595
- },
3596
- panel: {
3597
- width: "100%",
3598
- maxWidth: 480,
3599
- borderRadius: border.radius.m,
3600
- padding: spacing.l,
3601
- paddingTop: spacing.xl,
3602
- shadowColor: "#000",
3603
- shadowOffset: { width: 0, height: 4 },
3604
- shadowOpacity: 0.15,
3605
- shadowRadius: 12,
3606
- elevation: 8
3607
- },
3608
- header: {
3609
- flexDirection: "row",
3610
- justifyContent: "space-between",
3611
- alignItems: "center",
3612
- marginBottom: spacing.m
3613
- },
3614
- title: {
3615
- fontFamily: font.family.body,
3616
- fontSize: font.size.heading3,
3617
- fontWeight: font.weight.semibold,
3618
- flex: 1
3619
- },
3620
- closeButton: {
3621
- position: "absolute",
3622
- top: spacing.s,
3623
- end: spacing.s,
3624
- width: 44,
3625
- height: 44,
3626
- alignItems: "center",
3627
- justifyContent: "center",
3628
- zIndex: 1
3629
- },
3630
- closeText: {
3631
- fontFamily: font.family.body,
3632
- fontSize: 20,
3633
- lineHeight: 24
3634
- }
3635
- });
3636
- function Dialog({
3637
- isOpen = false,
3638
- onClose,
3639
- title,
3640
- children,
3641
- style
3642
- }) {
3643
- const { colors: colors2 } = useTheme();
3644
- return /* @__PURE__ */ jsx44(
3645
- Modal2,
3646
- {
3647
- visible: isOpen,
3648
- transparent: true,
3649
- animationType: "fade",
3650
- onRequestClose: onClose,
3651
- children: /* @__PURE__ */ jsx44(
3652
- Pressable22,
3653
- {
3654
- style: styles40.overlay,
3655
- onPress: onClose,
3656
- accessibilityRole: "button",
3657
- accessibilityLabel: "Close dialog",
3658
- children: /* @__PURE__ */ jsxs29(
3659
- Pressable22,
3660
- {
3661
- style: [styles40.panel, { backgroundColor: colors2.colorGreySubtle }, style],
3662
- onPress: () => {
3663
- },
3664
- accessibilityRole: "none",
3665
- children: [
3666
- /* @__PURE__ */ jsx44(
3667
- Pressable22,
3668
- {
3669
- style: styles40.closeButton,
3670
- onPress: onClose,
3671
- accessibilityRole: "button",
3672
- accessibilityLabel: "Close dialog",
3673
- hitSlop: 8,
3674
- children: /* @__PURE__ */ jsx44(
3675
- Text32,
3676
- {
3677
- style: [styles40.closeText, { color: colors2.colorOnBgSubtle }],
3678
- "aria-hidden": true,
3679
- children: "\u2715"
3680
- }
3681
- )
3682
- }
3683
- ),
3684
- !!title && /* @__PURE__ */ jsx44(View37, { style: styles40.header, children: /* @__PURE__ */ jsx44(Text32, { style: [styles40.title, { color: colors2.colorOnGreySubtle }], children: title }) }),
3685
- children
3686
- ]
3687
- }
3688
- )
3689
- }
3690
- )
3691
- }
3692
- );
3693
- }
3694
-
3695
- // src/components/interaction/Drawer/Drawer.native.tsx
3696
- import { useEffect as useEffect2, useRef as useRef4 } from "react";
3697
- import {
3698
- Modal as Modal3,
3699
- View as View38,
3700
- Pressable as Pressable23,
3701
- Text as Text33,
3702
- Animated as Animated3,
3703
- StyleSheet as StyleSheet41,
3704
- Dimensions as Dimensions2
3705
- } from "react-native";
3706
- import { jsx as jsx45, jsxs as jsxs30 } from "react/jsx-runtime";
3707
- var styles41 = StyleSheet41.create({
3708
- overlay: {
3709
- flex: 1,
3710
- justifyContent: "flex-end"
3711
- },
3712
- panel: {
3713
- maxHeight: "90%",
3714
- borderTopStartRadius: border.radius.m,
3715
- borderTopEndRadius: border.radius.m,
3716
- paddingTop: spacing.m,
3717
- paddingHorizontal: spacing.m,
3718
- paddingBottom: spacing.m,
3719
- shadowColor: "#000",
3720
- shadowOffset: { width: 0, height: -4 },
3721
- shadowOpacity: 0.15,
3722
- shadowRadius: 16,
3723
- elevation: 16
3724
- },
3725
- header: {
3726
- flexDirection: "row",
3727
- justifyContent: "space-between",
3728
- alignItems: "center",
3729
- paddingBottom: spacing.m,
3730
- borderBottomWidth: 1,
3731
- marginBottom: spacing.m
3732
- },
3733
- title: {
3734
- fontFamily: font.family.body,
3735
- fontSize: font.size.heading3,
3736
- fontWeight: font.weight.semibold,
3737
- flex: 1
3738
- },
3739
- closeButton: {
3740
- width: 44,
3741
- height: 44,
3742
- alignItems: "center",
3743
- justifyContent: "center"
3744
- },
3745
- closeText: {
3746
- fontFamily: font.family.body,
3747
- fontSize: 20,
3748
- lineHeight: 24
3749
- },
3750
- body: {
3751
- flex: 1
3752
- }
3753
- });
3754
- function Drawer({
3755
- isOpen,
3756
- onClose,
3757
- title,
3758
- children,
3759
- style
3760
- }) {
3761
- const { colors: colors2 } = useTheme();
3762
- const screenHeight = Dimensions2.get("window").height;
3763
- const slideAnim = useRef4(new Animated3.Value(screenHeight)).current;
3764
- const backdropAnim = useRef4(new Animated3.Value(0)).current;
3765
- useEffect2(() => {
3766
- if (isOpen) {
3767
- Animated3.parallel([
3768
- Animated3.timing(slideAnim, {
3769
- toValue: 0,
3770
- duration: 250,
3771
- useNativeDriver: true
3772
- }),
3773
- Animated3.timing(backdropAnim, {
3774
- toValue: 1,
3775
- duration: 250,
3776
- useNativeDriver: true
3777
- })
3778
- ]).start();
3779
- } else {
3780
- Animated3.parallel([
3781
- Animated3.timing(slideAnim, {
3782
- toValue: screenHeight,
3783
- duration: 200,
3784
- useNativeDriver: true
3785
- }),
3786
- Animated3.timing(backdropAnim, {
3787
- toValue: 0,
3788
- duration: 200,
3789
- useNativeDriver: true
3790
- })
3791
- ]).start();
3792
- }
3793
- }, [isOpen, slideAnim, backdropAnim, screenHeight]);
3794
- return /* @__PURE__ */ jsx45(
3795
- Modal3,
3796
- {
3797
- visible: isOpen,
3798
- transparent: true,
3799
- animationType: "none",
3800
- onRequestClose: onClose,
3801
- children: /* @__PURE__ */ jsxs30(View38, { style: styles41.overlay, children: [
3802
- /* @__PURE__ */ jsx45(
3803
- Animated3.View,
3804
- {
3805
- style: [
3806
- StyleSheet41.absoluteFill,
3807
- { backgroundColor: "rgba(0, 0, 0, 0.5)", opacity: backdropAnim }
3808
- ],
3809
- children: /* @__PURE__ */ jsx45(
3810
- Pressable23,
3811
- {
3812
- style: StyleSheet41.absoluteFill,
3813
- onPress: onClose,
3814
- accessibilityRole: "button",
3815
- accessibilityLabel: "Close drawer"
3816
- }
3817
- )
3818
- }
3819
- ),
3820
- /* @__PURE__ */ jsxs30(
3821
- Animated3.View,
3822
- {
3823
- style: [
3824
- styles41.panel,
3825
- {
3826
- backgroundColor: colors2.colorBg,
3827
- transform: [{ translateY: slideAnim }]
3828
- },
3829
- style
3830
- ],
3831
- accessibilityRole: "none",
3832
- children: [
3833
- /* @__PURE__ */ jsxs30(
3834
- View38,
3835
- {
3836
- style: [styles41.header, { borderBottomColor: colors2.colorBgSubtle }],
3837
- children: [
3838
- !!title && /* @__PURE__ */ jsx45(Text33, { style: [styles41.title, { color: colors2.colorOnBg }], children: title }),
3839
- /* @__PURE__ */ jsx45(
3840
- Pressable23,
3841
- {
3842
- style: styles41.closeButton,
3843
- onPress: onClose,
3844
- accessibilityRole: "button",
3845
- accessibilityLabel: "Close drawer",
3846
- hitSlop: 8,
3847
- children: /* @__PURE__ */ jsx45(
3848
- Text33,
3849
- {
3850
- style: [styles41.closeText, { color: colors2.colorOnBgSubtle }],
3851
- "aria-hidden": true,
3852
- children: "\u2715"
3853
- }
3854
- )
3855
- }
3856
- )
3857
- ]
3858
- }
3859
- ),
3860
- /* @__PURE__ */ jsx45(View38, { style: styles41.body, children })
3861
- ]
3862
- }
3863
- )
3864
- ] })
3865
- }
3866
- );
3867
- }
3868
-
3869
- // src/components/interaction/Toast/Toast.native.tsx
3870
- import {
3871
- useState as useState13,
3872
- useEffect as useEffect3,
3873
- useRef as useRef5,
3874
- useCallback as useCallback3,
3875
- useMemo as useMemo3,
3876
- createContext as createContext2,
3877
- useContext as useContext2
3878
- } from "react";
3879
- import {
3880
- View as View39,
3881
- Text as Text34,
3882
- Pressable as Pressable24,
3883
- Animated as Animated4,
3884
- StyleSheet as StyleSheet42
3885
- } from "react-native";
3886
- import { jsx as jsx46, jsxs as jsxs31 } from "react/jsx-runtime";
3887
- var ToastContext = createContext2(void 0);
3888
- var styles42 = StyleSheet42.create({
3889
- container: {
3890
- position: "absolute",
3891
- top: 0,
3892
- start: 0,
3893
- end: 0,
3894
- paddingTop: spacing.xxxl,
3895
- paddingHorizontal: spacing.m,
3896
- zIndex: 9999,
3897
- pointerEvents: "box-none"
3898
- },
3899
- toast: {
3900
- flexDirection: "row",
3901
- alignItems: "center",
3902
- justifyContent: "space-between",
3903
- paddingVertical: spacing.s,
3904
- paddingHorizontal: spacing.m,
3905
- borderRadius: border.radius.s,
3906
- marginBottom: spacing.xs,
3907
- minHeight: 48
3908
- },
3909
- message: {
3910
- fontFamily: font.family.body,
3911
- fontSize: font.size.body,
3912
- fontWeight: font.weight.semibold,
3913
- flex: 1
3914
- },
3915
- closeButton: {
3916
- width: 44,
3917
- height: 44,
3918
- alignItems: "center",
3919
- justifyContent: "center",
3920
- marginStart: spacing.xs
3921
- },
3922
- closeText: {
3923
- fontFamily: font.family.body,
3924
- fontSize: 16,
3925
- lineHeight: 20
3926
- }
3927
- });
3928
- function ToastItem({
3929
- toast,
3930
- onRemove
3931
- }) {
3932
- const { colors: colors2 } = useTheme();
3933
- const slideAnim = useRef5(new Animated4.Value(-100)).current;
3934
- const opacityAnim = useRef5(new Animated4.Value(0)).current;
3935
- const variantColors = useMemo3(
3936
- () => ({
3937
- success: { bg: colors2.colorSuccess, text: colors2.colorOnSuccess },
3938
- error: { bg: colors2.colorError, text: colors2.colorOnError },
3939
- info: { bg: colors2.colorBgSubtle, text: colors2.colorOnBgSubtle }
3940
- }),
3941
- [colors2]
3942
- );
3943
- useEffect3(() => {
3944
- Animated4.parallel([
3945
- Animated4.timing(slideAnim, {
3946
- toValue: 0,
3947
- duration: 200,
3948
- useNativeDriver: true
3949
- }),
3950
- Animated4.timing(opacityAnim, {
3951
- toValue: 1,
3952
- duration: 200,
3953
- useNativeDriver: true
3954
- })
3955
- ]).start();
3956
- }, [slideAnim, opacityAnim]);
3957
- useEffect3(() => {
3958
- const timer = setTimeout(onRemove, 5e3);
3959
- return () => clearTimeout(timer);
3960
- }, [onRemove]);
3961
- const { bg, text } = variantColors[toast.variant];
3962
- return /* @__PURE__ */ jsxs31(
3963
- Animated4.View,
3964
- {
3965
- style: [
3966
- styles42.toast,
3967
- {
3968
- backgroundColor: bg,
3969
- transform: [{ translateY: slideAnim }],
3970
- opacity: opacityAnim
3971
- }
3972
- ],
3973
- accessibilityRole: "alert",
3974
- accessibilityLiveRegion: "polite",
3975
- children: [
3976
- /* @__PURE__ */ jsx46(Text34, { style: [styles42.message, { color: text }], children: toast.message }),
3977
- /* @__PURE__ */ jsx46(
3978
- Pressable24,
3979
- {
3980
- style: styles42.closeButton,
3981
- onPress: onRemove,
3982
- accessibilityRole: "button",
3983
- accessibilityLabel: "Dismiss",
3984
- hitSlop: 8,
3985
- children: /* @__PURE__ */ jsx46(Text34, { style: [styles42.closeText, { color: text }], "aria-hidden": true, children: "\u2715" })
3986
- }
3987
- )
3988
- ]
3989
- }
3990
- );
3991
- }
3992
- function ToastProvider({
3993
- children,
3994
- style
3995
- }) {
3996
- const [toasts, setToasts] = useState13([]);
3997
- const showToast = useCallback3((message, variant) => {
3998
- const id = Math.random().toString(36).substring(2, 9);
3999
- setToasts((prev) => [...prev, { id, message, variant }]);
4000
- }, []);
4001
- const removeToast = useCallback3((id) => {
4002
- setToasts((prev) => prev.filter((t) => t.id !== id));
4003
- }, []);
4004
- const value = useMemo3(() => ({ showToast }), [showToast]);
4005
- return /* @__PURE__ */ jsx46(ToastContext.Provider, { value, children: /* @__PURE__ */ jsxs31(View39, { style: [{ flex: 1 }, style], children: [
4006
- children,
4007
- toasts.length > 0 && /* @__PURE__ */ jsx46(
4008
- View39,
4009
- {
4010
- style: styles42.container,
4011
- accessibilityRole: "summary",
4012
- accessibilityLabel: "Notifications",
4013
- children: toasts.map((toast) => /* @__PURE__ */ jsx46(
4014
- ToastItem,
4015
- {
4016
- toast,
4017
- onRemove: () => removeToast(toast.id)
4018
- },
4019
- toast.id
4020
- ))
4021
- }
4022
- )
4023
- ] }) });
4024
- }
4025
- function useToast() {
4026
- const context = useContext2(ToastContext);
4027
- if (!context) {
4028
- throw new Error("useToast must be used within a ToastProvider");
4029
- }
4030
- return context;
4031
- }
4032
-
4033
- // src/components/interaction/DropdownMenu/DropdownMenu.native.tsx
4034
- import React, { useState as useState14, useEffect as useEffect4, useRef as useRef6 } from "react";
4035
- import {
4036
- Modal as Modal4,
4037
- View as View40,
4038
- Pressable as Pressable25,
4039
- Text as Text35,
4040
- FlatList as FlatList2,
4041
- Animated as Animated5,
4042
- StyleSheet as StyleSheet43,
4043
- Dimensions as Dimensions3,
4044
- SafeAreaView as SafeAreaView2
4045
- } from "react-native";
4046
- import { Fragment as Fragment2, jsx as jsx47, jsxs as jsxs32 } from "react/jsx-runtime";
4047
- var styles43 = StyleSheet43.create({
4048
- overlay: {
4049
- flex: 1,
4050
- justifyContent: "flex-end"
4051
- },
4052
- sheet: {
4053
- maxHeight: "60%",
4054
- borderTopStartRadius: border.radius.m,
4055
- borderTopEndRadius: border.radius.m,
4056
- paddingTop: spacing.m,
4057
- paddingBottom: spacing.xxxl
4058
- },
4059
- sheetHeader: {
4060
- flexDirection: "row",
4061
- justifyContent: "space-between",
4062
- alignItems: "center",
4063
- paddingHorizontal: spacing.m,
4064
- paddingBottom: spacing.s,
4065
- borderBottomWidth: 1,
4066
- marginBottom: spacing.xxs
4067
- },
4068
- sheetTitle: {
4069
- fontFamily: font.family.body,
4070
- fontSize: font.size.heading3,
4071
- fontWeight: font.weight.semibold
4072
- },
4073
- closeText: {
4074
- fontFamily: font.family.body,
4075
- fontSize: font.size.body,
4076
- fontWeight: font.weight.semibold
4077
- },
4078
- separator: {
4079
- height: 1,
4080
- marginHorizontal: spacing.m,
4081
- marginVertical: spacing.xxs
4082
- },
4083
- item: {
4084
- flexDirection: "row",
4085
- alignItems: "center",
4086
- paddingHorizontal: spacing.m,
4087
- paddingVertical: spacing.s,
4088
- minHeight: 48,
4089
- gap: spacing.s
4090
- },
4091
- itemText: {
4092
- fontFamily: font.family.body,
4093
- fontSize: font.size.body,
4094
- lineHeight: lineHeight.body
4095
- }
4096
- });
4097
- function DropdownMenu({
4098
- trigger,
4099
- items,
4100
- title = "Menu",
4101
- style
4102
- }) {
4103
- const { colors: colors2 } = useTheme();
4104
- const [open, setOpen] = useState14(false);
4105
- const screenHeight = Dimensions3.get("window").height;
4106
- const slideAnim = useRef6(new Animated5.Value(screenHeight)).current;
4107
- const backdropAnim = useRef6(new Animated5.Value(0)).current;
4108
- useEffect4(() => {
4109
- if (open) {
4110
- Animated5.parallel([
4111
- Animated5.timing(slideAnim, {
4112
- toValue: 0,
4113
- duration: 250,
4114
- useNativeDriver: true
4115
- }),
4116
- Animated5.timing(backdropAnim, {
4117
- toValue: 1,
4118
- duration: 250,
4119
- useNativeDriver: true
4120
- })
4121
- ]).start();
4122
- } else {
4123
- Animated5.parallel([
4124
- Animated5.timing(slideAnim, {
4125
- toValue: screenHeight,
4126
- duration: 200,
4127
- useNativeDriver: true
4128
- }),
4129
- Animated5.timing(backdropAnim, {
4130
- toValue: 0,
4131
- duration: 200,
4132
- useNativeDriver: true
4133
- })
4134
- ]).start();
4135
- }
4136
- }, [open, slideAnim, backdropAnim, screenHeight]);
4137
- const handleItemPress = (item) => {
4138
- item.onPress?.();
4139
- setOpen(false);
4140
- };
4141
- return /* @__PURE__ */ jsxs32(View40, { style, children: [
4142
- React.cloneElement(trigger, {
4143
- onPress: () => setOpen(true),
4144
- accessibilityRole: "button",
4145
- accessibilityLabel: title
4146
- }),
4147
- /* @__PURE__ */ jsx47(
4148
- Modal4,
4149
- {
4150
- visible: open,
4151
- transparent: true,
4152
- animationType: "none",
4153
- onRequestClose: () => setOpen(false),
4154
- children: /* @__PURE__ */ jsxs32(View40, { style: styles43.overlay, children: [
4155
- /* @__PURE__ */ jsx47(
4156
- Animated5.View,
4157
- {
4158
- style: [
4159
- StyleSheet43.absoluteFill,
4160
- { backgroundColor: "rgba(0, 0, 0, 0.5)", opacity: backdropAnim }
4161
- ],
4162
- children: /* @__PURE__ */ jsx47(
4163
- Pressable25,
4164
- {
4165
- style: StyleSheet43.absoluteFill,
4166
- onPress: () => setOpen(false),
4167
- accessibilityRole: "button",
4168
- accessibilityLabel: "Close menu"
4169
- }
4170
- )
4171
- }
4172
- ),
4173
- /* @__PURE__ */ jsx47(
4174
- Animated5.View,
4175
- {
4176
- style: [
4177
- styles43.sheet,
4178
- {
4179
- backgroundColor: colors2.colorBg,
4180
- transform: [{ translateY: slideAnim }]
4181
- }
4182
- ],
4183
- children: /* @__PURE__ */ jsx47(
4184
- Pressable25,
4185
- {
4186
- onPress: () => {
4187
- },
4188
- children: /* @__PURE__ */ jsxs32(SafeAreaView2, { children: [
4189
- /* @__PURE__ */ jsxs32(
4190
- View40,
4191
- {
4192
- style: [
4193
- styles43.sheetHeader,
4194
- { borderBottomColor: colors2.colorBgSubtle }
4195
- ],
4196
- children: [
4197
- /* @__PURE__ */ jsx47(Text35, { style: [styles43.sheetTitle, { color: colors2.colorOnBg }], children: title }),
4198
- /* @__PURE__ */ jsx47(
4199
- Pressable25,
4200
- {
4201
- accessibilityRole: "button",
4202
- accessibilityLabel: "Close",
4203
- onPress: () => setOpen(false),
4204
- hitSlop: 8,
4205
- children: /* @__PURE__ */ jsx47(
4206
- Text35,
4207
- {
4208
- style: [
4209
- styles43.closeText,
4210
- { color: colors2.colorInteractive }
4211
- ],
4212
- children: "Done"
4213
- }
4214
- )
4215
- }
4216
- )
4217
- ]
4218
- }
4219
- ),
4220
- /* @__PURE__ */ jsx47(
4221
- FlatList2,
4222
- {
4223
- data: items,
4224
- keyExtractor: (item) => item.id,
4225
- renderItem: ({ item }) => /* @__PURE__ */ jsxs32(Fragment2, { children: [
4226
- item.separator && /* @__PURE__ */ jsx47(
4227
- View40,
4228
- {
4229
- style: [
4230
- styles43.separator,
4231
- { backgroundColor: colors2.colorBgSubtle }
4232
- ],
4233
- accessibilityRole: "none"
4234
- }
4235
- ),
4236
- /* @__PURE__ */ jsxs32(
4237
- Pressable25,
4238
- {
4239
- accessibilityRole: "menuitem",
4240
- accessibilityLabel: item.label,
4241
- accessibilityState: { disabled: item.disabled },
4242
- disabled: item.disabled,
4243
- onPress: () => handleItemPress(item),
4244
- style: ({ pressed }) => [
4245
- styles43.item,
4246
- pressed && { backgroundColor: colors2.colorBgSubtle },
4247
- item.disabled && { opacity: 0.4 }
4248
- ],
4249
- children: [
4250
- !!item.icon && /* @__PURE__ */ jsx47(
4251
- View40,
4252
- {
4253
- importantForAccessibility: "no-hide-descendants",
4254
- accessibilityElementsHidden: true,
4255
- children: item.icon
4256
- }
4257
- ),
4258
- /* @__PURE__ */ jsx47(
4259
- Text35,
4260
- {
4261
- style: [
4262
- styles43.itemText,
4263
- { color: colors2.colorOnBg }
4264
- ],
4265
- children: item.label
4266
- }
4267
- )
4268
- ]
4269
- }
4270
- )
4271
- ] })
4272
- }
4273
- )
4274
- ] })
4275
- }
4276
- )
4277
- }
4278
- )
4279
- ] })
4280
- }
4281
- )
4282
- ] });
4283
- }
4284
-
4285
- // src/components/interaction/Popover/Popover.native.tsx
4286
- import React2, { useState as useState15 } from "react";
4287
- import {
4288
- Modal as Modal5,
4289
- View as View41,
4290
- Pressable as Pressable26,
4291
- StyleSheet as StyleSheet44
4292
- } from "react-native";
4293
- import { jsx as jsx48, jsxs as jsxs33 } from "react/jsx-runtime";
4294
- var styles44 = StyleSheet44.create({
4295
- wrapper: {
4296
- alignSelf: "flex-start"
4297
- },
4298
- overlay: {
4299
- flex: 1,
4300
- justifyContent: "center",
4301
- alignItems: "center",
4302
- backgroundColor: "rgba(0, 0, 0, 0.25)",
4303
- padding: spacing.m
4304
- },
4305
- panel: {
4306
- width: "100%",
4307
- maxWidth: 360,
4308
- borderRadius: border.radius.s,
4309
- padding: spacing.m,
4310
- shadowColor: "#000",
4311
- shadowOffset: { width: 0, height: 2 },
4312
- shadowOpacity: 0.15,
4313
- shadowRadius: 8,
4314
- elevation: 4
4315
- }
4316
- });
4317
- function Popover({
4318
- children,
4319
- content,
4320
- accessibilityLabel,
4321
- style
4322
- }) {
4323
- const { colors: colors2 } = useTheme();
4324
- const [isOpen, setIsOpen] = useState15(false);
4325
- return /* @__PURE__ */ jsxs33(View41, { style: [styles44.wrapper, style], children: [
4326
- React2.cloneElement(children, {
4327
- onPress: () => setIsOpen(true),
4328
- accessibilityRole: "button",
4329
- accessibilityLabel: accessibilityLabel ?? "Open popover"
4330
- }),
4331
- /* @__PURE__ */ jsx48(
4332
- Modal5,
4333
- {
4334
- visible: isOpen,
4335
- transparent: true,
4336
- animationType: "fade",
4337
- onRequestClose: () => setIsOpen(false),
4338
- children: /* @__PURE__ */ jsx48(
4339
- Pressable26,
4340
- {
4341
- style: styles44.overlay,
4342
- onPress: () => setIsOpen(false),
4343
- accessibilityRole: "button",
4344
- accessibilityLabel: "Close popover",
4345
- children: /* @__PURE__ */ jsx48(
4346
- Pressable26,
4347
- {
4348
- style: [styles44.panel, { backgroundColor: colors2.colorBg }],
4349
- onPress: () => {
4350
- },
4351
- accessibilityRole: "none",
4352
- accessibilityLabel,
4353
- children: content
4354
- }
4355
- )
4356
- }
4357
- )
4358
- }
4359
- )
4360
- ] });
4361
- }
4362
- export {
4363
- Accordion,
4364
- Alert,
4365
- Avatar,
4366
- Badge,
4367
- Breadcrumb,
4368
- Button,
4369
- ButtonContainer,
4370
- ButtonGroup,
4371
- Calendar,
4372
- Card,
4373
- Carousel,
4374
- Checkbox,
4375
- CheckboxGroup,
4376
- Collapsible,
4377
- Combobox,
4378
- DescriptionList,
4379
- Dialog,
4380
- Drawer,
4381
- DropdownMenu,
4382
- FileInput,
4383
- FormInput,
4384
- IconWrapper,
4385
- Label,
4386
- Link,
4387
- Loading,
4388
- Message,
4389
- NotificationBanner,
4390
- NumberInput,
4391
- Pagination,
4392
- Popover,
4393
- Progress,
4394
- ProgressCircle,
4395
- Radio,
4396
- RadioGroup,
4397
- Rating,
4398
- SectionHeader,
4399
- SegmentedControl,
4400
- Select,
4401
- Separator,
4402
- Skeleton,
4403
- Slider,
4404
- Switch,
4405
- Table,
4406
- Tabs,
4407
- Textarea,
4408
- ThemeProvider,
4409
- ToastProvider,
4410
- Tooltip,
4411
- Typography,
4412
- animation,
4413
- border,
4414
- colors,
4415
- font,
4416
- lineHeight,
4417
- spacing,
4418
- useTheme,
4419
- useToast,
4420
- zIndex
4421
- };