ferns-ui 0.47.9 → 1.0.0-beta.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 (402) hide show
  1. package/dist/Accordion.d.ts +3 -0
  2. package/dist/Accordion.js +31 -0
  3. package/dist/Accordion.js.map +1 -0
  4. package/dist/ActionSheet.d.ts +9 -10
  5. package/dist/ActionSheet.js +8 -6
  6. package/dist/ActionSheet.js.map +1 -1
  7. package/dist/AddressField.d.ts +3 -0
  8. package/dist/AddressField.js +33 -0
  9. package/dist/AddressField.js.map +1 -0
  10. package/dist/Avatar.d.ts +2 -2
  11. package/dist/Avatar.js +132 -96
  12. package/dist/Avatar.js.map +1 -1
  13. package/dist/Badge.d.ts +1 -1
  14. package/dist/Badge.js +90 -20
  15. package/dist/Badge.js.map +1 -1
  16. package/dist/Banner.d.ts +1 -1
  17. package/dist/Banner.js +89 -51
  18. package/dist/Banner.js.map +1 -1
  19. package/dist/Body.js +4 -4
  20. package/dist/Body.js.map +1 -1
  21. package/dist/BooleanField.d.ts +3 -0
  22. package/dist/BooleanField.js +90 -0
  23. package/dist/BooleanField.js.map +1 -0
  24. package/dist/Box.js +80 -80
  25. package/dist/Box.js.map +1 -1
  26. package/dist/Button.d.ts +2 -2
  27. package/dist/Button.js +87 -109
  28. package/dist/Button.js.map +1 -1
  29. package/dist/Card.js +2 -2
  30. package/dist/Card.js.map +1 -1
  31. package/dist/CheckBox.d.ts +2 -2
  32. package/dist/CheckBox.js +23 -35
  33. package/dist/CheckBox.js.map +1 -1
  34. package/dist/Common.d.ts +1071 -406
  35. package/dist/Common.js +39 -3
  36. package/dist/Common.js.map +1 -1
  37. package/dist/CommonIconTypes.d.ts +3 -0
  38. package/dist/CommonIconTypes.js +2 -0
  39. package/dist/CommonIconTypes.js.map +1 -0
  40. package/dist/CustomSelectField.d.ts +3 -0
  41. package/dist/CustomSelectField.js +64 -0
  42. package/dist/CustomSelectField.js.map +1 -0
  43. package/dist/DateTimeActionSheet.d.ts +1 -1
  44. package/dist/DateTimeActionSheet.js +177 -156
  45. package/dist/DateTimeActionSheet.js.map +1 -1
  46. package/dist/DateTimeField.d.ts +3 -3
  47. package/dist/DateTimeField.js +140 -30
  48. package/dist/DateTimeField.js.map +1 -1
  49. package/dist/DateUtilities.js.map +1 -1
  50. package/dist/DateUtilities.test.js +2 -1
  51. package/dist/DateUtilities.test.js.map +1 -1
  52. package/dist/DecimalRangeActionSheet.js +3 -15
  53. package/dist/DecimalRangeActionSheet.js.map +1 -1
  54. package/dist/DismissButton.d.ts +3 -0
  55. package/dist/DismissButton.js +14 -0
  56. package/dist/DismissButton.js.map +1 -0
  57. package/dist/EmailField.d.ts +3 -0
  58. package/dist/EmailField.js +52 -0
  59. package/dist/EmailField.js.map +1 -0
  60. package/dist/ErrorBoundary.d.ts +1 -1
  61. package/dist/ErrorPage.js +2 -2
  62. package/dist/ErrorPage.js.map +1 -1
  63. package/dist/FernsProvider.js +1 -1
  64. package/dist/FernsProvider.js.map +1 -1
  65. package/dist/Field.d.ts +2 -2
  66. package/dist/Field.js +67 -136
  67. package/dist/Field.js.map +1 -1
  68. package/dist/Heading.js +37 -16
  69. package/dist/Heading.js.map +1 -1
  70. package/dist/HeightActionSheet.js +3 -7
  71. package/dist/HeightActionSheet.js.map +1 -1
  72. package/dist/Hyperlink.js +7 -1
  73. package/dist/Hyperlink.js.map +1 -1
  74. package/dist/Icon.d.ts +1 -2
  75. package/dist/Icon.js +8 -10
  76. package/dist/Icon.js.map +1 -1
  77. package/dist/IconButton.d.ts +2 -2
  78. package/dist/IconButton.js +93 -92
  79. package/dist/IconButton.js.map +1 -1
  80. package/dist/InfoTooltipButton.d.ts +1 -1
  81. package/dist/InfoTooltipButton.js +2 -2
  82. package/dist/InfoTooltipButton.js.map +1 -1
  83. package/dist/Link.d.ts +1 -1
  84. package/dist/Link.js +7 -3
  85. package/dist/Link.js.map +1 -1
  86. package/dist/MobileAddressAutoComplete.js +8 -8
  87. package/dist/MobileAddressAutoComplete.js.map +1 -1
  88. package/dist/Modal.d.ts +2 -2
  89. package/dist/Modal.js +95 -80
  90. package/dist/Modal.js.map +1 -1
  91. package/dist/MultiselectField.d.ts +3 -0
  92. package/dist/MultiselectField.js +49 -0
  93. package/dist/MultiselectField.js.map +1 -0
  94. package/dist/NumberField.d.ts +3 -0
  95. package/dist/NumberField.js +49 -0
  96. package/dist/NumberField.js.map +1 -0
  97. package/dist/NumberPickerActionSheet.js +2 -2
  98. package/dist/NumberPickerActionSheet.js.map +1 -1
  99. package/dist/OpenAPIContext.js.map +1 -1
  100. package/dist/Page.js +6 -6
  101. package/dist/Page.js.map +1 -1
  102. package/dist/Pagination.d.ts +2 -8
  103. package/dist/Pagination.js +107 -13
  104. package/dist/Pagination.js.map +1 -1
  105. package/dist/PasswordField.d.ts +2 -0
  106. package/dist/PasswordField.js +6 -0
  107. package/dist/PasswordField.js.map +1 -0
  108. package/dist/PhoneNumberField.d.ts +3 -0
  109. package/dist/PhoneNumberField.js +79 -0
  110. package/dist/PhoneNumberField.js.map +1 -0
  111. package/dist/PickerSelect.d.ts +6 -67
  112. package/dist/PickerSelect.js +145 -115
  113. package/dist/PickerSelect.js.map +1 -1
  114. package/dist/Radio.d.ts +3 -0
  115. package/dist/Radio.js +21 -0
  116. package/dist/Radio.js.map +1 -0
  117. package/dist/RadioField.d.ts +3 -0
  118. package/dist/RadioField.js +22 -0
  119. package/dist/RadioField.js.map +1 -0
  120. package/dist/SegmentedControl.d.ts +1 -1
  121. package/dist/SegmentedControl.js +35 -67
  122. package/dist/SegmentedControl.js.map +1 -1
  123. package/dist/SelectField.d.ts +3 -0
  124. package/dist/SelectField.js +20 -0
  125. package/dist/SelectField.js.map +1 -0
  126. package/dist/SideDrawer.js +8 -2
  127. package/dist/SideDrawer.js.map +1 -1
  128. package/dist/Signature.d.ts +1 -0
  129. package/dist/Signature.js +8 -7
  130. package/dist/Signature.js.map +1 -1
  131. package/dist/Signature.native.js +8 -7
  132. package/dist/Signature.native.js.map +1 -1
  133. package/dist/SignatureField.d.ts +3 -0
  134. package/dist/SignatureField.js +54 -0
  135. package/dist/SignatureField.js.map +1 -0
  136. package/dist/Spinner.js +17 -2
  137. package/dist/Spinner.js.map +1 -1
  138. package/dist/SplitPage.d.ts +1 -1
  139. package/dist/SplitPage.js +10 -10
  140. package/dist/SplitPage.js.map +1 -1
  141. package/dist/SplitPage.native.js +7 -7
  142. package/dist/SplitPage.native.js.map +1 -1
  143. package/dist/TapToEdit.d.ts +3 -3
  144. package/dist/TapToEdit.js +40 -32
  145. package/dist/TapToEdit.js.map +1 -1
  146. package/dist/Text.d.ts +1 -1
  147. package/dist/Text.js +70 -64
  148. package/dist/Text.js.map +1 -1
  149. package/dist/TextArea.d.ts +1 -1
  150. package/dist/TextArea.js +2 -14
  151. package/dist/TextArea.js.map +1 -1
  152. package/dist/TextField.d.ts +2 -2
  153. package/dist/TextField.js +89 -206
  154. package/dist/TextField.js.map +1 -1
  155. package/dist/TextFieldNumberActionSheet.js +2 -2
  156. package/dist/TextFieldNumberActionSheet.js.map +1 -1
  157. package/dist/Theme.d.ts +87 -3
  158. package/dist/Theme.js +197 -98
  159. package/dist/Theme.js.map +1 -1
  160. package/dist/TimezonePicker.js +3 -5
  161. package/dist/TimezonePicker.js.map +1 -1
  162. package/dist/Toast.d.ts +18 -5
  163. package/dist/Toast.js +130 -31
  164. package/dist/Toast.js.map +1 -1
  165. package/dist/Tooltip.d.ts +2 -2
  166. package/dist/Tooltip.js +189 -89
  167. package/dist/Tooltip.js.map +1 -1
  168. package/dist/UnifiedAddressAutoComplete.js +2 -2
  169. package/dist/UnifiedAddressAutoComplete.js.map +1 -1
  170. package/dist/Unifier.js.map +1 -1
  171. package/dist/Utilities.js +5 -3
  172. package/dist/Utilities.js.map +1 -1
  173. package/dist/WebAddressAutocomplete.js +2 -2
  174. package/dist/WebAddressAutocomplete.js.map +1 -1
  175. package/dist/fieldElements/FieldError.d.ts +6 -0
  176. package/dist/fieldElements/FieldError.js +14 -0
  177. package/dist/fieldElements/FieldError.js.map +1 -0
  178. package/dist/fieldElements/FieldHelperText.d.ts +6 -0
  179. package/dist/fieldElements/FieldHelperText.js +11 -0
  180. package/dist/fieldElements/FieldHelperText.js.map +1 -0
  181. package/dist/fieldElements/FieldTitle.d.ts +6 -0
  182. package/dist/fieldElements/FieldTitle.js +19 -0
  183. package/dist/fieldElements/FieldTitle.js.map +1 -0
  184. package/dist/fieldElements/index.d.ts +3 -0
  185. package/dist/fieldElements/index.js +4 -0
  186. package/dist/fieldElements/index.js.map +1 -0
  187. package/dist/icons/MobileIcon.d.ts +3 -0
  188. package/dist/icons/MobileIcon.js +24 -0
  189. package/dist/icons/MobileIcon.js.map +1 -0
  190. package/dist/icons/OfflineIcon.d.ts +3 -0
  191. package/dist/icons/OfflineIcon.js +23 -0
  192. package/dist/icons/OfflineIcon.js.map +1 -0
  193. package/dist/icons/OnlineIcon.d.ts +3 -0
  194. package/dist/icons/OnlineIcon.js +24 -0
  195. package/dist/icons/OnlineIcon.js.map +1 -0
  196. package/dist/icons/OutOfficeIcon.d.ts +3 -0
  197. package/dist/icons/OutOfficeIcon.js +24 -0
  198. package/dist/icons/OutOfficeIcon.js.map +1 -0
  199. package/dist/icons/index.d.ts +4 -0
  200. package/dist/icons/index.js +5 -0
  201. package/dist/icons/index.js.map +1 -0
  202. package/dist/index.d.ts +28 -14
  203. package/dist/index.js +28 -14
  204. package/dist/index.js.map +1 -1
  205. package/dist/setupTests.d.ts +1 -0
  206. package/dist/setupTests.js +1 -1
  207. package/dist/setupTests.js.map +1 -1
  208. package/dist/{Table.d.ts → table/Table.d.ts} +2 -2
  209. package/dist/{Table.js → table/Table.js} +18 -10
  210. package/dist/table/Table.js.map +1 -0
  211. package/dist/table/TableBadge.d.ts +6 -0
  212. package/dist/table/TableBadge.js +22 -0
  213. package/dist/table/TableBadge.js.map +1 -0
  214. package/dist/table/TableBoolean.d.ts +6 -0
  215. package/dist/table/TableBoolean.js +39 -0
  216. package/dist/table/TableBoolean.js.map +1 -0
  217. package/dist/table/TableDate.d.ts +3 -0
  218. package/dist/table/TableDate.js +26 -0
  219. package/dist/table/TableDate.js.map +1 -0
  220. package/dist/{TableHeader.d.ts → table/TableHeader.d.ts} +1 -1
  221. package/dist/{TableHeader.js → table/TableHeader.js} +2 -2
  222. package/dist/table/TableHeader.js.map +1 -0
  223. package/dist/{TableHeaderCell.d.ts → table/TableHeaderCell.d.ts} +2 -2
  224. package/dist/table/TableHeaderCell.js +58 -0
  225. package/dist/table/TableHeaderCell.js.map +1 -0
  226. package/dist/table/TableIconButton.d.ts +3 -0
  227. package/dist/table/TableIconButton.js +42 -0
  228. package/dist/table/TableIconButton.js.map +1 -0
  229. package/dist/table/TableNumber.d.ts +3 -0
  230. package/dist/table/TableNumber.js +18 -0
  231. package/dist/table/TableNumber.js.map +1 -0
  232. package/dist/{TableRow.d.ts → table/TableRow.d.ts} +1 -1
  233. package/dist/table/TableRow.js +28 -0
  234. package/dist/table/TableRow.js.map +1 -0
  235. package/dist/table/TableText.d.ts +3 -0
  236. package/dist/table/TableText.js +18 -0
  237. package/dist/table/TableText.js.map +1 -0
  238. package/dist/table/TableTitle.d.ts +3 -0
  239. package/dist/table/TableTitle.js +22 -0
  240. package/dist/table/TableTitle.js.map +1 -0
  241. package/dist/{tableContext.d.ts → table/tableContext.d.ts} +1 -1
  242. package/dist/table/tableContext.js.map +1 -0
  243. package/package.json +10 -4
  244. package/src/Accordion.tsx +84 -0
  245. package/src/ActionSheet.tsx +8 -5
  246. package/src/AddressField.tsx +122 -0
  247. package/src/Avatar.tsx +193 -147
  248. package/src/Badge.tsx +107 -49
  249. package/src/Banner.tsx +158 -111
  250. package/src/Body.tsx +4 -4
  251. package/src/BooleanField.tsx +122 -0
  252. package/src/Box.tsx +92 -82
  253. package/src/Button.tsx +151 -167
  254. package/src/Card.tsx +2 -2
  255. package/src/CheckBox.tsx +30 -111
  256. package/src/Common.ts +1304 -2041
  257. package/src/CommonIconTypes.ts +2030 -0
  258. package/src/CustomSelectField.tsx +116 -0
  259. package/src/DateTimeActionSheet.tsx +347 -255
  260. package/src/DateTimeField.tsx +168 -61
  261. package/src/DateUtilities.test.ts +6 -2
  262. package/src/DateUtilities.tsx +1 -1
  263. package/src/DecimalRangeActionSheet.tsx +2 -17
  264. package/src/DismissButton.tsx +31 -0
  265. package/src/EmailField.tsx +70 -0
  266. package/src/ErrorPage.tsx +2 -2
  267. package/src/FernsProvider.tsx +1 -1
  268. package/src/Field.tsx +83 -345
  269. package/src/Heading.tsx +44 -16
  270. package/src/HeightActionSheet.tsx +2 -9
  271. package/src/Hyperlink.tsx +8 -1
  272. package/src/Icon.tsx +22 -14
  273. package/src/IconButton.tsx +188 -156
  274. package/src/InfoTooltipButton.tsx +4 -6
  275. package/src/Link.tsx +14 -5
  276. package/src/MobileAddressAutoComplete.tsx +17 -13
  277. package/src/Modal.tsx +214 -190
  278. package/src/MultiselectField.tsx +103 -0
  279. package/src/NumberField.tsx +55 -0
  280. package/src/NumberPickerActionSheet.tsx +1 -4
  281. package/src/OpenAPIContext.tsx +1 -1
  282. package/src/Page.tsx +9 -13
  283. package/src/Pagination.tsx +171 -36
  284. package/src/PasswordField.tsx +7 -0
  285. package/src/PhoneNumberField.tsx +103 -0
  286. package/src/PickerSelect.tsx +169 -151
  287. package/src/Radio.tsx +33 -0
  288. package/src/RadioField.tsx +43 -0
  289. package/src/SegmentedControl.tsx +44 -96
  290. package/src/SelectField.tsx +41 -0
  291. package/src/SideDrawer.tsx +8 -2
  292. package/src/Signature.native.tsx +16 -9
  293. package/src/Signature.tsx +19 -11
  294. package/src/SignatureField.tsx +92 -0
  295. package/src/Spinner.tsx +16 -2
  296. package/src/SplitPage.native.tsx +9 -7
  297. package/src/SplitPage.tsx +11 -12
  298. package/src/TapToEdit.tsx +67 -39
  299. package/src/Text.tsx +79 -69
  300. package/src/TextArea.tsx +2 -2
  301. package/src/TextField.tsx +133 -285
  302. package/src/TextFieldNumberActionSheet.tsx +1 -4
  303. package/src/Theme.tsx +223 -172
  304. package/src/TimezonePicker.tsx +3 -18
  305. package/src/Toast.tsx +193 -70
  306. package/src/Tooltip.tsx +258 -141
  307. package/src/UnifiedAddressAutoComplete.tsx +3 -3
  308. package/src/Unifier.ts +4 -4
  309. package/src/Utilities.tsx +11 -3
  310. package/src/WebAddressAutocomplete.tsx +2 -3
  311. package/src/fieldElements/FieldError.tsx +24 -0
  312. package/src/fieldElements/FieldHelperText.tsx +20 -0
  313. package/src/fieldElements/FieldTitle.tsx +31 -0
  314. package/src/fieldElements/index.tsx +3 -0
  315. package/src/icons/MobileIcon.tsx +41 -0
  316. package/src/icons/OfflineIcon.tsx +38 -0
  317. package/src/icons/OnlineIcon.tsx +40 -0
  318. package/src/icons/OutOfficeIcon.tsx +37 -0
  319. package/src/icons/index.ts +4 -0
  320. package/src/index.tsx +28 -14
  321. package/src/setupTests.ts +1 -0
  322. package/src/{Table.tsx → table/Table.tsx} +24 -14
  323. package/src/table/TableBadge.tsx +46 -0
  324. package/src/table/TableBoolean.tsx +70 -0
  325. package/src/table/TableDate.tsx +38 -0
  326. package/src/{TableHeader.tsx → table/TableHeader.tsx} +3 -3
  327. package/src/table/TableHeaderCell.tsx +93 -0
  328. package/src/table/TableIconButton.tsx +62 -0
  329. package/src/table/TableNumber.tsx +29 -0
  330. package/src/{TableRow.tsx → table/TableRow.tsx} +28 -25
  331. package/src/table/TableText.tsx +29 -0
  332. package/src/table/TableTitle.tsx +32 -0
  333. package/src/{tableContext.tsx → table/tableContext.tsx} +1 -1
  334. package/dist/BlurBox.d.ts +0 -5
  335. package/dist/BlurBox.js +0 -28
  336. package/dist/BlurBox.js.map +0 -1
  337. package/dist/BlurBox.native.d.ts +0 -6
  338. package/dist/BlurBox.native.js +0 -30
  339. package/dist/BlurBox.native.js.map +0 -1
  340. package/dist/CustomSelect.d.ts +0 -3
  341. package/dist/CustomSelect.js +0 -47
  342. package/dist/CustomSelect.js.map +0 -1
  343. package/dist/DateTimeField.android.d.ts +0 -3
  344. package/dist/DateTimeField.android.js +0 -67
  345. package/dist/DateTimeField.android.js.map +0 -1
  346. package/dist/DateTimeField.ios.d.ts +0 -3
  347. package/dist/DateTimeField.ios.js +0 -49
  348. package/dist/DateTimeField.ios.js.map +0 -1
  349. package/dist/FieldWithLabels.d.ts +0 -3
  350. package/dist/FieldWithLabels.js +0 -8
  351. package/dist/FieldWithLabels.js.map +0 -1
  352. package/dist/Form.d.ts +0 -16
  353. package/dist/Form.js +0 -89
  354. package/dist/Form.js.map +0 -1
  355. package/dist/HeaderButtons.d.ts +0 -31
  356. package/dist/HeaderButtons.js +0 -53
  357. package/dist/HeaderButtons.js.map +0 -1
  358. package/dist/Mask.d.ts +0 -2
  359. package/dist/Mask.js +0 -19
  360. package/dist/Mask.js.map +0 -1
  361. package/dist/Pill.d.ts +0 -3
  362. package/dist/Pill.js +0 -8
  363. package/dist/Pill.js.map +0 -1
  364. package/dist/Pog.d.ts +0 -3
  365. package/dist/Pog.js +0 -48
  366. package/dist/Pog.js.map +0 -1
  367. package/dist/ProgressBar.d.ts +0 -3
  368. package/dist/ProgressBar.js +0 -35
  369. package/dist/ProgressBar.js.map +0 -1
  370. package/dist/SelectList.d.ts +0 -27
  371. package/dist/SelectList.js +0 -56
  372. package/dist/SelectList.js.map +0 -1
  373. package/dist/Switch.d.ts +0 -3
  374. package/dist/Switch.js +0 -20
  375. package/dist/Switch.js.map +0 -1
  376. package/dist/Table.js.map +0 -1
  377. package/dist/TableHeader.js.map +0 -1
  378. package/dist/TableHeaderCell.js +0 -36
  379. package/dist/TableHeaderCell.js.map +0 -1
  380. package/dist/TableRow.js +0 -30
  381. package/dist/TableRow.js.map +0 -1
  382. package/dist/WithLabel.d.ts +0 -3
  383. package/dist/WithLabel.js +0 -15
  384. package/dist/WithLabel.js.map +0 -1
  385. package/dist/tableContext.js.map +0 -1
  386. package/src/BlurBox.native.tsx +0 -40
  387. package/src/BlurBox.tsx +0 -31
  388. package/src/CustomSelect.tsx +0 -80
  389. package/src/DateTimeField.android.tsx +0 -103
  390. package/src/DateTimeField.ios.tsx +0 -85
  391. package/src/FieldWithLabels.tsx +0 -36
  392. package/src/Form.tsx +0 -175
  393. package/src/HeaderButtons.tsx +0 -107
  394. package/src/Mask.tsx +0 -21
  395. package/src/Pill.tsx +0 -22
  396. package/src/Pog.tsx +0 -75
  397. package/src/ProgressBar.tsx +0 -47
  398. package/src/SelectList.tsx +0 -109
  399. package/src/Switch.tsx +0 -18
  400. package/src/TableHeaderCell.tsx +0 -72
  401. package/src/WithLabel.tsx +0 -45
  402. /package/dist/{tableContext.js → table/tableContext.js} +0 -0
