@multiplatform.one/frappe-ui 7.23.1 → 7.24.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 (698) hide show
  1. package/dist/cjs/FrappeCalendar.cjs +1 -1
  2. package/dist/cjs/FrappeCalendar.native.js +1 -1
  3. package/dist/cjs/FrappeCalendar.native.js.map +1 -1
  4. package/dist/cjs/FrappeDashboard.cjs +1 -1
  5. package/dist/cjs/FrappeDashboard.native.js +1 -1
  6. package/dist/cjs/FrappeDashboard.native.js.map +1 -1
  7. package/dist/cjs/FrappeForm.cjs +8 -0
  8. package/dist/cjs/FrappeForm.native.js +9 -0
  9. package/dist/cjs/FrappeForm.native.js.map +1 -1
  10. package/dist/cjs/FrappeImageView.cjs +1 -1
  11. package/dist/cjs/FrappeImageView.native.js +1 -1
  12. package/dist/cjs/FrappeImageView.native.js.map +1 -1
  13. package/dist/cjs/FrappeInsights.cjs +380 -0
  14. package/dist/cjs/FrappeInsights.native.js +447 -0
  15. package/dist/cjs/FrappeInsights.native.js.map +1 -0
  16. package/dist/cjs/FrappeLikedBy.cjs +5 -2
  17. package/dist/cjs/FrappeLikedBy.native.js +5 -2
  18. package/dist/cjs/FrappeLikedBy.native.js.map +1 -1
  19. package/dist/cjs/FrappeListView.cjs +406 -39
  20. package/dist/cjs/FrappeListView.native.js +469 -42
  21. package/dist/cjs/FrappeListView.native.js.map +1 -1
  22. package/dist/cjs/FrappeNotConfigured.cjs +54 -0
  23. package/dist/cjs/FrappeNotConfigured.native.js +58 -0
  24. package/dist/cjs/FrappeNotConfigured.native.js.map +1 -0
  25. package/dist/cjs/FrappeRecordView.cjs +199 -0
  26. package/dist/cjs/FrappeRecordView.native.js +218 -0
  27. package/dist/cjs/FrappeRecordView.native.js.map +1 -0
  28. package/dist/cjs/FrappeReportBuilder.cjs +2 -2
  29. package/dist/cjs/FrappeReportBuilder.native.js +2 -2
  30. package/dist/cjs/FrappeReportBuilder.native.js.map +1 -1
  31. package/dist/cjs/FrappeReportView.cjs +1 -1
  32. package/dist/cjs/FrappeReportView.native.js +2 -2
  33. package/dist/cjs/FrappeReportView.native.js.map +1 -1
  34. package/dist/cjs/FrappeTreeView.cjs +1 -1
  35. package/dist/cjs/FrappeTreeView.native.js +1 -1
  36. package/dist/cjs/desk/awesomebar.cjs +1 -1
  37. package/dist/cjs/desk/awesomebar.native.js +3 -3
  38. package/dist/cjs/desk/awesomebar.native.js.map +1 -1
  39. package/dist/cjs/fields/CodeEditor/index.cjs +1 -1
  40. package/dist/cjs/fields/CodeEditor/index.native.js +1 -1
  41. package/dist/cjs/fields/CodeEditor/index.native.js.map +1 -1
  42. package/dist/cjs/fields/Color/index.cjs +1 -0
  43. package/dist/cjs/fields/Color/index.native.js +1 -0
  44. package/dist/cjs/fields/Color/index.native.js.map +1 -1
  45. package/dist/cjs/fields/FileUpload.cjs +1 -1
  46. package/dist/cjs/fields/FileUpload.native.js +1 -1
  47. package/dist/cjs/fields/FileUpload.native.js.map +1 -1
  48. package/dist/cjs/fields/Heading/index.cjs +19 -12
  49. package/dist/cjs/fields/Heading/index.native.js +22 -13
  50. package/dist/cjs/fields/Heading/index.native.js.map +1 -1
  51. package/dist/cjs/fields/MarkdownEditor/index.cjs +2 -1
  52. package/dist/cjs/fields/MarkdownEditor/index.native.js +1 -1
  53. package/dist/cjs/fields/MarkdownEditor/index.native.js.map +1 -1
  54. package/dist/cjs/frappeNavigation.cjs +12 -2
  55. package/dist/cjs/frappeNavigation.native.js +13 -2
  56. package/dist/cjs/frappeNavigation.native.js.map +1 -1
  57. package/dist/cjs/index.cjs +34 -0
  58. package/dist/cjs/index.native.js +34 -0
  59. package/dist/cjs/index.native.js.map +1 -1
  60. package/dist/cjs/insights/InsightsFacetTags.cjs +147 -0
  61. package/dist/cjs/insights/InsightsFacetTags.native.js +165 -0
  62. package/dist/cjs/insights/InsightsFacetTags.native.js.map +1 -0
  63. package/dist/cjs/insights/InsightsKpiBand.cjs +124 -0
  64. package/dist/cjs/insights/InsightsKpiBand.native.js +133 -0
  65. package/dist/cjs/insights/InsightsKpiBand.native.js.map +1 -0
  66. package/dist/cjs/insights/InsightsLeaders.cjs +150 -0
  67. package/dist/cjs/insights/InsightsLeaders.native.js +178 -0
  68. package/dist/cjs/insights/InsightsLeaders.native.js.map +1 -0
  69. package/dist/cjs/insights/InsightsRecords.cjs +105 -0
  70. package/dist/cjs/insights/InsightsRecords.native.js +109 -0
  71. package/dist/cjs/insights/InsightsRecords.native.js.map +1 -0
  72. package/dist/cjs/insights/InsightsTable.cjs +157 -0
  73. package/dist/cjs/insights/InsightsTable.native.js +194 -0
  74. package/dist/cjs/insights/InsightsTable.native.js.map +1 -0
  75. package/dist/cjs/insights/insightsData.cjs +114 -0
  76. package/dist/cjs/insights/insightsData.native.js +220 -0
  77. package/dist/cjs/insights/insightsData.native.js.map +1 -0
  78. package/dist/cjs/insights/insightsRecord.cjs +35 -0
  79. package/dist/cjs/insights/insightsRecord.native.js +38 -0
  80. package/dist/cjs/insights/insightsRecord.native.js.map +1 -0
  81. package/dist/cjs/list/FacetBadge.cjs +62 -0
  82. package/dist/cjs/list/FacetBadge.native.js +66 -0
  83. package/dist/cjs/list/FacetBadge.native.js.map +1 -0
  84. package/dist/cjs/list/FacetRail.cjs +199 -0
  85. package/dist/cjs/list/FacetRail.native.js +223 -0
  86. package/dist/cjs/list/FacetRail.native.js.map +1 -0
  87. package/dist/cjs/list/ImageWell.cjs +111 -0
  88. package/dist/cjs/list/ImageWell.native.js +126 -0
  89. package/dist/cjs/list/ImageWell.native.js.map +1 -0
  90. package/dist/cjs/list/ListControls.cjs +226 -0
  91. package/dist/cjs/list/ListControls.native.js +252 -0
  92. package/dist/cjs/list/ListControls.native.js.map +1 -0
  93. package/dist/cjs/list/ListToastHost.cjs +54 -0
  94. package/dist/cjs/list/ListToastHost.native.js +59 -0
  95. package/dist/cjs/list/ListToastHost.native.js.map +1 -0
  96. package/dist/cjs/list/RangeFilter.cjs +122 -0
  97. package/dist/cjs/list/RangeFilter.native.js +135 -0
  98. package/dist/cjs/list/RangeFilter.native.js.map +1 -0
  99. package/dist/cjs/list/RecordCard.cjs +233 -0
  100. package/dist/cjs/list/RecordCard.native.js +173 -0
  101. package/dist/cjs/list/RecordCard.native.js.map +1 -0
  102. package/dist/cjs/list/ShufflePanel.cjs +112 -0
  103. package/dist/cjs/list/ShufflePanel.native.js +139 -0
  104. package/dist/cjs/list/ShufflePanel.native.js.map +1 -0
  105. package/dist/cjs/list/facetReading.cjs +71 -0
  106. package/dist/cjs/list/facetReading.native.js +163 -0
  107. package/dist/cjs/list/facetReading.native.js.map +1 -0
  108. package/dist/cjs/list/favorites.cjs +79 -0
  109. package/dist/cjs/list/favorites.native.js +91 -0
  110. package/dist/cjs/list/favorites.native.js.map +1 -0
  111. package/dist/cjs/list/listState.cjs +100 -0
  112. package/dist/cjs/list/listState.native.js +234 -0
  113. package/dist/cjs/list/listState.native.js.map +1 -0
  114. package/dist/cjs/list/recordLook.cjs +35 -0
  115. package/dist/cjs/list/recordLook.native.js +39 -0
  116. package/dist/cjs/list/recordLook.native.js.map +1 -0
  117. package/dist/cjs/list/useListControls.cjs +189 -0
  118. package/dist/cjs/list/useListControls.native.js +272 -0
  119. package/dist/cjs/list/useListControls.native.js.map +1 -0
  120. package/dist/cjs/record/RecordBars.cjs +200 -0
  121. package/dist/cjs/record/RecordBars.native.js +225 -0
  122. package/dist/cjs/record/RecordBars.native.js.map +1 -0
  123. package/dist/cjs/record/RecordGallery.cjs +67 -0
  124. package/dist/cjs/record/RecordGallery.native.js +75 -0
  125. package/dist/cjs/record/RecordGallery.native.js.map +1 -0
  126. package/dist/cjs/record/RecordHero.cjs +239 -0
  127. package/dist/cjs/record/RecordHero.native.js +250 -0
  128. package/dist/cjs/record/RecordHero.native.js.map +1 -0
  129. package/dist/cjs/record/RecordPage.cjs +330 -0
  130. package/dist/cjs/record/RecordPage.native.js +364 -0
  131. package/dist/cjs/record/RecordPage.native.js.map +1 -0
  132. package/dist/cjs/record/RecordPager.cjs +125 -0
  133. package/dist/cjs/record/RecordPager.native.js +130 -0
  134. package/dist/cjs/record/RecordPager.native.js.map +1 -0
  135. package/dist/cjs/record/RecordRows.cjs +126 -0
  136. package/dist/cjs/record/RecordRows.native.js +140 -0
  137. package/dist/cjs/record/RecordRows.native.js.map +1 -0
  138. package/dist/cjs/record/recordData.cjs +122 -0
  139. package/dist/cjs/record/recordData.native.js +189 -0
  140. package/dist/cjs/record/recordData.native.js.map +1 -0
  141. package/dist/cjs/record/recordSections.cjs +30 -0
  142. package/dist/cjs/record/recordSections.native.js +33 -0
  143. package/dist/cjs/record/recordSections.native.js.map +1 -0
  144. package/dist/cjs/useFrappeFacets.cjs +1 -1
  145. package/dist/cjs/useFrappeFacets.native.js +1 -1
  146. package/dist/cjs/useFrappeFacets.native.js.map +1 -1
  147. package/dist/esm/FrappeCalendar.mjs +1 -1
  148. package/dist/esm/FrappeCalendar.mjs.map +1 -1
  149. package/dist/esm/FrappeCalendar.native.js +1 -1
  150. package/dist/esm/FrappeCalendar.native.js.map +1 -1
  151. package/dist/esm/FrappeDashboard.mjs +1 -1
  152. package/dist/esm/FrappeDashboard.mjs.map +1 -1
  153. package/dist/esm/FrappeDashboard.native.js +1 -1
  154. package/dist/esm/FrappeDashboard.native.js.map +1 -1
  155. package/dist/esm/FrappeForm.mjs +8 -0
  156. package/dist/esm/FrappeForm.mjs.map +1 -1
  157. package/dist/esm/FrappeForm.native.js +9 -0
  158. package/dist/esm/FrappeForm.native.js.map +1 -1
  159. package/dist/esm/FrappeImageView.mjs +1 -1
  160. package/dist/esm/FrappeImageView.mjs.map +1 -1
  161. package/dist/esm/FrappeImageView.native.js +1 -1
  162. package/dist/esm/FrappeImageView.native.js.map +1 -1
  163. package/dist/esm/FrappeInsights.mjs +355 -0
  164. package/dist/esm/FrappeInsights.mjs.map +1 -0
  165. package/dist/esm/FrappeInsights.native.js +419 -0
  166. package/dist/esm/FrappeInsights.native.js.map +1 -0
  167. package/dist/esm/FrappeLikedBy.mjs +6 -3
  168. package/dist/esm/FrappeLikedBy.mjs.map +1 -1
  169. package/dist/esm/FrappeLikedBy.native.js +6 -3
  170. package/dist/esm/FrappeLikedBy.native.js.map +1 -1
  171. package/dist/esm/FrappeListView.mjs +410 -43
  172. package/dist/esm/FrappeListView.mjs.map +1 -1
  173. package/dist/esm/FrappeListView.native.js +473 -46
  174. package/dist/esm/FrappeListView.native.js.map +1 -1
  175. package/dist/esm/FrappeNotConfigured.mjs +29 -0
  176. package/dist/esm/FrappeNotConfigured.mjs.map +1 -0
  177. package/dist/esm/FrappeNotConfigured.native.js +30 -0
  178. package/dist/esm/FrappeNotConfigured.native.js.map +1 -0
  179. package/dist/esm/FrappeRecordView.mjs +174 -0
  180. package/dist/esm/FrappeRecordView.mjs.map +1 -0
  181. package/dist/esm/FrappeRecordView.native.js +190 -0
  182. package/dist/esm/FrappeRecordView.native.js.map +1 -0
  183. package/dist/esm/FrappeReportBuilder.mjs +2 -2
  184. package/dist/esm/FrappeReportBuilder.mjs.map +1 -1
  185. package/dist/esm/FrappeReportBuilder.native.js +2 -2
  186. package/dist/esm/FrappeReportBuilder.native.js.map +1 -1
  187. package/dist/esm/FrappeReportView.mjs +1 -1
  188. package/dist/esm/FrappeReportView.mjs.map +1 -1
  189. package/dist/esm/FrappeReportView.native.js +2 -2
  190. package/dist/esm/FrappeReportView.native.js.map +1 -1
  191. package/dist/esm/FrappeTreeView.mjs +1 -1
  192. package/dist/esm/FrappeTreeView.mjs.map +1 -1
  193. package/dist/esm/FrappeTreeView.native.js +1 -1
  194. package/dist/esm/desk/awesomebar.mjs +1 -1
  195. package/dist/esm/desk/awesomebar.mjs.map +1 -1
  196. package/dist/esm/desk/awesomebar.native.js +3 -3
  197. package/dist/esm/desk/awesomebar.native.js.map +1 -1
  198. package/dist/esm/fields/CodeEditor/index.mjs +2 -2
  199. package/dist/esm/fields/CodeEditor/index.mjs.map +1 -1
  200. package/dist/esm/fields/CodeEditor/index.native.js +2 -2
  201. package/dist/esm/fields/CodeEditor/index.native.js.map +1 -1
  202. package/dist/esm/fields/Color/index.mjs +1 -0
  203. package/dist/esm/fields/Color/index.mjs.map +1 -1
  204. package/dist/esm/fields/Color/index.native.js +1 -0
  205. package/dist/esm/fields/Color/index.native.js.map +1 -1
  206. package/dist/esm/fields/FileUpload.mjs +2 -2
  207. package/dist/esm/fields/FileUpload.mjs.map +1 -1
  208. package/dist/esm/fields/FileUpload.native.js +2 -2
  209. package/dist/esm/fields/FileUpload.native.js.map +1 -1
  210. package/dist/esm/fields/Heading/index.mjs +21 -14
  211. package/dist/esm/fields/Heading/index.mjs.map +1 -1
  212. package/dist/esm/fields/Heading/index.native.js +24 -15
  213. package/dist/esm/fields/Heading/index.native.js.map +1 -1
  214. package/dist/esm/fields/MarkdownEditor/index.mjs +2 -1
  215. package/dist/esm/fields/MarkdownEditor/index.mjs.map +1 -1
  216. package/dist/esm/fields/MarkdownEditor/index.native.js +2 -2
  217. package/dist/esm/fields/MarkdownEditor/index.native.js.map +1 -1
  218. package/dist/esm/frappeNavigation.mjs +11 -2
  219. package/dist/esm/frappeNavigation.mjs.map +1 -1
  220. package/dist/esm/frappeNavigation.native.js +12 -2
  221. package/dist/esm/frappeNavigation.native.js.map +1 -1
  222. package/dist/esm/index.mjs +14 -2
  223. package/dist/esm/index.mjs.map +1 -1
  224. package/dist/esm/index.native.js +14 -2
  225. package/dist/esm/index.native.js.map +1 -1
  226. package/dist/esm/insights/InsightsFacetTags.mjs +122 -0
  227. package/dist/esm/insights/InsightsFacetTags.mjs.map +1 -0
  228. package/dist/esm/insights/InsightsFacetTags.native.js +137 -0
  229. package/dist/esm/insights/InsightsFacetTags.native.js.map +1 -0
  230. package/dist/esm/insights/InsightsKpiBand.mjs +99 -0
  231. package/dist/esm/insights/InsightsKpiBand.mjs.map +1 -0
  232. package/dist/esm/insights/InsightsKpiBand.native.js +105 -0
  233. package/dist/esm/insights/InsightsKpiBand.native.js.map +1 -0
  234. package/dist/esm/insights/InsightsLeaders.mjs +125 -0
  235. package/dist/esm/insights/InsightsLeaders.mjs.map +1 -0
  236. package/dist/esm/insights/InsightsLeaders.native.js +150 -0
  237. package/dist/esm/insights/InsightsLeaders.native.js.map +1 -0
  238. package/dist/esm/insights/InsightsRecords.mjs +80 -0
  239. package/dist/esm/insights/InsightsRecords.mjs.map +1 -0
  240. package/dist/esm/insights/InsightsRecords.native.js +81 -0
  241. package/dist/esm/insights/InsightsRecords.native.js.map +1 -0
  242. package/dist/esm/insights/InsightsTable.mjs +132 -0
  243. package/dist/esm/insights/InsightsTable.mjs.map +1 -0
  244. package/dist/esm/insights/InsightsTable.native.js +166 -0
  245. package/dist/esm/insights/InsightsTable.native.js.map +1 -0
  246. package/dist/esm/insights/insightsData.mjs +82 -0
  247. package/dist/esm/insights/insightsData.mjs.map +1 -0
  248. package/dist/esm/insights/insightsData.native.js +185 -0
  249. package/dist/esm/insights/insightsData.native.js.map +1 -0
  250. package/dist/esm/insights/insightsRecord.mjs +9 -0
  251. package/dist/esm/insights/insightsRecord.mjs.map +1 -0
  252. package/dist/esm/insights/insightsRecord.native.js +9 -0
  253. package/dist/esm/insights/insightsRecord.native.js.map +1 -0
  254. package/dist/esm/list/FacetBadge.mjs +37 -0
  255. package/dist/esm/list/FacetBadge.mjs.map +1 -0
  256. package/dist/esm/list/FacetBadge.native.js +38 -0
  257. package/dist/esm/list/FacetBadge.native.js.map +1 -0
  258. package/dist/esm/list/FacetRail.mjs +174 -0
  259. package/dist/esm/list/FacetRail.mjs.map +1 -0
  260. package/dist/esm/list/FacetRail.native.js +195 -0
  261. package/dist/esm/list/FacetRail.native.js.map +1 -0
  262. package/dist/esm/list/ImageWell.mjs +86 -0
  263. package/dist/esm/list/ImageWell.mjs.map +1 -0
  264. package/dist/esm/list/ImageWell.native.js +98 -0
  265. package/dist/esm/list/ImageWell.native.js.map +1 -0
  266. package/dist/esm/list/ListControls.mjs +201 -0
  267. package/dist/esm/list/ListControls.mjs.map +1 -0
  268. package/dist/esm/list/ListControls.native.js +224 -0
  269. package/dist/esm/list/ListControls.native.js.map +1 -0
  270. package/dist/esm/list/ListToastHost.mjs +18 -0
  271. package/dist/esm/list/ListToastHost.mjs.map +1 -0
  272. package/dist/esm/list/ListToastHost.native.js +20 -0
  273. package/dist/esm/list/ListToastHost.native.js.map +1 -0
  274. package/dist/esm/list/RangeFilter.mjs +85 -0
  275. package/dist/esm/list/RangeFilter.mjs.map +1 -0
  276. package/dist/esm/list/RangeFilter.native.js +95 -0
  277. package/dist/esm/list/RangeFilter.native.js.map +1 -0
  278. package/dist/esm/list/RecordCard.mjs +208 -0
  279. package/dist/esm/list/RecordCard.mjs.map +1 -0
  280. package/dist/esm/list/RecordCard.native.js +145 -0
  281. package/dist/esm/list/RecordCard.native.js.map +1 -0
  282. package/dist/esm/list/ShufflePanel.mjs +87 -0
  283. package/dist/esm/list/ShufflePanel.mjs.map +1 -0
  284. package/dist/esm/list/ShufflePanel.native.js +111 -0
  285. package/dist/esm/list/ShufflePanel.native.js.map +1 -0
  286. package/dist/esm/list/facetReading.mjs +45 -0
  287. package/dist/esm/list/facetReading.mjs.map +1 -0
  288. package/dist/esm/list/facetReading.native.js +134 -0
  289. package/dist/esm/list/facetReading.native.js.map +1 -0
  290. package/dist/esm/list/favorites.mjs +50 -0
  291. package/dist/esm/list/favorites.mjs.map +1 -0
  292. package/dist/esm/list/favorites.native.js +59 -0
  293. package/dist/esm/list/favorites.native.js.map +1 -0
  294. package/dist/esm/list/listState.mjs +71 -0
  295. package/dist/esm/list/listState.mjs.map +1 -0
  296. package/dist/esm/list/listState.native.js +202 -0
  297. package/dist/esm/list/listState.native.js.map +1 -0
  298. package/dist/esm/list/recordLook.mjs +10 -0
  299. package/dist/esm/list/recordLook.mjs.map +1 -0
  300. package/dist/esm/list/recordLook.native.js +11 -0
  301. package/dist/esm/list/recordLook.native.js.map +1 -0
  302. package/dist/esm/list/useListControls.mjs +164 -0
  303. package/dist/esm/list/useListControls.mjs.map +1 -0
  304. package/dist/esm/list/useListControls.native.js +244 -0
  305. package/dist/esm/list/useListControls.native.js.map +1 -0
  306. package/dist/esm/record/RecordBars.mjs +175 -0
  307. package/dist/esm/record/RecordBars.mjs.map +1 -0
  308. package/dist/esm/record/RecordBars.native.js +197 -0
  309. package/dist/esm/record/RecordBars.native.js.map +1 -0
  310. package/dist/esm/record/RecordGallery.mjs +42 -0
  311. package/dist/esm/record/RecordGallery.mjs.map +1 -0
  312. package/dist/esm/record/RecordGallery.native.js +47 -0
  313. package/dist/esm/record/RecordGallery.native.js.map +1 -0
  314. package/dist/esm/record/RecordHero.mjs +205 -0
  315. package/dist/esm/record/RecordHero.mjs.map +1 -0
  316. package/dist/esm/record/RecordHero.native.js +213 -0
  317. package/dist/esm/record/RecordHero.native.js.map +1 -0
  318. package/dist/esm/record/RecordPage.mjs +305 -0
  319. package/dist/esm/record/RecordPage.mjs.map +1 -0
  320. package/dist/esm/record/RecordPage.native.js +336 -0
  321. package/dist/esm/record/RecordPage.native.js.map +1 -0
  322. package/dist/esm/record/RecordPager.mjs +100 -0
  323. package/dist/esm/record/RecordPager.mjs.map +1 -0
  324. package/dist/esm/record/RecordPager.native.js +102 -0
  325. package/dist/esm/record/RecordPager.native.js.map +1 -0
  326. package/dist/esm/record/RecordRows.mjs +101 -0
  327. package/dist/esm/record/RecordRows.mjs.map +1 -0
  328. package/dist/esm/record/RecordRows.native.js +112 -0
  329. package/dist/esm/record/RecordRows.native.js.map +1 -0
  330. package/dist/esm/record/recordData.mjs +92 -0
  331. package/dist/esm/record/recordData.mjs.map +1 -0
  332. package/dist/esm/record/recordData.native.js +156 -0
  333. package/dist/esm/record/recordData.native.js.map +1 -0
  334. package/dist/esm/record/recordSections.mjs +5 -0
  335. package/dist/esm/record/recordSections.mjs.map +1 -0
  336. package/dist/esm/record/recordSections.native.js +5 -0
  337. package/dist/esm/record/recordSections.native.js.map +1 -0
  338. package/dist/esm/useFrappeFacets.mjs +1 -1
  339. package/dist/esm/useFrappeFacets.mjs.map +1 -1
  340. package/dist/esm/useFrappeFacets.native.js +1 -1
  341. package/dist/esm/useFrappeFacets.native.js.map +1 -1
  342. package/dist/jsx/FrappeCalendar.mjs +1 -1
  343. package/dist/jsx/FrappeCalendar.mjs.map +1 -1
  344. package/dist/jsx/FrappeCalendar.native.js +1 -1
  345. package/dist/jsx/FrappeCalendar.native.js.map +1 -1
  346. package/dist/jsx/FrappeDashboard.mjs +1 -1
  347. package/dist/jsx/FrappeDashboard.mjs.map +1 -1
  348. package/dist/jsx/FrappeDashboard.native.js +1 -1
  349. package/dist/jsx/FrappeDashboard.native.js.map +1 -1
  350. package/dist/jsx/FrappeForm.mjs +8 -0
  351. package/dist/jsx/FrappeForm.mjs.map +1 -1
  352. package/dist/jsx/FrappeForm.native.js +9 -0
  353. package/dist/jsx/FrappeForm.native.js.map +1 -1
  354. package/dist/jsx/FrappeImageView.mjs +1 -1
  355. package/dist/jsx/FrappeImageView.mjs.map +1 -1
  356. package/dist/jsx/FrappeImageView.native.js +1 -1
  357. package/dist/jsx/FrappeImageView.native.js.map +1 -1
  358. package/dist/jsx/FrappeInsights.mjs +355 -0
  359. package/dist/jsx/FrappeInsights.mjs.map +1 -0
  360. package/dist/jsx/FrappeInsights.native.js +447 -0
  361. package/dist/jsx/FrappeInsights.native.js.map +1 -0
  362. package/dist/jsx/FrappeLikedBy.mjs +6 -3
  363. package/dist/jsx/FrappeLikedBy.mjs.map +1 -1
  364. package/dist/jsx/FrappeLikedBy.native.js +5 -2
  365. package/dist/jsx/FrappeLikedBy.native.js.map +1 -1
  366. package/dist/jsx/FrappeListView.mjs +410 -43
  367. package/dist/jsx/FrappeListView.mjs.map +1 -1
  368. package/dist/jsx/FrappeListView.native.js +469 -42
  369. package/dist/jsx/FrappeListView.native.js.map +1 -1
  370. package/dist/jsx/FrappeNotConfigured.mjs +29 -0
  371. package/dist/jsx/FrappeNotConfigured.mjs.map +1 -0
  372. package/dist/jsx/FrappeNotConfigured.native.js +58 -0
  373. package/dist/jsx/FrappeNotConfigured.native.js.map +1 -0
  374. package/dist/jsx/FrappeRecordView.mjs +174 -0
  375. package/dist/jsx/FrappeRecordView.mjs.map +1 -0
  376. package/dist/jsx/FrappeRecordView.native.js +218 -0
  377. package/dist/jsx/FrappeRecordView.native.js.map +1 -0
  378. package/dist/jsx/FrappeReportBuilder.mjs +2 -2
  379. package/dist/jsx/FrappeReportBuilder.mjs.map +1 -1
  380. package/dist/jsx/FrappeReportBuilder.native.js +2 -2
  381. package/dist/jsx/FrappeReportBuilder.native.js.map +1 -1
  382. package/dist/jsx/FrappeReportView.mjs +1 -1
  383. package/dist/jsx/FrappeReportView.mjs.map +1 -1
  384. package/dist/jsx/FrappeReportView.native.js +2 -2
  385. package/dist/jsx/FrappeReportView.native.js.map +1 -1
  386. package/dist/jsx/FrappeTreeView.mjs +1 -1
  387. package/dist/jsx/FrappeTreeView.mjs.map +1 -1
  388. package/dist/jsx/FrappeTreeView.native.js +1 -1
  389. package/dist/jsx/desk/awesomebar.mjs +1 -1
  390. package/dist/jsx/desk/awesomebar.mjs.map +1 -1
  391. package/dist/jsx/desk/awesomebar.native.js +3 -3
  392. package/dist/jsx/desk/awesomebar.native.js.map +1 -1
  393. package/dist/jsx/fields/CodeEditor/index.mjs +2 -2
  394. package/dist/jsx/fields/CodeEditor/index.mjs.map +1 -1
  395. package/dist/jsx/fields/CodeEditor/index.native.js +1 -1
  396. package/dist/jsx/fields/CodeEditor/index.native.js.map +1 -1
  397. package/dist/jsx/fields/Color/index.mjs +1 -0
  398. package/dist/jsx/fields/Color/index.mjs.map +1 -1
  399. package/dist/jsx/fields/Color/index.native.js +1 -0
  400. package/dist/jsx/fields/Color/index.native.js.map +1 -1
  401. package/dist/jsx/fields/FileUpload.mjs +2 -2
  402. package/dist/jsx/fields/FileUpload.mjs.map +1 -1
  403. package/dist/jsx/fields/FileUpload.native.js +1 -1
  404. package/dist/jsx/fields/FileUpload.native.js.map +1 -1
  405. package/dist/jsx/fields/Heading/index.mjs +21 -14
  406. package/dist/jsx/fields/Heading/index.mjs.map +1 -1
  407. package/dist/jsx/fields/Heading/index.native.js +22 -13
  408. package/dist/jsx/fields/Heading/index.native.js.map +1 -1
  409. package/dist/jsx/fields/MarkdownEditor/index.mjs +2 -1
  410. package/dist/jsx/fields/MarkdownEditor/index.mjs.map +1 -1
  411. package/dist/jsx/fields/MarkdownEditor/index.native.js +1 -1
  412. package/dist/jsx/fields/MarkdownEditor/index.native.js.map +1 -1
  413. package/dist/jsx/frappeNavigation.mjs +11 -2
  414. package/dist/jsx/frappeNavigation.mjs.map +1 -1
  415. package/dist/jsx/frappeNavigation.native.js +13 -2
  416. package/dist/jsx/frappeNavigation.native.js.map +1 -1
  417. package/dist/jsx/index.js +14 -2
  418. package/dist/jsx/index.js.map +1 -1
  419. package/dist/jsx/index.mjs +14 -2
  420. package/dist/jsx/index.mjs.map +1 -1
  421. package/dist/jsx/index.native.js +34 -0
  422. package/dist/jsx/index.native.js.map +1 -1
  423. package/dist/jsx/insights/InsightsFacetTags.mjs +122 -0
  424. package/dist/jsx/insights/InsightsFacetTags.mjs.map +1 -0
  425. package/dist/jsx/insights/InsightsFacetTags.native.js +165 -0
  426. package/dist/jsx/insights/InsightsFacetTags.native.js.map +1 -0
  427. package/dist/jsx/insights/InsightsKpiBand.mjs +99 -0
  428. package/dist/jsx/insights/InsightsKpiBand.mjs.map +1 -0
  429. package/dist/jsx/insights/InsightsKpiBand.native.js +133 -0
  430. package/dist/jsx/insights/InsightsKpiBand.native.js.map +1 -0
  431. package/dist/jsx/insights/InsightsLeaders.mjs +125 -0
  432. package/dist/jsx/insights/InsightsLeaders.mjs.map +1 -0
  433. package/dist/jsx/insights/InsightsLeaders.native.js +178 -0
  434. package/dist/jsx/insights/InsightsLeaders.native.js.map +1 -0
  435. package/dist/jsx/insights/InsightsRecords.mjs +80 -0
  436. package/dist/jsx/insights/InsightsRecords.mjs.map +1 -0
  437. package/dist/jsx/insights/InsightsRecords.native.js +109 -0
  438. package/dist/jsx/insights/InsightsRecords.native.js.map +1 -0
  439. package/dist/jsx/insights/InsightsTable.mjs +132 -0
  440. package/dist/jsx/insights/InsightsTable.mjs.map +1 -0
  441. package/dist/jsx/insights/InsightsTable.native.js +194 -0
  442. package/dist/jsx/insights/InsightsTable.native.js.map +1 -0
  443. package/dist/jsx/insights/insightsData.mjs +82 -0
  444. package/dist/jsx/insights/insightsData.mjs.map +1 -0
  445. package/dist/jsx/insights/insightsData.native.js +220 -0
  446. package/dist/jsx/insights/insightsData.native.js.map +1 -0
  447. package/dist/jsx/insights/insightsRecord.mjs +9 -0
  448. package/dist/jsx/insights/insightsRecord.mjs.map +1 -0
  449. package/dist/jsx/insights/insightsRecord.native.js +38 -0
  450. package/dist/jsx/insights/insightsRecord.native.js.map +1 -0
  451. package/dist/jsx/list/FacetBadge.mjs +37 -0
  452. package/dist/jsx/list/FacetBadge.mjs.map +1 -0
  453. package/dist/jsx/list/FacetBadge.native.js +66 -0
  454. package/dist/jsx/list/FacetBadge.native.js.map +1 -0
  455. package/dist/jsx/list/FacetRail.mjs +174 -0
  456. package/dist/jsx/list/FacetRail.mjs.map +1 -0
  457. package/dist/jsx/list/FacetRail.native.js +223 -0
  458. package/dist/jsx/list/FacetRail.native.js.map +1 -0
  459. package/dist/jsx/list/ImageWell.mjs +86 -0
  460. package/dist/jsx/list/ImageWell.mjs.map +1 -0
  461. package/dist/jsx/list/ImageWell.native.js +126 -0
  462. package/dist/jsx/list/ImageWell.native.js.map +1 -0
  463. package/dist/jsx/list/ListControls.mjs +201 -0
  464. package/dist/jsx/list/ListControls.mjs.map +1 -0
  465. package/dist/jsx/list/ListControls.native.js +252 -0
  466. package/dist/jsx/list/ListControls.native.js.map +1 -0
  467. package/dist/jsx/list/ListToastHost.mjs +18 -0
  468. package/dist/jsx/list/ListToastHost.mjs.map +1 -0
  469. package/dist/jsx/list/ListToastHost.native.js +59 -0
  470. package/dist/jsx/list/ListToastHost.native.js.map +1 -0
  471. package/dist/jsx/list/RangeFilter.mjs +85 -0
  472. package/dist/jsx/list/RangeFilter.mjs.map +1 -0
  473. package/dist/jsx/list/RangeFilter.native.js +135 -0
  474. package/dist/jsx/list/RangeFilter.native.js.map +1 -0
  475. package/dist/jsx/list/RecordCard.mjs +208 -0
  476. package/dist/jsx/list/RecordCard.mjs.map +1 -0
  477. package/dist/jsx/list/RecordCard.native.js +173 -0
  478. package/dist/jsx/list/RecordCard.native.js.map +1 -0
  479. package/dist/jsx/list/ShufflePanel.mjs +87 -0
  480. package/dist/jsx/list/ShufflePanel.mjs.map +1 -0
  481. package/dist/jsx/list/ShufflePanel.native.js +139 -0
  482. package/dist/jsx/list/ShufflePanel.native.js.map +1 -0
  483. package/dist/jsx/list/facetReading.mjs +45 -0
  484. package/dist/jsx/list/facetReading.mjs.map +1 -0
  485. package/dist/jsx/list/facetReading.native.js +163 -0
  486. package/dist/jsx/list/facetReading.native.js.map +1 -0
  487. package/dist/jsx/list/favorites.mjs +50 -0
  488. package/dist/jsx/list/favorites.mjs.map +1 -0
  489. package/dist/jsx/list/favorites.native.js +91 -0
  490. package/dist/jsx/list/favorites.native.js.map +1 -0
  491. package/dist/jsx/list/listState.mjs +71 -0
  492. package/dist/jsx/list/listState.mjs.map +1 -0
  493. package/dist/jsx/list/listState.native.js +234 -0
  494. package/dist/jsx/list/listState.native.js.map +1 -0
  495. package/dist/jsx/list/recordLook.mjs +10 -0
  496. package/dist/jsx/list/recordLook.mjs.map +1 -0
  497. package/dist/jsx/list/recordLook.native.js +39 -0
  498. package/dist/jsx/list/recordLook.native.js.map +1 -0
  499. package/dist/jsx/list/useListControls.mjs +164 -0
  500. package/dist/jsx/list/useListControls.mjs.map +1 -0
  501. package/dist/jsx/list/useListControls.native.js +272 -0
  502. package/dist/jsx/list/useListControls.native.js.map +1 -0
  503. package/dist/jsx/record/RecordBars.mjs +175 -0
  504. package/dist/jsx/record/RecordBars.mjs.map +1 -0
  505. package/dist/jsx/record/RecordBars.native.js +225 -0
  506. package/dist/jsx/record/RecordBars.native.js.map +1 -0
  507. package/dist/jsx/record/RecordGallery.mjs +42 -0
  508. package/dist/jsx/record/RecordGallery.mjs.map +1 -0
  509. package/dist/jsx/record/RecordGallery.native.js +75 -0
  510. package/dist/jsx/record/RecordGallery.native.js.map +1 -0
  511. package/dist/jsx/record/RecordHero.mjs +205 -0
  512. package/dist/jsx/record/RecordHero.mjs.map +1 -0
  513. package/dist/jsx/record/RecordHero.native.js +250 -0
  514. package/dist/jsx/record/RecordHero.native.js.map +1 -0
  515. package/dist/jsx/record/RecordPage.mjs +305 -0
  516. package/dist/jsx/record/RecordPage.mjs.map +1 -0
  517. package/dist/jsx/record/RecordPage.native.js +364 -0
  518. package/dist/jsx/record/RecordPage.native.js.map +1 -0
  519. package/dist/jsx/record/RecordPager.mjs +100 -0
  520. package/dist/jsx/record/RecordPager.mjs.map +1 -0
  521. package/dist/jsx/record/RecordPager.native.js +130 -0
  522. package/dist/jsx/record/RecordPager.native.js.map +1 -0
  523. package/dist/jsx/record/RecordRows.mjs +101 -0
  524. package/dist/jsx/record/RecordRows.mjs.map +1 -0
  525. package/dist/jsx/record/RecordRows.native.js +140 -0
  526. package/dist/jsx/record/RecordRows.native.js.map +1 -0
  527. package/dist/jsx/record/recordData.mjs +92 -0
  528. package/dist/jsx/record/recordData.mjs.map +1 -0
  529. package/dist/jsx/record/recordData.native.js +189 -0
  530. package/dist/jsx/record/recordData.native.js.map +1 -0
  531. package/dist/jsx/record/recordSections.mjs +5 -0
  532. package/dist/jsx/record/recordSections.mjs.map +1 -0
  533. package/dist/jsx/record/recordSections.native.js +33 -0
  534. package/dist/jsx/record/recordSections.native.js.map +1 -0
  535. package/dist/jsx/useFrappeFacets.mjs +1 -1
  536. package/dist/jsx/useFrappeFacets.mjs.map +1 -1
  537. package/dist/jsx/useFrappeFacets.native.js +1 -1
  538. package/dist/jsx/useFrappeFacets.native.js.map +1 -1
  539. package/package.json +16 -16
  540. package/src/FormSidebar.stories.tsx +2 -0
  541. package/src/FrappeCalendar.stories.tsx +2 -0
  542. package/src/FrappeCalendar.tsx +2 -2
  543. package/src/FrappeChartCard.stories.tsx +2 -0
  544. package/src/FrappeDashboard.stories.tsx +2 -0
  545. package/src/FrappeDashboard.tsx +2 -2
  546. package/src/FrappeForm.tsx +7 -1
  547. package/src/FrappeImageView.stories.tsx +2 -0
  548. package/src/FrappeImageView.tsx +2 -1
  549. package/src/FrappeInsights.spec.tsx +171 -0
  550. package/src/FrappeInsights.tsx +422 -0
  551. package/src/FrappeKPICard.stories.tsx +3 -3
  552. package/src/FrappeKanban.stories.tsx +4 -8
  553. package/src/FrappeLikedBy.tsx +7 -5
  554. package/src/FrappeListView.card.spec.tsx +157 -0
  555. package/src/FrappeListView.controls.spec.tsx +225 -0
  556. package/src/FrappeListView.seed.spec.tsx +30 -0
  557. package/src/FrappeListView.stories.tsx +2 -0
  558. package/src/FrappeListView.tsx +589 -45
  559. package/src/FrappeNotConfigured.tsx +29 -0
  560. package/src/FrappeRecordView.spec.tsx +276 -0
  561. package/src/FrappeRecordView.tsx +231 -0
  562. package/src/FrappeReportBuilder.tsx +4 -5
  563. package/src/FrappeReportView.tsx +1 -1
  564. package/src/FrappeTreeView.tsx +1 -1
  565. package/src/clientCache.auth.spec.tsx +94 -0
  566. package/src/desk/DeskFormSidebar.stories.tsx +2 -0
  567. package/src/desk/DeskShell.stories.tsx +12 -6
  568. package/src/desk/awesomebar.auth.spec.tsx +77 -0
  569. package/src/desk/awesomebar.tsx +1 -1
  570. package/src/fields/CodeEditor/index.tsx +8 -2
  571. package/src/fields/Color/Color.stories.tsx +2 -0
  572. package/src/fields/Color/index.tsx +1 -0
  573. package/src/fields/FileUpload.tsx +8 -2
  574. package/src/fields/Heading/index.tsx +41 -17
  575. package/src/fields/MarkdownEditor/index.native.tsx +8 -2
  576. package/src/fields/MarkdownEditor/index.tsx +8 -1
  577. package/src/fields/ReadOnly/ReadOnly.stories.tsx +2 -0
  578. package/src/frappeNavigation.loader.spec.tsx +45 -0
  579. package/src/frappeNavigation.tsx +32 -1
  580. package/src/frappeRoutes.notConfigured.spec.tsx +77 -0
  581. package/src/index.ts +53 -1
  582. package/src/insights/InsightsFacetTags.tsx +131 -0
  583. package/src/insights/InsightsKpiBand.tsx +114 -0
  584. package/src/insights/InsightsLeaders.tsx +146 -0
  585. package/src/insights/InsightsRecords.tsx +71 -0
  586. package/src/insights/InsightsTable.tsx +169 -0
  587. package/src/insights/insightsData.spec.ts +143 -0
  588. package/src/insights/insightsData.ts +122 -0
  589. package/src/insights/insightsRecord.ts +36 -0
  590. package/src/list/FacetBadge.tsx +41 -0
  591. package/src/list/FacetRail.tsx +235 -0
  592. package/src/list/ImageWell.tsx +110 -0
  593. package/src/list/ListControls.tsx +208 -0
  594. package/src/list/ListToastHost.tsx +27 -0
  595. package/src/list/RangeFilter.tsx +83 -0
  596. package/src/list/RecordCard.native.tsx +126 -0
  597. package/src/list/RecordCard.tsx +260 -0
  598. package/src/list/ShufflePanel.tsx +107 -0
  599. package/src/list/facetReading.ts +79 -0
  600. package/src/list/favorites.spec.ts +80 -0
  601. package/src/list/favorites.ts +79 -0
  602. package/src/list/listState.spec.ts +156 -0
  603. package/src/list/listState.ts +184 -0
  604. package/src/list/recordLook.ts +37 -0
  605. package/src/list/useListControls.tsx +223 -0
  606. package/src/record/RecordBars.tsx +187 -0
  607. package/src/record/RecordGallery.tsx +47 -0
  608. package/src/record/RecordHero.tsx +186 -0
  609. package/src/record/RecordPage.tsx +358 -0
  610. package/src/record/RecordPager.tsx +97 -0
  611. package/src/record/RecordRows.tsx +90 -0
  612. package/src/record/recordData.spec.ts +148 -0
  613. package/src/record/recordData.ts +124 -0
  614. package/src/record/recordSections.ts +62 -0
  615. package/src/schemaForm/SchemaForm.stories.tsx +2 -2
  616. package/src/useFrappeFacets.ts +14 -7
  617. package/types/FrappeForm.d.ts +2 -1
  618. package/types/FrappeForm.d.ts.map +1 -1
  619. package/types/FrappeImageView.d.ts.map +1 -1
  620. package/types/FrappeInsights.d.ts +55 -0
  621. package/types/FrappeInsights.d.ts.map +1 -0
  622. package/types/FrappeLikedBy.d.ts.map +1 -1
  623. package/types/FrappeListView.d.ts +85 -3
  624. package/types/FrappeListView.d.ts.map +1 -1
  625. package/types/FrappeNotConfigured.d.ts +11 -0
  626. package/types/FrappeNotConfigured.d.ts.map +1 -0
  627. package/types/FrappeRecordView.d.ts +69 -0
  628. package/types/FrappeRecordView.d.ts.map +1 -0
  629. package/types/FrappeReportBuilder.d.ts.map +1 -1
  630. package/types/fields/CodeEditor/index.d.ts.map +1 -1
  631. package/types/fields/Color/index.d.ts.map +1 -1
  632. package/types/fields/FileUpload.d.ts.map +1 -1
  633. package/types/fields/Heading/index.d.ts.map +1 -1
  634. package/types/fields/MarkdownEditor/index.d.ts.map +1 -1
  635. package/types/fields/MarkdownEditor/index.native.d.ts.map +1 -1
  636. package/types/frappeNavigation.d.ts +21 -0
  637. package/types/frappeNavigation.d.ts.map +1 -1
  638. package/types/index.d.ts +14 -2
  639. package/types/index.d.ts.map +1 -1
  640. package/types/insights/InsightsFacetTags.d.ts +11 -0
  641. package/types/insights/InsightsFacetTags.d.ts.map +1 -0
  642. package/types/insights/InsightsKpiBand.d.ts +22 -0
  643. package/types/insights/InsightsKpiBand.d.ts.map +1 -0
  644. package/types/insights/InsightsLeaders.d.ts +16 -0
  645. package/types/insights/InsightsLeaders.d.ts.map +1 -0
  646. package/types/insights/InsightsRecords.d.ts +19 -0
  647. package/types/insights/InsightsRecords.d.ts.map +1 -0
  648. package/types/insights/InsightsTable.d.ts +17 -0
  649. package/types/insights/InsightsTable.d.ts.map +1 -0
  650. package/types/insights/insightsData.d.ts +45 -0
  651. package/types/insights/insightsData.d.ts.map +1 -0
  652. package/types/insights/insightsRecord.d.ts +29 -0
  653. package/types/insights/insightsRecord.d.ts.map +1 -0
  654. package/types/list/FacetBadge.d.ts +13 -0
  655. package/types/list/FacetBadge.d.ts.map +1 -0
  656. package/types/list/FacetRail.d.ts +26 -0
  657. package/types/list/FacetRail.d.ts.map +1 -0
  658. package/types/list/ImageWell.d.ts +24 -0
  659. package/types/list/ImageWell.d.ts.map +1 -0
  660. package/types/list/ListControls.d.ts +30 -0
  661. package/types/list/ListControls.d.ts.map +1 -0
  662. package/types/list/ListToastHost.d.ts +7 -0
  663. package/types/list/ListToastHost.d.ts.map +1 -0
  664. package/types/list/RangeFilter.d.ts +14 -0
  665. package/types/list/RangeFilter.d.ts.map +1 -0
  666. package/types/list/RecordCard.d.ts +38 -0
  667. package/types/list/RecordCard.d.ts.map +1 -0
  668. package/types/list/RecordCard.native.d.ts +9 -0
  669. package/types/list/RecordCard.native.d.ts.map +1 -0
  670. package/types/list/ShufflePanel.d.ts +24 -0
  671. package/types/list/ShufflePanel.d.ts.map +1 -0
  672. package/types/list/facetReading.d.ts +33 -0
  673. package/types/list/facetReading.d.ts.map +1 -0
  674. package/types/list/favorites.d.ts +26 -0
  675. package/types/list/favorites.d.ts.map +1 -0
  676. package/types/list/listState.d.ts +94 -0
  677. package/types/list/listState.d.ts.map +1 -0
  678. package/types/list/recordLook.d.ts +25 -0
  679. package/types/list/recordLook.d.ts.map +1 -0
  680. package/types/list/useListControls.d.ts +48 -0
  681. package/types/list/useListControls.d.ts.map +1 -0
  682. package/types/record/RecordBars.d.ts +11 -0
  683. package/types/record/RecordBars.d.ts.map +1 -0
  684. package/types/record/RecordGallery.d.ts +17 -0
  685. package/types/record/RecordGallery.d.ts.map +1 -0
  686. package/types/record/RecordHero.d.ts +42 -0
  687. package/types/record/RecordHero.d.ts.map +1 -0
  688. package/types/record/RecordPage.d.ts +54 -0
  689. package/types/record/RecordPage.d.ts.map +1 -0
  690. package/types/record/RecordPager.d.ts +13 -0
  691. package/types/record/RecordPager.d.ts.map +1 -0
  692. package/types/record/RecordRows.d.ts +13 -0
  693. package/types/record/RecordRows.d.ts.map +1 -0
  694. package/types/record/recordData.d.ts +46 -0
  695. package/types/record/recordData.d.ts.map +1 -0
  696. package/types/record/recordSections.d.ts +67 -0
  697. package/types/record/recordSections.d.ts.map +1 -0
  698. package/types/useFrappeFacets.d.ts.map +1 -1
