@mantis-core/ui 0.5.0 → 0.7.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 (378) hide show
  1. package/CHANGELOG.md +155 -0
  2. package/COMPONENTS.md +71 -73
  3. package/README.md +19 -6
  4. package/bin/mantis-llm.mjs +242 -0
  5. package/catalog.json +3031 -0
  6. package/dist/components/Buttons/Button.d.ts +39 -9
  7. package/dist/components/Buttons/Button.d.ts.map +1 -1
  8. package/dist/components/Buttons/Button.js +21 -13
  9. package/dist/components/Buttons/Button.js.map +1 -1
  10. package/dist/components/Forms/AutoCompleteField.d.ts +60 -0
  11. package/dist/components/Forms/AutoCompleteField.d.ts.map +1 -0
  12. package/dist/components/Forms/AutoCompleteField.js +125 -0
  13. package/dist/components/Forms/AutoCompleteField.js.map +1 -0
  14. package/dist/components/Forms/CKEditorInput.d.ts +5 -2
  15. package/dist/components/Forms/CKEditorInput.d.ts.map +1 -1
  16. package/dist/components/Forms/CKEditorInput.js +5 -2
  17. package/dist/components/Forms/CKEditorInput.js.map +1 -1
  18. package/dist/components/Forms/CheckboxField.d.ts +14 -0
  19. package/dist/components/Forms/CheckboxField.d.ts.map +1 -0
  20. package/dist/components/Forms/CheckboxField.js +26 -0
  21. package/dist/components/Forms/CheckboxField.js.map +1 -0
  22. package/dist/components/Forms/ColorPickerInput.d.ts +27 -8
  23. package/dist/components/Forms/ColorPickerInput.d.ts.map +1 -1
  24. package/dist/components/Forms/ColorPickerInput.js +57 -11
  25. package/dist/components/Forms/ColorPickerInput.js.map +1 -1
  26. package/dist/components/Forms/DateField.d.ts +68 -0
  27. package/dist/components/Forms/DateField.d.ts.map +1 -0
  28. package/dist/components/Forms/DateField.js +108 -0
  29. package/dist/components/Forms/DateField.js.map +1 -0
  30. package/dist/components/Forms/DatePresets.d.ts.map +1 -1
  31. package/dist/components/Forms/DatePresets.js +6 -3
  32. package/dist/components/Forms/DatePresets.js.map +1 -1
  33. package/dist/components/Forms/FieldShell.d.ts +24 -0
  34. package/dist/components/Forms/FieldShell.d.ts.map +1 -0
  35. package/dist/components/Forms/FieldShell.js +39 -0
  36. package/dist/components/Forms/FieldShell.js.map +1 -0
  37. package/dist/components/Forms/FileDropzone.d.ts +4 -2
  38. package/dist/components/Forms/FileDropzone.d.ts.map +1 -1
  39. package/dist/components/Forms/FileDropzone.js.map +1 -1
  40. package/dist/components/Forms/FormActionsBar.js +2 -2
  41. package/dist/components/Forms/FormActionsBar.js.map +1 -1
  42. package/dist/components/Forms/FormWizard.d.ts +1 -1
  43. package/dist/components/Forms/FormWizard.d.ts.map +1 -1
  44. package/dist/components/Forms/FormWizard.js +4 -5
  45. package/dist/components/Forms/FormWizard.js.map +1 -1
  46. package/dist/components/Forms/HiddenField.d.ts +12 -6
  47. package/dist/components/Forms/HiddenField.d.ts.map +1 -1
  48. package/dist/components/Forms/HiddenField.js +14 -5
  49. package/dist/components/Forms/HiddenField.js.map +1 -1
  50. package/dist/components/Forms/MaskField.d.ts +28 -0
  51. package/dist/components/Forms/MaskField.d.ts.map +1 -0
  52. package/dist/components/Forms/MaskField.js +74 -0
  53. package/dist/components/Forms/MaskField.js.map +1 -0
  54. package/dist/components/Forms/NumberField.d.ts +14 -0
  55. package/dist/components/Forms/NumberField.d.ts.map +1 -0
  56. package/dist/components/Forms/NumberField.js +51 -0
  57. package/dist/components/Forms/NumberField.js.map +1 -0
  58. package/dist/components/Forms/OtpInput.d.ts +23 -8
  59. package/dist/components/Forms/OtpInput.d.ts.map +1 -1
  60. package/dist/components/Forms/OtpInput.js +37 -8
  61. package/dist/components/Forms/OtpInput.js.map +1 -1
  62. package/dist/components/Forms/PasswordInput.d.ts +22 -9
  63. package/dist/components/Forms/PasswordInput.d.ts.map +1 -1
  64. package/dist/components/Forms/PasswordInput.js +63 -28
  65. package/dist/components/Forms/PasswordInput.js.map +1 -1
  66. package/dist/components/Forms/PhoneInput.d.ts +16 -8
  67. package/dist/components/Forms/PhoneInput.d.ts.map +1 -1
  68. package/dist/components/Forms/PhoneInput.js +13 -6
  69. package/dist/components/Forms/PhoneInput.js.map +1 -1
  70. package/dist/components/Forms/RadioGroup.d.ts +34 -13
  71. package/dist/components/Forms/RadioGroup.d.ts.map +1 -1
  72. package/dist/components/Forms/RadioGroup.js +49 -6
  73. package/dist/components/Forms/RadioGroup.js.map +1 -1
  74. package/dist/components/Forms/RangeSlider.d.ts +26 -11
  75. package/dist/components/Forms/RangeSlider.d.ts.map +1 -1
  76. package/dist/components/Forms/RangeSlider.js +40 -7
  77. package/dist/components/Forms/RangeSlider.js.map +1 -1
  78. package/dist/components/Forms/RatingInput.d.ts +24 -8
  79. package/dist/components/Forms/RatingInput.d.ts.map +1 -1
  80. package/dist/components/Forms/RatingInput.js +41 -9
  81. package/dist/components/Forms/RatingInput.js.map +1 -1
  82. package/dist/components/Forms/SearchInput.d.ts +18 -10
  83. package/dist/components/Forms/SearchInput.d.ts.map +1 -1
  84. package/dist/components/Forms/SearchInput.js +44 -23
  85. package/dist/components/Forms/SearchInput.js.map +1 -1
  86. package/dist/components/Forms/SelectField.d.ts +41 -0
  87. package/dist/components/Forms/SelectField.d.ts.map +1 -0
  88. package/dist/components/Forms/SelectField.js +110 -0
  89. package/dist/components/Forms/SelectField.js.map +1 -0
  90. package/dist/components/Forms/SwitchField.d.ts +14 -0
  91. package/dist/components/Forms/SwitchField.d.ts.map +1 -0
  92. package/dist/components/Forms/SwitchField.js +26 -0
  93. package/dist/components/Forms/SwitchField.js.map +1 -0
  94. package/dist/components/Forms/TagsInput.d.ts +29 -8
  95. package/dist/components/Forms/TagsInput.d.ts.map +1 -1
  96. package/dist/components/Forms/TagsInput.js +53 -9
  97. package/dist/components/Forms/TagsInput.js.map +1 -1
  98. package/dist/components/Forms/TextArea.d.ts +13 -10
  99. package/dist/components/Forms/TextArea.d.ts.map +1 -1
  100. package/dist/components/Forms/TextArea.js +27 -9
  101. package/dist/components/Forms/TextArea.js.map +1 -1
  102. package/dist/components/Forms/TextField.d.ts +14 -0
  103. package/dist/components/Forms/TextField.d.ts.map +1 -0
  104. package/dist/components/Forms/TextField.js +29 -0
  105. package/dist/components/Forms/TextField.js.map +1 -0
  106. package/dist/components/Forms/ToggleInlineButton.d.ts +33 -12
  107. package/dist/components/Forms/ToggleInlineButton.d.ts.map +1 -1
  108. package/dist/components/Forms/ToggleInlineButton.js +56 -6
  109. package/dist/components/Forms/ToggleInlineButton.js.map +1 -1
  110. package/dist/components/Forms/UploadFilesPreview.js +3 -3
  111. package/dist/components/Forms/UploadFilesPreview.js.map +1 -1
  112. package/dist/components/Forms/field-typing.test-d.d.ts +2 -0
  113. package/dist/components/Forms/field-typing.test-d.d.ts.map +1 -0
  114. package/dist/components/Forms/field-typing.test-d.js +24 -0
  115. package/dist/components/Forms/field-typing.test-d.js.map +1 -0
  116. package/dist/components/Forms/useFieldController.d.ts +85 -0
  117. package/dist/components/Forms/useFieldController.d.ts.map +1 -0
  118. package/dist/components/Forms/useFieldController.js +54 -0
  119. package/dist/components/Forms/useFieldController.js.map +1 -0
  120. package/dist/components/Loaders/Loading.d.ts.map +1 -1
  121. package/dist/components/Loaders/Loading.js +3 -2
  122. package/dist/components/Loaders/Loading.js.map +1 -1
  123. package/dist/components/Tables/ActionColumn.d.ts +20 -4
  124. package/dist/components/Tables/ActionColumn.d.ts.map +1 -1
  125. package/dist/components/Tables/ActionColumn.js +24 -5
  126. package/dist/components/Tables/ActionColumn.js.map +1 -1
  127. package/dist/components/Tables/FilterPannel.d.ts +9 -2
  128. package/dist/components/Tables/FilterPannel.d.ts.map +1 -1
  129. package/dist/components/Tables/FilterPannel.js +15 -11
  130. package/dist/components/Tables/FilterPannel.js.map +1 -1
  131. package/dist/components/Tables/IndexColumn.d.ts +12 -3
  132. package/dist/components/Tables/IndexColumn.d.ts.map +1 -1
  133. package/dist/components/Tables/IndexColumn.js +21 -5
  134. package/dist/components/Tables/IndexColumn.js.map +1 -1
  135. package/dist/components/Tables/MantisDataTable.d.ts +45 -0
  136. package/dist/components/Tables/MantisDataTable.d.ts.map +1 -0
  137. package/dist/components/Tables/MantisDataTable.js +63 -0
  138. package/dist/components/Tables/MantisDataTable.js.map +1 -0
  139. package/dist/components/Tables/MenuButton.d.ts +28 -7
  140. package/dist/components/Tables/MenuButton.d.ts.map +1 -1
  141. package/dist/components/Tables/MenuButton.js +20 -10
  142. package/dist/components/Tables/MenuButton.js.map +1 -1
  143. package/dist/components/Tables/PaginatedTable.d.ts +26 -17
  144. package/dist/components/Tables/PaginatedTable.d.ts.map +1 -1
  145. package/dist/components/Tables/PaginatedTable.js +24 -22
  146. package/dist/components/Tables/PaginatedTable.js.map +1 -1
  147. package/dist/components/Tables/cell-presets.d.ts +35 -0
  148. package/dist/components/Tables/cell-presets.d.ts.map +1 -0
  149. package/dist/components/Tables/cell-presets.js +40 -0
  150. package/dist/components/Tables/cell-presets.js.map +1 -0
  151. package/dist/components/Tables/columns.d.ts +40 -0
  152. package/dist/components/Tables/columns.d.ts.map +1 -0
  153. package/dist/components/Tables/columns.js +2 -0
  154. package/dist/components/Tables/columns.js.map +1 -0
  155. package/dist/components/Tables/filters/MultiSelectFilter.d.ts +24 -6
  156. package/dist/components/Tables/filters/MultiSelectFilter.d.ts.map +1 -1
  157. package/dist/components/Tables/filters/MultiSelectFilter.js +19 -6
  158. package/dist/components/Tables/filters/MultiSelectFilter.js.map +1 -1
  159. package/dist/components/auth/ChangePasswordForm.d.ts.map +1 -1
  160. package/dist/components/auth/ChangePasswordForm.js +12 -12
  161. package/dist/components/auth/ChangePasswordForm.js.map +1 -1
  162. package/dist/components/auth/ForgotPasswordForm.d.ts.map +1 -1
  163. package/dist/components/auth/ForgotPasswordForm.js +7 -5
  164. package/dist/components/auth/ForgotPasswordForm.js.map +1 -1
  165. package/dist/components/auth/LoginForm.d.ts +2 -2
  166. package/dist/components/auth/LoginForm.d.ts.map +1 -1
  167. package/dist/components/auth/LoginForm.js +15 -15
  168. package/dist/components/auth/LoginForm.js.map +1 -1
  169. package/dist/components/auth/ResetPasswordForm.d.ts.map +1 -1
  170. package/dist/components/auth/ResetPasswordForm.js +11 -12
  171. package/dist/components/auth/ResetPasswordForm.js.map +1 -1
  172. package/dist/components/auth/UserMenu.d.ts +11 -1
  173. package/dist/components/auth/UserMenu.d.ts.map +1 -1
  174. package/dist/components/auth/UserMenu.js +30 -87
  175. package/dist/components/auth/UserMenu.js.map +1 -1
  176. package/dist/components/data/Timeline.d.ts +2 -2
  177. package/dist/components/data/Timeline.d.ts.map +1 -1
  178. package/dist/components/data/Timeline.js +17 -17
  179. package/dist/components/data/Timeline.js.map +1 -1
  180. package/dist/components/feedback/Avatar.d.ts +4 -2
  181. package/dist/components/feedback/Avatar.d.ts.map +1 -1
  182. package/dist/components/feedback/Avatar.js +4 -4
  183. package/dist/components/feedback/Avatar.js.map +1 -1
  184. package/dist/components/feedback/CardSkeleton.d.ts.map +1 -1
  185. package/dist/components/feedback/CardSkeleton.js +3 -3
  186. package/dist/components/feedback/CardSkeleton.js.map +1 -1
  187. package/dist/components/feedback/TableSkeleton.d.ts.map +1 -1
  188. package/dist/components/feedback/TableSkeleton.js +3 -3
  189. package/dist/components/feedback/TableSkeleton.js.map +1 -1
  190. package/dist/components/feedback/Tag.d.ts +4 -2
  191. package/dist/components/feedback/Tag.d.ts.map +1 -1
  192. package/dist/components/feedback/Tag.js +4 -4
  193. package/dist/components/feedback/Tag.js.map +1 -1
  194. package/dist/components/navigation/CommandPalette.d.ts.map +1 -1
  195. package/dist/components/navigation/CommandPalette.js +5 -2
  196. package/dist/components/navigation/CommandPalette.js.map +1 -1
  197. package/dist/components/navigation/PageTabs.d.ts +10 -8
  198. package/dist/components/navigation/PageTabs.d.ts.map +1 -1
  199. package/dist/components/navigation/PageTabs.js +17 -13
  200. package/dist/components/navigation/PageTabs.js.map +1 -1
  201. package/dist/components/overlays/Drawer.d.ts +16 -3
  202. package/dist/components/overlays/Drawer.d.ts.map +1 -1
  203. package/dist/components/overlays/Drawer.js +9 -5
  204. package/dist/components/overlays/Drawer.js.map +1 -1
  205. package/dist/components/overlays/Modal.d.ts +18 -3
  206. package/dist/components/overlays/Modal.d.ts.map +1 -1
  207. package/dist/components/overlays/Modal.js +13 -5
  208. package/dist/components/overlays/Modal.js.map +1 -1
  209. package/dist/components/pages/app-shell/AppShell.d.ts.map +1 -1
  210. package/dist/components/pages/app-shell/AppShell.js +6 -6
  211. package/dist/components/pages/app-shell/AppShell.js.map +1 -1
  212. package/dist/components/ui/ConfirmDialog.d.ts +1 -2
  213. package/dist/components/ui/ConfirmDialog.d.ts.map +1 -1
  214. package/dist/components/ui/ConfirmDialog.js +10 -4
  215. package/dist/components/ui/ConfirmDialog.js.map +1 -1
  216. package/dist/components/ui/DataState.js +2 -2
  217. package/dist/components/ui/DataState.js.map +1 -1
  218. package/dist/index.d.ts +71 -42
  219. package/dist/index.d.ts.map +1 -1
  220. package/dist/index.js +114 -22
  221. package/dist/index.js.map +1 -1
  222. package/docs/README.md +1 -1
  223. package/docs/components/action-column.md +33 -7
  224. package/docs/components/admin-page-configurator.md +24 -5
  225. package/docs/components/admin-page-header.md +21 -3
  226. package/docs/components/admin-page-layout-shell.md +18 -4
  227. package/docs/components/admin-page-layout.md +34 -5
  228. package/docs/components/app-shell.md +31 -6
  229. package/docs/components/auto-complete-field.md +60 -0
  230. package/docs/components/avatar.md +18 -8
  231. package/docs/components/bar-chart.md +25 -7
  232. package/docs/components/breadcrumbs.md +15 -2
  233. package/docs/components/button.md +34 -15
  234. package/docs/components/card-skeleton.md +9 -3
  235. package/docs/components/change-password-form.md +23 -4
  236. package/docs/components/checkbox-field.md +38 -0
  237. package/docs/components/ckeditor-input.md +40 -8
  238. package/docs/components/color-picker-input.md +19 -8
  239. package/docs/components/command-palette.md +23 -2
  240. package/docs/components/confirm-dialog.md +36 -9
  241. package/docs/components/data-state.md +31 -6
  242. package/docs/components/date-field.md +39 -0
  243. package/docs/components/date-presets.md +19 -5
  244. package/docs/components/description-list.md +20 -2
  245. package/docs/components/dirty-form-guard.md +16 -4
  246. package/docs/components/donut-chart.md +24 -7
  247. package/docs/components/drawer.md +27 -8
  248. package/docs/components/empty-state.md +12 -2
  249. package/docs/components/error-boundary.md +16 -2
  250. package/docs/components/error-message.md +22 -3
  251. package/docs/components/field-shell.md +47 -0
  252. package/docs/components/file-dropzone.md +22 -6
  253. package/docs/components/filter-pannel.md +34 -7
  254. package/docs/components/forgot-password-form.md +23 -5
  255. package/docs/components/form-actions-bar.md +21 -2
  256. package/docs/components/form-field-render.md +36 -8
  257. package/docs/components/form-section.md +13 -1
  258. package/docs/components/form-wizard.md +34 -5
  259. package/docs/components/hidden-field.md +22 -6
  260. package/docs/components/index-column.md +25 -5
  261. package/docs/components/line-chart.md +25 -7
  262. package/docs/components/loading.md +14 -5
  263. package/docs/components/login-form.md +31 -6
  264. package/docs/components/mantis-data-table.md +61 -0
  265. package/docs/components/map-picker-client.md +29 -8
  266. package/docs/components/map-picker-osm.md +27 -9
  267. package/docs/components/map-picker.md +25 -4
  268. package/docs/components/mask-field.md +31 -0
  269. package/docs/components/menu-button.md +22 -7
  270. package/docs/components/modal.md +34 -9
  271. package/docs/components/multi-select-filter.md +25 -7
  272. package/docs/components/number-field.md +40 -0
  273. package/docs/components/otp-input.md +20 -7
  274. package/docs/components/page-tabs.md +23 -4
  275. package/docs/components/page-title.md +6 -1
  276. package/docs/components/paginated-table.md +36 -13
  277. package/docs/components/pagination.md +20 -7
  278. package/docs/components/password-input.md +20 -8
  279. package/docs/components/phone-input.md +17 -7
  280. package/docs/components/radio-group.md +39 -9
  281. package/docs/components/range-slider.md +18 -6
  282. package/docs/components/rating-input.md +19 -8
  283. package/docs/components/render-field.md +31 -3
  284. package/docs/components/reset-password-form.md +24 -4
  285. package/docs/components/rich-text-preview.md +17 -5
  286. package/docs/components/search-input.md +18 -7
  287. package/docs/components/select-field.md +55 -0
  288. package/docs/components/stat-card.md +14 -3
  289. package/docs/components/status-badge.md +17 -7
  290. package/docs/components/switch-field.md +32 -0
  291. package/docs/components/table-filter-field.md +22 -4
  292. package/docs/components/table-skeleton.md +9 -3
  293. package/docs/components/table-toolbar.md +18 -5
  294. package/docs/components/tag.md +16 -7
  295. package/docs/components/tags-input.md +21 -8
  296. package/docs/components/text-area.md +18 -8
  297. package/docs/components/text-field.md +32 -0
  298. package/docs/components/timeline.md +19 -3
  299. package/docs/components/toggle-inline-button.md +42 -10
  300. package/docs/components/upload-files-preview.md +23 -2
  301. package/docs/components/use-field-controller.md +58 -0
  302. package/docs/components/user-menu.md +26 -6
  303. package/docs/contracts/dependency-map.md +50 -52
  304. package/docs/contracts/field-controller.md +138 -0
  305. package/docs/contracts/style-imports.md +1 -20
  306. package/llms.txt +70 -72
  307. package/package.json +48 -11
  308. package/dist/components/Forms/AsyncSelect.d.ts +0 -20
  309. package/dist/components/Forms/AsyncSelect.d.ts.map +0 -1
  310. package/dist/components/Forms/AsyncSelect.js +0 -77
  311. package/dist/components/Forms/AsyncSelect.js.map +0 -1
  312. package/dist/components/Forms/Combobox.d.ts +0 -10
  313. package/dist/components/Forms/Combobox.d.ts.map +0 -1
  314. package/dist/components/Forms/Combobox.js +0 -11
  315. package/dist/components/Forms/Combobox.js.map +0 -1
  316. package/dist/components/Forms/CurrencyInput.d.ts +0 -12
  317. package/dist/components/Forms/CurrencyInput.d.ts.map +0 -1
  318. package/dist/components/Forms/CurrencyInput.js +0 -9
  319. package/dist/components/Forms/CurrencyInput.js.map +0 -1
  320. package/dist/components/Forms/DateInput.d.ts +0 -10
  321. package/dist/components/Forms/DateInput.d.ts.map +0 -1
  322. package/dist/components/Forms/DateInput.js +0 -11
  323. package/dist/components/Forms/DateInput.js.map +0 -1
  324. package/dist/components/Forms/DateRangeInput.d.ts +0 -10
  325. package/dist/components/Forms/DateRangeInput.d.ts.map +0 -1
  326. package/dist/components/Forms/DateRangeInput.js +0 -13
  327. package/dist/components/Forms/DateRangeInput.js.map +0 -1
  328. package/dist/components/Forms/DropDown.d.ts +0 -10
  329. package/dist/components/Forms/DropDown.d.ts.map +0 -1
  330. package/dist/components/Forms/DropDown.js +0 -11
  331. package/dist/components/Forms/DropDown.js.map +0 -1
  332. package/dist/components/Forms/MultiSelect.d.ts +0 -10
  333. package/dist/components/Forms/MultiSelect.d.ts.map +0 -1
  334. package/dist/components/Forms/MultiSelect.js +0 -13
  335. package/dist/components/Forms/MultiSelect.js.map +0 -1
  336. package/dist/components/Forms/NumberInput.d.ts +0 -10
  337. package/dist/components/Forms/NumberInput.d.ts.map +0 -1
  338. package/dist/components/Forms/NumberInput.js +0 -16
  339. package/dist/components/Forms/NumberInput.js.map +0 -1
  340. package/dist/components/Forms/Select.d.ts +0 -15
  341. package/dist/components/Forms/Select.d.ts.map +0 -1
  342. package/dist/components/Forms/Select.js +0 -48
  343. package/dist/components/Forms/Select.js.map +0 -1
  344. package/dist/components/Forms/Switch.d.ts +0 -18
  345. package/dist/components/Forms/Switch.d.ts.map +0 -1
  346. package/dist/components/Forms/Switch.js +0 -30
  347. package/dist/components/Forms/Switch.js.map +0 -1
  348. package/dist/components/Forms/TextInput.d.ts +0 -11
  349. package/dist/components/Forms/TextInput.d.ts.map +0 -1
  350. package/dist/components/Forms/TextInput.js +0 -12
  351. package/dist/components/Forms/TextInput.js.map +0 -1
  352. package/dist/components/Forms/TimePicker.d.ts +0 -13
  353. package/dist/components/Forms/TimePicker.d.ts.map +0 -1
  354. package/dist/components/Forms/TimePicker.js +0 -19
  355. package/dist/components/Forms/TimePicker.js.map +0 -1
  356. package/dist/components/Forms/Toggle.d.ts +0 -14
  357. package/dist/components/Forms/Toggle.d.ts.map +0 -1
  358. package/dist/components/Forms/Toggle.js +0 -10
  359. package/dist/components/Forms/Toggle.js.map +0 -1
  360. package/dist/components/Forms/types.d.ts +0 -9
  361. package/dist/components/Forms/types.d.ts.map +0 -1
  362. package/dist/components/Forms/types.js +0 -2
  363. package/dist/components/Forms/types.js.map +0 -1
  364. package/docs/components/async-select.md +0 -27
  365. package/docs/components/combobox.md +0 -19
  366. package/docs/components/currency-input.md +0 -21
  367. package/docs/components/date-input.md +0 -21
  368. package/docs/components/date-range-input.md +0 -20
  369. package/docs/components/drop-down.md +0 -26
  370. package/docs/components/multi-select.md +0 -22
  371. package/docs/components/number-input.md +0 -21
  372. package/docs/components/select.md +0 -28
  373. package/docs/components/switch.md +0 -24
  374. package/docs/components/text-input.md +0 -24
  375. package/docs/components/time-picker.md +0 -25
  376. package/docs/components/toggle.md +0 -24
  377. package/docs/contracts/component-doc-schema.md +0 -78
  378. package/docs/contracts/controller-props.md +0 -28