@@ -1,112 +1,60 @@
1
1
  import React from "react";
2
+ import {Pressable, View} from "react-native";
2
3
 
3
- import {Box} from "./Box";
4
- import {
5
- SegmentedControlProps,
6
- SegmentedControlPropsMultiSelect,
7
- SegmentedControlPropsSingleSelect,
8
- } from "./Common";
4
+ import {SegmentedControlProps} from "./Common";
9
5
  import {Text} from "./Text";
6
+ import {useTheme} from "./Theme";
10
7
 
11
8
  export const SegmentedControl = ({
12
9
  items,
13
10
  onChange = () => {},
14
- multiselect = false,
15
- selectLimit = 1,
16
- ...props
11
+ size = "md",
12
+ selectedIndex,
17
13
  }: SegmentedControlProps) => {
18
- const selectedItemIndex = (props as SegmentedControlPropsSingleSelect).selectedItemIndex;
19
- const selectedItemIndexes = (props as SegmentedControlPropsMultiSelect).selectedItemIndexes;
20
-
21
- const renderItem = (item: string | React.ReactNode) => {
22
- return (
23
- <Text align="center" weight="bold">
24
- {item}
25
- </Text>
26
- );
27
- // if (typeof item === "string") {
28
- // return <Text weight="bold">{item}</Text>;
29
- // } else {
30
- // return item;
31
- // }
32
- };
33
-
34
- if (selectedItemIndex === undefined && selectedItemIndexes === undefined) {
35
- console.warn("One of the following must be defined: selectedItemIndex, selectedItemIndexes");
36
- return null;
37
- }
38
-
39
- if (!multiselect && selectedItemIndexes?.length && selectedItemIndexes?.length > 1) {
40
- console.warn("Multiple selections not allowed without multiselect flag");
41
- return null;
42
- }
43
-
44
- if (selectedItemIndexes?.length && selectedItemIndexes?.length > selectLimit) {
45
- console.warn("The number of selected items exceeds the limit");
46
- return null;
47
- }
48
-
49
- const isTabActive = (index: any) => {
50
- return selectedItemIndex === index || selectedItemIndexes?.includes(index)
51
- ? "white"
52
- : "lightGray";
53
- };
54
-
14
+ const height = size === "md" ? 36 : 44;
15
+ const {theme} = useTheme();
55
16
  return (
56
- <Box
57
- color="lightGray"
58
- direction="row"
59
- display="flex"
60
- height={40}
61
- justifyContent="between"
62
- // padding={1}
63
- rounding={3}
64
- width="100%"
17
+ <View
18
+ style={{
19
+ display: "flex",
20
+ flexGrow: 1,
21
+ flexDirection: "row",
22
+ flexShrink: 1,
23
+ alignItems: "center",
24
+ gap: 4,
25
+ height,
26
+ borderRadius: theme.primitives.radius3xl,
27
+ borderColor: theme.primitives.neutral300,
28
+ borderWidth: 3,
29
+ backgroundColor: theme.primitives.neutral300,
30
+ }}
65
31
  >
66
32
  {items.map((item, index) => (
67
- <Box
33
+ <Pressable
68
34
  key={index}
69
- color={isTabActive(index)}
70
- height="100%"
71
- // paddingX={2}
72
- rounding={3}
73
- width={`${100 / items.length}%`}
35
+ accessibilityRole="button"
36
+ style={{
37
+ display: "flex",
38
+ paddingTop: theme.spacing.sm,
39
+ paddingBottom: theme.spacing.sm,
40
+ paddingLeft: theme.spacing.md,
41
+ paddingRight: theme.spacing.md,
42
+ justifyContent: "center",
43
+ alignItems: "center",
44
+ height: "100%",
45
+ flexBasis: 0,
46
+ gap: 12,
47
+ flexGrow: 1,
48
+ flexShrink: 0,
49
+ borderRadius: theme.primitives.radius3xl,
50
+ backgroundColor: index === selectedIndex ? theme.surface.base : undefined,
51
+ overflow: "hidden",
52
+ }}
53
+ onPress={() => onChange(index)}
74
54
  >
75
- <Box
76
- alignItems="center"
77
- display="flex"
78
- height="100%"
79
- justifyContent="center"
80
- paddingX={1}
81
- width="100%"
82
- onClick={() => {
83
- if (
84
- selectedItemIndexes?.length === selectLimit &&
85
- !selectedItemIndexes?.includes(index)
86
- ) {
87
- return;
88
- }
89
- if (multiselect) {
90
- const typedOnChange =
91
- onChange as unknown as SegmentedControlPropsMultiSelect["onChange"];
92
- if (selectedItemIndexes?.includes(index)) {
93
- typedOnChange({activeIndex: selectedItemIndexes.filter((i) => i !== index)});
94
- } else {
95
- const currentIndexes = [...(selectedItemIndexes as number[])];
96
- currentIndexes?.push(index);
97
- typedOnChange({activeIndex: currentIndexes?.sort() as number[]});
98
- }
99
- } else {
100
- const typedOnChange =
101
- onChange as unknown as SegmentedControlPropsSingleSelect["onChange"];
102
- typedOnChange({activeIndex: index});
103
- }
104
- }}
105
- >
106
- {renderItem(item)}
107
- </Box>
108
- </Box>
55
+ <Text>{item}</Text>
56
+ </Pressable>
109
57
  ))}
110
- </Box>
58
+ </View>
111
59
  );
112
60
  };
