@oxyhq/bloom 0.6.24 → 0.7.1

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 (423) hide show
  1. package/lib/commonjs/alert-dialog/AlertDialog.js +109 -0
  2. package/lib/commonjs/alert-dialog/AlertDialog.js.map +1 -0
  3. package/lib/commonjs/alert-dialog/AlertDialogHost.js +50 -0
  4. package/lib/commonjs/alert-dialog/AlertDialogHost.js.map +1 -0
  5. package/lib/commonjs/alert-dialog/confirm-store.js +80 -0
  6. package/lib/commonjs/alert-dialog/confirm-store.js.map +1 -0
  7. package/lib/commonjs/alert-dialog/index.js +19 -0
  8. package/lib/commonjs/alert-dialog/index.js.map +1 -0
  9. package/lib/commonjs/alert-dialog/index.web.js +19 -0
  10. package/lib/commonjs/alert-dialog/index.web.js.map +1 -0
  11. package/lib/commonjs/alert-dialog/types.js +6 -0
  12. package/lib/commonjs/alert-dialog/types.js.map +1 -0
  13. package/lib/commonjs/combobox/Combobox.js +227 -0
  14. package/lib/commonjs/combobox/Combobox.js.map +1 -0
  15. package/lib/commonjs/combobox/index.js +11 -0
  16. package/lib/commonjs/combobox/index.js.map +1 -0
  17. package/lib/commonjs/combobox/index.web.js +11 -0
  18. package/lib/commonjs/combobox/index.web.js.map +1 -0
  19. package/lib/commonjs/combobox/types.js +6 -0
  20. package/lib/commonjs/combobox/types.js.map +1 -0
  21. package/lib/commonjs/command/Command.js +256 -0
  22. package/lib/commonjs/command/Command.js.map +1 -0
  23. package/lib/commonjs/command/index.js +10 -0
  24. package/lib/commonjs/command/index.js.map +1 -0
  25. package/lib/commonjs/command/index.web.js +10 -0
  26. package/lib/commonjs/command/index.web.js.map +1 -0
  27. package/lib/commonjs/command/types.js +6 -0
  28. package/lib/commonjs/command/types.js.map +1 -0
  29. package/lib/commonjs/field/Field.js +68 -0
  30. package/lib/commonjs/field/Field.js.map +1 -0
  31. package/lib/commonjs/field/index.js +13 -0
  32. package/lib/commonjs/field/index.js.map +1 -0
  33. package/lib/commonjs/field/types.js +6 -0
  34. package/lib/commonjs/field/types.js.map +1 -0
  35. package/lib/commonjs/index.js +117 -25
  36. package/lib/commonjs/index.js.map +1 -1
  37. package/lib/commonjs/index.web.js +117 -25
  38. package/lib/commonjs/index.web.js.map +1 -1
  39. package/lib/commonjs/input-group/InputGroup.js +172 -0
  40. package/lib/commonjs/input-group/InputGroup.js.map +1 -0
  41. package/lib/commonjs/input-group/index.js +19 -0
  42. package/lib/commonjs/input-group/index.js.map +1 -0
  43. package/lib/commonjs/input-group/types.js +6 -0
  44. package/lib/commonjs/input-group/types.js.map +1 -0
  45. package/lib/commonjs/item/Item.js +172 -0
  46. package/lib/commonjs/item/Item.js.map +1 -0
  47. package/lib/commonjs/item/index.js +13 -0
  48. package/lib/commonjs/item/index.js.map +1 -0
  49. package/lib/commonjs/item/types.js +6 -0
  50. package/lib/commonjs/item/types.js.map +1 -0
  51. package/lib/commonjs/kbd/Kbd.js +79 -0
  52. package/lib/commonjs/kbd/Kbd.js.map +1 -0
  53. package/lib/commonjs/kbd/index.js +13 -0
  54. package/lib/commonjs/kbd/index.js.map +1 -0
  55. package/lib/commonjs/kbd/types.js +6 -0
  56. package/lib/commonjs/kbd/types.js.map +1 -0
  57. package/lib/commonjs/label/Label.js +60 -0
  58. package/lib/commonjs/label/Label.js.map +1 -0
  59. package/lib/commonjs/label/index.js +13 -0
  60. package/lib/commonjs/label/index.js.map +1 -0
  61. package/lib/commonjs/label/types.js +6 -0
  62. package/lib/commonjs/label/types.js.map +1 -0
  63. package/lib/commonjs/popover/context.js +18 -0
  64. package/lib/commonjs/popover/context.js.map +1 -0
  65. package/lib/commonjs/popover/index.js +111 -0
  66. package/lib/commonjs/popover/index.js.map +1 -0
  67. package/lib/commonjs/popover/index.web.js +286 -0
  68. package/lib/commonjs/popover/index.web.js.map +1 -0
  69. package/lib/commonjs/popover/types.js +6 -0
  70. package/lib/commonjs/popover/types.js.map +1 -0
  71. package/lib/commonjs/react-native-css.d.js +2 -0
  72. package/lib/commonjs/react-native-css.d.js.map +1 -0
  73. package/lib/commonjs/slider/Slider.js +255 -0
  74. package/lib/commonjs/slider/Slider.js.map +1 -0
  75. package/lib/commonjs/slider/index.js +13 -0
  76. package/lib/commonjs/slider/index.js.map +1 -0
  77. package/lib/commonjs/slider/types.js +6 -0
  78. package/lib/commonjs/slider/types.js.map +1 -0
  79. package/lib/commonjs/theme/BloomThemeProvider.js +39 -7
  80. package/lib/commonjs/theme/BloomThemeProvider.js.map +1 -1
  81. package/lib/commonjs/theme/color-presets.js +118 -118
  82. package/lib/commonjs/theme/color-presets.js.map +1 -1
  83. package/lib/commonjs/theme/color-scope/index.js +28 -6
  84. package/lib/commonjs/theme/color-scope/index.js.map +1 -1
  85. package/lib/commonjs/theme/color-scope/style-builder.js +35 -0
  86. package/lib/commonjs/theme/color-scope/style-builder.js.map +1 -1
  87. package/lib/commonjs/theme/native-root-vars.js +105 -0
  88. package/lib/commonjs/theme/native-root-vars.js.map +1 -0
  89. package/lib/commonjs/theme/native-root-vars.web.js +27 -0
  90. package/lib/commonjs/theme/native-root-vars.web.js.map +1 -0
  91. package/lib/commonjs/theme/preset-vars.js +4 -1
  92. package/lib/commonjs/theme/preset-vars.js.map +1 -1
  93. package/lib/module/alert-dialog/AlertDialog.js +104 -0
  94. package/lib/module/alert-dialog/AlertDialog.js.map +1 -0
  95. package/lib/module/alert-dialog/AlertDialogHost.js +45 -0
  96. package/lib/module/alert-dialog/AlertDialogHost.js.map +1 -0
  97. package/lib/module/alert-dialog/confirm-store.js +73 -0
  98. package/lib/module/alert-dialog/confirm-store.js.map +1 -0
  99. package/lib/module/alert-dialog/index.js +9 -0
  100. package/lib/module/alert-dialog/index.js.map +1 -0
  101. package/lib/module/alert-dialog/index.web.js +9 -0
  102. package/lib/module/alert-dialog/index.web.js.map +1 -0
  103. package/lib/module/alert-dialog/types.js +4 -0
  104. package/lib/module/alert-dialog/types.js.map +1 -0
  105. package/lib/module/combobox/Combobox.js +222 -0
  106. package/lib/module/combobox/Combobox.js.map +1 -0
  107. package/lib/module/combobox/index.js +6 -0
  108. package/lib/module/combobox/index.js.map +1 -0
  109. package/lib/module/combobox/index.web.js +6 -0
  110. package/lib/module/combobox/index.web.js.map +1 -0
  111. package/lib/module/combobox/types.js +4 -0
  112. package/lib/module/combobox/types.js.map +1 -0
  113. package/lib/module/command/Command.js +251 -0
  114. package/lib/module/command/Command.js.map +1 -0
  115. package/lib/module/command/index.js +6 -0
  116. package/lib/module/command/index.js.map +1 -0
  117. package/lib/module/command/index.web.js +6 -0
  118. package/lib/module/command/index.web.js.map +1 -0
  119. package/lib/module/command/types.js +4 -0
  120. package/lib/module/command/types.js.map +1 -0
  121. package/lib/module/field/Field.js +63 -0
  122. package/lib/module/field/Field.js.map +1 -0
  123. package/lib/module/field/index.js +4 -0
  124. package/lib/module/field/index.js.map +1 -0
  125. package/lib/module/field/types.js +4 -0
  126. package/lib/module/field/types.js.map +1 -0
  127. package/lib/module/index.js +10 -3
  128. package/lib/module/index.js.map +1 -1
  129. package/lib/module/index.web.js +10 -3
  130. package/lib/module/index.web.js.map +1 -1
  131. package/lib/module/input-group/InputGroup.js +167 -0
  132. package/lib/module/input-group/InputGroup.js.map +1 -0
  133. package/lib/module/input-group/index.js +4 -0
  134. package/lib/module/input-group/index.js.map +1 -0
  135. package/lib/module/input-group/types.js +4 -0
  136. package/lib/module/input-group/types.js.map +1 -0
  137. package/lib/module/item/Item.js +167 -0
  138. package/lib/module/item/Item.js.map +1 -0
  139. package/lib/module/item/index.js +4 -0
  140. package/lib/module/item/index.js.map +1 -0
  141. package/lib/module/item/types.js +4 -0
  142. package/lib/module/item/types.js.map +1 -0
  143. package/lib/module/kbd/Kbd.js +74 -0
  144. package/lib/module/kbd/Kbd.js.map +1 -0
  145. package/lib/module/kbd/index.js +4 -0
  146. package/lib/module/kbd/index.js.map +1 -0
  147. package/lib/module/kbd/types.js +4 -0
  148. package/lib/module/kbd/types.js.map +1 -0
  149. package/lib/module/label/Label.js +55 -0
  150. package/lib/module/label/Label.js.map +1 -0
  151. package/lib/module/label/index.js +4 -0
  152. package/lib/module/label/index.js.map +1 -0
  153. package/lib/module/label/types.js +4 -0
  154. package/lib/module/label/types.js.map +1 -0
  155. package/lib/module/popover/context.js +13 -0
  156. package/lib/module/popover/context.js.map +1 -0
  157. package/lib/module/popover/index.js +95 -0
  158. package/lib/module/popover/index.js.map +1 -0
  159. package/lib/module/popover/index.web.js +274 -0
  160. package/lib/module/popover/index.web.js.map +1 -0
  161. package/lib/module/popover/types.js +4 -0
  162. package/lib/module/popover/types.js.map +1 -0
  163. package/lib/module/react-native-css.d.js +2 -0
  164. package/lib/module/react-native-css.d.js.map +1 -0
  165. package/lib/module/slider/Slider.js +250 -0
  166. package/lib/module/slider/Slider.js.map +1 -0
  167. package/lib/module/slider/index.js +4 -0
  168. package/lib/module/slider/index.js.map +1 -0
  169. package/lib/module/slider/types.js +4 -0
  170. package/lib/module/slider/types.js.map +1 -0
  171. package/lib/module/theme/BloomThemeProvider.js +40 -8
  172. package/lib/module/theme/BloomThemeProvider.js.map +1 -1
  173. package/lib/module/theme/color-presets.js +118 -118
  174. package/lib/module/theme/color-presets.js.map +1 -1
  175. package/lib/module/theme/color-scope/index.js +29 -7
  176. package/lib/module/theme/color-scope/index.js.map +1 -1
  177. package/lib/module/theme/color-scope/style-builder.js +35 -0
  178. package/lib/module/theme/color-scope/style-builder.js.map +1 -1
  179. package/lib/module/theme/native-root-vars.js +101 -0
  180. package/lib/module/theme/native-root-vars.js.map +1 -0
  181. package/lib/module/theme/native-root-vars.web.js +23 -0
  182. package/lib/module/theme/native-root-vars.web.js.map +1 -0
  183. package/lib/module/theme/preset-vars.js +4 -1
  184. package/lib/module/theme/preset-vars.js.map +1 -1
  185. package/lib/typescript/commonjs/alert-dialog/AlertDialog.d.ts +21 -0
  186. package/lib/typescript/commonjs/alert-dialog/AlertDialog.d.ts.map +1 -0
  187. package/lib/typescript/commonjs/alert-dialog/AlertDialogHost.d.ts +15 -0
  188. package/lib/typescript/commonjs/alert-dialog/AlertDialogHost.d.ts.map +1 -0
  189. package/lib/typescript/commonjs/alert-dialog/confirm-store.d.ts +31 -0
  190. package/lib/typescript/commonjs/alert-dialog/confirm-store.d.ts.map +1 -0
  191. package/lib/typescript/commonjs/alert-dialog/index.d.ts +8 -0
  192. package/lib/typescript/commonjs/alert-dialog/index.d.ts.map +1 -0
  193. package/lib/typescript/commonjs/alert-dialog/index.web.d.ts +8 -0
  194. package/lib/typescript/commonjs/alert-dialog/index.web.d.ts.map +1 -0
  195. package/lib/typescript/commonjs/alert-dialog/types.d.ts +44 -0
  196. package/lib/typescript/commonjs/alert-dialog/types.d.ts.map +1 -0
  197. package/lib/typescript/commonjs/combobox/Combobox.d.ts +33 -0
  198. package/lib/typescript/commonjs/combobox/Combobox.d.ts.map +1 -0
  199. package/lib/typescript/commonjs/combobox/index.d.ts +6 -0
  200. package/lib/typescript/commonjs/combobox/index.d.ts.map +1 -0
  201. package/lib/typescript/commonjs/combobox/index.web.d.ts +6 -0
  202. package/lib/typescript/commonjs/combobox/index.web.d.ts.map +1 -0
  203. package/lib/typescript/commonjs/combobox/types.d.ts +40 -0
  204. package/lib/typescript/commonjs/combobox/types.d.ts.map +1 -0
  205. package/lib/typescript/commonjs/command/Command.d.ts +22 -0
  206. package/lib/typescript/commonjs/command/Command.d.ts.map +1 -0
  207. package/lib/typescript/commonjs/command/index.d.ts +6 -0
  208. package/lib/typescript/commonjs/command/index.d.ts.map +1 -0
  209. package/lib/typescript/commonjs/command/index.web.d.ts +6 -0
  210. package/lib/typescript/commonjs/command/index.web.d.ts.map +1 -0
  211. package/lib/typescript/commonjs/command/types.d.ts +46 -0
  212. package/lib/typescript/commonjs/command/types.d.ts.map +1 -0
  213. package/lib/typescript/commonjs/field/Field.d.ts +4 -0
  214. package/lib/typescript/commonjs/field/Field.d.ts.map +1 -0
  215. package/lib/typescript/commonjs/field/index.d.ts +3 -0
  216. package/lib/typescript/commonjs/field/index.d.ts.map +1 -0
  217. package/lib/typescript/commonjs/field/types.d.ts +26 -0
  218. package/lib/typescript/commonjs/field/types.d.ts.map +1 -0
  219. package/lib/typescript/commonjs/icons/common.d.ts +8 -8
  220. package/lib/typescript/commonjs/index.d.ts +19 -0
  221. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  222. package/lib/typescript/commonjs/index.web.d.ts +19 -0
  223. package/lib/typescript/commonjs/index.web.d.ts.map +1 -1
  224. package/lib/typescript/commonjs/input-group/InputGroup.d.ts +9 -0
  225. package/lib/typescript/commonjs/input-group/InputGroup.d.ts.map +1 -0
  226. package/lib/typescript/commonjs/input-group/index.d.ts +3 -0
  227. package/lib/typescript/commonjs/input-group/index.d.ts.map +1 -0
  228. package/lib/typescript/commonjs/input-group/types.d.ts +35 -0
  229. package/lib/typescript/commonjs/input-group/types.d.ts.map +1 -0
  230. package/lib/typescript/commonjs/item/Item.d.ts +4 -0
  231. package/lib/typescript/commonjs/item/Item.d.ts.map +1 -0
  232. package/lib/typescript/commonjs/item/index.d.ts +3 -0
  233. package/lib/typescript/commonjs/item/index.d.ts.map +1 -0
  234. package/lib/typescript/commonjs/item/types.d.ts +45 -0
  235. package/lib/typescript/commonjs/item/types.d.ts.map +1 -0
  236. package/lib/typescript/commonjs/kbd/Kbd.d.ts +4 -0
  237. package/lib/typescript/commonjs/kbd/Kbd.d.ts.map +1 -0
  238. package/lib/typescript/commonjs/kbd/index.d.ts +3 -0
  239. package/lib/typescript/commonjs/kbd/index.d.ts.map +1 -0
  240. package/lib/typescript/commonjs/kbd/types.d.ts +13 -0
  241. package/lib/typescript/commonjs/kbd/types.d.ts.map +1 -0
  242. package/lib/typescript/commonjs/label/Label.d.ts +4 -0
  243. package/lib/typescript/commonjs/label/Label.d.ts.map +1 -0
  244. package/lib/typescript/commonjs/label/index.d.ts +3 -0
  245. package/lib/typescript/commonjs/label/index.d.ts.map +1 -0
  246. package/lib/typescript/commonjs/label/types.d.ts +27 -0
  247. package/lib/typescript/commonjs/label/types.d.ts.map +1 -0
  248. package/lib/typescript/commonjs/popover/context.d.ts +15 -0
  249. package/lib/typescript/commonjs/popover/context.d.ts.map +1 -0
  250. package/lib/typescript/commonjs/popover/index.d.ts +14 -0
  251. package/lib/typescript/commonjs/popover/index.d.ts.map +1 -0
  252. package/lib/typescript/commonjs/popover/index.web.d.ts +14 -0
  253. package/lib/typescript/commonjs/popover/index.web.d.ts.map +1 -0
  254. package/lib/typescript/commonjs/popover/types.d.ts +54 -0
  255. package/lib/typescript/commonjs/popover/types.d.ts.map +1 -0
  256. package/lib/typescript/commonjs/slider/Slider.d.ts +4 -0
  257. package/lib/typescript/commonjs/slider/Slider.d.ts.map +1 -0
  258. package/lib/typescript/commonjs/slider/index.d.ts +3 -0
  259. package/lib/typescript/commonjs/slider/index.d.ts.map +1 -0
  260. package/lib/typescript/commonjs/slider/types.d.ts +30 -0
  261. package/lib/typescript/commonjs/slider/types.d.ts.map +1 -0
  262. package/lib/typescript/commonjs/theme/BloomThemeProvider.d.ts.map +1 -1
  263. package/lib/typescript/commonjs/theme/color-scope/index.d.ts +9 -2
  264. package/lib/typescript/commonjs/theme/color-scope/index.d.ts.map +1 -1
  265. package/lib/typescript/commonjs/theme/color-scope/style-builder.d.ts +32 -0
  266. package/lib/typescript/commonjs/theme/color-scope/style-builder.d.ts.map +1 -1
  267. package/lib/typescript/commonjs/theme/native-root-vars.d.ts +89 -0
  268. package/lib/typescript/commonjs/theme/native-root-vars.d.ts.map +1 -0
  269. package/lib/typescript/commonjs/theme/native-root-vars.web.d.ts +20 -0
  270. package/lib/typescript/commonjs/theme/native-root-vars.web.d.ts.map +1 -0
  271. package/lib/typescript/commonjs/theme/preset-vars.d.ts.map +1 -1
  272. package/lib/typescript/module/alert-dialog/AlertDialog.d.ts +21 -0
  273. package/lib/typescript/module/alert-dialog/AlertDialog.d.ts.map +1 -0
  274. package/lib/typescript/module/alert-dialog/AlertDialogHost.d.ts +15 -0
  275. package/lib/typescript/module/alert-dialog/AlertDialogHost.d.ts.map +1 -0
  276. package/lib/typescript/module/alert-dialog/confirm-store.d.ts +31 -0
  277. package/lib/typescript/module/alert-dialog/confirm-store.d.ts.map +1 -0
  278. package/lib/typescript/module/alert-dialog/index.d.ts +8 -0
  279. package/lib/typescript/module/alert-dialog/index.d.ts.map +1 -0
  280. package/lib/typescript/module/alert-dialog/index.web.d.ts +8 -0
  281. package/lib/typescript/module/alert-dialog/index.web.d.ts.map +1 -0
  282. package/lib/typescript/module/alert-dialog/types.d.ts +44 -0
  283. package/lib/typescript/module/alert-dialog/types.d.ts.map +1 -0
  284. package/lib/typescript/module/combobox/Combobox.d.ts +33 -0
  285. package/lib/typescript/module/combobox/Combobox.d.ts.map +1 -0
  286. package/lib/typescript/module/combobox/index.d.ts +6 -0
  287. package/lib/typescript/module/combobox/index.d.ts.map +1 -0
  288. package/lib/typescript/module/combobox/index.web.d.ts +6 -0
  289. package/lib/typescript/module/combobox/index.web.d.ts.map +1 -0
  290. package/lib/typescript/module/combobox/types.d.ts +40 -0
  291. package/lib/typescript/module/combobox/types.d.ts.map +1 -0
  292. package/lib/typescript/module/command/Command.d.ts +22 -0
  293. package/lib/typescript/module/command/Command.d.ts.map +1 -0
  294. package/lib/typescript/module/command/index.d.ts +6 -0
  295. package/lib/typescript/module/command/index.d.ts.map +1 -0
  296. package/lib/typescript/module/command/index.web.d.ts +6 -0
  297. package/lib/typescript/module/command/index.web.d.ts.map +1 -0
  298. package/lib/typescript/module/command/types.d.ts +46 -0
  299. package/lib/typescript/module/command/types.d.ts.map +1 -0
  300. package/lib/typescript/module/field/Field.d.ts +4 -0
  301. package/lib/typescript/module/field/Field.d.ts.map +1 -0
  302. package/lib/typescript/module/field/index.d.ts +3 -0
  303. package/lib/typescript/module/field/index.d.ts.map +1 -0
  304. package/lib/typescript/module/field/types.d.ts +26 -0
  305. package/lib/typescript/module/field/types.d.ts.map +1 -0
  306. package/lib/typescript/module/icons/common.d.ts +8 -8
  307. package/lib/typescript/module/index.d.ts +19 -0
  308. package/lib/typescript/module/index.d.ts.map +1 -1
  309. package/lib/typescript/module/index.web.d.ts +19 -0
  310. package/lib/typescript/module/index.web.d.ts.map +1 -1
  311. package/lib/typescript/module/input-group/InputGroup.d.ts +9 -0
  312. package/lib/typescript/module/input-group/InputGroup.d.ts.map +1 -0
  313. package/lib/typescript/module/input-group/index.d.ts +3 -0
  314. package/lib/typescript/module/input-group/index.d.ts.map +1 -0
  315. package/lib/typescript/module/input-group/types.d.ts +35 -0
  316. package/lib/typescript/module/input-group/types.d.ts.map +1 -0
  317. package/lib/typescript/module/item/Item.d.ts +4 -0
  318. package/lib/typescript/module/item/Item.d.ts.map +1 -0
  319. package/lib/typescript/module/item/index.d.ts +3 -0
  320. package/lib/typescript/module/item/index.d.ts.map +1 -0
  321. package/lib/typescript/module/item/types.d.ts +45 -0
  322. package/lib/typescript/module/item/types.d.ts.map +1 -0
  323. package/lib/typescript/module/kbd/Kbd.d.ts +4 -0
  324. package/lib/typescript/module/kbd/Kbd.d.ts.map +1 -0
  325. package/lib/typescript/module/kbd/index.d.ts +3 -0
  326. package/lib/typescript/module/kbd/index.d.ts.map +1 -0
  327. package/lib/typescript/module/kbd/types.d.ts +13 -0
  328. package/lib/typescript/module/kbd/types.d.ts.map +1 -0
  329. package/lib/typescript/module/label/Label.d.ts +4 -0
  330. package/lib/typescript/module/label/Label.d.ts.map +1 -0
  331. package/lib/typescript/module/label/index.d.ts +3 -0
  332. package/lib/typescript/module/label/index.d.ts.map +1 -0
  333. package/lib/typescript/module/label/types.d.ts +27 -0
  334. package/lib/typescript/module/label/types.d.ts.map +1 -0
  335. package/lib/typescript/module/popover/context.d.ts +15 -0
  336. package/lib/typescript/module/popover/context.d.ts.map +1 -0
  337. package/lib/typescript/module/popover/index.d.ts +14 -0
  338. package/lib/typescript/module/popover/index.d.ts.map +1 -0
  339. package/lib/typescript/module/popover/index.web.d.ts +14 -0
  340. package/lib/typescript/module/popover/index.web.d.ts.map +1 -0
  341. package/lib/typescript/module/popover/types.d.ts +54 -0
  342. package/lib/typescript/module/popover/types.d.ts.map +1 -0
  343. package/lib/typescript/module/slider/Slider.d.ts +4 -0
  344. package/lib/typescript/module/slider/Slider.d.ts.map +1 -0
  345. package/lib/typescript/module/slider/index.d.ts +3 -0
  346. package/lib/typescript/module/slider/index.d.ts.map +1 -0
  347. package/lib/typescript/module/slider/types.d.ts +30 -0
  348. package/lib/typescript/module/slider/types.d.ts.map +1 -0
  349. package/lib/typescript/module/theme/BloomThemeProvider.d.ts.map +1 -1
  350. package/lib/typescript/module/theme/color-scope/index.d.ts +9 -2
  351. package/lib/typescript/module/theme/color-scope/index.d.ts.map +1 -1
  352. package/lib/typescript/module/theme/color-scope/style-builder.d.ts +32 -0
  353. package/lib/typescript/module/theme/color-scope/style-builder.d.ts.map +1 -1
  354. package/lib/typescript/module/theme/native-root-vars.d.ts +89 -0
  355. package/lib/typescript/module/theme/native-root-vars.d.ts.map +1 -0
  356. package/lib/typescript/module/theme/native-root-vars.web.d.ts +20 -0
  357. package/lib/typescript/module/theme/native-root-vars.web.d.ts.map +1 -0
  358. package/lib/typescript/module/theme/preset-vars.d.ts.map +1 -1
  359. package/package.json +141 -1
  360. package/src/__tests__/Field.test.tsx +55 -0
  361. package/src/__tests__/InputGroup.test.tsx +44 -0
  362. package/src/__tests__/Item.test.tsx +73 -0
  363. package/src/__tests__/Kbd.test.tsx +27 -0
  364. package/src/__tests__/Label.test.tsx +30 -0
  365. package/src/__tests__/Slider.test.tsx +38 -0
  366. package/src/__tests__/confirm-store.test.ts +58 -0
  367. package/src/__tests__/native-root-vars.test.ts +125 -0
  368. package/src/alert-dialog/AlertDialog.stories.tsx +61 -0
  369. package/src/alert-dialog/AlertDialog.tsx +120 -0
  370. package/src/alert-dialog/AlertDialogHost.tsx +51 -0
  371. package/src/alert-dialog/confirm-store.ts +77 -0
  372. package/src/alert-dialog/index.ts +13 -0
  373. package/src/alert-dialog/index.web.ts +13 -0
  374. package/src/alert-dialog/types.ts +46 -0
  375. package/src/combobox/Combobox.stories.tsx +40 -0
  376. package/src/combobox/Combobox.tsx +274 -0
  377. package/src/combobox/index.ts +6 -0
  378. package/src/combobox/index.web.ts +6 -0
  379. package/src/combobox/types.ts +41 -0
  380. package/src/command/Command.stories.tsx +60 -0
  381. package/src/command/Command.tsx +276 -0
  382. package/src/command/index.ts +6 -0
  383. package/src/command/index.web.ts +6 -0
  384. package/src/command/types.ts +47 -0
  385. package/src/field/Field.stories.tsx +54 -0
  386. package/src/field/Field.tsx +77 -0
  387. package/src/field/index.ts +2 -0
  388. package/src/field/types.ts +26 -0
  389. package/src/index.ts +23 -0
  390. package/src/index.web.ts +23 -0
  391. package/src/input-group/InputGroup.stories.tsx +65 -0
  392. package/src/input-group/InputGroup.tsx +184 -0
  393. package/src/input-group/index.ts +2 -0
  394. package/src/input-group/types.ts +36 -0
  395. package/src/item/Item.stories.tsx +43 -0
  396. package/src/item/Item.tsx +180 -0
  397. package/src/item/index.ts +2 -0
  398. package/src/item/types.ts +45 -0
  399. package/src/kbd/Kbd.stories.tsx +36 -0
  400. package/src/kbd/Kbd.tsx +76 -0
  401. package/src/kbd/index.ts +2 -0
  402. package/src/kbd/types.ts +13 -0
  403. package/src/label/Label.stories.tsx +32 -0
  404. package/src/label/Label.tsx +64 -0
  405. package/src/label/index.ts +2 -0
  406. package/src/label/types.ts +27 -0
  407. package/src/popover/Popover.stories.tsx +61 -0
  408. package/src/popover/context.ts +26 -0
  409. package/src/popover/index.tsx +104 -0
  410. package/src/popover/index.web.tsx +325 -0
  411. package/src/popover/types.ts +60 -0
  412. package/src/react-native-css.d.ts +69 -0
  413. package/src/slider/Slider.stories.tsx +46 -0
  414. package/src/slider/Slider.tsx +275 -0
  415. package/src/slider/index.ts +2 -0
  416. package/src/slider/types.ts +30 -0
  417. package/src/theme/BloomThemeProvider.tsx +32 -6
  418. package/src/theme/color-presets.ts +118 -118
  419. package/src/theme/color-scope/index.tsx +30 -8
  420. package/src/theme/color-scope/style-builder.ts +40 -0
  421. package/src/theme/native-root-vars.ts +102 -0
  422. package/src/theme/native-root-vars.web.ts +22 -0
  423. package/src/theme/preset-vars.ts +4 -1