@@ -1,6 +1,15 @@
1
1
  import { HttpClient, useDocTypeMeta } from "@multiplatform.one/frappe";
2
2
  import type { DataTableColumn } from "@multiplatform.one/table";
3
- import { ArrowsClockwiseIcon, PlusIcon } from "@phosphor-icons/react";
3
+ import {
4
+ ArrowsClockwiseIcon,
5
+ HeartIcon,
6
+ ImageIcon,
7
+ ListIcon,
8
+ MagnifyingGlassIcon,
9
+ PlusIcon,
10
+ SparkleIcon,
11
+ TableIcon,
12
+ } from "@phosphor-icons/react";
4
13
  import React, { useState, useMemo, useCallback, useEffect } from "react";
5
14
  import { useTranslation } from "react-i18next";
6
15
  import { Button, SearchInput, Spinner } from "@multiplatform.one/forms";
@@ -9,21 +18,44 @@ import { SavedFilterDropdown, useSavedFilters, type ParsedFilter } from "@multip
9
18
  import {
10
19
  AsyncBoundary,
11
20
  Avatar,
21
+ EmptyState,
12
22
  ListPageLayout,
13
23
  PageHeader,
24
+ SkipLink,
25
+ Tooltip,
14
26
  ViewSwitcher,
15
27
  componentColors,
28
+ showToast,
16
29
  type ImageGridProps,
17
30
  } from "@multiplatform.one/components";