@@ -0,0 +1,41 @@
1
+ import React, {FC} from "react";
2
+ import {View} from "react-native";
3
+
4
+ import {SelectFieldProps} from "./Common";
5
+ import {FieldError, FieldHelperText, FieldTitle} from "./fieldElements";
6
+ import {RNPickerSelect} from "./PickerSelect";
7
+
8
+ export const SelectField: FC<SelectFieldProps> = ({
9
+ disabled = false,
10
+ errorText,
11
+ helperText,
12
+ options,
13
+ requireValue = false,
14
+ placeholder = "Please select an option.",
15
+ title,
16
+ value,
17
+ onChange,
18
+ }) => {
19
+ const clearOption = {label: placeholder ?? "---", value: ""};
20
+
21
+ return (
22
+ <View>
23
+ {title && <FieldTitle text={title} />}
24
+ {Boolean(errorText) && <FieldError text={errorText!} />}
25
+ <RNPickerSelect
26
+ disabled={disabled}
27
+ items={options}
28
+ placeholder={!requireValue ? clearOption : {}}
29
+ value={value ?? ""}
30
+ onValueChange={(v) => {
31
+ if (v === "" && !requireValue) {
32
+ (onChange as (val: string | undefined) => void)(undefined);
33
+ } else {
34
+ onChange(v);
35
+ }
36
+ }}
37
+ />
38
+ {helperText && <FieldHelperText text={helperText} />}
39
+ </View>
40
+ );
41
+ };
@@ -3,11 +3,11 @@ import {Platform, SafeAreaView, StyleProp, ViewStyle} from "react-native";
3
3
  import {Drawer} from "react-native-drawer-layout";