package/catalog.json ADDED
@@ -0,0 +1,3031 @@
1
+ {
2
+ "_generated": "GENERATED by `pnpm gen:catalog` — do not edit. Source: docs/components/*.md",
3
+ "package": "@mantis-core/ui",
4
+ "categories": {
5
+ "forms": [
6
+ {
7
+ "name": "AutoCompleteField",
8
+ "import": "@mantis-core/ui/components/Forms/AutoCompleteField",
9
+ "category": "forms",
10
+ "whenToUse": "Async (or sync) autocomplete text field wired to react-hook-form via `loadOptions`, with optional free-text `creatable` mode. Absorbs the former AsyncSelect + Combobox.",
11
+ "props": [
12
+ {
13
+ "name": "loadOptions",
14
+ "type": "(query: string) => Promise<readonly Record<string, unknown>[]> | readonly Record<string, unknown>[]",
15
+ "required": true,
16
+ "description": "Called on each query change (PR11 debounces via delay/minLength internally); replaces the old hand-rolled AsyncSelect debounce."
17
+ },
18
+ {
19
+ "name": "creatable",
20
+ "type": "boolean",
21
+ "required": false,
22
+ "default": "false",
23
+ "description": "Allow committing free text matching no option; typed text commits on each keystroke instead of being cleared on blur."
24
+ },
25
+ {
26
+ "name": "optionLabel",
27
+ "type": "string",
28
+ "required": false,
29
+ "default": "'label'",
30
+ "description": "Key read for each option's display label."
31
+ },
32
+ {
33
+ "name": "optionValue",
34
+ "type": "string",
35
+ "required": false,
36
+ "description": "Key read for each option's bound scalar value."
37
+ },
38
+ {
39
+ "name": "placeholder",
40
+ "type": "string",
41
+ "required": false
42
+ },
43
+ {
44
+ "name": "optionTemplate",
45
+ "type": "'default' | 'twoLine'",
46
+ "required": false,
47
+ "default": "'default'",
48
+ "description": "Named per-option render preset; 'twoLine' adds a second line from `descriptionField`."
49
+ },
50
+ {
51
+ "name": "descriptionField",
52
+ "type": "string",
53
+ "required": false,
54
+ "description": "Row key for the second line when optionTemplate is 'twoLine'."
55
+ },
56
+ {
57
+ "name": "renderOption",
58
+ "type": "(option: Record<string, unknown>, index: number) => ReactNode",
59
+ "required": false,
60
+ "description": "Escape hatch: full custom per-option render, overrides optionTemplate."
61
+ },
62
+ {
63
+ "name": "className",
64
+ "type": "string",
65
+ "required": false
66
+ }
67
+ ],
68
+ "example": "import { AutoCompleteField } from '@mantis-core/ui/components/Forms/AutoCompleteField';\nimport { useForm } from 'react-hook-form';\n\nconst CITIES = [\n { label: 'Quito', value: 'UIO' },\n { label: 'Cuenca', value: 'CUE' },\n];\n\nasync function searchCities(query: string) {\n return CITIES.filter((c) => c.label.toLowerCase().includes(query.toLowerCase()));\n}\n\nfunction Example() {\n const { control } = useForm({ defaultValues: { city: null } });\n return (\n <AutoCompleteField\n name='city'\n control={control}\n label='City'\n optionLabel='label'\n optionValue='value'\n loadOptions={searchCities}\n />\n );\n}"
69
+ },
70
+ {
71
+ "name": "CheckboxField",
72
+ "import": "@mantis-core/ui/components/Forms/CheckboxField",
73
+ "category": "forms",
74
+ "whenToUse": "Single boolean checkbox wired to react-hook-form.",
75
+ "props": [],
76
+ "example": "import { CheckboxField } from '@mantis-core/ui/components/Forms/CheckboxField';\nimport { useForm } from 'react-hook-form';\n\nfunction Example() {\n const { control } = useForm({ defaultValues: { acceptsTerms: false } });\n return (\n <CheckboxField\n name='acceptsTerms'\n control={control}\n label='I accept the terms'\n rules={{ required: 'You must accept.' }}\n />\n );\n}"
77
+ },
78
+ {
79
+ "name": "CKEditorInput",
80
+ "import": "@mantis-core/ui/components/Forms/CKEditorInput",
81
+ "category": "forms",
82
+ "whenToUse": "Rich-text WYSIWYG editor (CKEditor 5) wired to react-hook-form; emits an HTML string.",
83
+ "props": [
84
+ {
85
+ "name": "controller",
86
+ "type": "Pick<FieldControllerProps, \"name\" | \"control\" | \"rules\" | \"defaultValue\" | \"shouldUnregister\">",
87
+ "required": true,
88
+ "description": "Nested react-hook-form binding."
89
+ },
90
+ {
91
+ "name": "placeholder",
92
+ "type": "string",
93
+ "required": false,
94
+ "default": "'Escribe aqui...'"
95
+ },
96
+ {
97
+ "name": "disabled",
98
+ "type": "boolean",
99
+ "required": false
100
+ },
101
+ {
102
+ "name": "readOnly",
103
+ "type": "boolean",
104
+ "required": false
105
+ },
106
+ {
107
+ "name": "className",
108
+ "type": "string",
109
+ "required": false
110
+ },
111
+ {
112
+ "name": "preset",
113
+ "type": "'default' | 'blog' | 'property' | 'note'",
114
+ "required": false,
115
+ "default": "'default'",
116
+ "description": "Picks a bundled toolbar layout + min-height + stats visibility."
117
+ },
118
+ {
119
+ "name": "toolbarItems",
120
+ "type": "string[]",
121
+ "required": false,
122
+ "description": "Overrides the preset's toolbar items."
123
+ },
124
+ {
125
+ "name": "minHeight",
126
+ "type": "string",
127
+ "required": false,
128
+ "description": "Overrides the preset's min-height (CSS value)."
129
+ },
130
+ {
131
+ "name": "maxHeight",
132
+ "type": "string",
133
+ "required": false
134
+ },
135
+ {
136
+ "name": "showStats",
137
+ "type": "boolean",
138
+ "required": false,
139
+ "description": "Overrides the preset's word/character/read-time footer."
140
+ },
141
+ {
142
+ "name": "validateNonEmptyHtml",
143
+ "type": "boolean",
144
+ "required": false,
145
+ "default": "true",
146
+ "description": "When `rules.required` is set, also rejects HTML that has no plain-text content."
147
+ },
148
+ {
149
+ "name": "requiredMessage",
150
+ "type": "string",
151
+ "required": false,
152
+ "default": "'Este campo es obligatorio'"
153
+ },
154
+ {
155
+ "name": "config",
156
+ "type": "EditorConfig",
157
+ "required": false,
158
+ "description": "Deep-merged on top of the preset's CKEditor config (plugins/translations override rather than merge)."
159
+ },
160
+ {
161
+ "name": "onReady",
162
+ "type": "(editor: any) => void",
163
+ "required": false
164
+ },
165
+ {
166
+ "name": "onHtmlChange",
167
+ "type": "(html: string) => void",
168
+ "required": false
169
+ },
170
+ {
171
+ "name": "onPlainTextChange",
172
+ "type": "(plainText: string) => void",
173
+ "required": false
174
+ },
175
+ {
176
+ "name": "onMetricsChange",
177
+ "type": "(metrics: CKEditorContentMetrics) => void",
178
+ "required": false,
179
+ "description": "`{ plainText, words, characters, readTimeMinutes }`."
180
+ }
181
+ ],
182
+ "example": "import CKEditorInput from '@mantis-core/ui/components/Forms/CKEditorInput';\nimport { useForm, type FieldValues } from 'react-hook-form';\n\nfunction Example() {\n const { control } = useForm<FieldValues>({ defaultValues: { body: '' } });\n return (\n <CKEditorInput\n controller={{ name: 'body', control, rules: { required: true } }}\n preset='blog'\n />\n );\n}"
183
+ },
184
+ {
185
+ "name": "ColorPickerInput",
186
+ "import": "@mantis-core/ui/components/Forms/ColorPickerInput",
187
+ "category": "forms",
188
+ "whenToUse": "RHF-bound color picker over PR11's compound InputColor (area + sliders + swatch + eyedropper + hex input); value is a hex string.",
189
+ "props": [
190
+ {
191
+ "name": "format",
192
+ "type": "ColorSpace",
193
+ "required": false,
194
+ "description": "Picker color space (e.g. hsb, rgb) — the bound RHF value is always normalized to hex regardless."
195
+ }
196
+ ],
197
+ "example": "import { ColorPickerInput } from '@mantis-core/ui/components/Forms/ColorPickerInput';\nimport { useForm } from 'react-hook-form';\n\nfunction Example() {\n const { control } = useForm({ defaultValues: { brand: '#276def' } });\n return <ColorPickerInput name='brand' control={control} label='Color' />;\n}"
198
+ },
199
+ {
200
+ "name": "DateField",
201
+ "import": "@mantis-core/ui/components/Forms/DateField",
202
+ "category": "forms",
203
+ "whenToUse": "Single date, date-range, or time-only picker wired to react-hook-form; one wrapper covers all three via `selectionMode`/`timeOnly`/`showTime`.",
204
+ "props": [
205
+ {
206
+ "name": "selectionMode",
207
+ "type": "'single' | 'multiple' | 'range'",
208
+ "required": false,
209
+ "default": "'single'",
210
+ "description": "Drives the value shape: Date for single, Date[] for multiple, (Date|null)[] for range."
211
+ },
212
+ {
213
+ "name": "showTime",
214
+ "type": "boolean",
215
+ "required": false,
216
+ "default": "false",
217
+ "description": "Adds hour/minute pickers alongside the calendar."
218
+ },
219
+ {
220
+ "name": "timeOnly",
221
+ "type": "boolean",
222
+ "required": false,
223
+ "default": "false",
224
+ "description": "Hides the calendar, showing only the time pickers."
225
+ },
226
+ {
227
+ "name": "hourFormat",
228
+ "type": "'12' | '24'",
229
+ "required": false,
230
+ "default": "'24'",
231
+ "description": "Adds an AM/PM picker when set to 12."
232
+ },
233
+ {
234
+ "name": "showSeconds",
235
+ "type": "boolean",
236
+ "required": false,
237
+ "default": "false",
238
+ "description": "Adds a seconds picker (with showTime/timeOnly)."
239
+ },
240
+ {
241
+ "name": "minDate",
242
+ "type": "Date",
243
+ "required": false
244
+ },
245
+ {
246
+ "name": "maxDate",
247
+ "type": "Date",
248
+ "required": false
249
+ },
250
+ {
251
+ "name": "placeholder",
252
+ "type": "string",
253
+ "required": false
254
+ },
255
+ {
256
+ "name": "showButtonBar",
257
+ "type": "boolean",
258
+ "required": false,
259
+ "default": "false",
260
+ "description": "Renders a Today + Clear footer inside the panel."
261
+ }
262
+ ],
263
+ "example": "import { DateField } from '@mantis-core/ui/components/Forms/DateField';\nimport { useForm } from 'react-hook-form';\n\nfunction Example() {\n const { control } = useForm({ defaultValues: { fecha: null as Date | null } });\n return <DateField name='fecha' control={control} label='Fecha' />;\n}"
264
+ },
265
+ {
266
+ "name": "DatePresets",
267
+ "import": "@mantis-core/ui/components/Forms/DatePresets",
268
+ "category": "forms",
269
+ "whenToUse": "Row of quick-range preset buttons (Today, 7 days, 30 days, This month) that fire onChange with a [Date, Date] tuple. Not RHF-bound — pair with a `DateField` in `selectionMode=\"range\"`.",
270
+ "props": [
271
+ {
272
+ "name": "onChange",
273
+ "type": "(range: [Date, Date]) => void",
274
+ "required": true
275
+ },
276
+ {
277
+ "name": "presets",
278
+ "type": "{ label: string; resolve: () => [Date, Date] }[]",
279
+ "required": false,
280
+ "description": "Defaults to Today / 7 días / 30 días / Este mes."
281
+ },
282
+ {
283
+ "name": "className",
284
+ "type": "string",
285
+ "required": false
286
+ },
287
+ {
288
+ "name": "disabled",
289
+ "type": "boolean",
290
+ "required": false
291
+ }
292
+ ],
293
+ "example": "import DatePresets from '@mantis-core/ui/components/Forms/DatePresets';\nimport { useState } from 'react';\n\nfunction Example() {\n const [range, setRange] = useState<[Date, Date] | null>(null);\n return <DatePresets onChange={setRange} />;\n}"
294
+ },
295
+ {
296
+ "name": "DirtyFormGuard",
297
+ "import": "@mantis-core/ui/components/Forms/DirtyFormGuard",
298
+ "category": "forms",
299
+ "whenToUse": "Blocks tab-close/reload when a react-hook-form has unsaved changes; render it declaratively, or use the underlying useDirtyFormGuard hook to also guard programmatic navigation.",
300
+ "props": [
301
+ {
302
+ "name": "isDirty",
303
+ "type": "boolean",
304
+ "required": true,
305
+ "description": "Pass formState.isDirty from react-hook-form"
306
+ },
307
+ {
308
+ "name": "enabled",
309
+ "type": "boolean",
310
+ "required": false,
311
+ "default": "true",
312
+ "description": "Set to false to temporarily disable the guard"
313
+ },
314
+ {
315
+ "name": "message",
316
+ "type": "string",
317
+ "required": false,
318
+ "description": "Custom confirmation message shown to the user"
319
+ }
320
+ ],
321
+ "example": "import DirtyFormGuard from '@mantis-core/ui/components/Forms/DirtyFormGuard';\nimport { useForm } from 'react-hook-form';\n\nfunction Example() {\n const { formState } = useForm({ defaultValues: { name: '' } });\n return <DirtyFormGuard isDirty={formState.isDirty} />;\n}"
322
+ },
323
+ {
324
+ "name": "ErrorMessage",
325
+ "import": "@mantis-core/ui/components/Forms/ErrorMessage",
326
+ "category": "forms",
327
+ "whenToUse": "Standalone validation-error text for one named react-hook-form field, read from form context; use when composing a custom layout instead of FormFieldRender.",
328
+ "props": [
329
+ {
330
+ "name": "name",
331
+ "type": "string",
332
+ "required": true,
333
+ "description": "The RHF field name to read the error for."
334
+ }
335
+ ],
336
+ "example": "import ErrorMessage from '@mantis-core/ui/components/Forms/ErrorMessage';\nimport { FormProvider, useForm } from 'react-hook-form';\n\nfunction Example() {\n const methods = useForm({ defaultValues: { email: '' } });\n return (\n <FormProvider {...methods}>\n <ErrorMessage name='email' />\n </FormProvider>\n );\n}"
337
+ },
338
+ {
339
+ "name": "FieldShell",
340
+ "import": "@mantis-core/ui/components/Forms/FieldShell",
341
+ "category": "forms",
342
+ "whenToUse": "Presentation primitive for label + addon + help/error composition around one input; every FieldControllerProps-based field wrapper renders it internally — reach for it directly only when hand-building a new wrapper (see field-controller.md).",
343
+ "props": [
344
+ {
345
+ "name": "id",
346
+ "type": "string",
347
+ "required": true,
348
+ "description": "Input id; also roots the generated help/error ids (`${id}-help` / `${id}-error`)."
349
+ },
350
+ {
351
+ "name": "label",
352
+ "type": "string",
353
+ "required": false
354
+ },
355
+ {
356
+ "name": "required",
357
+ "type": "boolean",
358
+ "required": false,
359
+ "description": "Presentational ` *` marker on the label; validation is still driven by rules."
360
+ },
361
+ {
362
+ "name": "helpText",
363
+ "type": "string",
364
+ "required": false
365
+ },
366
+ {
367
+ "name": "errorMessage",
368
+ "type": "string",
369
+ "required": false,
370
+ "description": "Typically `useFieldController(...).errorMessage`."
371
+ },
372
+ {
373
+ "name": "labelMode",
374
+ "type": "LabelMode",
375
+ "required": false,
376
+ "description": "'ifta' | 'float' | 'beside' | 'top' | 'none' — defaults to MantisThemeProvider."
377
+ },
378
+ {
379
+ "name": "floatVariant",
380
+ "type": "FloatVariant",
381
+ "required": false,
382
+ "description": "'over' | 'in' | 'on' — only used when labelMode='float'."
383
+ },
384
+ {
385
+ "name": "addonBefore",
386
+ "type": "ReactNode",
387
+ "required": false
388
+ },
389
+ {
390
+ "name": "addonAfter",
391
+ "type": "ReactNode",
392
+ "required": false
393
+ },
394
+ {
395
+ "name": "children",
396
+ "type": "ReactNode",
397
+ "required": true,
398
+ "description": "The input/trigger element."
399
+ }
400
+ ],
401
+ "example": "import { FieldShell } from '@mantis-core/ui/components/Forms/FieldShell';\n\nfunction Example() {\n return (\n <FieldShell id='email' label='Email' helpText='We will never share it.'>\n <input id='email' type='email' />\n </FieldShell>\n );\n}"
402
+ },
403
+ {
404
+ "name": "FileDropzone",
405
+ "import": "@mantis-core/ui/components/Forms/FileDropzone",
406
+ "category": "forms",
407
+ "whenToUse": "Drag-and-drop file input with validation (type, size, count); supports a react-hook-form binding or plain controlled value/onChange.",
408
+ "props": [
409
+ {
410
+ "name": "controller",
411
+ "type": "Pick<FieldControllerProps, \"name\" | \"control\" | \"rules\" | \"defaultValue\" | \"shouldUnregister\">",
412
+ "required": false,
413
+ "description": "When provided, wires the dropzone to react-hook-form via this nested object."
414
+ },
415
+ {
416
+ "name": "value",
417
+ "type": "File[]",
418
+ "required": false,
419
+ "description": "Controlled file list (plain mode, when `controller` is omitted)"
420
+ },
421
+ {
422
+ "name": "onChange",
423
+ "type": "(files: File[]) => void",
424
+ "required": false,
425
+ "description": "Change handler (plain mode)"
426
+ },
427
+ {
428
+ "name": "onFilesAccepted",
429
+ "type": "(files: File[]) => void",
430
+ "required": false,
431
+ "description": "Called with accepted files after drop"
432
+ },
433
+ {
434
+ "name": "onFilesRejected",
435
+ "type": "(rejections: FileDropzoneRejectedFile[]) => void",
436
+ "required": false,
437
+ "description": "Called with rejected files after drop"
438
+ },
439
+ {
440
+ "name": "multiple",
441
+ "type": "boolean",
442
+ "required": false,
443
+ "default": "true",
444
+ "description": "Allow multiple files"
445
+ },
446
+ {
447
+ "name": "maxFiles",
448
+ "type": "number",
449
+ "required": false,
450
+ "default": "10",
451
+ "description": "Maximum number of files"
452
+ },
453
+ {
454
+ "name": "maxSizeBytes",
455
+ "type": "number",
456
+ "required": false,
457
+ "default": "10485760",
458
+ "description": "Max file size in bytes (default 10 MB)"
459
+ },
460
+ {
461
+ "name": "accept",
462
+ "type": "string | string[]",
463
+ "required": false,
464
+ "description": "Accepted MIME types or extensions"
465
+ },
466
+ {
467
+ "name": "disabled",
468
+ "type": "boolean",
469
+ "required": false,
470
+ "default": "false",
471
+ "description": "Disable the dropzone"
472
+ },
473
+ {
474
+ "name": "block",
475
+ "type": "boolean",
476
+ "required": false,
477
+ "default": "true",
478
+ "description": "Full-width layout"
479
+ },
480
+ {
481
+ "name": "label",
482
+ "type": "string",
483
+ "required": false,
484
+ "description": "Optional label above the zone"
485
+ },
486
+ {
487
+ "name": "hint",
488
+ "type": "string",
489
+ "required": false,
490
+ "description": "Hint text inside the zone"
491
+ },
492
+ {
493
+ "name": "dropTitle",
494
+ "type": "string",
495
+ "required": false,
496
+ "description": "Title text when idle"
497
+ },
498
+ {
499
+ "name": "dragOverTitle",
500
+ "type": "string",
501
+ "required": false,
502
+ "description": "Title text while dragging over"
503
+ },
504
+ {
505
+ "name": "className",
506
+ "type": "string",
507
+ "required": false,
508
+ "description": "Additional CSS class on the root element"
509
+ }
510
+ ],
511
+ "example": "import FileDropzone from '@mantis-core/ui/components/Forms/FileDropzone';\nimport { useForm, type FieldValues } from 'react-hook-form';\n\nfunction Example() {\n const { control } = useForm<FieldValues>({ defaultValues: { documents: [] as File[] } });\n return (\n <FileDropzone\n controller={{ name: 'documents', control }}\n accept={['.pdf', '.jpg']}\n maxFiles={5}\n />\n );\n}"
512
+ },
513
+ {
514
+ "name": "FormActionsBar",
515
+ "import": "@mantis-core/ui/components/Forms/FormActionsBar",
516
+ "category": "forms",
517
+ "whenToUse": "Sticky-capable action bar with primary/secondary buttons and optional left/right slots for form pages.",
518
+ "props": [
519
+ {
520
+ "name": "className",
521
+ "type": "string",
522
+ "required": false,
523
+ "description": "Additional CSS class on the root element"
524
+ },
525
+ {
526
+ "name": "align",
527
+ "type": "'start' | 'end' | 'between'",
528
+ "required": false,
529
+ "default": "'between'",
530
+ "description": "Horizontal alignment of action groups"
531
+ },
532
+ {
533
+ "name": "sticky",
534
+ "type": "boolean",
535
+ "required": false,
536
+ "default": "false",
537
+ "description": "Fix bar to bottom of viewport"
538
+ },
539
+ {
540
+ "name": "leftSlot",
541
+ "type": "ReactNode",
542
+ "required": false,
543
+ "description": "Content rendered on the left side"
544
+ },
545
+ {
546
+ "name": "rightSlot",
547
+ "type": "ReactNode",
548
+ "required": false,
549
+ "description": "Content rendered before the action buttons on the right"
550
+ },
551
+ {
552
+ "name": "primaryLabel",
553
+ "type": "string",
554
+ "required": false,
555
+ "default": "'Guardar'",
556
+ "description": "Label for the primary button"
557
+ },
558
+ {
559
+ "name": "primaryVariant",
560
+ "type": "ButtonVariant",
561
+ "required": false,
562
+ "default": "'primary'",
563
+ "description": "Design-system variant for primary button"
564
+ },
565
+ {
566
+ "name": "primaryType",
567
+ "type": "'button' | 'submit' | 'reset'",
568
+ "required": false,
569
+ "default": "'submit'",
570
+ "description": "HTML type for primary button"
571
+ },
572
+ {
573
+ "name": "primaryLoading",
574
+ "type": "boolean",
575
+ "required": false,
576
+ "default": "false",
577
+ "description": "Show loading spinner on primary button"
578
+ },
579
+ {
580
+ "name": "primaryDisabled",
581
+ "type": "boolean",
582
+ "required": false,
583
+ "default": "false",
584
+ "description": "Disable primary button"
585
+ },
586
+ {
587
+ "name": "onPrimaryClick",
588
+ "type": "() => void",
589
+ "required": false,
590
+ "description": "Click handler for primary button"
591
+ },
592
+ {
593
+ "name": "secondaryLabel",
594
+ "type": "string",
595
+ "required": false,
596
+ "description": "Label for the secondary button; omit to hide it"
597
+ },
598
+ {
599
+ "name": "secondaryVariant",
600
+ "type": "ButtonVariant",
601
+ "required": false,
602
+ "default": "'secondary'",
603
+ "description": "Design-system variant for secondary button"
604
+ },
605
+ {
606
+ "name": "secondaryType",
607
+ "type": "'button' | 'submit' | 'reset'",
608
+ "required": false,
609
+ "default": "'button'",
610
+ "description": "HTML type for secondary button"
611
+ },
612
+ {
613
+ "name": "secondaryOutlined",
614
+ "type": "boolean",
615
+ "required": false,
616
+ "default": "true",
617
+ "description": "Render secondary button as outlined"
618
+ },
619
+ {
620
+ "name": "secondaryDisabled",
621
+ "type": "boolean",
622
+ "required": false,
623
+ "default": "false",
624
+ "description": "Disable secondary button"
625
+ },
626
+ {
627
+ "name": "onSecondaryClick",
628
+ "type": "() => void",
629
+ "required": false,
630
+ "description": "Click handler for secondary button"
631
+ }
632
+ ],
633
+ "example": "import FormActionsBar from '@mantis-core/ui/components/Forms/FormActionsBar';\n\nfunction Example() {\n return (\n <FormActionsBar\n primaryLabel='Save'\n secondaryLabel='Cancel'\n onPrimaryClick={() => {}}\n onSecondaryClick={() => {}}\n />\n );\n}"
634
+ },
635
+ {
636
+ "name": "FormFieldRender",
637
+ "import": "@mantis-core/ui/components/Forms/FormFieldRender",
638
+ "category": "forms",
639
+ "whenToUse": "Composes a label, a render-prop input slot, and an inline ErrorMessage for one field; use to wrap a custom/non-Mantis input with the same label+error layout as the field wrappers.",
640
+ "props": [
641
+ {
642
+ "name": "name",
643
+ "type": "string",
644
+ "required": true,
645
+ "description": "RHF field name; forwarded to `render` and to the inline ErrorMessage."
646
+ },
647
+ {
648
+ "name": "label",
649
+ "type": "string | ReactElement",
650
+ "required": true
651
+ },
652
+ {
653
+ "name": "labelProps",
654
+ "type": "LabelHTMLAttributes<HTMLLabelElement>",
655
+ "required": false
656
+ },
657
+ {
658
+ "name": "containerClassName",
659
+ "type": "string",
660
+ "required": false
661
+ },
662
+ {
663
+ "name": "render",
664
+ "type": "({ name }: { name: string }) => ReactElement | ReactNode",
665
+ "required": true,
666
+ "description": "Renders the actual input; receives `name` to wire to your own Controller/register call."
667
+ }
668
+ ],
669
+ "example": "import FormFieldRender from '@mantis-core/ui/components/Forms/FormFieldRender';\nimport { Controller, FormProvider, useForm, type FieldValues } from 'react-hook-form';\n\nfunction Example() {\n const methods = useForm<FieldValues>({ defaultValues: { email: '' } });\n return (\n <FormProvider {...methods}>\n <FormFieldRender\n name='email'\n label='Email'\n render={({ name }) => (\n <Controller\n name={name}\n control={methods.control}\n render={({ field }) => <input {...field} id={name} />}\n />\n )}\n />\n </FormProvider>\n );\n}"
670
+ },
671
+ {
672
+ "name": "FormWizard",
673
+ "import": "@mantis-core/ui/components/Forms/FormWizard",
674
+ "category": "forms",
675
+ "whenToUse": "Multi-step form navigator with a PR11 Stepper step indicator and per-step field validation; must render inside a FormProvider, parent owns the <form onSubmit>.",
676
+ "props": [
677
+ {
678
+ "name": "steps",
679
+ "type": "FormWizardStep[]",
680
+ "required": true,
681
+ "description": "Each step: `{ label, fields?: string[], content: ReactNode }`. `fields` are validated (via `trigger`) before advancing."
682
+ },
683
+ {
684
+ "name": "onComplete",
685
+ "type": "() => void | Promise<void>",
686
+ "required": false,
687
+ "description": "Escape hatch for wizard usage outside a <form> element; when set, the final step's button uses type=\"button\" instead of \"submit\"."
688
+ },
689
+ {
690
+ "name": "submitLabel",
691
+ "type": "string",
692
+ "required": false,
693
+ "default": "'Finalizar'"
694
+ },
695
+ {
696
+ "name": "className",
697
+ "type": "string",
698
+ "required": false
699
+ }
700
+ ],
701
+ "example": "import FormWizard from '@mantis-core/ui/components/Forms/FormWizard';\nimport { FormProvider, useForm } from 'react-hook-form';\n\nfunction Example() {\n const form = useForm({ defaultValues: { name: '', email: '' } });\n return (\n <FormProvider {...form}>\n <form onSubmit={form.handleSubmit(() => {})}>\n <FormWizard\n steps={[\n { label: 'Data', fields: ['name', 'email'], content: <div>Step 1</div> },\n { label: 'Confirm', content: <div>Step 2</div> },\n ]}\n submitLabel='Save'\n />\n </form>\n </FormProvider>\n );\n}"
702
+ },
703
+ {
704
+ "name": "HiddenField",
705
+ "import": "@mantis-core/ui/components/Forms/HiddenField",
706
+ "category": "forms",
707
+ "whenToUse": "Registers a react-hook-form value with no visible UI.",
708
+ "props": [],
709
+ "example": "import { HiddenField } from '@mantis-core/ui/components/Forms/HiddenField';\nimport { useForm } from 'react-hook-form';\n\nfunction Example() {\n const { control } = useForm({ defaultValues: { id: '' } });\n return <HiddenField name='id' control={control} />;\n}"
710
+ },
711
+ {
712
+ "name": "MaskField",
713
+ "import": "@mantis-core/ui/components/Forms/MaskField",
714
+ "category": "forms",
715
+ "whenToUse": "Generic masked text input (digit/letter/alphanumeric tokens) wired to react-hook-form; value is the masked display string.",
716
+ "props": [
717
+ {
718
+ "name": "mask",
719
+ "type": "string",
720
+ "required": true,
721
+ "description": "Pattern: '9'=digit, 'a'=letter, '*'=alphanumeric; any other character is a literal emitted automatically."
722
+ }
723
+ ],
724
+ "example": "import { MaskField } from '@mantis-core/ui/components/Forms/MaskField';\nimport { useForm } from 'react-hook-form';\n\nfunction Example() {\n const { control } = useForm({ defaultValues: { code: '' } });\n return <MaskField name='code' control={control} mask='999-999' label='Code' />;\n}"
725
+ },
726
+ {
727
+ "name": "NumberField",
728
+ "import": "@mantis-core/ui/components/Forms/NumberField",
729
+ "category": "forms",
730
+ "whenToUse": "Numeric input (integer, decimal, or currency) wired to react-hook-form.",
731
+ "props": [
732
+ {
733
+ "name": "mode",
734
+ "type": "'decimal' | 'currency'",
735
+ "required": false,
736
+ "description": "PR11 InputNumber Root config. `currency` is the sole replacement for the removed CurrencyInput wrapper."
737
+ },
738
+ {
739
+ "name": "currency",
740
+ "type": "string",
741
+ "required": false,
742
+ "description": "ISO currency code, only used when mode=\"currency\" (e.g. \"USD\")."
743
+ },
744
+ {
745
+ "name": "locale",
746
+ "type": "string",
747
+ "required": false,
748
+ "description": "Intl locale for formatting."
749
+ },
750
+ {
751
+ "name": "min",
752
+ "type": "number",
753
+ "required": false
754
+ },
755
+ {
756
+ "name": "max",
757
+ "type": "number",
758
+ "required": false
759
+ },
760
+ {
761
+ "name": "step",
762
+ "type": "number",
763
+ "required": false
764
+ }
765
+ ],
766
+ "example": "import { NumberField } from '@mantis-core/ui/components/Forms/NumberField';\nimport { useForm } from 'react-hook-form';\n\nfunction Example() {\n const { control } = useForm({ defaultValues: { price: null as number | null } });\n return (\n <NumberField name='price' control={control} label='Price' mode='currency' currency='USD' />\n );\n}"
767
+ },
768
+ {
769
+ "name": "OtpInput",
770
+ "import": "@mantis-core/ui/components/Forms/OtpInput",
771
+ "category": "forms",
772
+ "whenToUse": "RHF-bound one-time-password input over PR11's compound InputOtp; renders `length` segmented boxes.",
773
+ "props": [
774
+ {
775
+ "name": "length",
776
+ "type": "number",
777
+ "required": false,
778
+ "default": "6",
779
+ "description": "How many segmented slots render."
780
+ },
781
+ {
782
+ "name": "integerOnly",
783
+ "type": "boolean",
784
+ "required": false,
785
+ "description": "Restrict input to digits."
786
+ },
787
+ {
788
+ "name": "mask",
789
+ "type": "boolean",
790
+ "required": false,
791
+ "description": "Obscure each slot like a password."
792
+ }
793
+ ],
794
+ "example": "import { OtpInput } from '@mantis-core/ui/components/Forms/OtpInput';\nimport { useForm } from 'react-hook-form';\n\nfunction Example() {\n const { control } = useForm({ defaultValues: { code: '' } });\n return <OtpInput name='code' control={control} label='Código' length={6} integerOnly />;\n}"
795
+ },
796
+ {
797
+ "name": "PasswordInput",
798
+ "import": "@mantis-core/ui/components/Forms/PasswordInput",
799
+ "category": "forms",
800
+ "whenToUse": "RHF-bound password field over PR11 InputPassword with a native show/hide toggle and a lightweight strength meter.",
801
+ "props": [
802
+ {
803
+ "name": "showToggle",
804
+ "type": "boolean",
805
+ "required": false,
806
+ "default": "true",
807
+ "description": "Renders the Eye/EyeSlash show/hide toggle."
808
+ },
809
+ {
810
+ "name": "feedback",
811
+ "type": "boolean",
812
+ "required": false,
813
+ "default": "true",
814
+ "description": "Renders the strength meter below the input."
815
+ }
816
+ ],
817
+ "example": "import { PasswordInput } from '@mantis-core/ui/components/Forms/PasswordInput';\nimport { useForm } from 'react-hook-form';\n\nfunction Example() {\n const { control } = useForm({ defaultValues: { password: '' } });\n return <PasswordInput name='password' control={control} label='Contraseña' rules={{ required: true }} />;\n}"
818
+ },
819
+ {
820
+ "name": "PhoneInput",
821
+ "import": "@mantis-core/ui/components/Forms/PhoneInput",
822
+ "category": "forms",
823
+ "whenToUse": "Phone-number preset of MaskField; defaults to a US-style (999) 999-9999 mask.",
824
+ "props": [
825
+ {
826
+ "name": "mask",
827
+ "type": "string",
828
+ "required": false,
829
+ "default": "'(999) 999-9999'",
830
+ "description": "Override the phone mask for other formats."
831
+ }
832
+ ],
833
+ "example": "import { PhoneInput } from '@mantis-core/ui/components/Forms/PhoneInput';\nimport { useForm } from 'react-hook-form';\n\nfunction Example() {\n const { control } = useForm({ defaultValues: { phone: '' } });\n return <PhoneInput name='phone' control={control} label='Teléfono' />;\n}"
834
+ },
835
+ {
836
+ "name": "RadioGroup",
837
+ "import": "@mantis-core/ui/components/Forms/RadioGroup",
838
+ "category": "forms",
839
+ "whenToUse": "Single-choice radio group over PR11's RadioButtonGroup; value is the selected option's value.",
840
+ "props": [
841
+ {
842
+ "name": "options",
843
+ "type": "Record<string, unknown>[]",
844
+ "required": true,
845
+ "description": "Option rows rendered as radio items."
846
+ },
847
+ {
848
+ "name": "optionLabel",
849
+ "type": "string",
850
+ "required": false,
851
+ "default": "'label'",
852
+ "description": "Key read for each option's display label."
853
+ },
854
+ {
855
+ "name": "optionValue",
856
+ "type": "string",
857
+ "required": false,
858
+ "default": "'value'",
859
+ "description": "Key read for each option's bound value."
860
+ },
861
+ {
862
+ "name": "renderOption",
863
+ "type": "(option: Record<string, unknown>, index: number) => ReactNode",
864
+ "required": false,
865
+ "description": "Escape hatch: full custom per-item label render."
866
+ }
867
+ ],
868
+ "example": "import { RadioGroup } from '@mantis-core/ui/components/Forms/RadioGroup';\nimport { useForm } from 'react-hook-form';\n\nconst PLANS = [\n { label: 'Basic', value: 'basic' },\n { label: 'Pro', value: 'pro' },\n];\n\nfunction Example() {\n const { control } = useForm({ defaultValues: { plan: 'basic' } });\n return (\n <RadioGroup\n name='plan'\n control={control}\n label='Plan'\n options={PLANS}\n optionLabel='label'\n optionValue='value'\n />\n );\n}"
869
+ },
870
+ {
871
+ "name": "RangeSlider",
872
+ "import": "@mantis-core/ui/components/Forms/RangeSlider",
873
+ "category": "forms",
874
+ "whenToUse": "RHF-bound slider over PR11's compound Slider; single-handle by default, dual-handle range when the field holds a [number, number] tuple.",
875
+ "props": [
876
+ {
877
+ "name": "min",
878
+ "type": "number",
879
+ "required": false
880
+ },
881
+ {
882
+ "name": "max",
883
+ "type": "number",
884
+ "required": false
885
+ },
886
+ {
887
+ "name": "step",
888
+ "type": "number",
889
+ "required": false
890
+ },
891
+ {
892
+ "name": "orientation",
893
+ "type": "'horizontal' | 'vertical'",
894
+ "required": false
895
+ }
896
+ ],
897
+ "example": "import { RangeSlider } from '@mantis-core/ui/components/Forms/RangeSlider';\nimport { useForm } from 'react-hook-form';\n\nfunction Example() {\n const { control } = useForm({ defaultValues: { price: 100 } });\n return <RangeSlider name='price' control={control} label='Precio' min={0} max={500} />;\n}"
898
+ },
899
+ {
900
+ "name": "RatingInput",
901
+ "import": "@mantis-core/ui/components/Forms/RatingInput",
902
+ "category": "forms",
903
+ "whenToUse": "RHF-bound star rating over PR11's compound Rating; stores a numeric value.",
904
+ "props": [
905
+ {
906
+ "name": "stars",
907
+ "type": "number",
908
+ "required": false,
909
+ "default": "5",
910
+ "description": "How many star options render."
911
+ }
912
+ ],
913
+ "example": "import { RatingInput } from '@mantis-core/ui/components/Forms/RatingInput';\nimport { useForm } from 'react-hook-form';\n\nfunction Example() {\n const { control } = useForm({ defaultValues: { score: null as number | null } });\n return <RatingInput name='score' control={control} label='Puntaje' stars={5} />;\n}"
914
+ },
915
+ {
916
+ "name": "RenderField",
917
+ "import": "@mantis-core/ui/components/Forms/RenderField",
918
+ "category": "forms",
919
+ "whenToUse": "Low-level escape hatch wrapping react-hook-form's Controller via a render prop; use to wire any custom or third-party input without building a full FieldControllerProps wrapper.",
920
+ "props": [
921
+ {
922
+ "name": "name",
923
+ "type": "string",
924
+ "required": true
925
+ },
926
+ {
927
+ "name": "render",
928
+ "type": "(props: { field, fieldState, formState, value }) => ReactElement",
929
+ "required": true
930
+ },
931
+ {
932
+ "name": "defaultValue",
933
+ "type": "any",
934
+ "required": false
935
+ },
936
+ {
937
+ "name": "rules",
938
+ "type": "RegisterOptions",
939
+ "required": false
940
+ },
941
+ {
942
+ "name": "control",
943
+ "type": "Control",
944
+ "required": false
945
+ }
946
+ ],
947
+ "example": "import RenderField from '@mantis-core/ui/components/Forms/RenderField';\nimport { useForm, type FieldValues } from 'react-hook-form';\n\nfunction Example() {\n const { control } = useForm<FieldValues>({ defaultValues: { rating: 0 } });\n return (\n <RenderField\n name='rating'\n control={control}\n render={({ field }) => (\n <input\n type='number'\n value={field.value}\n onChange={(e) => field.onChange(Number(e.target.value))}\n />\n )}\n />\n );\n}"
948
+ },
949
+ {
950
+ "name": "SearchInput",
951
+ "import": "@mantis-core/ui/components/Forms/SearchInput",
952
+ "category": "forms",
953
+ "whenToUse": "RHF-bound search box over PR11 InputText with a search icon and a debounced onSearch callback; ideal for live table/list filtering.",
954
+ "props": [
955
+ {
956
+ "name": "onSearch",
957
+ "type": "(value: string) => void",
958
+ "required": false,
959
+ "description": "Fires debounced with the current value on each change."
960
+ },
961
+ {
962
+ "name": "debounceMs",
963
+ "type": "number",
964
+ "required": false,
965
+ "default": "300"
966
+ }
967
+ ],
968
+ "example": "import { SearchInput } from '@mantis-core/ui/components/Forms/SearchInput';\nimport { useForm } from 'react-hook-form';\n\nfunction Example() {\n const { control } = useForm({ defaultValues: { q: '' } });\n return <SearchInput name='q' control={control} label='Buscar' onSearch={(value) => console.log(value)} />;\n}"
969
+ },
970
+ {
971
+ "name": "SelectField",
972
+ "import": "@mantis-core/ui/components/Forms/SelectField",
973
+ "category": "forms",
974
+ "whenToUse": "Single- or multi-select dropdown wired to react-hook-form over PR11's portal-based Select; pass `multiple` for array-value mode. Absorbs the former Select/DropDown/MultiSelect.",
975
+ "props": [
976
+ {
977
+ "name": "options",
978
+ "type": "Record<string, unknown>[]",
979
+ "required": true,
980
+ "description": "Option rows rendered in the popup."
981
+ },
982
+ {
983
+ "name": "optionLabel",
984
+ "type": "string",
985
+ "required": false,
986
+ "default": "'label'",
987
+ "description": "Key read for each option's display label."
988
+ },
989
+ {
990
+ "name": "optionValue",
991
+ "type": "string",
992
+ "required": false,
993
+ "description": "Key read for each option's bound value; falls back to the whole row."
994
+ },
995
+ {
996
+ "name": "multiple",
997
+ "type": "boolean",
998
+ "required": false,
999
+ "default": "false",
1000
+ "description": "Array-value mode with in-popup filter + checkmark indicators; empty selection binds `[]`, never `null`."
1001
+ },
1002
+ {
1003
+ "name": "placeholder",
1004
+ "type": "string",
1005
+ "required": false,
1006
+ "description": "Trigger placeholder; suppressed automatically in floating label modes (ifta/float) when a label is set."
1007
+ },
1008
+ {
1009
+ "name": "optionTemplate",
1010
+ "type": "'default' | 'twoLine'",
1011
+ "required": false,
1012
+ "default": "'default'",
1013
+ "description": "Named per-option render preset; 'twoLine' adds a second line from `descriptionField`."
1014
+ },
1015
+ {
1016
+ "name": "descriptionField",
1017
+ "type": "string",
1018
+ "required": false,
1019
+ "description": "Row key for the second line when optionTemplate is 'twoLine'."
1020
+ },
1021
+ {
1022
+ "name": "renderOption",
1023
+ "type": "(option: Record<string, unknown>, index: number) => ReactNode",
1024
+ "required": false,
1025
+ "description": "Escape hatch: full custom per-option render, overrides optionTemplate."
1026
+ },
1027
+ {
1028
+ "name": "className",
1029
+ "type": "string",
1030
+ "required": false
1031
+ }
1032
+ ],
1033
+ "example": "import { SelectField } from '@mantis-core/ui/components/Forms/SelectField';\nimport { useForm } from 'react-hook-form';\n\nconst CITIES = [\n { label: 'Quito', value: 'UIO' },\n { label: 'Cuenca', value: 'CUE' },\n];\n\nfunction Example() {\n const { control } = useForm({ defaultValues: { city: null } });\n return (\n <SelectField\n name='city'\n control={control}\n label='City'\n options={CITIES}\n optionLabel='label'\n optionValue='value'\n />\n );\n}"
1034
+ },
1035
+ {
1036
+ "name": "SwitchField",
1037
+ "import": "@mantis-core/ui/components/Forms/SwitchField",
1038
+ "category": "forms",
1039
+ "whenToUse": "Boolean on/off toggle wired to react-hook-form.",
1040
+ "props": [],
1041
+ "example": "import { SwitchField } from '@mantis-core/ui/components/Forms/SwitchField';\nimport { useForm } from 'react-hook-form';\n\nfunction Example() {\n const { control } = useForm({ defaultValues: { featured: false } });\n return <SwitchField name='featured' control={control} label='Featured' />;\n}"
1042
+ },
1043
+ {
1044
+ "name": "TagsInput",
1045
+ "import": "@mantis-core/ui/components/Forms/TagsInput",
1046
+ "category": "forms",
1047
+ "whenToUse": "RHF-bound tag/chip input over PR11's compound InputTags; stores value as string[].",
1048
+ "props": [
1049
+ {
1050
+ "name": "placeholder",
1051
+ "type": "string",
1052
+ "required": false,
1053
+ "description": "Shown on the entry input only while no tags are present."
1054
+ },
1055
+ {
1056
+ "name": "max",
1057
+ "type": "number",
1058
+ "required": false,
1059
+ "description": "Max number of tags."
1060
+ },
1061
+ {
1062
+ "name": "delimiter",
1063
+ "type": "string | RegExp",
1064
+ "required": false,
1065
+ "description": "Extra character(s) that commit a tag besides Enter."
1066
+ },
1067
+ {
1068
+ "name": "allowDuplicate",
1069
+ "type": "boolean",
1070
+ "required": false
1071
+ }
1072
+ ],
1073
+ "example": "import { TagsInput } from '@mantis-core/ui/components/Forms/TagsInput';\nimport { useForm } from 'react-hook-form';\n\nfunction Example() {\n const { control } = useForm({ defaultValues: { tags: [] as string[] } });\n return <TagsInput name='tags' control={control} label='Etiquetas' placeholder='Agregar etiqueta...' />;\n}"
1074
+ },
1075
+ {
1076
+ "name": "TextArea",
1077
+ "import": "@mantis-core/ui/components/Forms/TextArea",
1078
+ "category": "forms",
1079
+ "whenToUse": "Multi-line text field wired to react-hook-form.",
1080
+ "props": [
1081
+ {
1082
+ "name": "rows",
1083
+ "type": "number",
1084
+ "required": false,
1085
+ "description": "Native <textarea> passthrough beyond FieldControllerProps."
1086
+ }
1087
+ ],
1088
+ "example": "import { TextArea } from '@mantis-core/ui/components/Forms/TextArea';\nimport { useForm } from 'react-hook-form';\n\nfunction Example() {\n const { control } = useForm({ defaultValues: { notes: '' } });\n return <TextArea name='notes' control={control} label='Notes' rows={4} />;\n}"
1089
+ },
1090
+ {
1091
+ "name": "TextField",
1092
+ "import": "@mantis-core/ui/components/Forms/TextField",
1093
+ "category": "forms",
1094
+ "whenToUse": "Single-line text field wired to react-hook-form.",
1095
+ "props": [
1096
+ {
1097
+ "name": "placeholder",
1098
+ "type": "string",
1099
+ "required": false,
1100
+ "description": "Native <input> passthrough beyond FieldControllerProps."
1101
+ },
1102
+ {
1103
+ "name": "maxLength",
1104
+ "type": "number",
1105
+ "required": false,
1106
+ "description": "Native <input> passthrough beyond FieldControllerProps."
1107
+ }
1108
+ ],
1109
+ "example": "import { TextField } from '@mantis-core/ui/components/Forms/TextField';\nimport { useForm } from 'react-hook-form';\n\nfunction Example() {\n const { control } = useForm({ defaultValues: { title: '' } });\n return <TextField name='title' control={control} label='Title' rules={{ required: true }} />;\n}"
1110
+ },
1111
+ {
1112
+ "name": "ToggleInlineButton",
1113
+ "import": "@mantis-core/ui/components/Forms/ToggleInlineButton",
1114
+ "category": "forms",
1115
+ "whenToUse": "Segmented single- or multi-choice control over PR11's ToggleButtonGroup; pass `multiple` for array-value mode.",
1116
+ "props": [
1117
+ {
1118
+ "name": "options",
1119
+ "type": "Record<string, unknown>[]",
1120
+ "required": true,
1121
+ "description": "Option rows rendered as segments."
1122
+ },
1123
+ {
1124
+ "name": "optionLabel",
1125
+ "type": "string",
1126
+ "required": false,
1127
+ "default": "'label'",
1128
+ "description": "Key read for each option's display label."
1129
+ },
1130
+ {
1131
+ "name": "optionValue",
1132
+ "type": "string",
1133
+ "required": false,
1134
+ "default": "'value'",
1135
+ "description": "Key read for each option's bound value."
1136
+ },
1137
+ {
1138
+ "name": "multiple",
1139
+ "type": "boolean",
1140
+ "required": false,
1141
+ "default": "false",
1142
+ "description": "Array-value mode; toggles per-segment selection instead of single scalar selection."
1143
+ },
1144
+ {
1145
+ "name": "renderOption",
1146
+ "type": "(option: Record<string, unknown>, index: number) => ReactNode",
1147
+ "required": false,
1148
+ "description": "Escape hatch: full custom per-segment render."
1149
+ }
1150
+ ],
1151
+ "example": "import { ToggleInlineButton } from '@mantis-core/ui/components/Forms/ToggleInlineButton';\nimport { useForm } from 'react-hook-form';\n\nconst VIEWS = [\n { label: 'List', value: 'list' },\n { label: 'Grid', value: 'grid' },\n];\n\nfunction Example() {\n const { control } = useForm({ defaultValues: { view: 'list' } });\n return (\n <ToggleInlineButton\n name='view'\n control={control}\n label='View'\n options={VIEWS}\n optionLabel='label'\n optionValue='value'\n />\n );\n}"
1152
+ },
1153
+ {
1154
+ "name": "UploadFilesPreview",
1155
+ "import": "@mantis-core/ui/components/Forms/UploadFilesPreview",
1156
+ "category": "forms",
1157
+ "whenToUse": "Drag-and-drop upload zone with live preview grid, drag-to-reorder, and async upload queue; designed for image galleries, not react-hook-form bound.",
1158
+ "props": [
1159
+ {
1160
+ "name": "previews",
1161
+ "type": "TItem[]",
1162
+ "required": false,
1163
+ "default": "[]",
1164
+ "description": "Already-uploaded items to display in the preview grid"
1165
+ },
1166
+ {
1167
+ "name": "onUploadFile",
1168
+ "type": "(file: File) => Promise<TItem>",
1169
+ "required": true,
1170
+ "description": "Called per file; resolves to the stored item"
1171
+ },
1172
+ {
1173
+ "name": "onFileUploaded",
1174
+ "type": "(file: TItem) => void",
1175
+ "required": true,
1176
+ "description": "Called after each successful upload"
1177
+ },
1178
+ {
1179
+ "name": "onRemoveFile",
1180
+ "type": "(item: TItem) => void",
1181
+ "required": true,
1182
+ "description": "Called when user removes a preview item"
1183
+ },
1184
+ {
1185
+ "name": "onReorder",
1186
+ "type": "(items: TItem[]) => void",
1187
+ "required": true,
1188
+ "description": "Called after drag-to-reorder with new order"
1189
+ },
1190
+ {
1191
+ "name": "accept",
1192
+ "type": "string",
1193
+ "required": false,
1194
+ "default": "'image/*'",
1195
+ "description": "Accepted MIME types for the file input"
1196
+ },
1197
+ {
1198
+ "name": "disabled",
1199
+ "type": "boolean",
1200
+ "required": false,
1201
+ "default": "false",
1202
+ "description": "Disable uploads and interactions"
1203
+ },
1204
+ {
1205
+ "name": "disabledMessage",
1206
+ "type": "string",
1207
+ "required": false,
1208
+ "description": "Message shown in the drop zone when disabled"
1209
+ },
1210
+ {
1211
+ "name": "copy",
1212
+ "type": "Partial<UploadFilesPreviewCopy>",
1213
+ "required": false,
1214
+ "description": "Override any UI text strings"
1215
+ }
1216
+ ],
1217
+ "example": "import UploadFilesPreview from '@mantis-core/ui/components/Forms/UploadFilesPreview';\n\nfunction Example() {\n return (\n <UploadFilesPreview\n previews={[{ id: '1', fullUrl: 'https://example.com/photo.jpg' }]}\n onUploadFile={async (file) => ({ id: file.name, fullUrl: URL.createObjectURL(file) })}\n onFileUploaded={() => {}}\n onRemoveFile={() => {}}\n onReorder={() => {}}\n />\n );\n}"
1218
+ },
1219
+ {
1220
+ "name": "useFieldController",
1221
+ "import": "@mantis-core/ui/components/Forms/useFieldController",
1222
+ "category": "forms",
1223
+ "whenToUse": "Hook every RHF field wrapper calls internally to wire useController + a stable id/aria/disabled/error-message resolution; call it directly only when hand-building a new field wrapper (see field-controller.md).",
1224
+ "props": [],
1225
+ "example": "import { FieldShell } from '@mantis-core/ui/components/Forms/FieldShell';\nimport { useFieldController, type FieldControllerProps } from '@mantis-core/ui/components/Forms/useFieldController';\nimport { useForm, type FieldValues, type FieldPath } from 'react-hook-form';\n\nfunction RatingField<TFieldValues extends FieldValues, TName extends FieldPath<TFieldValues>>(\n props: FieldControllerProps<TFieldValues, TName>,\n) {\n const f = useFieldController<TFieldValues, TName>(props);\n return (\n <FieldShell id={f.id} label={props.label} errorMessage={f.errorMessage}>\n <input\n id={f.id}\n type='number'\n value={(f.field.value as number) ?? 0}\n onChange={(e) => f.field.onChange(Number(e.target.value))}\n onBlur={f.field.onBlur}\n disabled={f.disabled}\n {...f.aria}\n />\n </FieldShell>\n );\n}\n\nfunction Example() {\n const { control } = useForm({ defaultValues: { rating: 0 } });\n return <RatingField name='rating' control={control} label='Rating' />;\n}"
1226
+ }
1227
+ ],
1228
+ "tables": [
1229
+ {
1230
+ "name": "ActionColumn",
1231
+ "import": "@mantis-core/ui/components/Tables/ActionColumn",
1232
+ "category": "tables",
1233
+ "whenToUse": "Factory that returns a row-action `ColumnDef` for MantisDataTable/PaginatedTable's `columns` array; each row's `body` renders a `MenuButton` populated by `items(row)`.",
1234
+ "props": [
1235
+ {
1236
+ "name": "items",
1237
+ "type": "(row: T) => ActionMenuItem[]",
1238
+ "required": true,
1239
+ "description": "First factory argument — produces the per-row menu entries."
1240
+ },
1241
+ {
1242
+ "name": "label",
1243
+ "type": "string",
1244
+ "required": false,
1245
+ "description": "Second argument (ActionColumnOptions): trigger button label."
1246
+ },
1247
+ {
1248
+ "name": "icon",
1249
+ "type": "string",
1250
+ "required": false,
1251
+ "description": "Second argument (ActionColumnOptions): trigger button icon (PrimeIcons class)."
1252
+ }
1253
+ ],
1254
+ "example": "import { actionColumn } from '@mantis-core/ui/components/Tables/ActionColumn';\nimport { MantisDataTable } from '@mantis-core/ui/components/Tables/MantisDataTable';\nimport type { ColumnDef } from '@mantis-core/ui/components/Tables/columns';\n\ninterface Property {\n id: string;\n name: string;\n}\n\nfunction Example() {\n const rows: Property[] = [{ id: '1', name: 'Casa Ceibos' }];\n const columns: ColumnDef<Property>[] = [\n { field: 'name', header: 'Name' },\n actionColumn<Property>((p) => [\n { label: 'Edit', icon: 'pi pi-pencil', route: `/properties/${p.id}/edit` },\n { label: 'Delete', icon: 'pi pi-trash', command: () => console.log(p.id) },\n ]),\n ];\n return <MantisDataTable rows={rows} columns={columns} />;\n}"
1255
+ },
1256
+ {
1257
+ "name": "FilterPannel",
1258
+ "import": "@mantis-core/ui/components/Tables/FilterPannel",
1259
+ "category": "tables",
1260
+ "whenToUse": "Slide-in filter sidebar for tables; wraps RHF-bound filter fields in their own `FormProvider` and calls `onApplyFilter` with the cleaned form data.",
1261
+ "props": [
1262
+ {
1263
+ "name": "onApplyFilter",
1264
+ "type": "(data: T) => Promise<void>",
1265
+ "required": true,
1266
+ "description": "Called with the cleaned form data on submit (Aplicar), or `{}` on reset (Restaurar)."
1267
+ }
1268
+ ],
1269
+ "example": "import FilterPannel from '@mantis-core/ui/components/Tables/FilterPannel';\nimport TableFilterField from '@mantis-core/ui/components/table-filter-field';\nimport { useFormContext } from 'react-hook-form';\n\ninterface Filters {\n search: string;\n}\n\nfunction SearchField() {\n const { register } = useFormContext<Filters>();\n return (\n <TableFilterField label='Search' htmlFor='search'>\n <input id='search' {...register('search')} />\n </TableFilterField>\n );\n}\n\nfunction Example() {\n const onApplyFilter = async (data: Filters) => console.log(data);\n return (\n <FilterPannel<Filters> onApplyFilter={onApplyFilter}>\n <SearchField />\n </FilterPannel>\n );\n}"
1270
+ },
1271
+ {
1272
+ "name": "IndexColumn",
1273
+ "import": "@mantis-core/ui/components/Tables/IndexColumn",
1274
+ "category": "tables",
1275
+ "whenToUse": "Factory that returns a 1-based row-number `ColumnDef` for MantisDataTable/PaginatedTable's `columns` array.",
1276
+ "props": [
1277
+ {
1278
+ "name": "overrides",
1279
+ "type": "Partial<ColumnDef<T>>",
1280
+ "required": false,
1281
+ "description": "Overrides merged onto the default index ColumnDef (field/header/width/body)."
1282
+ }
1283
+ ],
1284
+ "example": "import { indexColumn } from '@mantis-core/ui/components/Tables/IndexColumn';\nimport { MantisDataTable } from '@mantis-core/ui/components/Tables/MantisDataTable';\nimport type { ColumnDef } from '@mantis-core/ui/components/Tables/columns';\n\ninterface Property {\n id: string;\n name: string;\n}\n\nfunction Example() {\n const rows: Property[] = [{ id: '1', name: 'Casa Ceibos' }];\n const columns: ColumnDef<Property>[] = [indexColumn<Property>({ width: '3rem' }), { field: 'name', header: 'Name' }];\n return <MantisDataTable rows={rows} columns={columns} />;\n}"
1285
+ },
1286
+ {
1287
+ "name": "MantisDataTable",
1288
+ "import": "@mantis-core/ui/components/Tables/MantisDataTable",
1289
+ "category": "tables",
1290
+ "whenToUse": "The 90% shortcut over PR11's compound DataTable — one flat `columns: ColumnDef[]` array renders the whole TableContainer→Table→THead→TBody→EmptyTBody tree with striped rows + gridlines. Default table for any grid; drop to `PaginatedTable` for pagination + index/action columns baked in.",
1291
+ "props": [
1292
+ {
1293
+ "name": "rows",
1294
+ "type": "T[]",
1295
+ "required": true,
1296
+ "description": "Row data (PR11's `data`, renamed since PR11 root's own `rows` means page size)."
1297
+ },
1298
+ {
1299
+ "name": "columns",
1300
+ "type": "ColumnDef<T>[]",
1301
+ "required": true,
1302
+ "description": "Flat column descriptor array — see ColumnDef shape below."
1303
+ },
1304
+ {
1305
+ "name": "rowsPerPage",
1306
+ "type": "number",
1307
+ "required": false,
1308
+ "description": "Forwarded to PR11 Root's `rows` (page size). Only relevant with `paginator`."
1309
+ },
1310
+ {
1311
+ "name": "selectable",
1312
+ "type": "boolean",
1313
+ "required": false,
1314
+ "default": "false",
1315
+ "description": "Prepends a checkbox selection column. Requires `selectionMode` on the passthrough root props."
1316
+ },
1317
+ {
1318
+ "name": "emptyMessage",
1319
+ "type": "ReactNode",
1320
+ "required": false,
1321
+ "default": "'No records'"
1322
+ },
1323
+ {
1324
+ "name": "filters",
1325
+ "type": "Record<string, string>",
1326
+ "required": false,
1327
+ "description": "Current per-field filter values (page-owned state, not RHF)."
1328
+ },
1329
+ {
1330
+ "name": "onFilterChange",
1331
+ "type": "(field: string, value: string) => void",
1332
+ "required": false,
1333
+ "description": "Fires when a header filter control (text/dropdown preset or custom filterElement) changes."
1334
+ }
1335
+ ],
1336
+ "example": "import { MantisDataTable } from '@mantis-core/ui/components/Tables/MantisDataTable';\nimport { currencyCell, badgeCell } from '@mantis-core/ui/components/Tables/cell-presets';\nimport type { ColumnDef } from '@mantis-core/ui/components/Tables/columns';\n\ninterface Property {\n id: string;\n name: string;\n price: number;\n status: string;\n}\n\nconst COLUMNS: ColumnDef<Property>[] = [\n { field: 'name', header: 'Name', sortable: true, filter: 'text' },\n { field: 'price', header: 'Price', cell: currencyCell({ currency: 'USD' }) },\n {\n field: 'status',\n header: 'Status',\n cell: badgeCell({ styles: { active: 'bg-green-100 text-green-700' } }),\n filter: 'dropdown',\n filterOptions: [\n { label: 'Active', value: 'active' },\n { label: 'Draft', value: 'draft' },\n ],\n },\n];\n\nfunction Example() {\n const rows: Property[] = [{ id: '1', name: 'Casa Ceibos', price: 125000, status: 'active' }];\n return <MantisDataTable rows={rows} columns={COLUMNS} emptyMessage='No properties yet' />;\n}"
1337
+ },
1338
+ {
1339
+ "name": "MenuButton",
1340
+ "import": "@mantis-core/ui/components/Tables/MenuButton",
1341
+ "category": "tables",
1342
+ "whenToUse": "Row-action overlay menu — a trigger button that opens a popup list of actions; used inside `actionColumn`/table row cells, or standalone.",
1343
+ "props": [
1344
+ {
1345
+ "name": "label",
1346
+ "type": "string",
1347
+ "required": false,
1348
+ "description": "Trigger button label."
1349
+ },
1350
+ {
1351
+ "name": "icon",
1352
+ "type": "string",
1353
+ "required": false,
1354
+ "default": "'pi pi-cog'",
1355
+ "description": "Trigger button icon (PrimeIcons class)."
1356
+ },
1357
+ {
1358
+ "name": "items",
1359
+ "type": "ActionMenuItem[]",
1360
+ "required": false,
1361
+ "default": "[]"
1362
+ }
1363
+ ],
1364
+ "example": "import MenuButton, { type ActionMenuItem } from '@mantis-core/ui/components/Tables/MenuButton';\n\nfunction Example() {\n const items: ActionMenuItem[] = [\n { label: 'Edit', icon: 'pi pi-pencil', route: '/properties/1/edit' },\n { label: 'Delete', icon: 'pi pi-trash', command: () => console.log('delete') },\n ];\n return <MenuButton items={items} label='Actions' />;\n}"
1365
+ },
1366
+ {
1367
+ "name": "MultiSelectFilter",
1368
+ "import": "@mantis-core/ui/components/Tables/filters/MultiSelectFilter",
1369
+ "category": "tables",
1370
+ "whenToUse": "Multi-value header filter over the themed PR11 `Select` (multiple mode) — drops into a `ColumnDef`'s `filterElement` escape hatch when a column needs array-valued filtering instead of the scalar `filters` map.",
1371
+ "props": [
1372
+ {
1373
+ "name": "options",
1374
+ "type": "FilterOption[]",
1375
+ "required": true
1376
+ },
1377
+ {
1378
+ "name": "value",
1379
+ "type": "string[]",
1380
+ "required": false,
1381
+ "default": "[]"
1382
+ },
1383
+ {
1384
+ "name": "onChange",
1385
+ "type": "(value: string[]) => void",
1386
+ "required": true
1387
+ },
1388
+ {
1389
+ "name": "loading",
1390
+ "type": "boolean",
1391
+ "required": false,
1392
+ "default": "false",
1393
+ "description": "Disables the control while the option list loads."
1394
+ },
1395
+ {
1396
+ "name": "placeholder",
1397
+ "type": "string",
1398
+ "required": false,
1399
+ "default": "'Seleccione'"
1400
+ }
1401
+ ],
1402
+ "example": "import MultiSelectFilter from '@mantis-core/ui/components/Tables/filters/MultiSelectFilter';\nimport { useState } from 'react';\n\nfunction Example() {\n const [selected, setSelected] = useState<string[]>([]);\n const options = [\n { label: 'Active', value: 'active' },\n { label: 'Draft', value: 'draft' },\n ];\n return <MultiSelectFilter options={options} value={selected} onChange={setSelected} />;\n}"
1403
+ },
1404
+ {
1405
+ "name": "PaginatedTable",
1406
+ "import": "@mantis-core/ui/components/Tables/PaginatedTable",
1407
+ "category": "tables",
1408
+ "whenToUse": "Thin preset over MantisDataTable with `paginator` on by default plus optional index/action columns — the default table shell for admin list pages.",
1409
+ "props": [
1410
+ {
1411
+ "name": "rows",
1412
+ "type": "T[]",
1413
+ "required": true
1414
+ },
1415
+ {
1416
+ "name": "columns",
1417
+ "type": "ColumnDef<T>[]",
1418
+ "required": true
1419
+ },
1420
+ {
1421
+ "name": "paginator",
1422
+ "type": "boolean",
1423
+ "required": false,
1424
+ "default": "true",
1425
+ "description": "PR11 Root prop; PaginatedTable flips the MantisDataTable default on."
1426
+ },
1427
+ {
1428
+ "name": "showIndexColumn",
1429
+ "type": "boolean",
1430
+ "required": false,
1431
+ "default": "true",
1432
+ "description": "Prepend a 1-based row-number column."
1433
+ },
1434
+ {
1435
+ "name": "indexColumnOptions",
1436
+ "type": "Partial<ColumnDef<T>>",
1437
+ "required": false,
1438
+ "description": "Overrides for the prepended index column."
1439
+ },
1440
+ {
1441
+ "name": "showActionColumn",
1442
+ "type": "boolean",
1443
+ "required": false,
1444
+ "default": "false",
1445
+ "description": "Append a row-action menu column."
1446
+ },
1447
+ {
1448
+ "name": "actionColumnItems",
1449
+ "type": "(row: T) => ActionMenuItem[]",
1450
+ "required": false,
1451
+ "description": "Per-row action items for the appended action column."
1452
+ },
1453
+ {
1454
+ "name": "actionColumnOptions",
1455
+ "type": "ActionColumnOptions<T>",
1456
+ "required": false,
1457
+ "description": "Overrides for the appended action column."
1458
+ }
1459
+ ],
1460
+ "example": "import { PaginatedTable } from '@mantis-core/ui/components/Tables/PaginatedTable';\nimport type { ColumnDef } from '@mantis-core/ui/components/Tables/columns';\n\ninterface Property {\n id: string;\n name: string;\n}\n\nconst COLUMNS: ColumnDef<Property>[] = [{ field: 'name', header: 'Name' }];\n\nfunction Example() {\n const rows: Property[] = [{ id: '1', name: 'Casa Ceibos' }];\n return (\n <PaginatedTable\n rows={rows}\n columns={COLUMNS}\n rowsPerPage={10}\n showActionColumn\n actionColumnItems={(p) => [{ label: 'Edit', route: `/properties/${p.id}/edit` }]}\n />\n );\n}"
1461
+ },
1462
+ {
1463
+ "name": "TableFilterField",
1464
+ "import": "@mantis-core/ui/components/table-filter-field",
1465
+ "category": "tables",
1466
+ "whenToUse": "Wraps a form control with a `<label>` inside a `FilterPannel`, providing consistent layout.",
1467
+ "props": [
1468
+ {
1469
+ "name": "label",
1470
+ "type": "ReactNode",
1471
+ "required": true
1472
+ },
1473
+ {
1474
+ "name": "htmlFor",
1475
+ "type": "string",
1476
+ "required": true
1477
+ },
1478
+ {
1479
+ "name": "className",
1480
+ "type": "string",
1481
+ "required": false
1482
+ },
1483
+ {
1484
+ "name": "labelClassName",
1485
+ "type": "string",
1486
+ "required": false
1487
+ }
1488
+ ],
1489
+ "example": "import TableFilterField from '@mantis-core/ui/components/table-filter-field';\n\nfunction Example() {\n return (\n <TableFilterField label='Status' htmlFor='filter-status'>\n <select id='filter-status'>\n <option value='active'>Active</option>\n </select>\n </TableFilterField>\n );\n}"
1490
+ },
1491
+ {
1492
+ "name": "TableToolbar",
1493
+ "import": "@mantis-core/ui/components/table-toolbar",
1494
+ "category": "tables",
1495
+ "whenToUse": "Header bar above a table showing title, record-count meta, and an action buttons slot.",
1496
+ "props": [
1497
+ {
1498
+ "name": "title",
1499
+ "type": "ReactNode",
1500
+ "required": false
1501
+ },
1502
+ {
1503
+ "name": "totalRecords",
1504
+ "type": "number",
1505
+ "required": false,
1506
+ "description": "When `meta` is omitted, renders as \"{n} registros disponibles\"."
1507
+ },
1508
+ {
1509
+ "name": "meta",
1510
+ "type": "ReactNode",
1511
+ "required": false,
1512
+ "description": "Overrides the auto-generated `totalRecords` copy."
1513
+ },
1514
+ {
1515
+ "name": "actions",
1516
+ "type": "ReactNode",
1517
+ "required": false
1518
+ },
1519
+ {
1520
+ "name": "className",
1521
+ "type": "string",
1522
+ "required": false
1523
+ },
1524
+ {
1525
+ "name": "copyClassName",
1526
+ "type": "string",
1527
+ "required": false,
1528
+ "description": "Extra class on the title+meta wrapper."
1529
+ },
1530
+ {
1531
+ "name": "actionsClassName",
1532
+ "type": "string",
1533
+ "required": false,
1534
+ "description": "Extra class on the actions wrapper."
1535
+ }
1536
+ ],
1537
+ "example": "import TableToolbar from '@mantis-core/ui/components/table-toolbar';\nimport Button from '@mantis-core/ui/components/Buttons/Button';\n\nfunction Example() {\n return <TableToolbar title='Users' totalRecords={42} actions={<Button label='New' />} />;\n}"
1538
+ }
1539
+ ],
1540
+ "pages": [
1541
+ {
1542
+ "name": "AdminPageConfigurator",
1543
+ "import": "@mantis-core/ui/components/pages/admin-layout/AdminPageConfigurator",
1544
+ "category": "pages",
1545
+ "whenToUse": "Sets the page title, description, breadcrumbs, and actions in the admin layout shell via context; wrap each page's content with this.",
1546
+ "props": [
1547
+ {
1548
+ "name": "config",
1549
+ "type": "AdminPageLayoutConfig",
1550
+ "required": true,
1551
+ "description": "{ title?, description?, breadcrumbs?, actions?, hideHeader? }"
1552
+ },
1553
+ {
1554
+ "name": "children",
1555
+ "type": "ReactNode",
1556
+ "required": true
1557
+ }
1558
+ ],
1559
+ "example": "import AdminPageConfigurator from '@mantis-core/ui/components/pages/admin-layout/AdminPageConfigurator';\nimport { AdminPageLayoutProvider } from '@mantis-core/ui';\n\nfunction Example() {\n return (\n <AdminPageLayoutProvider>\n <AdminPageConfigurator\n config={{\n title: 'Properties',\n description: 'Manage listings',\n breadcrumbs: [{ label: 'Home', href: '/' }, { label: 'Properties' }],\n }}>\n <div>Properties view</div>\n </AdminPageConfigurator>\n </AdminPageLayoutProvider>\n );\n}"
1560
+ },
1561
+ {
1562
+ "name": "AdminPageHeader",
1563
+ "import": "@mantis-core/ui/components/pages/AdminPageHeader",
1564
+ "category": "pages",
1565
+ "whenToUse": "Gradient page header with title, optional description, breadcrumbs, and a right-side actions slot; rendered by AdminPageLayoutShell — avoid rendering directly inside feature views.",
1566
+ "props": [
1567
+ {
1568
+ "name": "title",
1569
+ "type": "string",
1570
+ "required": true
1571
+ },
1572
+ {
1573
+ "name": "description",
1574
+ "type": "string",
1575
+ "required": false
1576
+ },
1577
+ {
1578
+ "name": "actions",
1579
+ "type": "ReactNode",
1580
+ "required": false
1581
+ },
1582
+ {
1583
+ "name": "breadcrumbs",
1584
+ "type": "readonly AdminBreadcrumbItem[]",
1585
+ "required": false
1586
+ }
1587
+ ],
1588
+ "example": "import AdminPageHeader from '@mantis-core/ui/components/pages/AdminPageHeader';\nimport Button from '@mantis-core/ui/components/Buttons/Button';\n\nfunction Example() {\n return (\n <AdminPageHeader\n title='Blog'\n description='Manage posts'\n actions={<Button label='New Post' onClick={() => {}} />}\n />\n );\n}"
1589
+ },
1590
+ {
1591
+ "name": "AdminPageLayoutShell",
1592
+ "import": "@mantis-core/ui/components/pages/admin-layout/AdminPageLayoutShell",
1593
+ "category": "pages",
1594
+ "whenToUse": "Root layout shell for admin pages; renders AdminPageHeader from context set by AdminPageConfigurator and provides the page grid/max-width.",
1595
+ "props": [
1596
+ {
1597
+ "name": "children",
1598
+ "type": "ReactNode",
1599
+ "required": true
1600
+ }
1601
+ ],
1602
+ "example": "import AdminPageLayoutShell from '@mantis-core/ui/components/pages/admin-layout/AdminPageLayoutShell';\nimport { AdminPageLayoutProvider } from '@mantis-core/ui';\n\nfunction Example() {\n return (\n <AdminPageLayoutProvider>\n <AdminPageLayoutShell>\n <div>Page content</div>\n </AdminPageLayoutShell>\n </AdminPageLayoutProvider>\n );\n}"
1603
+ },
1604
+ {
1605
+ "name": "AppShell",
1606
+ "import": "@mantis-core/ui/components/pages/app-shell/AppShell",
1607
+ "category": "pages",
1608
+ "whenToUse": "Full-page app shell with responsive sidebar nav, topbar, and mobile drawer; use as the root layout wrapper for authenticated pages.",
1609
+ "props": [
1610
+ {
1611
+ "name": "navItems",
1612
+ "type": "AppNavItem[]",
1613
+ "required": true,
1614
+ "description": "Each item: { label, href?, icon?, children? }. Items with children render as a collapsible group."
1615
+ },
1616
+ {
1617
+ "name": "children",
1618
+ "type": "ReactNode",
1619
+ "required": true
1620
+ },
1621
+ {
1622
+ "name": "brand",
1623
+ "type": "ReactNode",
1624
+ "required": false,
1625
+ "description": "Logo/name slot rendered in the sidebar header and mobile topbar."
1626
+ },
1627
+ {
1628
+ "name": "topbarActions",
1629
+ "type": "ReactNode",
1630
+ "required": false
1631
+ },
1632
+ {
1633
+ "name": "user",
1634
+ "type": "ReactNode",
1635
+ "required": false,
1636
+ "description": "Rendered at the end of the topbar."
1637
+ },
1638
+ {
1639
+ "name": "footer",
1640
+ "type": "ReactNode",
1641
+ "required": false,
1642
+ "description": "Rendered at the bottom of the sidebar and mobile drawer."
1643
+ },
1644
+ {
1645
+ "name": "collapsible",
1646
+ "type": "boolean",
1647
+ "required": false,
1648
+ "default": false,
1649
+ "description": "Enables a toggle button to collapse the desktop sidebar to icons-only."
1650
+ },
1651
+ {
1652
+ "name": "defaultCollapsed",
1653
+ "type": "boolean",
1654
+ "required": false,
1655
+ "default": false
1656
+ }
1657
+ ],
1658
+ "example": "import AppShell from '@mantis-core/ui/components/pages/app-shell/AppShell';\n\nfunction Example() {\n return (\n <AppShell\n navItems={[\n { label: 'Dashboard', href: '/admin' },\n { label: 'Properties', href: '/admin/properties' },\n ]}\n brand={<span>Atlas</span>}>\n <div>Page content</div>\n </AppShell>\n );\n}"
1659
+ },
1660
+ {
1661
+ "name": "Breadcrumbs",
1662
+ "import": "@mantis-core/ui/components/pages/app-shell/Breadcrumbs",
1663
+ "category": "pages",
1664
+ "whenToUse": "Standalone breadcrumb nav; renders nothing when items is empty.",
1665
+ "props": [
1666
+ {
1667
+ "name": "items",
1668
+ "type": "readonly AdminBreadcrumbItem[]",
1669
+ "required": true,
1670
+ "description": "Each item: { label, href? }. The last item never links even if it has an href."
1671
+ }
1672
+ ],
1673
+ "example": "import Breadcrumbs from '@mantis-core/ui/components/pages/app-shell/Breadcrumbs';\n\nfunction Example() {\n return <Breadcrumbs items={[{ label: 'Home', href: '/' }, { label: 'Settings' }]} />;\n}"
1674
+ },
1675
+ {
1676
+ "name": "FormSection",
1677
+ "import": "@mantis-core/ui/components/pages/FormSection",
1678
+ "category": "pages",
1679
+ "whenToUse": "Bordered card section with a header (title + description + icon) and a padded body; groups related form fields.",
1680
+ "props": [
1681
+ {
1682
+ "name": "title",
1683
+ "type": "string",
1684
+ "required": true
1685
+ },
1686
+ {
1687
+ "name": "description",
1688
+ "type": "string",
1689
+ "required": false
1690
+ },
1691
+ {
1692
+ "name": "icon",
1693
+ "type": "ReactNode",
1694
+ "required": false
1695
+ },
1696
+ {
1697
+ "name": "children",
1698
+ "type": "ReactNode",
1699
+ "required": true
1700
+ },
1701
+ {
1702
+ "name": "className",
1703
+ "type": "string",
1704
+ "required": false
1705
+ }
1706
+ ],
1707
+ "example": "import FormSection from '@mantis-core/ui/components/pages/FormSection';\nimport { TextField } from '@mantis-core/ui/components/Forms/TextField';\nimport { useForm } from 'react-hook-form';\n\nfunction Example() {\n const { control } = useForm({ defaultValues: { email: '' } });\n return (\n <FormSection title='Contact Info' description='Public contact details'>\n <TextField name='email' control={control} label='Email' />\n </FormSection>\n );\n}"
1708
+ },
1709
+ {
1710
+ "name": "PageTitle",
1711
+ "import": "@mantis-core/ui/components/pages/PageTitle",
1712
+ "category": "pages",
1713
+ "whenToUse": "Centered display-font heading for public-facing pages.",
1714
+ "props": [
1715
+ {
1716
+ "name": "children",
1717
+ "type": "ReactNode",
1718
+ "required": true
1719
+ }
1720
+ ],
1721
+ "example": "import PageTitle from '@mantis-core/ui/components/pages/PageTitle';\n\nfunction Example() {\n return <PageTitle>Propiedades en Venta</PageTitle>;\n}"
1722
+ }
1723
+ ],
1724
+ "maps": [
1725
+ {
1726
+ "name": "MapPicker",
1727
+ "import": "@mantis-core/ui/components/Maps/MapPicker",
1728
+ "category": "maps",
1729
+ "whenToUse": "SSR-safe entry point for the Leaflet lat/lng picker; lazy-loads MapPickerClient via next/dynamic (ssr:false).",
1730
+ "props": [
1731
+ {
1732
+ "name": "onLocationSelect",
1733
+ "type": "(lat: number, lng: number) => void",
1734
+ "required": true,
1735
+ "description": "Fired on map click with the picked coordinates."
1736
+ },
1737
+ {
1738
+ "name": "initialLat",
1739
+ "type": "number | null",
1740
+ "required": false
1741
+ },
1742
+ {
1743
+ "name": "initialLng",
1744
+ "type": "number | null",
1745
+ "required": false
1746
+ }
1747
+ ],
1748
+ "example": "import { useState } from 'react';\nimport MapPicker from '@mantis-core/ui/components/Maps/MapPicker';\n\nfunction Example() {\n const [coords, setCoords] = useState<{ lat: number; lng: number } | null>(null);\n\n return (\n <MapPicker\n onLocationSelect={(lat, lng) => setCoords({ lat, lng })}\n initialLat={-3.26}\n initialLng={-79.28}\n />\n );\n}"
1749
+ },
1750
+ {
1751
+ "name": "MapPickerClient",
1752
+ "import": "@mantis-core/ui/components/Maps/MapPickerClient",
1753
+ "category": "maps",
1754
+ "whenToUse": "Client-only react-leaflet map (click-to-pick marker); the piece MapPicker lazy-loads. Use directly only if you already own the ssr:false boundary.",
1755
+ "props": [
1756
+ {
1757
+ "name": "onLocationSelect",
1758
+ "type": "(lat: number, lng: number) => void",
1759
+ "required": true,
1760
+ "description": "Fired on map click with the picked coordinates."
1761
+ },
1762
+ {
1763
+ "name": "initialLat",
1764
+ "type": "number | null",
1765
+ "required": false,
1766
+ "description": "Initial marker/center latitude; defaults to a fixed Yunguilla-area center when omitted."
1767
+ },
1768
+ {
1769
+ "name": "initialLng",
1770
+ "type": "number | null",
1771
+ "required": false,
1772
+ "description": "Initial marker/center longitude; defaults to a fixed Yunguilla-area center when omitted."
1773
+ }
1774
+ ],
1775
+ "example": "'use client';\nimport { useState } from 'react';\nimport MapPickerClient from '@mantis-core/ui/components/Maps/MapPickerClient';\n\nfunction Example() {\n const [coords, setCoords] = useState<{ lat: number; lng: number } | null>(null);\n\n return (\n <MapPickerClient\n onLocationSelect={(lat, lng) => setCoords({ lat, lng })}\n initialLat={-3.26}\n initialLng={-79.28}\n />\n );\n}"
1776
+ },
1777
+ {
1778
+ "name": "MapPickerOSM",
1779
+ "import": "@mantis-core/ui/components/Maps/MapPickerOSM",
1780
+ "category": "maps",
1781
+ "whenToUse": "Script-injected Leaflet map (no react-leaflet/SSR bundle cost) with a draggable marker and an explicit \"save location\" button.",
1782
+ "props": [
1783
+ {
1784
+ "name": "initialPosition",
1785
+ "type": "LatLng",
1786
+ "required": false,
1787
+ "default": "{ lat: -12.0464, lng: -77.0428 }",
1788
+ "description": "Initial marker/center position."
1789
+ },
1790
+ {
1791
+ "name": "zoom",
1792
+ "type": "number",
1793
+ "required": false,
1794
+ "default": "12"
1795
+ },
1796
+ {
1797
+ "name": "height",
1798
+ "type": "string",
1799
+ "required": false,
1800
+ "default": "'400px'",
1801
+ "description": "CSS height of the map container."
1802
+ },
1803
+ {
1804
+ "name": "onChange",
1805
+ "type": "(pos: LatLng) => void",
1806
+ "required": false,
1807
+ "description": "Fired on every click or marker drag."
1808
+ },
1809
+ {
1810
+ "name": "onSave",
1811
+ "type": "(pos: LatLng) => void",
1812
+ "required": false,
1813
+ "description": "Fired only when the user clicks the \"Guardar ubicación\" button."
1814
+ }
1815
+ ],
1816
+ "example": "'use client';\nimport MapPickerOSM from '@mantis-core/ui/components/Maps/MapPickerOSM';\nimport type { LatLng } from '@mantis-core/ui/components/Maps/MapPickerOSM';\n\nfunction Example() {\n const handleSave = (pos: LatLng) => console.log('saved', pos);\n\n return <MapPickerOSM initialPosition={{ lat: -3.26, lng: -79.28 }} onSave={handleSave} />;\n}"
1817
+ }
1818
+ ],
1819
+ "overlays": [
1820
+ {
1821
+ "name": "Drawer",
1822
+ "import": "@mantis-core/ui/components/overlays/Drawer",
1823
+ "category": "overlays",
1824
+ "whenToUse": "Controlled slide-in side panel; composes PR11's headless Drawer compound (Root/Portal/Backdrop/Popup/Header/Content/Footer — no Positioner, unlike Dialog) behind a simple `open`/`side`/`title`/`footer` API.",
1825
+ "props": [
1826
+ {
1827
+ "name": "open",
1828
+ "type": "boolean",
1829
+ "required": true,
1830
+ "description": "Controlled visibility."
1831
+ },
1832
+ {
1833
+ "name": "onOpenChange",
1834
+ "type": "(open: boolean) => void",
1835
+ "required": true,
1836
+ "description": "Fires with the next open value when the backdrop/close toggles it."
1837
+ },
1838
+ {
1839
+ "name": "side",
1840
+ "type": "'left' | 'right' | 'top' | 'bottom'",
1841
+ "required": false,
1842
+ "default": "'right'",
1843
+ "description": "Edge the panel slides in from — maps to PR11 `position`."
1844
+ },
1845
+ {
1846
+ "name": "title",
1847
+ "type": "ReactNode",
1848
+ "required": false,
1849
+ "description": "Header title. Omit to render no header."
1850
+ },
1851
+ {
1852
+ "name": "footer",
1853
+ "type": "ReactNode",
1854
+ "required": false,
1855
+ "description": "Footer content. Omit to render no footer."
1856
+ },
1857
+ {
1858
+ "name": "className",
1859
+ "type": "string",
1860
+ "required": false,
1861
+ "description": "Extra class on the Popup element."
1862
+ },
1863
+ {
1864
+ "name": "children",
1865
+ "type": "ReactNode",
1866
+ "required": false
1867
+ }
1868
+ ],
1869
+ "example": "import Drawer from '@mantis-core/ui/components/overlays/Drawer';\nimport { useState } from 'react';\n\nfunction Example() {\n const [open, setOpen] = useState(false);\n return (\n <Drawer open={open} onOpenChange={setOpen} side='right' title='Filters'>\n <p>Filter form</p>\n </Drawer>\n );\n}"
1870
+ },
1871
+ {
1872
+ "name": "Modal",
1873
+ "import": "@mantis-core/ui/components/overlays/Modal",
1874
+ "category": "overlays",
1875
+ "whenToUse": "Controlled dialog/modal; composes PR11's headless Dialog compound (Root/Portal/Backdrop/Positioner/Popup/Header/Content/Footer) behind a simple `open`/`title`/`footer` API.",
1876
+ "props": [
1877
+ {
1878
+ "name": "open",
1879
+ "type": "boolean",
1880
+ "required": true,
1881
+ "description": "Controlled visibility."
1882
+ },
1883
+ {
1884
+ "name": "onOpenChange",
1885
+ "type": "(open: boolean) => void",
1886
+ "required": true,
1887
+ "description": "Fires with the next open value when the backdrop/close toggles it."
1888
+ },
1889
+ {
1890
+ "name": "title",
1891
+ "type": "ReactNode",
1892
+ "required": false,
1893
+ "description": "Header title. Omit to render no header."
1894
+ },
1895
+ {
1896
+ "name": "footer",
1897
+ "type": "ReactNode",
1898
+ "required": false,
1899
+ "description": "Footer content, usually action buttons. Omit to render no footer."
1900
+ },
1901
+ {
1902
+ "name": "size",
1903
+ "type": "'sm' | 'md' | 'lg' | 'xl'",
1904
+ "required": false,
1905
+ "default": "'md'",
1906
+ "description": "Popup width preset."
1907
+ },
1908
+ {
1909
+ "name": "modal",
1910
+ "type": "boolean",
1911
+ "required": false,
1912
+ "default": "true",
1913
+ "description": "Whether the dialog blocks pointer events behind it."
1914
+ },
1915
+ {
1916
+ "name": "className",
1917
+ "type": "string",
1918
+ "required": false,
1919
+ "description": "Extra class on the Popup element."
1920
+ },
1921
+ {
1922
+ "name": "children",
1923
+ "type": "ReactNode",
1924
+ "required": false
1925
+ }
1926
+ ],
1927
+ "example": "import Modal from '@mantis-core/ui/components/overlays/Modal';\nimport { useState } from 'react';\n\nfunction Example() {\n const [open, setOpen] = useState(false);\n return (\n <Modal\n open={open}\n onOpenChange={setOpen}\n title='Edit property'\n size='lg'\n footer={<button onClick={() => setOpen(false)}>Close</button>}>\n <p>Modal content</p>\n </Modal>\n );\n}"
1928
+ }
1929
+ ],
1930
+ "navigation": [
1931
+ {
1932
+ "name": "CommandPalette",
1933
+ "import": "@mantis-core/ui/components/navigation/CommandPalette",
1934
+ "category": "navigation",
1935
+ "whenToUse": "Keyboard-driven command search overlay (Ctrl/Cmd+K); pair with the `useCommandPalette` hook to wire the shortcut.",
1936
+ "props": [
1937
+ {
1938
+ "name": "commands",
1939
+ "type": "{ id: string; label: string; icon?: ReactNode; keywords?: string[]; onSelect: () => void }[]",
1940
+ "required": true
1941
+ },
1942
+ {
1943
+ "name": "open",
1944
+ "type": "boolean",
1945
+ "required": false,
1946
+ "default": "false"
1947
+ },
1948
+ {
1949
+ "name": "onOpenChange",
1950
+ "type": "(open: boolean) => void",
1951
+ "required": false
1952
+ }
1953
+ ],
1954
+ "example": "import CommandPalette, { useCommandPalette } from '@mantis-core/ui/components/navigation/CommandPalette';\nimport { useState } from 'react';\n\nfunction Example() {\n const [open, setOpen] = useState(false);\n useCommandPalette(() => setOpen(true));\n return (\n <CommandPalette\n open={open}\n onOpenChange={setOpen}\n commands={[{ id: 'new', label: 'New property', onSelect: () => console.log('new') }]}\n />\n );\n}"
1955
+ },
1956
+ {
1957
+ "name": "PageTabs",
1958
+ "import": "@mantis-core/ui/components/navigation/PageTabs",
1959
+ "category": "navigation",
1960
+ "whenToUse": "Page-level navigation tab bar (no panels) over PR11's Tabs compound; each tab navigates via `href` (Next.js router) or runs a `command`. Active tab is derived from the current pathname.",
1961
+ "props": [
1962
+ {
1963
+ "name": "tabs",
1964
+ "type": "{ label: string; icon?: ReactNode; href?: string; command?: () => void }[]",
1965
+ "required": true
1966
+ },
1967
+ {
1968
+ "name": "activeIndex",
1969
+ "type": "number",
1970
+ "required": false,
1971
+ "description": "Forces the active tab index; otherwise derived from the pathname (matched against the tab `href`)."
1972
+ },
1973
+ {
1974
+ "name": "className",
1975
+ "type": "string",
1976
+ "required": false,
1977
+ "default": "'mantis-core-page-tabs'"
1978
+ }
1979
+ ],
1980
+ "example": "import PageTabs from '@mantis-core/ui/components/navigation/PageTabs';\n\nfunction Example() {\n return (\n <PageTabs\n tabs={[\n { label: 'General', href: '/admin/settings' },\n { label: 'Security', href: '/admin/settings/security' },\n ]}\n />\n );\n}"
1981
+ }
1982
+ ],
1983
+ "data": [
1984
+ {
1985
+ "name": "DescriptionList",
1986
+ "import": "@mantis-core/ui/components/data/DescriptionList",
1987
+ "category": "data",
1988
+ "whenToUse": "Grid-based label/value list for detail views; supports 1, 2, or 3 columns.",
1989
+ "props": [
1990
+ {
1991
+ "name": "items",
1992
+ "type": "{ label: string; value: ReactNode }[]",
1993
+ "required": true
1994
+ },
1995
+ {
1996
+ "name": "columns",
1997
+ "type": "1 | 2 | 3",
1998
+ "required": false,
1999
+ "default": "1"
2000
+ }
2001
+ ],
2002
+ "example": "import DescriptionList from '@mantis-core/ui/components/data/DescriptionList';\n\nfunction Example() {\n return (\n <DescriptionList\n columns={2}\n items={[\n { label: 'Name', value: 'Jane Doe' },\n { label: 'Email', value: 'jane@example.com' },\n ]}\n />\n );\n}"
2003
+ },
2004
+ {
2005
+ "name": "StatCard",
2006
+ "import": "@mantis-core/ui/components/data/StatCard",
2007
+ "category": "data",
2008
+ "whenToUse": "KPI card showing a metric label, large value, optional icon, trend indicator, and footer.",
2009
+ "props": [
2010
+ {
2011
+ "name": "label",
2012
+ "type": "string",
2013
+ "required": true
2014
+ },
2015
+ {
2016
+ "name": "value",
2017
+ "type": "ReactNode",
2018
+ "required": true
2019
+ },
2020
+ {
2021
+ "name": "icon",
2022
+ "type": "ReactNode",
2023
+ "required": false
2024
+ },
2025
+ {
2026
+ "name": "trend",
2027
+ "type": "{ value: number; direction: 'up' | 'down' }",
2028
+ "required": false
2029
+ },
2030
+ {
2031
+ "name": "footer",
2032
+ "type": "ReactNode",
2033
+ "required": false
2034
+ }
2035
+ ],
2036
+ "example": "import StatCard from '@mantis-core/ui/components/data/StatCard';\n\nfunction Example() {\n return <StatCard label='Leads' value={142} trend={{ value: 12, direction: 'up' }} />;\n}"
2037
+ },
2038
+ {
2039
+ "name": "Timeline",
2040
+ "import": "@mantis-core/ui/components/data/Timeline",
2041
+ "category": "data",
2042
+ "whenToUse": "Vertical event timeline backed by the PR11 Timeline compound; items render a title, description, date, and optional icon/color.",
2043
+ "props": [
2044
+ {
2045
+ "name": "items",
2046
+ "type": "{ title: string; description?: string; date?: string; icon?: ReactNode; color?: string }[]",
2047
+ "required": true
2048
+ }
2049
+ ],
2050
+ "example": "import Timeline from '@mantis-core/ui/components/data/Timeline';\n\nfunction Example() {\n return (\n <Timeline\n items={[\n { title: 'Lead created', date: '2025-01-10', description: 'Web form' },\n { title: 'Contacted', date: '2025-01-11' },\n ]}\n />\n );\n}"
2051
+ }
2052
+ ],
2053
+ "feedback": [
2054
+ {
2055
+ "name": "Avatar",
2056
+ "import": "@mantis-core/ui/components/feedback/Avatar",
2057
+ "category": "feedback",
2058
+ "whenToUse": "User avatar that renders an image or auto-derived initials; composes the PR11 headless Avatar (Root/Image/Fallback).",
2059
+ "props": [
2060
+ {
2061
+ "name": "name",
2062
+ "type": "string",
2063
+ "required": false,
2064
+ "description": "Derives initials (first + last word) when no image/label is given."
2065
+ },
2066
+ {
2067
+ "name": "image",
2068
+ "type": "string",
2069
+ "required": false,
2070
+ "description": "Image source; when set, no fallback initials render."
2071
+ },
2072
+ {
2073
+ "name": "label",
2074
+ "type": "string",
2075
+ "required": false,
2076
+ "description": "Overrides the name-derived initials."
2077
+ },
2078
+ {
2079
+ "name": "size",
2080
+ "type": "'normal' | 'large' | 'xlarge'",
2081
+ "required": false,
2082
+ "default": "'normal'"
2083
+ },
2084
+ {
2085
+ "name": "shape",
2086
+ "type": "'circle' | 'square'",
2087
+ "required": false,
2088
+ "default": "'square'"
2089
+ }
2090
+ ],
2091
+ "example": "import Avatar from '@mantis-core/ui/components/feedback/Avatar';\n\nfunction Example() {\n return <Avatar name='Diego Condo' size='large' shape='circle' />;\n}"
2092
+ },
2093
+ {
2094
+ "name": "CardSkeleton",
2095
+ "import": "@mantis-core/ui/components/feedback/CardSkeleton",
2096
+ "category": "feedback",
2097
+ "whenToUse": "Animated skeleton for card-grid layouts while data loads; composes the PR11 Skeleton primitive.",
2098
+ "props": [
2099
+ {
2100
+ "name": "count",
2101
+ "type": "number",
2102
+ "required": false,
2103
+ "default": "3"
2104
+ }
2105
+ ],
2106
+ "example": "import CardSkeleton from '@mantis-core/ui/components/feedback/CardSkeleton';\n\nfunction Example() {\n return <CardSkeleton count={6} />;\n}"
2107
+ },
2108
+ {
2109
+ "name": "ConfirmDialog",
2110
+ "import": "@mantis-core/ui/components/ui/ConfirmDialog",
2111
+ "category": "feedback",
2112
+ "whenToUse": "Confirm/cancel dialog for destructive or non-trivial actions; composed from the migrated Modal + Button.",
2113
+ "props": [
2114
+ {
2115
+ "name": "visible",
2116
+ "type": "boolean",
2117
+ "required": true
2118
+ },
2119
+ {
2120
+ "name": "onConfirm",
2121
+ "type": "() => void | Promise<void>",
2122
+ "required": true
2123
+ },
2124
+ {
2125
+ "name": "onCancel",
2126
+ "type": "() => void",
2127
+ "required": true
2128
+ },
2129
+ {
2130
+ "name": "title",
2131
+ "type": "ReactNode",
2132
+ "required": false,
2133
+ "default": "'Confirmar accion'"
2134
+ },
2135
+ {
2136
+ "name": "message",
2137
+ "type": "ReactNode",
2138
+ "required": false,
2139
+ "default": "'Esta accion no se puede deshacer.'"
2140
+ },
2141
+ {
2142
+ "name": "icon",
2143
+ "type": "ReactNode",
2144
+ "required": false
2145
+ },
2146
+ {
2147
+ "name": "confirmLabel",
2148
+ "type": "string",
2149
+ "required": false,
2150
+ "default": "'Confirmar'"
2151
+ },
2152
+ {
2153
+ "name": "cancelLabel",
2154
+ "type": "string",
2155
+ "required": false,
2156
+ "default": "'Cancelar'"
2157
+ },
2158
+ {
2159
+ "name": "confirmSeverity",
2160
+ "type": "'primary' | 'info' | 'success' | 'warning' | 'danger'",
2161
+ "required": false,
2162
+ "default": "'danger'"
2163
+ },
2164
+ {
2165
+ "name": "loading",
2166
+ "type": "boolean",
2167
+ "required": false,
2168
+ "default": "false"
2169
+ },
2170
+ {
2171
+ "name": "disabled",
2172
+ "type": "boolean",
2173
+ "required": false,
2174
+ "default": "false"
2175
+ },
2176
+ {
2177
+ "name": "className",
2178
+ "type": "string",
2179
+ "required": false
2180
+ }
2181
+ ],
2182
+ "example": "import ConfirmDialog from '@mantis-core/ui/components/ui/ConfirmDialog';\nimport { useState } from 'react';\n\nfunction Example() {\n const [visible, setVisible] = useState(false);\n return (\n <ConfirmDialog\n visible={visible}\n title='Delete property?'\n message='This cannot be undone.'\n confirmSeverity='danger'\n onConfirm={() => setVisible(false)}\n onCancel={() => setVisible(false)}\n />\n );\n}"
2183
+ },
2184
+ {
2185
+ "name": "DataState",
2186
+ "import": "@mantis-core/ui/components/ui/DataState",
2187
+ "category": "feedback",
2188
+ "whenToUse": "Loading/empty/error/ready placeholder for data-fetching views; renders `children` unchanged when `status=\"ready\"`, otherwise a titled state panel.",
2189
+ "props": [
2190
+ {
2191
+ "name": "status",
2192
+ "type": "'ready' | 'loading' | 'empty' | 'error'",
2193
+ "required": true
2194
+ },
2195
+ {
2196
+ "name": "className",
2197
+ "type": "string",
2198
+ "required": false
2199
+ },
2200
+ {
2201
+ "name": "children",
2202
+ "type": "ReactNode",
2203
+ "required": false,
2204
+ "description": "Rendered as-is only when `status` is `\"ready\"`."
2205
+ },
2206
+ {
2207
+ "name": "icon",
2208
+ "type": "ReactNode",
2209
+ "required": false,
2210
+ "description": "Overrides the default per-status icon (spinner/inbox/triangle)."
2211
+ },
2212
+ {
2213
+ "name": "loadingTitle",
2214
+ "type": "ReactNode",
2215
+ "required": false,
2216
+ "default": "'Cargando informacion'"
2217
+ },
2218
+ {
2219
+ "name": "loadingDescription",
2220
+ "type": "ReactNode",
2221
+ "required": false,
2222
+ "default": "'Espera un momento mientras consultamos los datos.'"
2223
+ },
2224
+ {
2225
+ "name": "emptyTitle",
2226
+ "type": "ReactNode",
2227
+ "required": false,
2228
+ "default": "'Sin resultados'"
2229
+ },
2230
+ {
2231
+ "name": "emptyDescription",
2232
+ "type": "ReactNode",
2233
+ "required": false,
2234
+ "default": "'No hay registros para mostrar con los filtros actuales.'"
2235
+ },
2236
+ {
2237
+ "name": "emptyAction",
2238
+ "type": "ReactNode",
2239
+ "required": false
2240
+ },
2241
+ {
2242
+ "name": "errorTitle",
2243
+ "type": "ReactNode",
2244
+ "required": false,
2245
+ "default": "'No se pudo cargar la informacion'"
2246
+ },
2247
+ {
2248
+ "name": "errorDescription",
2249
+ "type": "ReactNode",
2250
+ "required": false,
2251
+ "default": "'Ocurrio un error al consultar los datos.'"
2252
+ },
2253
+ {
2254
+ "name": "errorAction",
2255
+ "type": "ReactNode",
2256
+ "required": false,
2257
+ "description": "Overrides the default retry Button built from `onRetry`."
2258
+ },
2259
+ {
2260
+ "name": "onRetry",
2261
+ "type": "() => void",
2262
+ "required": false,
2263
+ "description": "Renders a default retry Button on `error` when `errorAction` is not given."
2264
+ },
2265
+ {
2266
+ "name": "retryLabel",
2267
+ "type": "string",
2268
+ "required": false,
2269
+ "default": "'Reintentar'"
2270
+ }
2271
+ ],
2272
+ "example": "import DataState from '@mantis-core/ui/components/ui/DataState';\n\nfunction Example() {\n return (\n <DataState status='empty' emptyTitle='No properties found' emptyDescription='Try adjusting your filters.'>\n <ul />\n </DataState>\n );\n}"
2273
+ },
2274
+ {
2275
+ "name": "EmptyState",
2276
+ "import": "@mantis-core/ui/components/feedback/EmptyState",
2277
+ "category": "feedback",
2278
+ "whenToUse": "Centered empty-state placeholder with icon, title, optional description, and action button.",
2279
+ "props": [
2280
+ {
2281
+ "name": "title",
2282
+ "type": "ReactNode",
2283
+ "required": true
2284
+ },
2285
+ {
2286
+ "name": "icon",
2287
+ "type": "ReactNode",
2288
+ "required": false
2289
+ },
2290
+ {
2291
+ "name": "description",
2292
+ "type": "ReactNode",
2293
+ "required": false
2294
+ },
2295
+ {
2296
+ "name": "action",
2297
+ "type": "ReactNode",
2298
+ "required": false
2299
+ }
2300
+ ],
2301
+ "example": "import EmptyState from '@mantis-core/ui/components/feedback/EmptyState';\n\nfunction Example() {\n return <EmptyState title='No properties yet' description='Create your first property to get started.' />;\n}"
2302
+ },
2303
+ {
2304
+ "name": "ErrorBoundary",
2305
+ "import": "@mantis-core/ui/components/feedback/ErrorBoundary",
2306
+ "category": "feedback",
2307
+ "whenToUse": "React class error boundary; renders fallback UI on uncaught render errors in its children.",
2308
+ "props": [
2309
+ {
2310
+ "name": "children",
2311
+ "type": "ReactNode",
2312
+ "required": true
2313
+ },
2314
+ {
2315
+ "name": "fallback",
2316
+ "type": "ReactNode | ((error: Error) => ReactNode)",
2317
+ "required": false
2318
+ },
2319
+ {
2320
+ "name": "onError",
2321
+ "type": "(error: Error, info: ErrorInfo) => void",
2322
+ "required": false
2323
+ }
2324
+ ],
2325
+ "example": "import ErrorBoundary from '@mantis-core/ui/components/feedback/ErrorBoundary';\n\nfunction Example() {\n return (\n <ErrorBoundary fallback={<p>Something went wrong.</p>}>\n <div>Feature content</div>\n </ErrorBoundary>\n );\n}"
2326
+ },
2327
+ {
2328
+ "name": "Loading",
2329
+ "import": "@mantis-core/ui/components/Loaders/Loading",
2330
+ "category": "feedback",
2331
+ "whenToUse": "Full-screen loading overlay with a themed spinner; renders children unchanged when not loading.",
2332
+ "props": [
2333
+ {
2334
+ "name": "loading",
2335
+ "type": "boolean",
2336
+ "required": false,
2337
+ "default": "false"
2338
+ },
2339
+ {
2340
+ "name": "texto",
2341
+ "type": "string",
2342
+ "required": false,
2343
+ "default": "'Cargando...'"
2344
+ },
2345
+ {
2346
+ "name": "className",
2347
+ "type": "string",
2348
+ "required": false
2349
+ },
2350
+ {
2351
+ "name": "children",
2352
+ "type": "ReactNode",
2353
+ "required": false
2354
+ }
2355
+ ],
2356
+ "example": "import Loading from '@mantis-core/ui/components/Loaders/Loading';\n\nfunction Example() {\n return (\n <Loading loading={true} texto='Loading...'>\n <div>Page content</div>\n </Loading>\n );\n}"
2357
+ },
2358
+ {
2359
+ "name": "Pagination",
2360
+ "import": "@mantis-core/ui/components/ui/Pagination",
2361
+ "category": "feedback",
2362
+ "whenToUse": "Standalone page-number control (custom Tailwind markup, not PrimeReact Paginator); use when not relying on PaginatedTable's built-in paginator.",
2363
+ "props": [
2364
+ {
2365
+ "name": "currentPage",
2366
+ "type": "number",
2367
+ "required": true
2368
+ },
2369
+ {
2370
+ "name": "totalPages",
2371
+ "type": "number",
2372
+ "required": true
2373
+ },
2374
+ {
2375
+ "name": "onPageChange",
2376
+ "type": "(page: number) => void",
2377
+ "required": true
2378
+ },
2379
+ {
2380
+ "name": "hasNextPage",
2381
+ "type": "boolean",
2382
+ "required": false,
2383
+ "default": "currentPage < totalPages"
2384
+ },
2385
+ {
2386
+ "name": "hasPreviousPage",
2387
+ "type": "boolean",
2388
+ "required": false,
2389
+ "default": "currentPage > 1"
2390
+ },
2391
+ {
2392
+ "name": "maxVisible",
2393
+ "type": "number",
2394
+ "required": false,
2395
+ "default": "7"
2396
+ },
2397
+ {
2398
+ "name": "showFirstLast",
2399
+ "type": "boolean",
2400
+ "required": false,
2401
+ "default": "true"
2402
+ },
2403
+ {
2404
+ "name": "disabled",
2405
+ "type": "boolean",
2406
+ "required": false,
2407
+ "default": "false"
2408
+ },
2409
+ {
2410
+ "name": "className",
2411
+ "type": "string",
2412
+ "required": false
2413
+ }
2414
+ ],
2415
+ "example": "import { Pagination } from '@mantis-core/ui/components/ui/Pagination';\nimport { useState } from 'react';\n\nfunction Example() {\n const [page, setPage] = useState(1);\n return <Pagination currentPage={page} totalPages={12} onPageChange={setPage} />;\n}"
2416
+ },
2417
+ {
2418
+ "name": "RichTextPreview",
2419
+ "import": "@mantis-core/ui/components/ui/RichTextPreview",
2420
+ "category": "feedback",
2421
+ "whenToUse": "Safely renders a CKEditor HTML string (sanitized by default) with CKEditor content styles applied.",
2422
+ "props": [
2423
+ {
2424
+ "name": "html",
2425
+ "type": "string | null",
2426
+ "required": false,
2427
+ "description": "HTML source. `null`/undefined is treated as empty."
2428
+ },
2429
+ {
2430
+ "name": "className",
2431
+ "type": "string",
2432
+ "required": false
2433
+ },
2434
+ {
2435
+ "name": "sanitize",
2436
+ "type": "boolean",
2437
+ "required": false,
2438
+ "default": "true",
2439
+ "description": "Runs the HTML through `sanitizeHtmlContent` (`@mantis-core/utils`) before rendering."
2440
+ },
2441
+ {
2442
+ "name": "size",
2443
+ "type": "'sm' | 'md' | 'lg'",
2444
+ "required": false,
2445
+ "default": "'md'"
2446
+ },
2447
+ {
2448
+ "name": "emptyFallback",
2449
+ "type": "ReactNode",
2450
+ "required": false,
2451
+ "default": "null",
2452
+ "description": "Rendered instead when the (sanitized) content is empty/whitespace-only."
2453
+ }
2454
+ ],
2455
+ "example": "import RichTextPreview from '@mantis-core/ui/components/ui/RichTextPreview';\n\nfunction Example() {\n return <RichTextPreview html={'<p>Hello <strong>world</strong></p>'} size='md' />;\n}"
2456
+ },
2457
+ {
2458
+ "name": "StatusBadge",
2459
+ "import": "@mantis-core/ui/components/ui/StatusBadge",
2460
+ "category": "feedback",
2461
+ "whenToUse": "Colored pill badge to communicate a status with semantic tone (e.g. a lead or property status).",
2462
+ "props": [
2463
+ {
2464
+ "name": "label",
2465
+ "type": "ReactNode",
2466
+ "required": false,
2467
+ "description": "Takes precedence over `children` when both are given."
2468
+ },
2469
+ {
2470
+ "name": "tone",
2471
+ "type": "'success' | 'muted' | 'warning' | 'info' | 'danger'",
2472
+ "required": false,
2473
+ "default": "'muted'"
2474
+ },
2475
+ {
2476
+ "name": "size",
2477
+ "type": "'sm' | 'md'",
2478
+ "required": false,
2479
+ "default": "'md'"
2480
+ },
2481
+ {
2482
+ "name": "block",
2483
+ "type": "boolean",
2484
+ "required": false,
2485
+ "default": "false"
2486
+ },
2487
+ {
2488
+ "name": "children",
2489
+ "type": "ReactNode",
2490
+ "required": false,
2491
+ "description": "Fallback content when `label` is not given."
2492
+ }
2493
+ ],
2494
+ "example": "import StatusBadge from '@mantis-core/ui/components/ui/StatusBadge';\n\nfunction Example() {\n return <StatusBadge label='Active' tone='success' />;\n}"
2495
+ },
2496
+ {
2497
+ "name": "TableSkeleton",
2498
+ "import": "@mantis-core/ui/components/feedback/TableSkeleton",
2499
+ "category": "feedback",
2500
+ "whenToUse": "Animated skeleton placeholder that mimics a table grid while data loads; composes the PR11 Skeleton primitive.",
2501
+ "props": [
2502
+ {
2503
+ "name": "rows",
2504
+ "type": "number",
2505
+ "required": false,
2506
+ "default": "5"
2507
+ },
2508
+ {
2509
+ "name": "columns",
2510
+ "type": "number",
2511
+ "required": false,
2512
+ "default": "4"
2513
+ }
2514
+ ],
2515
+ "example": "import TableSkeleton from '@mantis-core/ui/components/feedback/TableSkeleton';\n\nfunction Example() {\n return <TableSkeleton rows={8} columns={5} />;\n}"
2516
+ },
2517
+ {
2518
+ "name": "Tag",
2519
+ "import": "@mantis-core/ui/components/feedback/Tag",
2520
+ "category": "feedback",
2521
+ "whenToUse": "Styled label chip for status labels, categories, or counts; wraps the PR11 Tag primitive.",
2522
+ "props": [
2523
+ {
2524
+ "name": "children",
2525
+ "type": "ReactNode",
2526
+ "required": false,
2527
+ "description": "Tag content — PR11 dropped value/icon; content is now children."
2528
+ },
2529
+ {
2530
+ "name": "severity",
2531
+ "type": "'secondary' | 'success' | 'info' | 'warn' | 'danger' | 'contrast'",
2532
+ "required": false
2533
+ },
2534
+ {
2535
+ "name": "rounded",
2536
+ "type": "boolean",
2537
+ "required": false,
2538
+ "default": "false"
2539
+ }
2540
+ ],
2541
+ "example": "import Tag from '@mantis-core/ui/components/feedback/Tag';\n\nfunction Example() {\n return <Tag severity='success' rounded>Sold</Tag>;\n}"
2542
+ }
2543
+ ],
2544
+ "auth": [
2545
+ {
2546
+ "name": "ChangePasswordForm",
2547
+ "import": "@mantis-core/ui/components/auth/ChangePasswordForm",
2548
+ "category": "auth",
2549
+ "whenToUse": "Current + new + confirm password form for an authenticated user changing their own password.",
2550
+ "props": [
2551
+ {
2552
+ "name": "onSubmit",
2553
+ "type": "(values: ChangePasswordFormValues) => void | Promise<void>",
2554
+ "required": true,
2555
+ "description": "Receives { currentPassword, newPassword, confirmPassword }; form manages isSubmitting via RHF."
2556
+ },
2557
+ {
2558
+ "name": "title",
2559
+ "type": "string",
2560
+ "required": false,
2561
+ "default": "\"Cambiar contraseña\""
2562
+ },
2563
+ {
2564
+ "name": "submitLabel",
2565
+ "type": "string",
2566
+ "required": false,
2567
+ "default": "\"Actualizar contraseña\""
2568
+ },
2569
+ {
2570
+ "name": "minPasswordLength",
2571
+ "type": "number",
2572
+ "required": false,
2573
+ "default": "8",
2574
+ "description": "Feeds minLengthRule for the newPassword field."
2575
+ },
2576
+ {
2577
+ "name": "className",
2578
+ "type": "string",
2579
+ "required": false
2580
+ }
2581
+ ],
2582
+ "example": "import ChangePasswordForm from '@mantis-core/ui/components/auth/ChangePasswordForm';\nimport type { ChangePasswordFormValues } from '@mantis-core/ui/components/auth/ChangePasswordForm';\n\nfunction Example() {\n const handleSubmit = async (values: ChangePasswordFormValues) => {\n await fetch('/api/auth/change-password', { method: 'POST', body: JSON.stringify(values) });\n };\n\n return <ChangePasswordForm onSubmit={handleSubmit} />;\n}"
2583
+ },
2584
+ {
2585
+ "name": "ForgotPasswordForm",
2586
+ "import": "@mantis-core/ui/components/auth/ForgotPasswordForm",
2587
+ "category": "auth",
2588
+ "whenToUse": "Email-only form to trigger a password-reset email; caller owns the actual reset request.",
2589
+ "props": [
2590
+ {
2591
+ "name": "onSubmit",
2592
+ "type": "(values: ForgotPasswordFormValues) => void | Promise<void>",
2593
+ "required": true,
2594
+ "description": "Receives { email }; form manages isSubmitting via RHF."
2595
+ },
2596
+ {
2597
+ "name": "title",
2598
+ "type": "string",
2599
+ "required": false,
2600
+ "default": "\"Recuperar contraseña\""
2601
+ },
2602
+ {
2603
+ "name": "subtitle",
2604
+ "type": "string",
2605
+ "required": false
2606
+ },
2607
+ {
2608
+ "name": "submitLabel",
2609
+ "type": "string",
2610
+ "required": false,
2611
+ "default": "\"Enviar enlace\""
2612
+ },
2613
+ {
2614
+ "name": "backSlot",
2615
+ "type": "ReactNode",
2616
+ "required": false,
2617
+ "description": "Rendered below the submit button (e.g. a \"back to login\" link)."
2618
+ },
2619
+ {
2620
+ "name": "className",
2621
+ "type": "string",
2622
+ "required": false
2623
+ }
2624
+ ],
2625
+ "example": "import ForgotPasswordForm from '@mantis-core/ui/components/auth/ForgotPasswordForm';\nimport type { ForgotPasswordFormValues } from '@mantis-core/ui/components/auth/ForgotPasswordForm';\n\nfunction Example() {\n const handleSubmit = async ({ email }: ForgotPasswordFormValues) => {\n await fetch('/api/auth/forgot-password', { method: 'POST', body: JSON.stringify({ email }) });\n };\n\n return <ForgotPasswordForm onSubmit={handleSubmit} />;\n}"
2626
+ },
2627
+ {
2628
+ "name": "LoginForm",
2629
+ "import": "@mantis-core/ui/components/auth/LoginForm",
2630
+ "category": "auth",
2631
+ "whenToUse": "Self-contained login form (identifier + password) built on migrated TextField/PasswordInput/Button; pass onSubmit to wire signIn/Supabase from the app layer.",
2632
+ "props": [
2633
+ {
2634
+ "name": "onSubmit",
2635
+ "type": "(values: LoginFormValues) => void | Promise<void>",
2636
+ "required": true,
2637
+ "description": "Receives { identifier, password }; form manages isSubmitting via RHF."
2638
+ },
2639
+ {
2640
+ "name": "brand",
2641
+ "type": "ReactNode",
2642
+ "required": false,
2643
+ "description": "Rendered above the title."
2644
+ },
2645
+ {
2646
+ "name": "title",
2647
+ "type": "string",
2648
+ "required": false,
2649
+ "default": "\"Iniciar sesión\""
2650
+ },
2651
+ {
2652
+ "name": "subtitle",
2653
+ "type": "string",
2654
+ "required": false
2655
+ },
2656
+ {
2657
+ "name": "footer",
2658
+ "type": "ReactNode",
2659
+ "required": false,
2660
+ "description": "Rendered below the submit button (e.g. forgot-password link)."
2661
+ },
2662
+ {
2663
+ "name": "identifierField",
2664
+ "type": "'email' | 'username'",
2665
+ "required": false,
2666
+ "default": "\"email\"",
2667
+ "description": "Switches the identifier field's validation, type, and autoComplete between email and plain username."
2668
+ },
2669
+ {
2670
+ "name": "identifierLabel",
2671
+ "type": "string",
2672
+ "required": false,
2673
+ "description": "Overrides the default label (\"Correo electrónico\" / \"Usuario\") derived from identifierField."
2674
+ },
2675
+ {
2676
+ "name": "identifierPlaceholder",
2677
+ "type": "string",
2678
+ "required": false
2679
+ },
2680
+ {
2681
+ "name": "passwordLabel",
2682
+ "type": "string",
2683
+ "required": false,
2684
+ "default": "\"Contraseña\""
2685
+ },
2686
+ {
2687
+ "name": "passwordPlaceholder",
2688
+ "type": "string",
2689
+ "required": false
2690
+ },
2691
+ {
2692
+ "name": "submitLabel",
2693
+ "type": "string",
2694
+ "required": false,
2695
+ "default": "\"Ingresar\""
2696
+ },
2697
+ {
2698
+ "name": "className",
2699
+ "type": "string",
2700
+ "required": false
2701
+ }
2702
+ ],
2703
+ "example": "import LoginForm from '@mantis-core/ui/components/auth/LoginForm';\nimport type { LoginFormValues } from '@mantis-core/ui/components/auth/LoginForm';\n\nfunction Example() {\n const handleSubmit = async (values: LoginFormValues) => {\n await fetch('/api/auth/login', { method: 'POST', body: JSON.stringify(values) });\n };\n\n return <LoginForm onSubmit={handleSubmit} identifierField='email' />;\n}"
2704
+ },
2705
+ {
2706
+ "name": "ResetPasswordForm",
2707
+ "import": "@mantis-core/ui/components/auth/ResetPasswordForm",
2708
+ "category": "auth",
2709
+ "whenToUse": "New password + confirm-password form for a reset-token flow; caller owns token validation and the API call.",
2710
+ "props": [
2711
+ {
2712
+ "name": "onSubmit",
2713
+ "type": "(values: ResetPasswordFormValues) => void | Promise<void>",
2714
+ "required": true,
2715
+ "description": "Receives { newPassword, confirmPassword }; form manages isSubmitting via RHF."
2716
+ },
2717
+ {
2718
+ "name": "title",
2719
+ "type": "string",
2720
+ "required": false,
2721
+ "default": "\"Nueva contraseña\""
2722
+ },
2723
+ {
2724
+ "name": "subtitle",
2725
+ "type": "string",
2726
+ "required": false
2727
+ },
2728
+ {
2729
+ "name": "submitLabel",
2730
+ "type": "string",
2731
+ "required": false,
2732
+ "default": "\"Guardar contraseña\""
2733
+ },
2734
+ {
2735
+ "name": "minPasswordLength",
2736
+ "type": "number",
2737
+ "required": false,
2738
+ "default": "8",
2739
+ "description": "Feeds minLengthRule for the newPassword field."
2740
+ },
2741
+ {
2742
+ "name": "className",
2743
+ "type": "string",
2744
+ "required": false
2745
+ }
2746
+ ],
2747
+ "example": "import ResetPasswordForm from '@mantis-core/ui/components/auth/ResetPasswordForm';\nimport type { ResetPasswordFormValues } from '@mantis-core/ui/components/auth/ResetPasswordForm';\n\nfunction Example() {\n const handleSubmit = async ({ newPassword }: ResetPasswordFormValues) => {\n await fetch('/api/auth/reset-password', { method: 'POST', body: JSON.stringify({ newPassword }) });\n };\n\n return <ResetPasswordForm onSubmit={handleSubmit} minPasswordLength={10} />;\n}"
2748
+ },
2749
+ {
2750
+ "name": "UserMenu",
2751
+ "import": "@mantis-core/ui/components/auth/UserMenu",
2752
+ "category": "auth",
2753
+ "whenToUse": "Topbar avatar-triggered dropdown (custom nav items + sign-out); no auth-lib coupling.",
2754
+ "props": [
2755
+ {
2756
+ "name": "user",
2757
+ "type": "UserMenuUser",
2758
+ "required": true,
2759
+ "description": "{ name?, email?, avatarUrl? } — displayName falls back to email."
2760
+ },
2761
+ {
2762
+ "name": "items",
2763
+ "type": "UserMenuItem[]",
2764
+ "required": false,
2765
+ "description": "{ label, icon?, href?, onClick? }; href navigates via next/navigation, otherwise onClick fires."
2766
+ },
2767
+ {
2768
+ "name": "onSignOut",
2769
+ "type": "() => void",
2770
+ "required": false,
2771
+ "description": "When set, appends a separator + sign-out item."
2772
+ },
2773
+ {
2774
+ "name": "signOutLabel",
2775
+ "type": "string",
2776
+ "required": false,
2777
+ "default": "\"Cerrar sesión\""
2778
+ },
2779
+ {
2780
+ "name": "className",
2781
+ "type": "string",
2782
+ "required": false
2783
+ }
2784
+ ],
2785
+ "example": "import UserMenu from '@mantis-core/ui/components/auth/UserMenu';\n\nfunction Example() {\n return (\n <UserMenu\n user={{ name: 'Diego Condo', email: 'diego@example.com' }}\n items={[{ label: 'Perfil', icon: 'pi pi-user', href: '/perfil' }]}\n onSignOut={() => console.log('sign out')}\n />\n );\n}"
2786
+ }
2787
+ ],
2788
+ "buttons": [
2789
+ {
2790
+ "name": "Button",
2791
+ "import": "@mantis-core/ui/components/Buttons/Button",
2792
+ "category": "buttons",
2793
+ "whenToUse": "Primary action button; wraps PR11's `@primereact/ui/button`, mapping the Mantis semantic `variant` to PR11 `severity` and restoring the `label`/`icon`/`loading` affordances PR11 dropped. Supports `href` for Next.js client navigation.",
2794
+ "props": [
2795
+ {
2796
+ "name": "variant",
2797
+ "type": "'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info' | 'gray' | 'danger'",
2798
+ "required": false,
2799
+ "default": "'primary'",
2800
+ "description": "Maps to PR11 `severity`: `primary` = PR11 default (no severity), `gray`→`contrast`, `warning`→`warn`, `error`/`danger`→`danger`."
2801
+ },
2802
+ {
2803
+ "name": "outlined",
2804
+ "type": "boolean",
2805
+ "required": false,
2806
+ "default": "false",
2807
+ "description": "PR11 `variant=\"outlined\"`."
2808
+ },
2809
+ {
2810
+ "name": "text",
2811
+ "type": "boolean",
2812
+ "required": false,
2813
+ "default": "false",
2814
+ "description": "PR11 `variant=\"text\"`; wins over `outlined` when both are set."
2815
+ },
2816
+ {
2817
+ "name": "block",
2818
+ "type": "boolean",
2819
+ "required": false,
2820
+ "default": "false",
2821
+ "description": "Full width — maps to PR11 `fluid`."
2822
+ },
2823
+ {
2824
+ "name": "sm",
2825
+ "type": "boolean",
2826
+ "required": false,
2827
+ "default": "false",
2828
+ "description": "→ size='small'."
2829
+ },
2830
+ {
2831
+ "name": "lg",
2832
+ "type": "boolean",
2833
+ "required": false,
2834
+ "default": "false",
2835
+ "description": "→ size='large'."
2836
+ },
2837
+ {
2838
+ "name": "rounded",
2839
+ "type": "boolean",
2840
+ "required": false,
2841
+ "default": "false"
2842
+ },
2843
+ {
2844
+ "name": "label",
2845
+ "type": "ReactNode",
2846
+ "required": false,
2847
+ "description": "Rendered as a child span — PR11 Button has no `label` prop."
2848
+ },
2849
+ {
2850
+ "name": "icon",
2851
+ "type": "string",
2852
+ "required": false,
2853
+ "description": "PrimeIcons class string, e.g. `pi pi-filter`; rendered before the label."
2854
+ },
2855
+ {
2856
+ "name": "loading",
2857
+ "type": "boolean",
2858
+ "required": false,
2859
+ "default": "false",
2860
+ "description": "Shows a spinner icon and disables the button — PR11 Button has no `loading` prop."
2861
+ },
2862
+ {
2863
+ "name": "href",
2864
+ "type": "string",
2865
+ "required": false,
2866
+ "description": "Internal path; pushed with `next/navigation` router after `onClick` runs."
2867
+ },
2868
+ {
2869
+ "name": "type",
2870
+ "type": "'button' | 'submit' | 'reset'",
2871
+ "required": false,
2872
+ "default": "'button'"
2873
+ },
2874
+ {
2875
+ "name": "disabled",
2876
+ "type": "boolean",
2877
+ "required": false
2878
+ },
2879
+ {
2880
+ "name": "onClick",
2881
+ "type": "(evt: MouseEvent<HTMLButtonElement>) => void",
2882
+ "required": false
2883
+ },
2884
+ {
2885
+ "name": "children",
2886
+ "type": "ReactNode",
2887
+ "required": false
2888
+ }
2889
+ ],
2890
+ "example": "import Button from '@mantis-core/ui/components/Buttons/Button';\n\nfunction Example() {\n return (\n <Button\n variant='danger'\n outlined\n label='Delete'\n icon='pi pi-trash'\n onClick={() => console.log('deleted')}\n />\n );\n}"
2891
+ }
2892
+ ],
2893
+ "charts": [
2894
+ {
2895
+ "name": "BarChart",
2896
+ "import": "@mantis-core/ui/components/charts/BarChart",
2897
+ "category": "charts",
2898
+ "whenToUse": "Categorical comparisons rendered as a bar chart, zero-config over chart.js defaults.",
2899
+ "props": [
2900
+ {
2901
+ "name": "labels",
2902
+ "type": "string[]",
2903
+ "required": true
2904
+ },
2905
+ {
2906
+ "name": "datasets",
2907
+ "type": "BarChartDataset[]",
2908
+ "required": true,
2909
+ "description": "ChartDataset<'bar'> minus 'data', plus data: number[]."
2910
+ },
2911
+ {
2912
+ "name": "options",
2913
+ "type": "ChartOptions<'bar'>",
2914
+ "required": false,
2915
+ "description": "Deep-merged over defaultBarOptions (plugins/scales merge shallowly one level)."
2916
+ },
2917
+ {
2918
+ "name": "colors",
2919
+ "type": "string[]",
2920
+ "required": false,
2921
+ "default": "DEFAULT_COLORS (8-color palette)",
2922
+ "description": "Applied per-dataset (cycled by index) to datasets that don't specify their own backgroundColor/borderColor."
2923
+ },
2924
+ {
2925
+ "name": "height",
2926
+ "type": "number",
2927
+ "required": false,
2928
+ "default": "300",
2929
+ "description": "Container height in px."
2930
+ },
2931
+ {
2932
+ "name": "className",
2933
+ "type": "string",
2934
+ "required": false
2935
+ }
2936
+ ],
2937
+ "example": "import BarChart from '@mantis-core/ui/components/charts/BarChart';\n\nfunction Example() {\n return (\n <BarChart\n labels={['Q1', 'Q2', 'Q3']}\n datasets={[{ label: 'Sales', data: [40, 70, 55] }]}\n />\n );\n}"
2938
+ },
2939
+ {
2940
+ "name": "DonutChart",
2941
+ "import": "@mantis-core/ui/components/charts/DonutChart",
2942
+ "category": "charts",
2943
+ "whenToUse": "Part-to-whole breakdown rendered as a doughnut chart, zero-config over chart.js defaults.",
2944
+ "props": [
2945
+ {
2946
+ "name": "labels",
2947
+ "type": "string[]",
2948
+ "required": true
2949
+ },
2950
+ {
2951
+ "name": "datasets",
2952
+ "type": "{ data: number[]; label?: string }[]",
2953
+ "required": true,
2954
+ "description": "Typically a single-entry array — one value per label/slice."
2955
+ },
2956
+ {
2957
+ "name": "options",
2958
+ "type": "ChartOptions<'doughnut'>",
2959
+ "required": false,
2960
+ "description": "Deep-merged over defaultDonutOptions (plugins merge shallowly one level)."
2961
+ },
2962
+ {
2963
+ "name": "colors",
2964
+ "type": "string[]",
2965
+ "required": false,
2966
+ "default": "DEFAULT_COLORS (8-color palette)",
2967
+ "description": "Applied per-slice (cycled by label index) unless the dataset supplies its own backgroundColor/borderColor."
2968
+ },
2969
+ {
2970
+ "name": "height",
2971
+ "type": "number",
2972
+ "required": false,
2973
+ "default": "300",
2974
+ "description": "Container height in px."
2975
+ },
2976
+ {
2977
+ "name": "className",
2978
+ "type": "string",
2979
+ "required": false
2980
+ }
2981
+ ],
2982
+ "example": "import DonutChart from '@mantis-core/ui/components/charts/DonutChart';\n\nfunction Example() {\n return (\n <DonutChart\n labels={['Leads', 'Closed', 'Lost']}\n datasets={[{ data: [60, 25, 15] }]}\n />\n );\n}"
2983
+ },
2984
+ {
2985
+ "name": "LineChart",
2986
+ "import": "@mantis-core/ui/components/charts/LineChart",
2987
+ "category": "charts",
2988
+ "whenToUse": "Time-series/trend data rendered as a line chart, zero-config over chart.js defaults.",
2989
+ "props": [
2990
+ {
2991
+ "name": "labels",
2992
+ "type": "string[]",
2993
+ "required": true
2994
+ },
2995
+ {
2996
+ "name": "datasets",
2997
+ "type": "LineChartDataset[]",
2998
+ "required": true,
2999
+ "description": "ChartDataset<'line'> minus 'data', plus data: number[]."
3000
+ },
3001
+ {
3002
+ "name": "options",
3003
+ "type": "ChartOptions<'line'>",
3004
+ "required": false,
3005
+ "description": "Deep-merged over defaultLineOptions (plugins/scales merge shallowly one level)."
3006
+ },
3007
+ {
3008
+ "name": "colors",
3009
+ "type": "string[]",
3010
+ "required": false,
3011
+ "default": "DEFAULT_COLORS (8-color palette)",
3012
+ "description": "Applied per-dataset (cycled by index) to datasets that don't specify their own borderColor/backgroundColor."
3013
+ },
3014
+ {
3015
+ "name": "height",
3016
+ "type": "number",
3017
+ "required": false,
3018
+ "default": "300",
3019
+ "description": "Container height in px."
3020
+ },
3021
+ {
3022
+ "name": "className",
3023
+ "type": "string",
3024
+ "required": false
3025
+ }
3026
+ ],
3027
+ "example": "import LineChart from '@mantis-core/ui/components/charts/LineChart';\n\nfunction Example() {\n return (\n <LineChart\n labels={['Jan', 'Feb', 'Mar']}\n datasets={[{ label: 'Revenue', data: [100, 200, 150] }]}\n height={250}\n />\n );\n}"
3028
+ }
3029
+ ]
3030
+ }
3031
+ }