18
31
  import { pressTargetStyle, useResolvedKnobs } from "@multiplatform.one/theme";
19
32
  import { storage } from "@multiplatform.one/store";
20
33
  import { useFrappeConfig } from "./FrappeProvider";
21
34
  import { FrappeList, type FrappeListProps } from "./FrappeList";
35
+ import { FrappeNotConfigured } from "./FrappeNotConfigured";
36
+ import { FrappeRowsReader, type FrappeRowsSnapshot } from "./FrappeRowsReader";
22
37
  import { FrappeTable } from "./FrappeTable";
23
38
  import { useDocRights } from "./formEngine/useDocRights";
24
- import { frappeRouteHref, useFrappeRouter } from "./frappeNavigation";
39
+ import { frappeRouteHref, useFrappeRouter, useRouteLoaderData } from "./frappeNavigation";
25
40
  import { connectionsFromMeta, type FrappeConnection } from "./frappeConnections";
26
41
  import { isPermissionError } from "./liveErrors";
42
+ import { favoritesKey } from "./list/favorites";
43
+ import { RecordCard } from "./list/RecordCard";
44
+ import { recordTitle, type FrappeRecordLook } from "./list/recordLook";
45
+ import { ListControls } from "./list/ListControls";
46
+ import {
47
+ isListNarrowed,
48
+ listStateFilters,
49
+ listStateOrderBy,
50
+ type FrappeListControls,
51
+ type FrappeListFacet,
52
+ type FrappeListFilter,
53
+ type FrappeListRange,
54
+ type FrappeListSort,
55
+ } from "./list/listState";
56
+ import { ListToastHost } from "./list/ListToastHost";
57
+ import { ShufflePanel } from "./list/ShufflePanel";
58
+ import { useListControls } from "./list/useListControls";
27
59
  import { useConnectionFilters, type FrappeDoctypeFilter } from "./useConnectionFilters";