4
4
 
5
5
  import {SideDrawerProps} from "./Common";
6
+ import {useTheme} from "./Theme";
6
7
 
7
8
  const DEFAULT_STYLES: StyleProp<ViewStyle> = {
8
9
  width: Platform.OS === "web" ? "40%" : "95%",
9
10
  height: "100%",
10
- backgroundColor: "lightgray",
11
11
  borderWidth: 1,
12
12
  borderColor: "gray",
13
13
  };
@@ -30,6 +30,7 @@ export const SideDrawer = ({
30
30
  children,
31
31
  drawerStyles = {},
32
32
  }: SideDrawerProps): ReactElement => {
33
+ const {theme} = useTheme();
33
34
  const renderDrawerContent = useCallback((): ReactElement => {
34
35
  return <SafeAreaView>{renderContent()}</SafeAreaView>;
35
36
  }, [renderContent]);
@@ -37,7 +38,12 @@ export const SideDrawer = ({
37
38
  return (
38
39
  <Drawer
39
40
  drawerPosition={position}
40
- drawerStyle={[DEFAULT_STYLES, drawerStyles, addWebScroll(isOpen)]}
41
+ drawerStyle={[
42
+ DEFAULT_STYLES,
43
+ {backgroundColor: theme.surface.neutralLight},
44
+ drawerStyles,
45
+ addWebScroll(isOpen),
46
+ ]}
41
47
  drawerType={drawerType}
42
48
  open={isOpen}
43
49
  renderDrawerContent={renderDrawerContent}
@@ -1,8 +1,8 @@
1
1
  import React, {useRef} from "react";
2
+ import {Text, View} from "react-native";
2
3
  import SignatureScreen, {SignatureViewRef} from "react-native-signature-canvas";
3
4
 
4
- import {Box} from "./Box";
5
- import {Button} from "./Button";
5
+ import {useTheme} from "./Theme";
6
6
 
7
7
  interface Props {
8
8
  onChange: (signature: string) => void;
@@ -14,6 +14,7 @@ const style = `.m-signature-pad--footer {display: none; margin: 0px;}`;
14
14
 
15
15
  export const Signature: React.FC<Props> = ({onChange, onStart, onEnd}: Props) => {
16
16
  const ref = useRef<SignatureViewRef>(null);
17
+ const {theme} = useTheme();
17
18
 
18
19
  const handleClear = () => {
19
20
  ref.current?.clearSignature();
@@ -31,20 +32,26 @@ export const Signature: React.FC<Props> = ({onChange, onStart, onEnd}: Props) =>
31
32
  };
32
33
 
33
34
  return (
34
- <Box>
35
- <Box border="black" height={100}>
35
+ <View style={{minWidth: 220}}>
36
+ <View style={{borderColor: theme.border.dark, borderWidth: 1, minHeight: 90}}>
36
37
  <SignatureScreen
37
38
  ref={ref}
39
+ backgroundColor={theme.surface.base}
38
40
  trimWhitespace
39
41
  webStyle={style}
40
42
  onBegin={onBegin}
41
43
  onEnd={handleEnd}
42
44
  onOK={(img) => onChange(img)}
43
45
  />
44
- </Box>
45
- <Box direction="row">
46
- <Button text="Clear" onClick={handleClear} />
47
- </Box>
48
- </Box>
46
+ </View>
47
+ <View style={{flexDirection: "row"}}>
48
+ <Text
49
+ style={{color: theme.text.link, textDecorationLine: "underline"}}
50
+ onPress={handleClear}
51
+ >
52
+ Clear
53
+ </Text>
54
+ </View>
55
+ </View>
49
56
  );
50
57
  };
package/src/Signature.tsx CHANGED
@@ -1,17 +1,19 @@
1
1
  import React, {ReactElement, useRef} from "react";
2
+ import {Text, View} from "react-native";
2
3
  import SignatureCanvas from "react-signature-canvas";
3
4
 
4
- import {Box} from "./Box";
5
- import {Button} from "./Button";
5
+ import {useTheme} from "./Theme";
6
6
 
7
7
  export interface SignatureProps {
8
8
  onChange: (signature: string) => void;
9
9
  onStart?: () => void;
10
10
  onEnd?: () => void;
11
+ value?: string; // note this
11
12
  }
12
13
 
13
14
  export const Signature = ({onChange}: SignatureProps): ReactElement | null => {
14
15
  const ref = useRef<SignatureCanvas>(null);
16
+ const {theme} = useTheme();
15
17
 
16
18
  const onClear = () => {
17
19
  ref.current?.clear();
@@ -22,15 +24,21 @@ export const Signature = ({onChange}: SignatureProps): ReactElement | null => {
22
24
  onChange(ref.current.toDataURL());
23
25
  }
24
26
  };
25
-
26
27
  return (
27
- <Box width={300}>
28
- <Box border="black">
29
- <SignatureCanvas ref={ref} backgroundColor="white" onEnd={onUpdatedSignature} />
30
- </Box>
31
- <Box direction="row">
32
- <Button color="gray" text="Clear" onClick={onClear} />
33
- </Box>
34
- </Box>
28
+ <View>
29
+ <View style={{borderColor: theme.border.dark, borderWidth: 1, width: "100%", maxWidth: 300}}>
30
+ <SignatureCanvas
31
+ ref={ref}
32
+ backgroundColor={theme.surface.base}
33
+ penColor={theme.text.secondaryDark}
34
+ onEnd={onUpdatedSignature}
35
+ />
36
+ </View>
37
+ <View>
38
+ <Text style={{color: theme.text.link, textDecorationLine: "underline"}} onPress={onClear}>
39
+ Clear
40
+ </Text>
41
+ </View>
42
+ </View>
35
43
  );
36
44
  };
@@ -0,0 +1,92 @@
1
+ import React, {ReactElement} from "react";
2
+ import {Image, View} from "react-native";
3
+
4
+ import {SignatureFieldProps} from "./Common";
5
+ import {Heading} from "./Heading";
6
+ import {Icon} from "./Icon";
7
+ import {Signature} from "./Signature";
8
+ import {Text} from "./Text";
9
+ import {useTheme} from "./Theme";
10
+
11
+ // NOTE: When using this inside a ScrollView, you must set the scrollEnabled prop to false on the
12
+ // ScrollView onStart and to true onEnd or it will try to scroll the whole view around this
13
+ // component.
14
+ export const SignatureField = ({
15
+ disabled = false,
16
+ title = "Signature",
17
+ value,
18
+ onChange,
19
+ onStart,
20
+ onEnd,
21
+ disabledText,
22
+ errorText,
23
+ }: SignatureFieldProps): ReactElement => {
24
+ const {theme} = useTheme();
25
+ if (disabled) {
26
+ if (value) {
27
+ return (
28
+ <View>
29
+ <Heading size="sm">{title}</Heading>
30
+ <View style={{marginVertical: 8}}>{SignatureImage(value)}</View>
31
+ <Text size="sm">{disabledText}</Text>
32
+ </View>
33
+ );
34
+ } else {
35
+ // we don't have a value so should show a grayed out signature field as a box
36
+ // there is no disabled state for the Signature components
37
+ return (
38
+ <View>
39
+ <View
40
+ style={{
41
+ height: 90,
42
+ width: 300,
43
+ backgroundColor: theme.surface.neutralLight,
44
+ marginVertical: 8,
45
+ }}
46
+ />
47
+ <Text size="sm">{disabledText}</Text>
48
+ </View>
49
+ );
50
+ }
51
+ }
52
+ return (
53
+ <View>
54
+ <Heading size="sm">{title}</Heading>
55
+ {Boolean(errorText) && (
56
+ <View style={{flexDirection: "row"}}>
57
+ <Icon color="error" iconName="triangle-exclamation" />
58
+ <View style={{marginLeft: 4}}>
59
+ <Text color="error">{errorText}</Text>
60
+ </View>
61
+ </View>
62
+ )}
63
+ <View style={{marginVertical: 8}}>
64
+ <Signature
65
+ onChange={onChange}
66
+ onEnd={() => {
67
+ onEnd && onEnd();
68
+ }}
69
+ onStart={() => {
70
+ onStart && onStart();
71
+ }}
72
+ />
73
+ </View>
74
+ </View>
75
+ );
76
+ };
77
+
78
+ const SignatureImage = (image: string): ReactElement => {
79
+ return (
80
+ <Image
81
+ accessibilityIgnoresInvertColors={false}
82
+ resizeMode="contain"
83
+ source={{uri: image}}
84
+ style={{
85
+ width: 300,
86
+ height: 80,
87
+ borderWidth: 1,
88
+ borderColor: "black",
89
+ }}
90
+ />
91
+ );
92
+ };
package/src/Spinner.tsx CHANGED
@@ -2,9 +2,22 @@ import React, {ReactElement, useEffect, useState} from "react";
2
2
  import {ActivityIndicator} from "react-native";
3
3
 
4
4
  import {SpinnerProps} from "./Common";
5
+ import {useTheme} from "./Theme";
5
6
 
6
- export const Spinner = ({size, color}: SpinnerProps): ReactElement | null => {
7
+ export const Spinner = ({size = "md", color = "light"}: SpinnerProps): ReactElement | null => {
7
8
  const [show, setShow] = useState(false);
9
+ const {theme} = useTheme();
10
+
11
+ let computedColor = "";
12
+ if (color === "light") {
13
+ computedColor = theme.primitives.neutral400;
14
+ } else if (color === "dark") {
15
+ computedColor = theme.primitives.neutral000;
16
+ } else if (color === "accent") {
17
+ computedColor = theme.primitives.accent700;
18
+ } else if (color === "secondary") {
19
+ computedColor = theme.primitives.secondary600;
20
+ }
8
21
 
9
22
  // The delay is for perceived performance. You don't want to show a spinner when you're doing a
10
23
  // quick action.
@@ -16,6 +29,7 @@ export const Spinner = ({size, color}: SpinnerProps): ReactElement | null => {
16
29
  if (!show) {
17
30
  return null;
18
31
  }
32
+
19
33
  const spinnerSize: "small" | "large" = size === "sm" ? "small" : "large";
20
- return <ActivityIndicator color={color ?? "darkGray"} size={spinnerSize} />;
34
+ return <ActivityIndicator color={computedColor} size={spinnerSize} />;
21
35
  };
@@ -1,5 +1,5 @@
1
1
  // TODO: Update SplitPage native to have desktop UX for tablet sized screens
2
- import React, {useCallback, useContext, useEffect, useState} from "react";
2
+ import React, {useCallback, useEffect, useState} from "react";
3
3
  import flattenChildren from "react-keyed-flatten-children";
4
4
  import {Dimensions, ListRenderItemInfo, View} from "react-native";
5
5
  import {SwiperFlatList} from "react-native-swiper-flatlist";
@@ -9,7 +9,7 @@ import {SplitPageProps} from "./Common";
9
9
  import {FlatList} from "./FlatList";
10
10
  import {IconButton} from "./IconButton";
11
11
  import {Spinner} from "./Spinner";
12
- import {ThemeContext} from "./Theme";
12
+ import {useTheme} from "./Theme";
13
13
  import {Unifier} from "./Unifier";
14
14
 
15
15
  export const SplitPage = ({
@@ -26,7 +26,7 @@ export const SplitPage = ({
26
26
  bottomNavBarHeight,
27
27
  showItemList,
28
28
  }: SplitPageProps) => {
29
- const {theme} = useContext(ThemeContext);
29
+ const {theme} = useTheme();
30
30
  const [selectedId, setSelectedId] = useState<number | undefined>(undefined);
31
31
 
32
32
  // flattenChildren is necessary to pull children from a React Fragment. Without this,
@@ -63,6 +63,8 @@ export const SplitPage = ({
63
63
  const renderItem = (itemInfo: ListRenderItemInfo<any>) => {
64
64
  return (
65
65
  <Box
66
+ accessibilityHint=""
67
+ accessibilityLabel="Edit"
66
68
  onClick={async () => {
67
69
  await Unifier.utils.haptic();
68
70
  await onItemSelect(itemInfo);
@@ -109,9 +111,9 @@ export const SplitPage = ({
109
111
  <Box flex="grow" padding={2}>
110
112
  <Box width="100%">
111
113
  <IconButton
114
+ accessibilityHint="close split page"
112
115
  accessibilityLabel="close"
113
- icon="times"
114
- iconColor="darkGray"
116
+ iconName="xmark"
115
117
  onClick={() => onItemDeselect()}
116
118
  />
117
119
  </Box>
@@ -150,13 +152,13 @@ export const SplitPage = ({
150
152
  return (
151
153
  <Box
152
154
  avoidKeyboard
153
- color={color || "lightGray"}
155
+ color={color || "neutralLight"}
154
156
  flex="grow"
155
157
  height="100%"
156
158
  keyboardOffset={keyboardOffset}
157
159
  width="100%"
158
160
  >
159
- {loading === true && <Spinner color={theme.darkGray as any} size="md" />}
161
+ {loading === true && <Spinner color="light" size="md" />}
160
162
  {selectedId === undefined ? renderList() : renderMainContent}
161
163
  </Box>
162
164
  );
package/src/SplitPage.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import React, {Children, useCallback, useContext, useEffect, useState} from "react";
1
+ import React, {Children, useCallback, useEffect, useState} from "react";
2
2
  import {Dimensions, ListRenderItemInfo, ScrollView, View} from "react-native";
3
3
  import {SwiperFlatList} from "react-native-swiper-flatlist";
4
4
 
@@ -9,7 +9,7 @@ import {IconButton} from "./IconButton";
9
9
  import {mediaQueryLargerThan} from "./MediaQuery";
10
10
  import {SegmentedControl} from "./SegmentedControl";
11
11
  import {Spinner} from "./Spinner";
12
- import {ThemeContext} from "./Theme";
12
+ import {useTheme} from "./Theme";
13
13
 
14
14
  // A component for rendering a list on one side and a details view on the right for large screens,
15
15
  // and a scrollable list where clicking an item takes you the details view.
@@ -28,9 +28,8 @@ export const SplitPage = ({
28
28
  listViewWidth,
29
29
  bottomNavBarHeight,
30
30
  showItemList,
31
- selectLimit,
32
31
  }: SplitPageProps) => {
33
- const {theme} = useContext(ThemeContext);
32
+ const {theme} = useTheme();
34
33
  const [selectedId, setSelectedId] = useState<number | undefined>(undefined);
35
34
  const [activeTabs, setActiveTabs] = useState<number[]>([0, 1]);
36
35
  const {width} = Dimensions.get("window");
@@ -72,6 +71,8 @@ export const SplitPage = ({
72
71
  const renderItem = (itemInfo: ListRenderItemInfo<any>) => {
73
72
  return (
74
73
  <Box
74
+ accessibilityHint=""
75
+ accessibilityLabel="Select"
75
76
  onClick={async () => {
76
77
  await onItemSelect(itemInfo);
77
78
  }}
@@ -126,11 +127,9 @@ export const SplitPage = ({
126
127
  <Box marginBottom={4} paddingX={4} width="100%">
127
128
  <SegmentedControl
128
129
  items={tabs}
129
- multiselect
130
- selectLimit={selectLimit || tabs.length}
131
- selectedItemIndexes={activeTabs}
130
+ selectedIndex={activeTabs[0]}
132
131
  onChange={(index) => {
133
- setActiveTabs([...(index.activeIndex as number[])]);
132
+ setActiveTabs([...([index] as number[])]);
134
133
  }}
135
134
  />
136
135
  </Box>
@@ -227,9 +226,9 @@ export const SplitPage = ({
227
226
  {isMobileDevice && (
228
227
  <Box width="100%">
229
228
  <IconButton
229
+ accessibilityHint="close split page"
230
230
  accessibilityLabel="close"
231
- icon="times"
232
- iconColor="darkGray"
231
+ iconName="xmark"
233
232
  onClick={() => onItemDeselect()}
234
233
  />
235
234
  </Box>
@@ -289,7 +288,7 @@ export const SplitPage = ({
289
288
  return (
290
289
  <Box
291
290
  avoidKeyboard
292
- color={color || "lightGray"}
291
+ color={color || "neutralLight"}
293
292
  direction="row"
294
293
  display="flex"
295
294
  height="100%"
@@ -297,7 +296,7 @@ export const SplitPage = ({
297
296
  padding={2}
298
297
  width="100%"
299
298
  >
300
- {loading === true && <Spinner color={theme.darkGray as any} size="md" />}
299
+ {loading === true && <Spinner color={theme.text.primary as any} size="md" />}
301
300
  {Boolean(isMobileDevice) ? renderMobileSplitPage() : renderSplitPage()}
302
301
  </Box>
303
302
  );