@@ -0,0 +1,274 @@
1
+ import React, { useCallback, useMemo, useRef } from 'react';
2
+ import {
3
+ Platform,
4
+ Pressable,
5
+ ScrollView,
6
+ StyleSheet,
7
+ type TextInput,
8
+ View,
9
+ } from 'react-native';
10
+
11
+ import { useTheme } from '../theme/use-theme';
12
+ import { useControllableState } from '../hooks/useControllableState';
13
+ import { Text } from '../typography';
14
+ import { Item } from '../item';
15
+ import { SearchInput } from '../search-input';
16
+ import { borderRadius, fontSize, space } from '../styles/tokens';
17
+ import {
18
+ ChevronTopBottom_Stroke2_Corner0_Rounded as ChevronUpDownIcon,
19
+ } from '../icons/Chevron';
20
+ import { Check_Stroke2_Corner0_Rounded as CheckIcon } from '../icons/Check';
21
+ import type {
22
+ PopoverContentProps,
23
+ PopoverRootProps,
24
+ PopoverTriggerProps,
25
+ } from '../popover/types';
26
+ import type { usePopoverContext as usePopoverContextType } from '../popover/context';
27
+ import type { ComboboxOption, ComboboxProps } from './types';
28
+
29
+ /**
30
+ * Structural shape of the `Popover` module, satisfied by both the native and
31
+ * web platform forks. Defined explicitly (rather than `typeof import(...)`) so
32
+ * the slightly different render-return types between forks (web `Content` may
33
+ * return `null`) don't make the modules mutually unassignable.
34
+ */
35
+ interface PopoverModule {
36
+ Root: (props: PopoverRootProps) => React.ReactElement;
37
+ Trigger: (props: PopoverTriggerProps) => React.ReactElement;
38
+ Content: (props: PopoverContentProps) => React.ReactElement | null;
39
+ usePopoverContext: typeof usePopoverContextType;
40
+ }
41
+
42
+ function defaultFilter<T>(option: ComboboxOption<T>, query: string): boolean {
43
+ const q = query.trim().toLowerCase();
44
+ if (!q) return true;
45
+ return (
46
+ option.label.toLowerCase().includes(q) ||
47
+ (option.description?.toLowerCase().includes(q) ?? false)
48
+ );
49
+ }
50
+
51
+ /**
52
+ * Build the `Combobox` bound to a platform `Popover` module. The platform
53
+ * entry files (`index.ts` / `index.web.ts`) inject the correct one (native
54
+ * bottom sheet vs web anchored panel) — this repo never relies on implicit
55
+ * `.web` resolution. The combobox logic is single-source.
56
+ *
57
+ * `Combobox` is a filterable autocomplete select that delegates its overlay to
58
+ * Bloom's `Popover` and composes `SearchInput` + `Item`. The trigger + panel
59
+ * read the overlay control from `Popover` context (via an inner component) so
60
+ * selecting an option reliably closes the overlay on every platform.
61
+ */
62
+ export function createCombobox(Popover: PopoverModule) {
63
+ function ComboboxInner<T>({
64
+ options,
65
+ value,
66
+ onValueChange,
67
+ placeholder,
68
+ label,
69
+ emptyText,
70
+ filter,
71
+ query: queryProp,
72
+ onQueryChange,
73
+ disabled,
74
+ maxListHeight,
75
+ }: Required<
76
+ Pick<
77
+ ComboboxProps<T>,
78
+ 'options' | 'value' | 'onValueChange' | 'placeholder' | 'emptyText' | 'filter' | 'maxListHeight'
79
+ >
80
+ > &
81
+ Pick<ComboboxProps<T>, 'label' | 'query' | 'onQueryChange' | 'disabled'>) {
82
+ const theme = useTheme();
83
+ const { control } = Popover.usePopoverContext();
84
+ const searchRef = useRef<TextInput>(null);
85
+
86
+ const [query, setQuery] = useControllableState<string>({
87
+ value: queryProp,
88
+ defaultValue: '',
89
+ onChange: onQueryChange,
90
+ });
91
+
92
+ const selectedOption = useMemo(
93
+ () => options.find((o) => o.value === value) ?? null,
94
+ [options, value],
95
+ );
96
+
97
+ const filtered = useMemo(
98
+ () => options.filter((o) => filter(o, query)),
99
+ [options, filter, query],
100
+ );
101
+
102
+ const handleSelect = useCallback(
103
+ (option: ComboboxOption<T>) => {
104
+ if (option.disabled) return;
105
+ onValueChange(option.value);
106
+ setQuery('');
107
+ control.close();
108
+ },
109
+ [onValueChange, setQuery, control],
110
+ );
111
+
112
+ const accessibleLabel = label ?? placeholder;
113
+
114
+ return (
115
+ <>
116
+ <Popover.Trigger label={accessibleLabel}>
117
+ {({ props }) => (
118
+ <Pressable
119
+ {...props}
120
+ disabled={disabled}
121
+ onPress={() => {
122
+ if (disabled) return;
123
+ props.onPress();
124
+ if (Platform.OS === 'web') {
125
+ requestAnimationFrame(() => searchRef.current?.focus());
126
+ }
127
+ }}
128
+ accessibilityState={{ disabled: disabled ?? false }}
129
+ style={[
130
+ styles.trigger,
131
+ {
132
+ backgroundColor: theme.colors.contrast50,
133
+ borderColor: theme.colors.borderLight,
134
+ },
135
+ disabled && styles.disabled,
136
+ ]}>
137
+ <Text
138
+ numberOfLines={1}
139
+ style={[
140
+ styles.triggerText,
141
+ {
142
+ color: selectedOption
143
+ ? theme.colors.text
144
+ : theme.colors.textSecondary,
145
+ },
146
+ ]}>
147
+ {selectedOption ? selectedOption.label : placeholder}
148
+ </Text>
149
+ <ChevronUpDownIcon size="xs" fill={theme.colors.textSecondary} />
150
+ </Pressable>
151
+ )}
152
+ </Popover.Trigger>
153
+
154
+ <Popover.Content label={accessibleLabel} placement="bottom-start" minWidth={240}>
155
+ <View style={styles.searchWrap}>
156
+ <SearchInput
157
+ ref={searchRef}
158
+ label={label ?? 'Search'}
159
+ value={query}
160
+ onChangeText={setQuery}
161
+ onClearText={() => setQuery('')}
162
+ autoFocus={Platform.OS !== 'web'}
163
+ />
164
+ </View>
165
+
166
+ {filtered.length === 0 ? (
167
+ <View style={styles.empty}>
168
+ <Text style={{ color: theme.colors.textSecondary, fontSize: fontSize.sm }}>
169
+ {emptyText}
170
+ </Text>
171
+ </View>
172
+ ) : (
173
+ <ScrollView
174
+ style={{ maxHeight: maxListHeight }}
175
+ keyboardShouldPersistTaps="handled"
176
+ showsVerticalScrollIndicator={false}>
177
+ {filtered.map((option) => {
178
+ const isSelected = option.value === value;
179
+ return (
180
+ <Item
181
+ key={String(option.value)}
182
+ title={option.label}
183
+ subtitle={option.description}
184
+ density="compact"
185
+ disabled={option.disabled}
186
+ selected={isSelected}
187
+ role="option"
188
+ onPress={() => handleSelect(option)}
189
+ trailing={
190
+ isSelected ? (
191
+ <CheckIcon size="sm" fill={theme.colors.primary} />
192
+ ) : null
193
+ }
194
+ />
195
+ );
196
+ })}
197
+ </ScrollView>
198
+ )}
199
+ </Popover.Content>
200
+ </>
201
+ );
202
+ }
203
+
204
+ function Combobox<T = string>({
205
+ options,
206
+ value,
207
+ onValueChange,
208
+ placeholder = 'Select…',
209
+ label,
210
+ emptyText = 'No results',
211
+ filter = defaultFilter,
212
+ query,
213
+ onQueryChange,
214
+ disabled = false,
215
+ maxListHeight = 280,
216
+ style,
217
+ testID,
218
+ }: ComboboxProps<T>) {
219
+ return (
220
+ <Popover.Root>
221
+ <View style={style} testID={testID}>
222
+ <ComboboxInner<T>
223
+ options={options}
224
+ value={value}
225
+ onValueChange={onValueChange}
226
+ placeholder={placeholder}
227
+ label={label}
228
+ emptyText={emptyText}
229
+ filter={filter}
230
+ query={query}
231
+ onQueryChange={onQueryChange}
232
+ disabled={disabled}
233
+ maxListHeight={maxListHeight}
234
+ />
235
+ </View>
236
+ </Popover.Root>
237
+ );
238
+ }
239
+
240
+ Combobox.displayName = 'Combobox';
241
+ return Combobox;
242
+ }
243
+
244
+ const styles = StyleSheet.create({
245
+ trigger: {
246
+ flexDirection: 'row',
247
+ alignItems: 'center',
248
+ justifyContent: 'space-between',
249
+ gap: space.sm,
250
+ paddingVertical: space.sm,
251
+ paddingHorizontal: space.md,
252
+ borderRadius: borderRadius.sm,
253
+ borderWidth: 1,
254
+ minHeight: 44,
255
+ width: '100%',
256
+ },
257
+ triggerText: {
258
+ flex: 1,
259
+ fontSize: fontSize.md,
260
+ },
261
+ disabled: {
262
+ opacity: 0.5,
263
+ },
264
+ searchWrap: {
265
+ paddingHorizontal: space.sm,
266
+ paddingTop: space.sm,
267
+ paddingBottom: space.xs,
268
+ },
269
+ empty: {
270
+ paddingHorizontal: space.lg,
271
+ paddingVertical: space.lg,
272
+ alignItems: 'center',
273
+ },
274
+ });
@@ -0,0 +1,6 @@
1
+ import * as Popover from '../popover/index';
2
+ import { createCombobox } from './Combobox';
3
+
4
+ export const Combobox = createCombobox(Popover);
5
+
6
+ export type { ComboboxProps, ComboboxOption } from './types';
@@ -0,0 +1,6 @@
1
+ import * as Popover from '../popover/index.web';
2
+ import { createCombobox } from './Combobox';
3
+
4
+ export const Combobox = createCombobox(Popover);
5
+
6
+ export type { ComboboxProps, ComboboxOption } from './types';
@@ -0,0 +1,41 @@
1
+ import type { StyleProp, ViewStyle } from 'react-native';
2
+
3
+ export interface ComboboxOption<T = string> {
4
+ /** Stable value used for selection + comparison. */
5
+ value: T;
6
+ /** Display label. */
7
+ label: string;
8
+ /** Optional secondary text shown beneath the label. */
9
+ description?: string;
10
+ /** Disable selecting this option. */
11
+ disabled?: boolean;
12
+ }
13
+
14
+ export interface ComboboxProps<T = string> {
15
+ /** All selectable options. */
16
+ options: ComboboxOption<T>[];
17
+ /** Currently selected value (controlled). `null` = nothing selected. */
18
+ value: T | null;
19
+ /** Fired when the user picks an option. */
20
+ onValueChange: (value: T) => void;
21
+ /** Placeholder shown in the input when nothing is selected. */
22
+ placeholder?: string;
23
+ /** Accessible label for the input. Defaults to `placeholder` or `'Search'`. */
24
+ label?: string;
25
+ /** Text shown when the filtered list is empty. Defaults to `'No results'`. */
26
+ emptyText?: string;
27
+ /**
28
+ * Custom filter predicate. Defaults to a case-insensitive substring match
29
+ * against `label` and `description`.
30
+ */
31
+ filter?: (option: ComboboxOption<T>, query: string) => boolean;
32
+ /** Controlled query text. When omitted the combobox owns the query. */
33
+ query?: string;
34
+ /** Notified on query changes (works controlled or uncontrolled). */
35
+ onQueryChange?: (query: string) => void;
36
+ disabled?: boolean;
37
+ /** Max height of the option list in px. Defaults to `280`. */
38
+ maxListHeight?: number;
39
+ style?: StyleProp<ViewStyle>;
40
+ testID?: string;
41
+ }
@@ -0,0 +1,60 @@
1
+ import React, { useState } from 'react';
2
+ import { View } from 'react-native';
3
+ import type { Meta, StoryObj } from '@storybook/react-vite';
4
+
5
+ import { Command } from './index';
6
+ import type { CommandItem } from './types';
7
+ import { Button } from '../button';
8
+ import { Person_Stroke2_Corner0_Rounded as PersonIcon } from '../icons/Person';
9
+ import { SettingsGear2_Stroke2_Corner0_Rounded as GearIcon } from '../icons/SettingsGear2';
10
+
11
+ const meta: Meta = {
12
+ title: 'Overlays/Command',
13
+ };
14
+
15
+ export default meta;
16
+
17
+ type Story = StoryObj;
18
+
19
+ export const Basic: Story = {
20
+ render: () => {
21
+ const [open, setOpen] = useState(false);
22
+ const items: CommandItem[] = [
23
+ {
24
+ id: 'profile',
25
+ label: 'Go to profile',
26
+ icon: PersonIcon,
27
+ group: 'Navigation',
28
+ shortcut: 'G P',
29
+ onSelect: () => {},
30
+ },
31
+ {
32
+ id: 'settings',
33
+ label: 'Open settings',
34
+ icon: GearIcon,
35
+ group: 'Navigation',
36
+ onSelect: () => {},
37
+ },
38
+ {
39
+ id: 'new-app',
40
+ label: 'Create application',
41
+ description: 'Register a new OAuth client',
42
+ group: 'Actions',
43
+ keywords: ['oauth', 'client'],
44
+ onSelect: () => {},
45
+ },
46
+ {
47
+ id: 'signout',
48
+ label: 'Sign out',
49
+ group: 'Actions',
50
+ onSelect: () => {},
51
+ },
52
+ ];
53
+ return (
54
+ <View style={{ padding: 40 }}>
55
+ <Button onPress={() => setOpen(true)}>Open command palette (⌘K)</Button>
56
+ <Command visible={open} onClose={() => setOpen(false)} items={items} />
57
+ </View>
58
+ );
59
+ },
60
+ };
@@ -0,0 +1,276 @@
1
+ import React, { useCallback, useMemo, useRef, useState } from 'react';
2
+ import {
3
+ Platform,
4
+ ScrollView,
5
+ StyleSheet,
6
+ type TextInput,
7
+ View,
8
+ } from 'react-native';
9
+
10
+ import { useTheme } from '../theme/use-theme';
11
+ import { useControllableState } from '../hooks/useControllableState';
12
+ import { Text } from '../typography';
13
+ import { Item } from '../item';
14
+ import { Kbd } from '../kbd';
15
+ import { SearchInput } from '../search-input';
16
+ import { fontSize, space } from '../styles/tokens';
17
+ import type { CenteredDialogProps } from '../dialog';
18
+ import type { CommandItem, CommandProps } from './types';
19
+
20
+ type CenteredDialogComponent = React.ComponentType<CenteredDialogProps>;
21
+
22
+ function defaultFilter(item: CommandItem, query: string): boolean {
23
+ const q = query.trim().toLowerCase();
24
+ if (!q) return true;
25
+ if (item.label.toLowerCase().includes(q)) return true;
26
+ if (item.description?.toLowerCase().includes(q)) return true;
27
+ return (item.keywords ?? []).some((k) => k.toLowerCase().includes(q));
28
+ }
29
+
30
+ interface FlatEntry {
31
+ type: 'header' | 'item';
32
+ group?: string;
33
+ item?: CommandItem;
34
+ /** Index into the flat list of selectable items (only for `type === 'item'`). */
35
+ selectableIndex?: number;
36
+ }
37
+
38
+ /**
39
+ * Build the `Command` palette bound to a platform `CenteredDialog`. The
40
+ * platform entry files (`index.ts` / `index.web.ts`) inject the correct one
41
+ * (native RN `Modal` vs pure-DOM web overlay) — this repo never relies on
42
+ * implicit `.web` resolution. The body is single-source.
43
+ *
44
+ * `Command` is a ⌘K command palette built on Bloom's `CenteredDialog`,
45
+ * `SearchInput`, an `Item` results list and `Kbd` shortcut hints. Items group
46
+ * by their `group` field (ungrouped first). On web the list is
47
+ * keyboard-navigable (Up/Down/Enter); on native, tap to select.
48
+ */
49
+ export function createCommand(CenteredDialog: CenteredDialogComponent) {
50
+ const Command = function Command({
51
+ visible,
52
+ onClose,
53
+ items,
54
+ placeholder = 'Type a command or search…',
55
+ emptyText = 'No results found.',
56
+ query: queryProp,
57
+ onQueryChange,
58
+ filter = defaultFilter,
59
+ maxListHeight = 360,
60
+ style,
61
+ testID,
62
+ }: CommandProps) {
63
+ const theme = useTheme();
64
+ const searchRef = useRef<TextInput>(null);
65
+ const [activeIndex, setActiveIndex] = useState(0);
66
+
67
+ const [query, setQuery] = useControllableState<string>({
68
+ value: queryProp,
69
+ defaultValue: '',
70
+ onChange: onQueryChange,
71
+ });
72
+
73
+ const filtered = useMemo(
74
+ () => items.filter((it) => filter(it, query)),
75
+ [items, filter, query],
76
+ );
77
+
78
+ // Build a flattened render list with group headers, and a parallel list of
79
+ // just the selectable items for keyboard navigation.
80
+ const { entries, selectable } = useMemo(() => {
81
+ const groups = new Map<string, CommandItem[]>();
82
+ const ungrouped: CommandItem[] = [];
83
+ for (const it of filtered) {
84
+ if (it.group) {
85
+ const arr = groups.get(it.group) ?? [];
86
+ arr.push(it);
87
+ groups.set(it.group, arr);
88
+ } else {
89
+ ungrouped.push(it);
90
+ }
91
+ }
92
+
93
+ const flat: FlatEntry[] = [];
94
+ const sel: CommandItem[] = [];
95
+ const pushItem = (it: CommandItem) => {
96
+ flat.push({ type: 'item', item: it, selectableIndex: sel.length });
97
+ sel.push(it);
98
+ };
99
+
100
+ for (const it of ungrouped) pushItem(it);
101
+ for (const [group, arr] of groups) {
102
+ flat.push({ type: 'header', group });
103
+ for (const it of arr) pushItem(it);
104
+ }
105
+ return { entries: flat, selectable: sel };
106
+ }, [filtered]);
107
+
108
+ // Keep the active index in range as the filtered set changes. Reset to the
109
+ // first selectable item whenever the query changes (derive, no effect).
110
+ const prevQueryRef = useRef(query);
111
+ if (prevQueryRef.current !== query) {
112
+ prevQueryRef.current = query;
113
+ if (activeIndex !== 0) setActiveIndex(0);
114
+ }
115
+
116
+ // Reset the active index and focus the search field on the closed→open
117
+ // transition, derived from the `visible` prop (no effect). Focusing happens
118
+ // on the next frame so the dialog has mounted.
119
+ const prevVisibleRef = useRef(visible);
120
+ if (prevVisibleRef.current !== visible) {
121
+ prevVisibleRef.current = visible;
122
+ if (visible) {
123
+ if (activeIndex !== 0) setActiveIndex(0);
124
+ if (Platform.OS === 'web') {
125
+ requestAnimationFrame(() => searchRef.current?.focus());
126
+ }
127
+ }
128
+ }
129
+
130
+ const clampedActive = Math.min(activeIndex, Math.max(0, selectable.length - 1));
131
+
132
+ const select = useCallback(
133
+ (item: CommandItem | undefined) => {
134
+ if (!item || item.disabled) return;
135
+ item.onSelect();
136
+ setQuery('');
137
+ onClose();
138
+ },
139
+ [setQuery, onClose],
140
+ );
141
+
142
+ // Web keyboard navigation on the search input.
143
+ const webKeyHandler: Record<string, unknown> =
144
+ Platform.OS === 'web'
145
+ ? {
146
+ onKeyDown: (e: { key: string; preventDefault: () => void }) => {
147
+ if (selectable.length === 0) return;
148
+ switch (e.key) {
149
+ case 'ArrowDown':
150
+ e.preventDefault();
151
+ setActiveIndex((i) => (i + 1) % selectable.length);
152
+ break;
153
+ case 'ArrowUp':
154
+ e.preventDefault();
155
+ setActiveIndex(
156
+ (i) => (i - 1 + selectable.length) % selectable.length,
157
+ );
158
+ break;
159
+ case 'Enter':
160
+ e.preventDefault();
161
+ select(selectable[clampedActive]);
162
+ break;
163
+ default:
164
+ break;
165
+ }
166
+ },
167
+ }
168
+ : {};
169
+
170
+ return (
171
+ <CenteredDialog
172
+ visible={visible}
173
+ onClose={onClose}
174
+ dismissible
175
+ showClose={false}
176
+ maxWidth={560}
177
+ accessibilityLabel="Command palette"
178
+ cardStyle={style}
179
+ contentStyle={styles.content}
180
+ testID={testID}>
181
+ <View {...webKeyHandler}>
182
+ <View style={[styles.searchWrap, { borderBottomColor: theme.colors.borderLight }]}>
183
+ <SearchInput
184
+ ref={searchRef}
185
+ label={placeholder}
186
+ placeholder={placeholder}
187
+ value={query}
188
+ onChangeText={setQuery}
189
+ onClearText={() => setQuery('')}
190
+ autoFocus={Platform.OS !== 'web'}
191
+ />
192
+ </View>
193
+
194
+ {selectable.length === 0 ? (
195
+ <View style={styles.empty}>
196
+ <Text style={{ color: theme.colors.textSecondary, fontSize: fontSize.sm }}>
197
+ {emptyText}
198
+ </Text>
199
+ </View>
200
+ ) : (
201
+ <ScrollView
202
+ style={{ maxHeight: maxListHeight }}
203
+ keyboardShouldPersistTaps="handled"
204
+ showsVerticalScrollIndicator={false}>
205
+ {entries.map((entry, i) => {
206
+ if (entry.type === 'header') {
207
+ return (
208
+ <Text
209
+ key={`h-${entry.group}-${i}`}
210
+ style={[styles.groupHeader, { color: theme.colors.textTertiary }]}>
211
+ {entry.group}
212
+ </Text>
213
+ );
214
+ }
215
+ const item = entry.item;
216
+ if (!item) return null;
217
+ const Icon = item.icon;
218
+ const isActive = entry.selectableIndex === clampedActive;
219
+ return (
220
+ <Item
221
+ key={item.id}
222
+ title={item.label}
223
+ subtitle={item.description}
224
+ density="compact"
225
+ disabled={item.disabled}
226
+ active={isActive}
227
+ role="option"
228
+ onPress={() => select(item)}
229
+ leading={
230
+ Icon ? (
231
+ <Icon size="sm" fill={theme.colors.textSecondary} />
232
+ ) : null
233
+ }
234
+ trailing={item.shortcut ? <Kbd size="sm">{item.shortcut}</Kbd> : null}
235
+ />
236
+ );
237
+ })}
238
+ </ScrollView>
239
+ )}
240
+ </View>
241
+ </CenteredDialog>
242
+ );
243
+ };
244
+
245
+ Command.displayName = 'Command';
246
+ return Command;
247
+ }
248
+
249
+ export type CommandType = ReturnType<typeof createCommand>;
250
+
251
+ const styles = StyleSheet.create({
252
+ content: {
253
+ paddingHorizontal: 0,
254
+ paddingTop: 0,
255
+ paddingBottom: space.xs,
256
+ },
257
+ searchWrap: {
258
+ paddingHorizontal: space.md,
259
+ paddingTop: space.sm,
260
+ paddingBottom: space.sm,
261
+ borderBottomWidth: StyleSheet.hairlineWidth,
262
+ },
263
+ groupHeader: {
264
+ fontSize: fontSize.xs,
265
+ fontWeight: '600',
266
+ textTransform: 'uppercase',
267
+ letterSpacing: 0.6,
268
+ paddingHorizontal: space.lg,
269
+ paddingTop: space.sm,
270
+ paddingBottom: space.xs,
271
+ },
272
+ empty: {
273
+ paddingVertical: space._2xl,
274
+ alignItems: 'center',
275
+ },
276
+ });
@@ -0,0 +1,6 @@
1
+ import { CenteredDialog } from '../dialog/index';
2
+ import { createCommand } from './Command';
3
+
4
+ export const Command = createCommand(CenteredDialog);
5
+
6
+ export type { CommandProps, CommandItem } from './types';
@@ -0,0 +1,6 @@
1
+ import { CenteredDialog } from '../dialog/index.web';
2
+ import { createCommand } from './Command';
3
+
4
+ export const Command = createCommand(CenteredDialog);
5
+
6
+ export type { CommandProps, CommandItem } from './types';