28
60
 
29
61
  interface ListFieldConfig {
@@ -34,6 +66,30 @@ interface ListFieldConfig {
34
66
 
35
67
  export type ListViewMode = "list" | "table" | "grid";
36
68
 
69
+ /** What a card needs from the list beyond its row. */
70
+ export interface FrappeListCard {
71
+ /** The record's page, when the list is routed. */
72
+ href?: string;
73
+ /** Opens the record the way a row press does. */
74
+ open: () => void;
75
+ /** Facet param to the record's values (a Pokemon's types, in slot order). */
76
+ facets: Record<string, string[]>;
77
+ /** Present when the list offers favorites. */
78
+ favorite?: { active: boolean; toggle: () => void };
79
+ }
80
+
81
+ /** A page-header action of a routed list; icon-only under sm. */
82
+ export interface FrappeListAction {
83
+ label: string;
84
+ icon?: React.ComponentType<{ size?: number }>;
85
+ /** Opened through the FrappeProvider's navigation. */
86
+ href?: string;
87
+ onPress?: () => void;
88
+ /** Tooltip. */
89
+ hint?: string;
90
+ testID?: string;
91
+ }
92
+
37
93
  export interface FrappeListViewProps<TDoc extends { name: string; doctype: string }> extends Omit<
38
94
  YStackProps,
39
95
  "children"
@@ -70,14 +126,27 @@ export interface FrappeListViewProps<TDoc extends { name: string; doctype: strin
70
126
  orderBy?: FrappeListProps<TDoc>["orderBy"];
71
127
  limit?: number;
72
128
  initialRows?: readonly Partial<TDoc>[];
129
+ /**
130
+ * The route's loader (`frappeListLoader`): the rows it rendered on the
131
+ * server seed the list, read through the host's navigation.
132
+ */
133
+ loader?: (...args: never[]) => Promise<{ rows: readonly Partial<TDoc>[] }>;
73
134
  columns?: DataTableColumn<Partial<TDoc>>[];
74
135
  displayFields?: ListFieldConfig[];
75
136
  /**
76
137
  * Per-row card slot. Given, the view gains a card grid (`grid` mode, the
77
138
  * catalog ImageGrid) that draws each row with it; loading, empty and error
78
- * stay the view's own states.
139
+ * stay the view's own states. A host that draws the grid itself may leave
140
+ * `card` out.
79
141
  */
80
- renderCard?: (doc: Partial<TDoc>, index: number) => React.ReactNode;
142
+ renderCard?: (doc: Partial<TDoc>, index: number, card?: FrappeListCard) => React.ReactNode;
143
+ /**
144
+ * How the doctype's records present. With `images` and no card slot, the
145
+ * grid draws each record as a RecordCard: the look's title, code,
146
+ * subtitle and images, the well tinted and badged by the first facet that
147
+ * declares tints, the favorite heart when the list keeps favorites.
148
+ */
149
+ look?: FrappeRecordLook<TDoc>;
81
150
  /** Card grid: column count, tile rung and media aspect. */
82
151
  gridProps?: Pick<ImageGridProps<Partial<TDoc>>, "columns" | "tileSize" | "mediaAspect">;
83
152
  /** Replaces the default empty message in list and card modes. */
@@ -97,6 +166,40 @@ export interface FrappeListViewProps<TDoc extends { name: string; doctype: strin
97
166
  showFilterSidebar?: boolean;
98
167
  /** @deprecated The toolbar always renders the List/Table switcher now. */
99
168
  enableViewSwitcher?: boolean;
169
+ /** Routed page title; defaults to the doctype. */
170
+ title?: string;
171
+ /** Routed page subtitle from the number of records the list reads. */
172
+ subtitle?: (count: number) => string;
173
+ /**
174
+ * Routed page actions. With the toolbar off, the view switcher and Add
175
+ * join them in the page header.
176
+ */
177
+ actions?: readonly FrappeListAction[];
178
+ /** Header content ahead of the actions. */
179
+ headerAccessory?: React.ReactNode;
180
+ /** The field that names a record in toasts; defaults to meta.title_field. */
181
+ titleField?: string;
182
+ /** Sort choices, first is the default; given, a Sort select joins the controls. */
183
+ sorts?: readonly FrappeListSort[];
184
+ /** The bench filters a search becomes; defaults to a like on the title field. */
185
+ searchFilter?: (query: string) => readonly FrappeListFilter[];
186
+ searchPlaceholder?: string;
187
+ /** One chip rail per facet, with each value's record count. */
188
+ facets?: readonly FrappeListFacet[];
189
+ /** One minimum-value slider per numeric field. */
190
+ ranges?: readonly FrappeListRange[];
191
+ /**
192
+ * Star records on this device and filter to them: true keys the stars by
193
+ * doctype, a string names the storage key.
194
+ */
195
+ favorites?: boolean | string;
196
+ /** A random-record picker; `label` names a record on its wheel. */
197
+ shuffle?: { label: (doc: Partial<TDoc>) => string };
198
+ /**
199
+ * Keep the controls and the view in the route's query params, so a
200
+ * refresh or a shared link reproduces the list.
201
+ */
202
+ urlState?: boolean;
100
203
  baseURL?: string;
101
204
  auth?: { useToken?: boolean; token?: string; type?: string };
102
205
  syncOptions?: Record<string, unknown>;
@@ -104,6 +207,9 @@ export interface FrappeListViewProps<TDoc extends { name: string; doctype: strin
104
207
 
105
208
  const storageKeyPrefix = "frappe-listview-";
106
209
 
210
+ /** Cards whose images load eagerly; the rest wait until they near the viewport. */
211
+ const eagerCards = 6;
212
+
107
213
  // Frappe document bookkeeping keys -- never useful as display columns.
108
214
  const internalDocKeys = new Set([
109
215
  "name",
@@ -170,8 +276,20 @@ async function setStoredViewMode(doctype: string, mode: ListViewMode): Promise<v
170
276
  *
171
277
  * Delegates to `FrappeList` (which delegates to generic `List`) or
172
278
  * `FrappeTable` (which delegates to `DataTable`) based on the view mode.
279
+ * With neither a bench URL nor a fixture corpus it says Frappe is not
280
+ * configured.
173
281
  */
174
- export function FrappeListView<TDoc extends { name: string; doctype: string }>({
282
+ export function FrappeListView<TDoc extends { name: string; doctype: string }>(
283
+ props: FrappeListViewProps<TDoc>,
284
+ ) {
285
+ const config = useFrappeConfig();
286
+ if (!(props.baseURL ?? config?.baseURL) && !config?.fixtures) {
287
+ return <FrappeNotConfigured doctype={props.doctype} page={props.route !== undefined} />;
288
+ }
289
+ return <FrappeListViewBody<TDoc> {...props} />;
290
+ }
291
+
292
+ function FrappeListViewBody<TDoc extends { name: string; doctype: string }>({
175
293
  doctype,
176
294
  fields,
177
295
  connections,
@@ -184,10 +302,12 @@ export function FrappeListView<TDoc extends { name: string; doctype: string }>({
184
302
  route,
185
303
  orderBy,
186
304
  limit,
187
- initialRows,
305
+ initialRows: initialRowsProp,
306
+ loader,
188
307
  columns,
189
308
  displayFields,
190
309
  renderCard,
310
+ look,
191
311
  gridProps,
192
312
  emptyState,
193
313
  onRetry,
@@ -198,13 +318,27 @@ export function FrappeListView<TDoc extends { name: string; doctype: string }>({
198
318
  showFilterSidebar = false,
199
319
  // deprecated: switcher always renders; destructured so it stays out of stackProps
200
320
  enableViewSwitcher: _enableViewSwitcher,
321
+ title,
322
+ subtitle,
323
+ actions,
324
+ headerAccessory,
325
+ titleField,
326
+ sorts,
327
+ searchFilter,
328
+ searchPlaceholder,
329
+ facets,
330
+ ranges,
331
+ favorites,
332
+ shuffle,
333
+ urlState = false,
201
334
  baseURL,
202
335
  auth,
203
336
  syncOptions,
204
337
  ...stackProps
205
338
  }: FrappeListViewProps<TDoc>) {
206
339
  const config = useFrappeConfig();
207
- const navigate = useFrappeRouter()?.navigate;
340
+ const router = useFrappeRouter();
341
+ const navigate = router?.navigate;
208
342
  const { knobProps } = useResolvedKnobs();
209
343
  const { t } = useTranslation();
210
344
  const theme = useTheme();
@@ -229,9 +363,6 @@ export function FrappeListView<TDoc extends { name: string; doctype: string }>({
229
363
  };
230
364
 
231
365
  const [storedViewMode, setViewModeState] = useState<ListViewMode>(defaultViewMode);
232
- const requestedViewMode = controlledViewMode ?? storedViewMode;
233
- const viewMode: ListViewMode =
234
- requestedViewMode === "grid" && !renderCard ? "list" : requestedViewMode;
235
366
 
236
367
  useEffect(() => {
237
368
  let cancelled = false;
@@ -247,16 +378,6 @@ export function FrappeListView<TDoc extends { name: string; doctype: string }>({
247
378
  };
248
379
  }, [doctype, defaultViewMode]);
249
380
 
250
- const setViewMode = useCallback(
251
- (mode: ListViewMode) => {
252
- onViewModeChange?.(mode);
253
- if (controlledViewMode !== undefined) return;
254
- setViewModeState(mode);
255
- void setStoredViewMode(doctype, mode);
256
- },
257
- [doctype, controlledViewMode, onViewModeChange],
258
- );
259
-
260
381
  const {
261
382
  meta,
262
383
  isLoading: isMetaLoading,
@@ -277,15 +398,6 @@ export function FrappeListView<TDoc extends { name: string; doctype: string }>({
277
398
  (route !== undefined && navigate
278
399
  ? () => navigate(frappeRouteHref(route, { mode: "create" }))
279
400
  : undefined));
280
- const asPage = (view: React.ReactElement) =>
281
- route === undefined ? (
282
- view
283
- ) : (
284
- <ListPageLayout scroll={false} header={<PageHeader title={doctype} divider={false} />}>
285
- {view}
286
- </ListPageLayout>
287
- );
288
-
289
401
  // Guest fallback: DocType meta is permission-gated (Guests get 403) while
290
402
  // the documents themselves are often guest-readable. Peek one doc with
291
403
  // fields=["*"] and derive display fields from its keys so the views render
@@ -459,10 +571,108 @@ export function FrappeListView<TDoc extends { name: string; doctype: string }>({
459
571
  () => connections ?? (isMetaLoading ? undefined : connectionsFromMeta(meta)),
460
572
  [connections, isMetaLoading, meta],
461
573
  );
574
+
575
+ const searchField = useMemo(() => {
576
+ if (meta?.title_field) return meta.title_field;
577
+ if (metaListFields.length > 0) return metaListFields[0].fieldname;
578
+ if (peekedFields && peekedFields.length > 0) return peekedFields[0];
579
+ return "name";
580
+ }, [meta, metaListFields, peekedFields]);
581
+
582
+ // The list's controls (sorts, facets, ranges, favorites, shuffle) own a
583
+ // state the filters and order derive from; a list without them keeps the
584
+ // plain search band below and its own view memory.
585
+ const hasCards = Boolean(renderCard || look?.images);
586
+ const listControls: FrappeListControls = {
587
+ sorts,
588
+ facets,
589
+ ranges,
590
+ views: hasCards ? ["grid", "list", "table"] : ["list", "table"],
591
+ defaultView: defaultViewMode,
592
+ };
593
+ const hasControls = Boolean(
594
+ sorts?.length || facets?.length || ranges?.length || favorites || shuffle,
595
+ );
596
+ const favoritesStorageKey = favorites
597
+ ? typeof favorites === "string"
598
+ ? favorites
599
+ : favoritesKey(doctype)
600
+ : undefined;
601
+ const list = useListControls({
602
+ doctype,
603
+ controls: listControls,
604
+ connections: effectiveConnections,
605
+ connection: connectionConfig,
606
+ limit,
607
+ favoritesKey: favoritesStorageKey,
608
+ router: urlState ? router : undefined,
609
+ readBase: Boolean(subtitle || facets?.length || ranges?.length),
610
+ });
611
+ const updateList = list.update;
612
+
613
+ const requestedViewMode =
614
+ controlledViewMode ?? (urlState ? list.state.view : undefined) ?? storedViewMode;
615
+ const viewMode: ListViewMode =
616
+ requestedViewMode === "grid" && !hasCards ? "list" : requestedViewMode;
617
+
618
+ const setViewMode = useCallback(
619
+ (mode: ListViewMode) => {
620
+ onViewModeChange?.(mode);
621
+ if (controlledViewMode !== undefined) return;
622
+ if (urlState) {
623
+ updateList({ view: mode });
624
+ return;
625
+ }
626
+ setViewModeState(mode);
627
+ void setStoredViewMode(doctype, mode);
628
+ },
629
+ [doctype, controlledViewMode, onViewModeChange, urlState, updateList],
630
+ );
631
+
632
+ const controlsKey = JSON.stringify({
633
+ facets: facets?.map((facet) => [facet.param, facet.field, facet.doctype]),
634
+ ranges: ranges?.map((range) => [range.param, range.field]),
635
+ sorts: sorts?.map((sort) => [sort.value, sort.orderBy]),
636
+ });
637
+ const controlFilters = useMemo(() => {
638
+ if (!hasControls) return activeFilters;
639
+ const base = !activeFilters
640
+ ? []
641
+ : Array.isArray(activeFilters)
642
+ ? activeFilters
643
+ : Object.entries(activeFilters).map(([field, value]) => [field, "=", value]);
644
+ return listStateFilters(list.state, listControls, {
645
+ base: base as FrappeListFilter[],
646
+ search: searchFilter ?? ((query) => [[searchField, "like", `%${query}%`]]),
647
+ favorites: list.favorites.favoriteSet,
648
+ });
649
+ // controlsKey stands for the facet and range definitions listControls carries.
650
+ }, [
651
+ hasControls,
652
+ activeFilters,
653
+ list.state,
654
+ list.favorites.favoriteSet,
655
+ searchFilter,
656
+ searchField,
657
+ controlsKey,
658
+ ]);
659
+ const effectiveOrderBy = hasControls
660
+ ? (listStateOrderBy(list.state, listControls, orderBy) as typeof orderBy)
661
+ : orderBy;
662
+ // The server page is the unfiltered list in its default order; any other
663
+ // query waits for its own read rather than flash rows it would drop.
664
+ const loaded = useRouteLoaderData(loader) as { rows?: readonly Partial<TDoc>[] } | undefined;
665
+ const initialRows = initialRowsProp ?? loaded?.rows;
666
+ const seedRows =
667
+ !hasControls ||
668
+ (!isListNarrowed(list.state) && (!sorts?.length || list.state.sort === sorts[0].value))
669
+ ? initialRows
670
+ : undefined;
671
+
462
672
  const linkFilters = useConnectionFilters(
463
673
  connectionConfig,
464
674
  doctype,
465
- activeFilters as Parameters<typeof useConnectionFilters>[2],
675
+ controlFilters as Parameters<typeof useConnectionFilters>[2],
466
676
  effectiveConnections,
467
677
  );
468
678
  const resolvedFilters = linkFilters.filters as typeof activeFilters;
@@ -474,13 +684,6 @@ export function FrappeListView<TDoc extends { name: string; doctype: string }>({
474
684
  const [searchText, setSearchText] = useState("");
475
685
  const [debouncedSearch, setDebouncedSearch] = useState("");
476
686
 
477
- const searchField = useMemo(() => {
478
- if (meta?.title_field) return meta.title_field;
479
- if (metaListFields.length > 0) return metaListFields[0].fieldname;
480
- if (peekedFields && peekedFields.length > 0) return peekedFields[0];
481
- return "name";
482
- }, [meta, metaListFields, peekedFields]);
483
-
484
687
  const listFilters = useMemo(() => {
485
688
  const query = debouncedSearch.trim();
486
689
  if (!query) return resolvedFilters;
@@ -538,6 +741,343 @@ export function FrappeListView<TDoc extends { name: string; doctype: string }>({
538
741
  [savedFiltersHook],
539
742
  );
540
743
 
744
+ const slug = doctype.toLowerCase().replace(/\s+/g, "-");
745
+ const searchId = `${slug}-list-search`;
746
+ const resultsId = `${slug}-results`;
747
+ const nameField = titleField ?? meta?.title_field;
748
+
749
+ const [shuffleOpen, setShuffleOpen] = useState(false);
750
+ const [shuffleRows, setShuffleRows] = useState<Partial<TDoc>[]>([]);
751
+ const handleShuffleRows = useCallback(
752
+ (snapshot: FrappeRowsSnapshot<TDoc>) => setShuffleRows(snapshot.rows),
753
+ [],
754
+ );
755
+ const shuffleOrderKey = JSON.stringify(sorts?.[0]?.orderBy ?? orderBy ?? null);
756
+ const shuffleFiltersKey = JSON.stringify(resolvedFilters ?? null);
757
+ const shuffleFieldsKey = JSON.stringify(effectiveFields);
758
+ const shuffleOptions = useMemo(
759
+ () => ({
760
+ fields: JSON.parse(shuffleFieldsKey),
761
+ filters: JSON.parse(shuffleFiltersKey) ?? undefined,
762
+ orderBy: JSON.parse(shuffleOrderKey) ?? undefined,
763
+ limit: limit ?? 0,
764
+ }),
765
+ [shuffleFieldsKey, shuffleFiltersKey, shuffleOrderKey, limit],
766
+ );
767
+
768
+ const { isFavorite, toggle: toggleStar } = list.favorites;
769
+ const toggleFavorite = useCallback(
770
+ (doc: Partial<TDoc>) => {
771
+ const name = doc.name;
772
+ if (!name) return;
773
+ const starred = isFavorite(name);
774
+ toggleStar(name);
775
+ const titleValue = nameField ? (doc as Record<string, unknown>)[nameField] : undefined;
776
+ const label = typeof titleValue === "string" && titleValue ? titleValue : name;
777
+ showToast(
778
+ starred
779
+ ? {
780
+ id: `${slug}-favorite-${name}`,
781
+ title: t("{{name}} removed from favorites", { name: label }),
782
+ intent: "accent",
783
+ action: { label: t("Undo"), onPress: () => toggleStar(name) },
784
+ }
785
+ : {
786
+ id: `${slug}-favorite-${name}`,
787
+ title: t("{{name}} added to favorites", { name: label }),
788
+ intent: "success",
789
+ },
790
+ );
791
+ },
792
+ [isFavorite, toggleStar, nameField, slug, t],
793
+ );
794
+
795
+ const cardFor = (doc: Partial<TDoc>): FrappeListCard => {
796
+ const name = doc.name ?? "";
797
+ const row = doc as Record<string, unknown>;
798
+ return {
799
+ href:
800
+ route !== undefined && name ? frappeRouteHref(route, { mode: "view", name }) : undefined,
801
+ open: () => onItemClick?.(doc),
802
+ facets: Object.fromEntries(
803
+ (facets ?? []).map((facet) => [
804
+ facet.param,
805
+ facet.doctype
806
+ ? (list.facets[facet.param]?.values.get(name) ?? [])
807
+ : row[facet.field] === undefined || row[facet.field] === null
808
+ ? []
809
+ : [String(row[facet.field])],
810
+ ]),
811
+ ),
812
+ favorite:
813
+ favoritesStorageKey && name
814
+ ? { active: isFavorite(name), toggle: () => toggleFavorite(doc) }
815
+ : undefined,
816
+ };
817
+ };
818
+ const tintFacet = facets?.find((facet) => facet.tint);
819
+ const drawRecordCard = (doc: Partial<TDoc>, index: number) => {
820
+ const card = cardFor(doc);
821
+ const name = doc.name ?? "";
822
+ const values = tintFacet ? (card.facets[tintFacet.param] ?? []) : [];
823
+ const title = recordTitle(doc, look, nameField);
824
+ return (
825
+ <RecordCard
826
+ title={title}
827
+ subtitle={look?.subtitle?.(doc)}
828
+ code={look?.code?.(doc)}
829
+ images={look?.images?.(doc, finalBaseURL) ?? []}
830
+ tints={values.slice(0, 2).map((value) => tintFacet?.tint?.(value))}
831
+ badges={values.map((value) => ({
832
+ value,
833
+ label: tintFacet?.optionLabel?.(value) ?? value,
834
+ tint: tintFacet?.tint?.(value),
835
+ }))}
836
+ href={card.href}
837
+ onPress={card.open}
838
+ favorite={card.favorite}
839
+ lazy={index >= eagerCards}
840
+ testID={`${slug}-card-${name}`}
841
+ favoriteTestID={`${slug}-favorite-${name}`}
842
+ />
843
+ );
844
+ };
845
+ const drawCard = renderCard
846
+ ? (doc: Partial<TDoc>, index: number) => renderCard(doc, index, cardFor(doc))
847
+ : look?.images
848
+ ? drawRecordCard
849
+ : undefined;
850
+
851
+ // "/" jumps to the search box on web, the common list-page affordance.
852
+ // Document scope adds no tab stop (LC-49); it stands down while the reader
853
+ // types in any editable control or works inside an open overlay.
854
+ useEffect(() => {
855
+ if (!isWeb || typeof document === "undefined" || !showSearch) return;
856
+ const handleKeyDown = (event: KeyboardEvent) => {
857
+ if (event.key !== "/" || event.metaKey || event.ctrlKey || event.altKey) return;
858
+ if (event.defaultPrevented) return;
859
+ const target = event.target as HTMLElement | null;
860
+ if (target) {
861
+ const tag = target.tagName;
862
+ if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") return;
863
+ if (target.isContentEditable) return;
864
+ if (target.closest?.('[role="dialog"], [role="menu"], [role="listbox"]')) return;
865
+ }
866
+ const input = document.getElementById(searchId)?.querySelector("input");
867
+ if (!input) return;
868
+ event.preventDefault();
869
+ input.focus();
870
+ input.select?.();
871
+ };
872
+ document.addEventListener("keydown", handleKeyDown);
873
+ return () => document.removeEventListener("keydown", handleKeyDown);
874
+ }, [searchId, showSearch]);
875
+
876
+ const headerOwnsTools = route !== undefined && !showToolbar;
877
+ const pressFor = (action: FrappeListAction) =>
878
+ action.onPress ?? (action.href && navigate ? () => navigate(action.href as string) : undefined);
879
+ const headerActions =
880
+ headerOwnsTools || headerAccessory || actions?.length ? (
881
+ <XStack {...knobProps.gap} alignItems="center" flexWrap="wrap" flexShrink={1} minWidth={0}>
882
+ {headerOwnsTools ? (
883
+ <Tooltip content={t("Switch views")}>
884
+ <XStack>
885
+ <ViewSwitcher
886
+ views={[
887
+ ...(hasCards ? [{ type: "grid", label: t("Cards"), icon: ImageIcon }] : []),
888
+ { type: "list", label: t("List"), icon: ListIcon },
889
+ { type: "table", label: t("Table"), icon: TableIcon },
890
+ ]}
891
+ currentView={viewMode}
892
+ onViewChange={(v) => setViewMode(v as ListViewMode)}
893
+ />
894
+ </XStack>
895
+ </Tooltip>
896
+ ) : null}
897
+ {headerAccessory}
898
+ {actions?.map((action) => {
899
+ const Icon = action.icon;
900
+ const onPress = pressFor(action);
901
+ return (
902
+ <React.Fragment key={action.label}>
903
+ <Tooltip content={action.hint ?? action.label}>
904
+ <Button
905
+ outlined
906
+ onPress={onPress}
907
+ icon={Icon ? <Icon size={16} /> : undefined}
908
+ $max-sm={{ display: "none" }}
909
+ testID={action.testID}
910
+ >
911
+ {action.label}
912
+ </Button>
913
+ </Tooltip>
914
+ <Button
915
+ outlined
916
+ circular
917
+ onPress={onPress}
918
+ icon={Icon ? <Icon size={16} /> : undefined}
919
+ display="none"
920
+ aria-label={action.label}
921
+ $max-sm={{ display: "flex" }}
922
+ />
923
+ </React.Fragment>
924
+ );
925
+ })}
926
+ {headerOwnsTools && onAdd ? (
927
+ <>
928
+ <Button
929
+ theme="accent"
930
+ onPress={onAdd}
931
+ icon={<PlusIcon size={16} />}
932
+ $max-sm={{ display: "none" }}
933
+ >
934
+ {t("Add {{doctype}}", { doctype })}
935
+ </Button>
936
+ <Button
937
+ theme="accent"
938
+ onPress={onAdd}
939
+ icon={<PlusIcon size={16} />}
940
+ display="none"
941
+ $max-sm={{ display: "flex" }}
942
+ >
943
+ {t("Add")}
944
+ </Button>
945
+ </>
946
+ ) : null}
947
+ </XStack>
948
+ ) : undefined;
949
+
950
+ const controlsBand = hasControls ? (
951
+ <ListControls
952
+ controls={listControls}
953
+ list={list}
954
+ searchId={searchId}
955
+ searchPlaceholder={searchPlaceholder}
956
+ showSearch={showSearch}
957
+ showFavorites={Boolean(favoritesStorageKey)}
958
+ shuffle={
959
+ shuffle
960
+ ? {
961
+ open: shuffleOpen,
962
+ toggle: () => setShuffleOpen((open) => !open),
963
+ panelId: `${slug}-shuffle-panel`,
964
+ }
965
+ : undefined
966
+ }
967
+ shufflePanel={
968
+ shuffle && shuffleOpen && shuffleRows.length > 0 && drawCard ? (
969
+ <ShufflePanel<Partial<TDoc>>
970
+ id={`${slug}-shuffle-panel`}
971
+ label={t("Surprise me")}
972
+ rows={shuffleRows}
973
+ itemLabel={shuffle.label}
974
+ renderPick={(doc) => drawCard(doc, 0)}
975
+ onGo={(doc) => {
976
+ setShuffleOpen(false);
977
+ onItemClick?.(doc);
978
+ }}
979
+ testID={`${slug}-shuffle-panel`}
980
+ />
981
+ ) : null
982
+ }
983
+ separator={!surface}
984
+ testID={slug}
985
+ />
986
+ ) : null;
987
+
988
+ const asPage = (view: React.ReactElement) => {
989
+ const extras = (
990
+ <>
991
+ {list.readers}
992
+ {shuffle && shuffleOpen && !linkFilters.pending ? (
993
+ <FrappeRowsReader<TDoc>
994
+ connection={connectionConfig}
995
+ doctype={doctype}
996
+ options={shuffleOptions as never}
997
+ onChange={handleShuffleRows}
998
+ />
999
+ ) : null}
1000
+ {favoritesStorageKey ? <ListToastHost /> : null}
1001
+ </>
1002
+ );
1003
+ if (route === undefined) {
1004
+ return controlsBand ? (
1005
+ <YStack {...knobProps.gap} flex={viewMode === "grid" ? undefined : 1}>
1006
+ {controlsBand}
1007
+ {view}
1008
+ {extras}
1009
+ </YStack>
1010
+ ) : (
1011
+ <>
1012
+ {view}
1013
+ {extras}
1014
+ </>
1015
+ );
1016
+ }
1017
+ return (
1018
+ <ListPageLayout
1019
+ scroll={!surface}
1020
+ header={
1021
+ <>
1022
+ {controlsBand ? <SkipLink targetId={resultsId}>{t("Skip to results")}</SkipLink> : null}
1023
+ <PageHeader
1024
+ title={title ?? doctype}
1025
+ subtitle={subtitle && list.total !== undefined ? subtitle(list.total) : undefined}
1026
+ actions={headerActions}
1027
+ divider={!surface}
1028
+ />
1029
+ </>
1030
+ }
1031
+ toolbar={controlsBand ?? undefined}
1032
+ >
1033
+ {view}
1034
+ {extras}
1035
+ </ListPageLayout>
1036
+ );
1037
+ };
1038
+
1039
+ const controlsEmptyState = hasControls ? (
1040
+ <EmptyState
1041
+ aria-live="polite"
1042
+ icon={
1043
+ list.state.favoritesOnly ? (
1044
+ <HeartIcon size={28} />
1045
+ ) : isListNarrowed(list.state) ? (
1046
+ <MagnifyingGlassIcon size={28} />
1047
+ ) : (
1048
+ <SparkleIcon size={28} />
1049
+ )
1050
+ }
1051
+ title={
1052
+ list.state.favoritesOnly
1053
+ ? t("No favorites yet")
1054
+ : list.state.search.trim()
1055
+ ? t('No match for "{{query}}"', { query: list.state.search.trim() })
1056
+ : isListNarrowed(list.state)
1057
+ ? t("No {{doctype}} match the active filters", { doctype })
1058
+ : t("No {{doctype}} yet", { doctype })
1059
+ }
1060
+ description={
1061
+ list.state.favoritesOnly
1062
+ ? t("Tap the heart on a record to favorite it.")
1063
+ : isListNarrowed(list.state)
1064
+ ? t("Try a different search or filter.")
1065
+ : undefined
1066
+ }
1067
+ action={
1068
+ isListNarrowed(list.state) ? (
1069
+ <Button outlined onPress={list.clear}>
1070
+ {t("Clear filters")}
1071
+ </Button>
1072
+ ) : onAdd ? (
1073
+ <Button theme="accent" onPress={onAdd}>
1074
+ {t("Add your first {{doctype}}", { doctype })}
1075
+ </Button>
1076
+ ) : undefined
1077
+ }
1078
+ />
1079
+ ) : undefined;
1080
+
541
1081
  // Named fields need no schema to read or draw: the view renders now (on
542
1082
  // the server too) and labels settle when meta lands.
543
1083
  if (isMetaLoading && !fields) {
@@ -546,10 +1086,11 @@ export function FrappeListView<TDoc extends { name: string; doctype: string }>({
546
1086
  {...knobProps.panelPadding}
547
1087
  alignItems="center"
548
1088
  justifyContent="center"
1089
+ gap="$2"
549
1090
  {...stackProps}
550
1091
  >
551
1092
  <Spinner size="large" />
552
- <Text {...knobProps.body} color={knobProps.textAccentColor} marginTop="$2">
1093
+ <Text {...knobProps.body} color={knobProps.textAccentColor}>
553
1094
  {t("Loading {{doctype}} schema...", { doctype })}
554
1095
  </Text>
555
1096
  </YStack>,
@@ -573,7 +1114,7 @@ export function FrappeListView<TDoc extends { name: string; doctype: string }>({
573
1114
  <XStack alignItems="center" {...knobProps.gap}>
574
1115
  <ViewSwitcher
575
1116
  views={[
576
- ...(renderCard ? [{ type: "grid", label: t("Cards") }] : []),
1117
+ ...(hasCards ? [{ type: "grid", label: t("Cards") }] : []),
577
1118
  { type: "list", label: t("List") },
578
1119
  { type: "table", label: t("Table") },
579
1120
  ]}
@@ -678,7 +1219,7 @@ export function FrappeListView<TDoc extends { name: string; doctype: string }>({
678
1219
  borderBottomWidth={1}
679
1220
  borderBottomColor="$borderColor"
680
1221
  >
681
- <View flex={1}>
1222
+ <View flex={1} id={searchId}>
682
1223
  <SearchInput
683
1224
  value={searchText}
684
1225
  onChange={setSearchText}
@@ -698,19 +1239,19 @@ export function FrappeListView<TDoc extends { name: string; doctype: string }>({
698
1239
  const isGrid = viewMode === "grid";
699
1240
  return (
700
1241
  <YStack flex={isGrid ? undefined : 1}>
701
- {showSearch ? renderListSearch() : null}
1242
+ {showSearch && !hasControls ? renderListSearch() : null}
702
1243
  <FrappeList
703
1244
  key={`${viewMode}-${refreshKey}`}
704
1245
  layout={isGrid ? "grid" : "list"}
705
1246
  gridProps={gridProps}
706
- emptyState={emptyState}
1247
+ emptyState={emptyState ?? controlsEmptyState}
707
1248
  pageSize={pageSize}
708
1249
  onRetry={onRetry ?? handleRefresh}
709
1250
  doctype={doctype}
710
1251
  fields={effectiveFields as readonly ("name" | "doctype")[]}
711
1252
  filters={listFilters as Partial<{ name: string; doctype: string }>}
712
1253
  renderItem={
713
- (isGrid && renderCard ? renderCard : renderListItem) as unknown as (
1254
+ (isGrid && drawCard ? drawCard : renderListItem) as unknown as (
714
1255
  item: Partial<{ name: string; doctype: string }>,
715
1256
  index: number,
716
1257
  ) => React.ReactNode
@@ -723,10 +1264,12 @@ export function FrappeListView<TDoc extends { name: string; doctype: string }>({
723
1264
  baseURL={finalBaseURL}
724
1265
  auth={finalAuth}
725
1266
  syncOptions={finalSyncOptions}
726
- orderBy={orderBy as FrappeListProps<{ name: string; doctype: string }>["orderBy"]}
1267
+ orderBy={
1268
+ effectiveOrderBy as FrappeListProps<{ name: string; doctype: string }>["orderBy"]
1269
+ }
727
1270
  limit={limit}
728
1271
  initialRows={
729
- initialRows as FrappeListProps<{ name: string; doctype: string }>["initialRows"]
1272
+ seedRows as FrappeListProps<{ name: string; doctype: string }>["initialRows"]
730
1273
  }
731
1274
  // Only override when narrowing is active: FrappeList's own
732
1275
  // "No {doctype} records found" stays the true-empty message.
@@ -779,6 +1322,7 @@ export function FrappeListView<TDoc extends { name: string; doctype: string }>({
779
1322
  {...(surface ? knobProps.containerRadius : {})}
780
1323
  overflow={surface ? "hidden" : undefined}
781
1324
  testID={`${doctype.toLowerCase()}-list`}
1325
+ {...(hasControls ? { id: resultsId } : {})}
782
1326
  {...stackProps}
783
1327
  >
784
1328
  {renderToolbar()}