pixelize-design-library 2.4.2-beta.4 → 2.4.2-beta.41

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 (527) hide show
  1. package/COMPONENT-GOTCHAS.md +1102 -0
  2. package/README.md +26 -0
  3. package/dist/Components/Accordion/Accordion.d.ts +1 -0
  4. package/dist/Components/Accordion/Accordion.js +4 -1
  5. package/dist/Components/Accordion/AccordionProps.d.ts +2 -0
  6. package/dist/Components/AlertDialog/AlertDialog.d.ts +1 -0
  7. package/dist/Components/AlertDialog/AlertDialog.js +1 -0
  8. package/dist/Components/AlertDialog/AlertDialogProps.d.ts +2 -0
  9. package/dist/Components/Apexcharts/ApexAreaChart/ApexAreaChart.d.ts +1 -0
  10. package/dist/Components/Apexcharts/ApexAreaChart/ApexAreaChart.js +1 -0
  11. package/dist/Components/Apexcharts/ApexAreaChart/ApexAreaChartProps.d.ts +4 -0
  12. package/dist/Components/Apexcharts/ApexBarChart/ApexBarChart.d.ts +1 -0
  13. package/dist/Components/Apexcharts/ApexBarChart/ApexBarChart.js +1 -0
  14. package/dist/Components/Apexcharts/ApexBarChart/ApexBarChartProps.d.ts +6 -0
  15. package/dist/Components/Apexcharts/ApexLineChart/ApexLineChart.d.ts +1 -0
  16. package/dist/Components/Apexcharts/ApexLineChart/ApexLineChart.js +1 -0
  17. package/dist/Components/Apexcharts/ApexLineChart/ApexLineChartProps.d.ts +8 -0
  18. package/dist/Components/Apexcharts/ApexPieChart/ApexPieChart.d.ts +1 -0
  19. package/dist/Components/Apexcharts/ApexPieChart/ApexPieChart.js +1 -0
  20. package/dist/Components/Apexcharts/ApexPieChart/ApexPieChartProps.d.ts +6 -0
  21. package/dist/Components/Apexcharts/ApexPolarCharts/ApexPolarCharts.d.ts +1 -0
  22. package/dist/Components/Apexcharts/ApexPolarCharts/ApexPolarCharts.js +1 -0
  23. package/dist/Components/Apexcharts/ApexPolarCharts/ApexPolarChartsProps.d.ts +3 -0
  24. package/dist/Components/Apexcharts/ApexRadialChart/ApexRadialChart.d.ts +1 -0
  25. package/dist/Components/Apexcharts/ApexRadialChart/ApexRadialChart.js +1 -0
  26. package/dist/Components/Apexcharts/ApexRadialChart/ApexRadialChartProps.d.ts +3 -0
  27. package/dist/Components/AppSwitcher/AppMark.d.ts +19 -0
  28. package/dist/Components/AppSwitcher/AppMark.js +62 -0
  29. package/dist/Components/AppSwitcher/AppSwitcher.d.ts +4 -0
  30. package/dist/Components/AppSwitcher/AppSwitcher.js +278 -0
  31. package/dist/Components/AppSwitcher/AppSwitcherProps.d.ts +70 -0
  32. package/dist/Components/AppSwitcher/AppSwitcherProps.js +86 -0
  33. package/dist/Components/AppSwitcher/useAppSwitcherShortcut.d.ts +3 -0
  34. package/dist/Components/AppSwitcher/useAppSwitcherShortcut.js +31 -0
  35. package/dist/Components/AppearanceSettings/AppearanceSettings.js +2 -1
  36. package/dist/Components/AppearanceSettings/AppearanceSettingsProps.d.ts +2 -0
  37. package/dist/Components/Breadcrumbs/BreadcrumbsProps.d.ts +3 -0
  38. package/dist/Components/Button/Button.d.ts +2 -2
  39. package/dist/Components/Button/Button.js +4 -3
  40. package/dist/Components/Button/Button.styles.js +37 -23
  41. package/dist/Components/Button/ButtonProps.d.ts +9 -1
  42. package/dist/Components/ButtonGroupIcon/ButtonGoupIconProps.d.ts +7 -0
  43. package/dist/Components/ButtonGroupIcon/ButtonGroupIcon.js +2 -4
  44. package/dist/Components/Buttons/ButtonsProps.d.ts +2 -0
  45. package/dist/Components/Card/Card.d.ts +1 -1
  46. package/dist/Components/Card/Card.js +2 -2
  47. package/dist/Components/Card/CardProps.d.ts +3 -1
  48. package/dist/Components/Card/PaymentCard/PaymentCard.js +21 -12
  49. package/dist/Components/Card/PaymentCard/PaymentCardProps.d.ts +6 -0
  50. package/dist/Components/Checkbox/Checkbox.d.ts +1 -0
  51. package/dist/Components/Checkbox/Checkbox.js +2 -1
  52. package/dist/Components/Checkbox/Checkbox.styles.js +12 -7
  53. package/dist/Components/Checkbox/CheckboxProps.d.ts +4 -0
  54. package/dist/Components/Common/ErrorComponent.d.ts +2 -0
  55. package/dist/Components/Common/ErrorComponent.js +7 -5
  56. package/dist/Components/Common/ErrorMessage.js +2 -2
  57. package/dist/Components/Common/FormLabel.d.ts +4 -0
  58. package/dist/Components/Common/FormLabel.js +1 -0
  59. package/dist/Components/Common/FormattedDescription.d.ts +2 -0
  60. package/dist/Components/Common/FormattedDescription.js +1 -0
  61. package/dist/Components/Common/HelperText.d.ts +2 -0
  62. package/dist/Components/Common/HelperText.js +2 -0
  63. package/dist/Components/Common/Label.d.ts +1 -0
  64. package/dist/Components/Common/Label.js +1 -0
  65. package/dist/Components/Common/fieldStyles.js +1 -1
  66. package/dist/Components/ContactForm/ContactForm.d.ts +1 -0
  67. package/dist/Components/ContactForm/ContactForm.js +1 -0
  68. package/dist/Components/ContactForm/ContactFormProps.d.ts +4 -0
  69. package/dist/Components/CopyButton/CopyButton.d.ts +3 -1
  70. package/dist/Components/CopyButton/CopyButton.js +9 -3
  71. package/dist/Components/CustomModulesTable/CustomModulesTableProps.d.ts +8 -0
  72. package/dist/Components/DatePicker/CalendarPanel.d.ts +6 -0
  73. package/dist/Components/DatePicker/CalendarPanel.js +37 -15
  74. package/dist/Components/DatePicker/DatePicker.d.ts +1 -0
  75. package/dist/Components/DatePicker/DatePicker.js +1 -0
  76. package/dist/Components/DatePicker/DatePickerProps.d.ts +30 -0
  77. package/dist/Components/DatePicker/RangeDatePicker.d.ts +1 -0
  78. package/dist/Components/DatePicker/RangeDatePicker.js +30 -5
  79. package/dist/Components/DatePicker/SingleDatePicker.d.ts +1 -0
  80. package/dist/Components/DatePicker/SingleDatePicker.js +49 -14
  81. package/dist/Components/DatePicker/ThemeDatePicker.d.ts +1 -0
  82. package/dist/Components/DatePicker/ThemeDatePicker.js +1 -0
  83. package/dist/Components/DatePicker/TimeOnlyPicker.d.ts +1 -0
  84. package/dist/Components/DatePicker/TimeOnlyPicker.js +11 -2
  85. package/dist/Components/DatePicker/TimePicker.d.ts +1 -0
  86. package/dist/Components/DatePicker/TimePicker.js +4 -3
  87. package/dist/Components/DatePicker/TimePickerInput.d.ts +1 -0
  88. package/dist/Components/DatePicker/TimePickerInput.js +2 -1
  89. package/dist/Components/DatePicker/dayStates.d.ts +56 -0
  90. package/dist/Components/DatePicker/dayStates.js +87 -0
  91. package/dist/Components/Divider/Divider.d.ts +1 -0
  92. package/dist/Components/Divider/Divider.js +1 -0
  93. package/dist/Components/Drawer/DrawerProps.d.ts +2 -0
  94. package/dist/Components/Dropdown/DropDown.d.ts +1 -0
  95. package/dist/Components/Dropdown/DropDown.js +22 -6
  96. package/dist/Components/Dropdown/DropdownProps.d.ts +3 -0
  97. package/dist/Components/Editor/Editor.d.ts +1 -0
  98. package/dist/Components/Editor/Editor.js +1 -0
  99. package/dist/Components/Editor/EditorProps.d.ts +2 -0
  100. package/dist/Components/EmailCards/VerifyEmailOtp/VerifyEmailOtp.d.ts +1 -0
  101. package/dist/Components/EmailCards/VerifyEmailOtp/VerifyEmailOtp.js +2 -5
  102. package/dist/Components/EmailCards/VerifyEmailOtp/VerifyEmailOtpProps.d.ts +4 -0
  103. package/dist/Components/EmptyState/EmptyState.d.ts +1 -0
  104. package/dist/Components/EmptyState/EmptyState.js +4 -2
  105. package/dist/Components/EmptyState/EmptyStateProps.d.ts +3 -0
  106. package/dist/Components/FeedbackForm/FeedbackForm.d.ts +3 -0
  107. package/dist/Components/FeedbackForm/FeedbackForm.js +1 -0
  108. package/dist/Components/FieldSelectModal/FieldSelectModal.d.ts +3 -2
  109. package/dist/Components/FieldSelectModal/FieldSelectModal.js +1 -0
  110. package/dist/Components/FilePreview/FilePreview.d.ts +1 -0
  111. package/dist/Components/FilePreview/FilePreview.js +3 -1
  112. package/dist/Components/FilePreview/FilePreviewProps.d.ts +5 -2
  113. package/dist/Components/FileUpload/FileUpload.d.ts +1 -0
  114. package/dist/Components/FileUpload/FileUpload.js +7 -5
  115. package/dist/Components/FileUpload/FileUploadProps.d.ts +7 -1
  116. package/dist/Components/FileUpload/constants.js +1 -0
  117. package/dist/Components/FileUploader/FileUploader.d.ts +1 -0
  118. package/dist/Components/FileUploader/FileUploader.js +1 -0
  119. package/dist/Components/FileUploader/FileUploaderProps.d.ts +2 -0
  120. package/dist/Components/FilterSidebar/FilterSidebar.d.ts +3 -0
  121. package/dist/Components/FilterSidebar/FilterSidebar.js +5 -5
  122. package/dist/Components/FilterSidebar/filterHoverStyle.d.ts +2 -10
  123. package/dist/Components/FilterSidebar/filterHoverStyle.js +3 -10
  124. package/dist/Components/Form/FormWrapper.d.ts +3 -0
  125. package/dist/Components/Form/FormWrapper.js +2 -1
  126. package/dist/Components/Header/HeaderProps.d.ts +5 -0
  127. package/dist/Components/Header/components/mobileMenu.js +12 -3
  128. package/dist/Components/Input/Input/InputProps.d.ts +2 -0
  129. package/dist/Components/Input/PhoneNumberInput.d.ts +1 -0
  130. package/dist/Components/Input/PhoneNumberInput.js +1 -0
  131. package/dist/Components/Input/PhoneNumberInputProps.d.ts +3 -0
  132. package/dist/Components/Input/Switch/InputSwitch.d.ts +2 -0
  133. package/dist/Components/Input/Switch/InputSwitch.js +1 -0
  134. package/dist/Components/Input/TextInput.js +1 -0
  135. package/dist/Components/Input/TextInput.styles.js +8 -10
  136. package/dist/Components/Input/TextInputProps.d.ts +2 -0
  137. package/dist/Components/InputTextArea/InputTextArea.d.ts +1 -0
  138. package/dist/Components/InputTextArea/InputTextArea.js +1 -0
  139. package/dist/Components/InputTextArea/InputTextArea.style.js +7 -6
  140. package/dist/Components/InputTextArea/InputTextAreaProps.d.ts +1 -0
  141. package/dist/Components/KanbanBoard/AccountCard.d.ts +3 -0
  142. package/dist/Components/KanbanBoard/AccountCard.js +1 -0
  143. package/dist/Components/KanbanBoard/AccountRow.d.ts +1 -0
  144. package/dist/Components/KanbanBoard/AccountRow.js +1 -0
  145. package/dist/Components/KanbanBoard/KanbanActions/KanbanActions.d.ts +2 -0
  146. package/dist/Components/KanbanBoard/KanbanActions/KanbanActions.js +2 -2
  147. package/dist/Components/KanbanBoard/KanbanBoard.d.ts +1 -0
  148. package/dist/Components/KanbanBoard/KanbanBoard.js +1 -0
  149. package/dist/Components/KanbanBoard/KanbanBoardProps.d.ts +39 -14
  150. package/dist/Components/KanbanBoard/MeasuredItem.d.ts +1 -0
  151. package/dist/Components/KanbanBoard/MeasuredItem.js +1 -0
  152. package/dist/Components/LazyWrapper/LazyWrapper.d.ts +3 -2
  153. package/dist/Components/LazyWrapper/LazyWrapper.js +1 -0
  154. package/dist/Components/LimitReachedModal/LimitReachedModalProps.d.ts +4 -1
  155. package/dist/Components/LimitReachedModal/limitReachedCopy.d.ts +2 -0
  156. package/dist/Components/LimitReachedModal/limitReachedCopy.js +2 -0
  157. package/dist/Components/Loading/Loading.d.ts +1 -0
  158. package/dist/Components/Loading/Loading.js +16 -14
  159. package/dist/Components/Loading/LoadingProps.d.ts +2 -0
  160. package/dist/Components/Modal/ModalProps.d.ts +2 -0
  161. package/dist/Components/MoreItems/MoreItems.d.ts +1 -0
  162. package/dist/Components/MoreItems/MoreItems.js +4 -1
  163. package/dist/Components/MoreItems/MoreItemsProps.d.ts +4 -2
  164. package/dist/Components/MultiSelect/MultiSelect.js +2 -2
  165. package/dist/Components/MultiSelect/MultiSelectProps.d.ts +2 -0
  166. package/dist/Components/NavigationBar/NavigationBar.js +9 -10
  167. package/dist/Components/NavigationBar/NavigationBarProps.d.ts +3 -0
  168. package/dist/Components/NoteTextArea/NoteTextArea.d.ts +1 -0
  169. package/dist/Components/NoteTextArea/NoteTextArea.js +10 -4
  170. package/dist/Components/NoteTextArea/NoteTextAreaProps.d.ts +2 -0
  171. package/dist/Components/Notification/Notification.d.ts +1 -0
  172. package/dist/Components/Notification/Notification.js +1 -0
  173. package/dist/Components/Notification/NotificationProps.d.ts +6 -0
  174. package/dist/Components/NumberInput/NumberInput.d.ts +1 -0
  175. package/dist/Components/NumberInput/NumberInput.js +4 -1
  176. package/dist/Components/NumberInput/NumberInput.styles.js +7 -6
  177. package/dist/Components/NumberInput/NumberInputProps.d.ts +3 -0
  178. package/dist/Components/OrgSwitcher/OrgSwitcher.js +14 -10
  179. package/dist/Components/OrgSwitcher/OrgSwitcherProps.d.ts +6 -1
  180. package/dist/Components/OrgSwitcher/OrgSwitcherProps.js +1 -0
  181. package/dist/Components/OrganizationDetails/OrganizationDetails.d.ts +1 -0
  182. package/dist/Components/OrganizationDetails/OrganizationDetails.js +4 -2
  183. package/dist/Components/OrganizationDetails/OrganizationDetailsProps.d.ts +17 -4
  184. package/dist/Components/PdfViewer/PdfViewer.d.ts +2 -1
  185. package/dist/Components/PdfViewer/PdfViewer.js +7 -1
  186. package/dist/Components/PinInput/PinInput.d.ts +1 -0
  187. package/dist/Components/PinInput/PinInput.js +1 -0
  188. package/dist/Components/PinInput/PinInputProps.d.ts +2 -0
  189. package/dist/Components/PinInputs/PinInputs.d.ts +1 -0
  190. package/dist/Components/PinInputs/PinInputs.js +1 -0
  191. package/dist/Components/PinInputs/PinInputsProps.d.ts +1 -0
  192. package/dist/Components/PlanBadge/PlanBadgeProps.d.ts +2 -0
  193. package/dist/Components/PlanPill/PlanPillProps.d.ts +2 -0
  194. package/dist/Components/Primitives/Primitives.d.ts +6 -0
  195. package/dist/Components/Primitives/Primitives.js +113 -0
  196. package/dist/Components/ProductCard/ProductCardProps.d.ts +10 -0
  197. package/dist/Components/ProductCard/ProductReview.d.ts +1 -0
  198. package/dist/Components/ProductCard/ProductReview.js +6 -1
  199. package/dist/Components/ProductCard/ProductTags.js +1 -1
  200. package/dist/Components/ProductDetails/ProductDetailsProps.d.ts +7 -0
  201. package/dist/Components/ProfileCard/ProfileCard.js +1 -1
  202. package/dist/Components/ProfileCard/ProfileCardProps.d.ts +3 -0
  203. package/dist/Components/ProfilePhotoViewer/ProfilePhotoViewer.d.ts +1 -0
  204. package/dist/Components/ProfilePhotoViewer/ProfilePhotoViewer.js +5 -3
  205. package/dist/Components/ProfilePhotoViewer/ProfilePhotoViewerProps.d.ts +9 -1
  206. package/dist/Components/ProgressBar/ProgressBar.d.ts +1 -0
  207. package/dist/Components/ProgressBar/ProgressBar.js +1 -0
  208. package/dist/Components/ProgressBar/ProgressBarProps.d.ts +2 -0
  209. package/dist/Components/RadioButton/RadioButton.js +3 -2
  210. package/dist/Components/RadioButton/RadioButtonProps.d.ts +2 -0
  211. package/dist/Components/Reorder/Reorder.d.ts +2 -0
  212. package/dist/Components/Reorder/Reorder.js +1 -0
  213. package/dist/Components/Reorder/ReorderProps.d.ts +3 -0
  214. package/dist/Components/RolesPermission/RolesPermission.d.ts +1 -0
  215. package/dist/Components/RolesPermission/RolesPermission.js +5 -3
  216. package/dist/Components/RolesPermission/RolesPermissionProps.d.ts +16 -1
  217. package/dist/Components/ScrollToTop/ScrollToTop.d.ts +3 -2
  218. package/dist/Components/ScrollToTop/ScrollToTop.js +4 -1
  219. package/dist/Components/ScrollbarBox/ScrollbarBox.d.ts +7 -0
  220. package/dist/Components/ScrollbarBox/ScrollbarBox.js +1 -0
  221. package/dist/Components/Search/Search.d.ts +1 -0
  222. package/dist/Components/Search/Search.js +3 -2
  223. package/dist/Components/Search/SearchProps.d.ts +2 -0
  224. package/dist/Components/SearchSelect/SearchSelect.d.ts +1 -0
  225. package/dist/Components/SearchSelect/SearchSelect.js +48 -37
  226. package/dist/Components/SearchSelect/SearchSelectProps.d.ts +23 -0
  227. package/dist/Components/SegmentedControl/SegmentedControl.d.ts +3 -0
  228. package/dist/Components/SegmentedControl/SegmentedControl.js +89 -0
  229. package/dist/Components/SegmentedControl/SegmentedControlProps.d.ts +23 -0
  230. package/dist/Components/SegmentedControl/SegmentedControlProps.js +2 -0
  231. package/dist/Components/Select/Select.d.ts +1 -1
  232. package/dist/Components/Select/Select.js +4 -2
  233. package/dist/Components/Select/Select.styles.js +3 -2
  234. package/dist/Components/Select/SelectProps.d.ts +6 -0
  235. package/dist/Components/SelectSearch/SelectSearch.d.ts +1 -0
  236. package/dist/Components/SelectSearch/SelectSearch.js +37 -15
  237. package/dist/Components/SelectSearch/SelectSearchProps.d.ts +5 -0
  238. package/dist/Components/SelectV2/SelectV2.d.ts +1 -0
  239. package/dist/Components/SelectV2/SelectV2.js +20 -5
  240. package/dist/Components/SelectV2/SelectV2Props.d.ts +6 -1
  241. package/dist/Components/SideBar/SecondaryBar.js +1 -1
  242. package/dist/Components/SideBar/SideBar.js +5 -3
  243. package/dist/Components/SideBar/SideBarProps.d.ts +38 -24
  244. package/dist/Components/SideBar/components/MenuItemBox.js +15 -11
  245. package/dist/Components/SideBar/components/MenuPopoverContent.js +13 -10
  246. package/dist/Components/SignInActivityTable/SignInActivityTableProps.d.ts +3 -0
  247. package/dist/Components/Skeletons/SkeletonProps.d.ts +2 -0
  248. package/dist/Components/Skeletons/Skeletons.d.ts +1 -0
  249. package/dist/Components/Skeletons/Skeletons.js +1 -0
  250. package/dist/Components/Slider/Slider.d.ts +3 -0
  251. package/dist/Components/Slider/Slider.js +9 -1
  252. package/dist/Components/StageProgress/StageItem.d.ts +1 -0
  253. package/dist/Components/StageProgress/StageItem.js +1 -0
  254. package/dist/Components/StageProgress/StageProgress.d.ts +1 -0
  255. package/dist/Components/StageProgress/StageProgress.js +1 -0
  256. package/dist/Components/StageProgress/StageProgressProps.d.ts +45 -4
  257. package/dist/Components/StageProgress/StageProgressProps.js +6 -4
  258. package/dist/Components/StageProgress/StepperStage.js +2 -2
  259. package/dist/Components/Switch/Switch.d.ts +1 -0
  260. package/dist/Components/Switch/Switch.js +1 -0
  261. package/dist/Components/Switch/SwitchProps.d.ts +1 -0
  262. package/dist/Components/Table/Table.d.ts +2 -1
  263. package/dist/Components/Table/Table.js +15 -5
  264. package/dist/Components/Table/TableProps.d.ts +47 -0
  265. package/dist/Components/Table/components/Pagination.js +1 -1
  266. package/dist/Components/Table/components/TableActions.js +2 -2
  267. package/dist/Components/Table/components/TableBody.js +44 -18
  268. package/dist/Components/Table/components/TableGroupRow.js +1 -1
  269. package/dist/Components/Table/components/TableHeader.js +21 -8
  270. package/dist/Components/Table/components/TableSearch.js +1 -1
  271. package/dist/Components/Table/filters/CompactSelect.d.ts +1 -0
  272. package/dist/Components/Table/filters/CompactSelect.js +29 -8
  273. package/dist/Components/Table/filters/LeftFilterPane.d.ts +9 -1
  274. package/dist/Components/Table/filters/LeftFilterPane.js +1 -1
  275. package/dist/Components/Table/settings/ManageColumns.js +8 -5
  276. package/dist/Components/Table/settings/TableSettings.js +6 -4
  277. package/dist/Components/Table/variants/TableVariantContext.d.ts +4 -0
  278. package/dist/Components/Table/variants/TableVariantContext.js +17 -0
  279. package/dist/Components/Table/variants/classic.d.ts +6 -0
  280. package/dist/Components/Table/variants/classic.js +47 -0
  281. package/dist/Components/Table/variants/index.d.ts +7 -0
  282. package/dist/Components/Table/variants/index.js +27 -0
  283. package/dist/Components/Table/variants/pillInk.d.ts +6 -0
  284. package/dist/Components/Table/variants/pillInk.js +21 -0
  285. package/dist/Components/Table/variants/studio.d.ts +6 -0
  286. package/dist/Components/Table/variants/studio.js +50 -0
  287. package/dist/Components/Table/variants/tokens.d.ts +49 -0
  288. package/dist/Components/Table/variants/tokens.js +2 -0
  289. package/dist/Components/Tag/Tag.d.ts +1 -0
  290. package/dist/Components/Tag/Tag.js +1 -0
  291. package/dist/Components/Tag/Tag.styles.js +16 -11
  292. package/dist/Components/Tag/TagProps.d.ts +7 -0
  293. package/dist/Components/Timeline/Timeline.d.ts +1 -0
  294. package/dist/Components/Timeline/Timeline.js +1 -0
  295. package/dist/Components/Timeline/TimelineProps.d.ts +8 -0
  296. package/dist/Components/Toaster/Toaster.d.ts +1 -0
  297. package/dist/Components/Toaster/Toaster.js +1 -0
  298. package/dist/Components/Toaster/ToasterProps.d.ts +3 -0
  299. package/dist/Components/Toggle/TableToggle.d.ts +1 -0
  300. package/dist/Components/Toggle/TableToggle.js +73 -18
  301. package/dist/Components/Toggle/TableToggleProps.d.ts +6 -0
  302. package/dist/Components/ToggleSwitch/ToggleSwitch.d.ts +3 -0
  303. package/dist/Components/ToggleSwitch/ToggleSwitch.js +19 -0
  304. package/dist/Components/ToggleSwitch/ToggleSwitchProps.d.ts +13 -0
  305. package/dist/Components/ToggleSwitch/ToggleSwitchProps.js +2 -0
  306. package/dist/Components/ToolTip/ToolTip.d.ts +1 -0
  307. package/dist/Components/ToolTip/ToolTip.js +7 -6
  308. package/dist/Components/ToolTip/ToolTipProps.d.ts +5 -1
  309. package/dist/Components/Trail/EditableCell.d.ts +2 -0
  310. package/dist/Components/Trail/EditableCell.js +2 -1
  311. package/dist/Components/Trail/SelectAllCheckbox.d.ts +1 -0
  312. package/dist/Components/Trail/SelectAllCheckbox.js +1 -0
  313. package/dist/Components/Trail/TrailWorks.d.ts +1 -0
  314. package/dist/Components/Trail/TrailWorks.js +2 -1
  315. package/dist/Components/UpgradeButton/UpgradeButtonProps.d.ts +6 -2
  316. package/dist/Components/UserDetails/DeactivateConfirmModal.js +1 -1
  317. package/dist/Components/UserDetails/UserDetails.d.ts +1 -0
  318. package/dist/Components/UserDetails/UserDetails.js +6 -3
  319. package/dist/Components/UserDetails/UserDetailsProps.d.ts +30 -1
  320. package/dist/Components/WorkspaceWindow/WorkspaceWindowProps.d.ts +6 -1
  321. package/dist/Hooks/exclusiveOverlay.d.ts +4 -0
  322. package/dist/Hooks/exclusiveOverlay.js +22 -0
  323. package/dist/Hooks/useExclusiveOverlay.d.ts +5 -0
  324. package/dist/Hooks/useExclusiveOverlay.js +24 -0
  325. package/dist/Theme/assertPalette.d.ts +1 -1
  326. package/dist/Theme/assertPalette.js +3 -2
  327. package/dist/Theme/chakra/Menu.styles.d.ts +2 -0
  328. package/dist/Theme/chakra/Menu.styles.js +9 -5
  329. package/dist/Theme/chakra/Popover.styles.d.ts +3 -0
  330. package/dist/Theme/chakra/Popover.styles.js +5 -1
  331. package/dist/Theme/chakra/componentStyles.d.ts +5 -0
  332. package/dist/Theme/chakra/componentStyles.js +16 -9
  333. package/dist/Theme/chakra/createBrandTheme.js +22 -9
  334. package/dist/Theme/chakra/focusRing.styles.d.ts +52 -0
  335. package/dist/Theme/chakra/focusRing.styles.js +46 -0
  336. package/dist/Theme/provider/ThemeSwitcher.js +5 -2
  337. package/dist/Theme/tokens/brands/index.js +6 -1
  338. package/dist/Theme/tokens/brands/zinc/palette.dark.d.ts +1 -0
  339. package/dist/Theme/tokens/builders/buildDarkPalette.js +6 -1
  340. package/dist/Theme/tokens/builders/chartColorsFromTheme.js +1 -1
  341. package/dist/Theme/tokens/builders/filledSurface.d.ts +29 -0
  342. package/dist/Theme/tokens/builders/filledSurface.js +74 -0
  343. package/dist/Theme/tokens/builders/focusRing.d.ts +52 -0
  344. package/dist/Theme/tokens/builders/focusRing.js +92 -0
  345. package/dist/Theme/tokens/builders/index.d.ts +2 -0
  346. package/dist/Theme/tokens/builders/index.js +2 -0
  347. package/dist/Theme/tokens/builders/outlineRung.d.ts +41 -3
  348. package/dist/Theme/tokens/builders/outlineRung.js +82 -5
  349. package/dist/Theme/tokens/builders/placeholderInk.d.ts +19 -0
  350. package/dist/Theme/tokens/builders/placeholderInk.js +35 -0
  351. package/dist/Theme/tokens/builders/resolvedRungs.d.ts +5 -1
  352. package/dist/Theme/tokens/builders/resolvedRungs.js +7 -2
  353. package/dist/Theme/tokens/builders/rowStates.d.ts +13 -0
  354. package/dist/Theme/tokens/builders/rowStates.js +19 -0
  355. package/dist/Theme/tokens/builders/scrollShadow.d.ts +2 -0
  356. package/dist/Theme/tokens/builders/scrollShadow.js +16 -0
  357. package/dist/Theme/tokens/builders/surfaceRungs.d.ts +5 -2
  358. package/dist/Theme/tokens/builders/surfaceRungs.js +19 -9
  359. package/dist/Theme/tokens/types.d.ts +21 -1
  360. package/dist/Utils/table.d.ts +3 -0
  361. package/dist/Utils/table.js +49 -3
  362. package/dist/esm/Components/Accordion/Accordion.js +4 -1
  363. package/dist/esm/Components/AlertDialog/AlertDialog.js +1 -0
  364. package/dist/esm/Components/Apexcharts/ApexAreaChart/ApexAreaChart.js +1 -0
  365. package/dist/esm/Components/Apexcharts/ApexBarChart/ApexBarChart.js +1 -0
  366. package/dist/esm/Components/Apexcharts/ApexLineChart/ApexLineChart.js +1 -0
  367. package/dist/esm/Components/Apexcharts/ApexPieChart/ApexPieChart.js +1 -0
  368. package/dist/esm/Components/Apexcharts/ApexPolarCharts/ApexPolarCharts.js +1 -0
  369. package/dist/esm/Components/Apexcharts/ApexRadialChart/ApexRadialChart.js +1 -0
  370. package/dist/esm/Components/AppSwitcher/AppMark.js +56 -0
  371. package/dist/esm/Components/AppSwitcher/AppSwitcher.js +243 -0
  372. package/dist/esm/Components/AppSwitcher/AppSwitcherProps.js +78 -0
  373. package/dist/esm/Components/AppSwitcher/useAppSwitcherShortcut.js +27 -0
  374. package/dist/esm/Components/AppearanceSettings/AppearanceSettings.js +2 -1
  375. package/dist/esm/Components/Button/Button.js +5 -4
  376. package/dist/esm/Components/Button/Button.styles.js +38 -24
  377. package/dist/esm/Components/ButtonGroupIcon/ButtonGroupIcon.js +2 -4
  378. package/dist/esm/Components/Card/Card.js +2 -2
  379. package/dist/esm/Components/Card/PaymentCard/PaymentCard.js +21 -12
  380. package/dist/esm/Components/Checkbox/Checkbox.js +2 -1
  381. package/dist/esm/Components/Checkbox/Checkbox.styles.js +13 -8
  382. package/dist/esm/Components/Common/ErrorComponent.js +7 -5
  383. package/dist/esm/Components/Common/ErrorMessage.js +2 -2
  384. package/dist/esm/Components/Common/FormLabel.js +1 -0
  385. package/dist/esm/Components/Common/FormattedDescription.js +1 -0
  386. package/dist/esm/Components/Common/HelperText.js +2 -0
  387. package/dist/esm/Components/Common/Label.js +1 -0
  388. package/dist/esm/Components/Common/fieldStyles.js +1 -1
  389. package/dist/esm/Components/ContactForm/ContactForm.js +1 -0
  390. package/dist/esm/Components/CopyButton/CopyButton.js +10 -4
  391. package/dist/esm/Components/DatePicker/CalendarPanel.js +38 -16
  392. package/dist/esm/Components/DatePicker/DatePicker.js +1 -0
  393. package/dist/esm/Components/DatePicker/RangeDatePicker.js +31 -6
  394. package/dist/esm/Components/DatePicker/SingleDatePicker.js +50 -15
  395. package/dist/esm/Components/DatePicker/ThemeDatePicker.js +1 -0
  396. package/dist/esm/Components/DatePicker/TimeOnlyPicker.js +11 -2
  397. package/dist/esm/Components/DatePicker/TimePicker.js +4 -3
  398. package/dist/esm/Components/DatePicker/TimePickerInput.js +2 -1
  399. package/dist/esm/Components/DatePicker/dayStates.js +79 -0
  400. package/dist/esm/Components/Divider/Divider.js +1 -0
  401. package/dist/esm/Components/Dropdown/DropDown.js +23 -7
  402. package/dist/esm/Components/Editor/Editor.js +1 -0
  403. package/dist/esm/Components/EmailCards/VerifyEmailOtp/VerifyEmailOtp.js +2 -5
  404. package/dist/esm/Components/EmptyState/EmptyState.js +4 -2
  405. package/dist/esm/Components/FeedbackForm/FeedbackForm.js +1 -0
  406. package/dist/esm/Components/FieldSelectModal/FieldSelectModal.js +1 -0
  407. package/dist/esm/Components/FilePreview/FilePreview.js +3 -1
  408. package/dist/esm/Components/FileUpload/FileUpload.js +8 -6
  409. package/dist/esm/Components/FileUpload/constants.js +1 -0
  410. package/dist/esm/Components/FileUploader/FileUploader.js +1 -0
  411. package/dist/esm/Components/FilterSidebar/FilterSidebar.js +5 -5
  412. package/dist/esm/Components/FilterSidebar/filterHoverStyle.js +3 -10
  413. package/dist/esm/Components/Form/FormWrapper.js +2 -1
  414. package/dist/esm/Components/Header/components/mobileMenu.js +12 -3
  415. package/dist/esm/Components/Input/PhoneNumberInput.js +1 -0
  416. package/dist/esm/Components/Input/Switch/InputSwitch.js +1 -0
  417. package/dist/esm/Components/Input/TextInput.js +1 -0
  418. package/dist/esm/Components/Input/TextInput.styles.js +8 -10
  419. package/dist/esm/Components/InputTextArea/InputTextArea.js +1 -0
  420. package/dist/esm/Components/InputTextArea/InputTextArea.style.js +7 -6
  421. package/dist/esm/Components/KanbanBoard/AccountCard.js +1 -0
  422. package/dist/esm/Components/KanbanBoard/AccountRow.js +1 -0
  423. package/dist/esm/Components/KanbanBoard/KanbanActions/KanbanActions.js +2 -2
  424. package/dist/esm/Components/KanbanBoard/KanbanBoard.js +1 -0
  425. package/dist/esm/Components/KanbanBoard/MeasuredItem.js +1 -0
  426. package/dist/esm/Components/LazyWrapper/LazyWrapper.js +1 -0
  427. package/dist/esm/Components/LimitReachedModal/limitReachedCopy.js +2 -0
  428. package/dist/esm/Components/Loading/Loading.js +13 -11
  429. package/dist/esm/Components/MoreItems/MoreItems.js +4 -1
  430. package/dist/esm/Components/MultiSelect/MultiSelect.js +2 -2
  431. package/dist/esm/Components/NavigationBar/NavigationBar.js +9 -10
  432. package/dist/esm/Components/NoteTextArea/NoteTextArea.js +10 -4
  433. package/dist/esm/Components/Notification/Notification.js +1 -0
  434. package/dist/esm/Components/NumberInput/NumberInput.js +5 -2
  435. package/dist/esm/Components/NumberInput/NumberInput.styles.js +7 -6
  436. package/dist/esm/Components/OrgSwitcher/OrgSwitcher.js +14 -10
  437. package/dist/esm/Components/OrgSwitcher/OrgSwitcherProps.js +1 -0
  438. package/dist/esm/Components/OrganizationDetails/OrganizationDetails.js +5 -3
  439. package/dist/esm/Components/PdfViewer/PdfViewer.js +7 -1
  440. package/dist/esm/Components/PinInput/PinInput.js +1 -0
  441. package/dist/esm/Components/PinInputs/PinInputs.js +1 -0
  442. package/dist/esm/Components/Primitives/Primitives.js +6 -0
  443. package/dist/esm/Components/ProductCard/ProductReview.js +6 -1
  444. package/dist/esm/Components/ProductCard/ProductTags.js +1 -1
  445. package/dist/esm/Components/ProfileCard/ProfileCard.js +1 -1
  446. package/dist/esm/Components/ProfilePhotoViewer/ProfilePhotoViewer.js +6 -4
  447. package/dist/esm/Components/ProgressBar/ProgressBar.js +1 -0
  448. package/dist/esm/Components/RadioButton/RadioButton.js +3 -2
  449. package/dist/esm/Components/Reorder/Reorder.js +1 -0
  450. package/dist/esm/Components/RolesPermission/RolesPermission.js +5 -3
  451. package/dist/esm/Components/ScrollToTop/ScrollToTop.js +4 -1
  452. package/dist/esm/Components/ScrollbarBox/ScrollbarBox.js +1 -0
  453. package/dist/esm/Components/Search/Search.js +3 -2
  454. package/dist/esm/Components/SearchSelect/SearchSelect.js +48 -37
  455. package/dist/esm/Components/SegmentedControl/SegmentedControl.js +86 -0
  456. package/dist/esm/Components/SegmentedControl/SegmentedControlProps.js +1 -0
  457. package/dist/esm/Components/Select/Select.js +5 -3
  458. package/dist/esm/Components/Select/Select.styles.js +3 -2
  459. package/dist/esm/Components/SelectSearch/SelectSearch.js +37 -15
  460. package/dist/esm/Components/SelectV2/SelectV2.js +20 -5
  461. package/dist/esm/Components/SideBar/SecondaryBar.js +1 -1
  462. package/dist/esm/Components/SideBar/SideBar.js +5 -3
  463. package/dist/esm/Components/SideBar/components/MenuItemBox.js +15 -11
  464. package/dist/esm/Components/SideBar/components/MenuPopoverContent.js +13 -10
  465. package/dist/esm/Components/Skeletons/Skeletons.js +1 -0
  466. package/dist/esm/Components/Slider/Slider.js +9 -1
  467. package/dist/esm/Components/StageProgress/StageItem.js +1 -0
  468. package/dist/esm/Components/StageProgress/StageProgress.js +1 -0
  469. package/dist/esm/Components/StageProgress/StageProgressProps.js +7 -5
  470. package/dist/esm/Components/StageProgress/StepperStage.js +2 -2
  471. package/dist/esm/Components/Switch/Switch.js +1 -0
  472. package/dist/esm/Components/Table/Table.js +15 -5
  473. package/dist/esm/Components/Table/components/Pagination.js +1 -1
  474. package/dist/esm/Components/Table/components/TableActions.js +2 -2
  475. package/dist/esm/Components/Table/components/TableBody.js +44 -18
  476. package/dist/esm/Components/Table/components/TableGroupRow.js +1 -1
  477. package/dist/esm/Components/Table/components/TableHeader.js +21 -8
  478. package/dist/esm/Components/Table/components/TableSearch.js +1 -1
  479. package/dist/esm/Components/Table/filters/CompactSelect.js +29 -8
  480. package/dist/esm/Components/Table/filters/LeftFilterPane.js +1 -1
  481. package/dist/esm/Components/Table/settings/ManageColumns.js +8 -5
  482. package/dist/esm/Components/Table/settings/TableSettings.js +7 -5
  483. package/dist/esm/Components/Table/variants/TableVariantContext.js +13 -0
  484. package/dist/esm/Components/Table/variants/classic.js +43 -0
  485. package/dist/esm/Components/Table/variants/index.js +9 -0
  486. package/dist/esm/Components/Table/variants/pillInk.js +18 -0
  487. package/dist/esm/Components/Table/variants/studio.js +46 -0
  488. package/dist/esm/Components/Table/variants/tokens.js +1 -0
  489. package/dist/esm/Components/Tag/Tag.js +1 -0
  490. package/dist/esm/Components/Tag/Tag.styles.js +17 -12
  491. package/dist/esm/Components/Timeline/Timeline.js +1 -0
  492. package/dist/esm/Components/Toaster/Toaster.js +1 -0
  493. package/dist/esm/Components/Toggle/TableToggle.js +72 -17
  494. package/dist/esm/Components/ToggleSwitch/ToggleSwitch.js +16 -0
  495. package/dist/esm/Components/ToggleSwitch/ToggleSwitchProps.js +1 -0
  496. package/dist/esm/Components/ToolTip/ToolTip.js +7 -6
  497. package/dist/esm/Components/Trail/EditableCell.js +2 -1
  498. package/dist/esm/Components/Trail/SelectAllCheckbox.js +1 -0
  499. package/dist/esm/Components/Trail/TrailWorks.js +2 -1
  500. package/dist/esm/Components/UserDetails/DeactivateConfirmModal.js +1 -1
  501. package/dist/esm/Components/UserDetails/UserDetails.js +6 -3
  502. package/dist/esm/Hooks/exclusiveOverlay.js +16 -0
  503. package/dist/esm/Hooks/useExclusiveOverlay.js +20 -0
  504. package/dist/esm/Theme/assertPalette.js +3 -2
  505. package/dist/esm/Theme/chakra/Menu.styles.js +9 -5
  506. package/dist/esm/Theme/chakra/Popover.styles.js +5 -1
  507. package/dist/esm/Theme/chakra/componentStyles.js +16 -9
  508. package/dist/esm/Theme/chakra/createBrandTheme.js +22 -9
  509. package/dist/esm/Theme/chakra/focusRing.styles.js +40 -0
  510. package/dist/esm/Theme/provider/ThemeSwitcher.js +5 -2
  511. package/dist/esm/Theme/tokens/brands/index.js +6 -1
  512. package/dist/esm/Theme/tokens/builders/buildDarkPalette.js +6 -1
  513. package/dist/esm/Theme/tokens/builders/chartColorsFromTheme.js +1 -1
  514. package/dist/esm/Theme/tokens/builders/filledSurface.js +67 -0
  515. package/dist/esm/Theme/tokens/builders/focusRing.js +85 -0
  516. package/dist/esm/Theme/tokens/builders/index.js +2 -0
  517. package/dist/esm/Theme/tokens/builders/outlineRung.js +78 -4
  518. package/dist/esm/Theme/tokens/builders/placeholderInk.js +29 -0
  519. package/dist/esm/Theme/tokens/builders/resolvedRungs.js +7 -2
  520. package/dist/esm/Theme/tokens/builders/rowStates.js +15 -0
  521. package/dist/esm/Theme/tokens/builders/scrollShadow.js +13 -0
  522. package/dist/esm/Theme/tokens/builders/surfaceRungs.js +20 -10
  523. package/dist/esm/Utils/table.js +50 -5
  524. package/dist/esm/index.js +26 -1
  525. package/dist/index.d.ts +26 -3
  526. package/dist/index.js +67 -4
  527. package/package.json +11 -4
@@ -0,0 +1,1102 @@
1
+ # Component Gotchas & Decision Guide
2
+
3
+ For anyone — human or AI — consuming `pixelize-design-library` in an app. Read this **before**
4
+ choosing a component or a prop value, not after something looks wrong. Every entry below compiles
5
+ cleanly, accepts what you pass, and produces the wrong result with no warning — TypeScript cannot
6
+ catch any of these, and a unit suite that mocks the library won't either.
7
+
8
+ This file ships inside the published package (`node_modules/pixelize-design-library/COMPONENT-GOTCHAS.md`)
9
+ so it's available without checking out the library's source repo.
10
+
11
+ ---
12
+
13
+ ## Choosing between components
14
+
15
+ ### Segmented control look — `SegmentedControl` / `Toggle/TableToggle`
16
+
17
+ Both take `variant?: "default" | "brandSlide" | "underlineSlide"` (default `"default"` — always
18
+ opt-in, never assume a non-default look).
19
+
20
+ | Context | `variant` | Look |
21
+ | --- | --- | --- |
22
+ | Most call sites — settings rows, filters, table view switches | `"default"` | Neutral chip |
23
+ | The primary, hard-to-miss view switcher on a page (not a dense toolbar) | `"brandSlide"` | Solid brand-filled pill slides behind the active segment |
24
+ | A dense toolbar, table header, or anywhere a boxed control feels heavy | `"underlineSlide"` | Thin brand-colored bar glides under the active label, no fill/chip |
25
+
26
+ Pick by density and emphasis, not by taste. When unsure, or migrating an existing call site, leave
27
+ it on `"default"` — it's the only variant guaranteed to match previously-shipped screenshots.
28
+
29
+ ### Which "select" component — seven components overlap in name, not purpose
30
+
31
+ **Not picking a value from an options list at all:**
32
+
33
+ | Doing | Component | Why not the others |
34
+ | --- | --- | --- |
35
+ | Triggering a labelled *action* (export, row menu, "...") | `Dropdown` | A menu-button, not a form field — nothing is "selected" and persisted |
36
+ | Typing free-text tags (e.g. email addresses), no options list | `MultiSelect` | Despite the name, there is nothing to pick from — see gotcha below |
37
+ | Choosing which *fields/columns* to include, in a modal, from a checkbox grid | `FieldSelectModal` | Multi-checkbox selection UI, not an inline field control |
38
+
39
+ **Picking one or more values from an options list, inline in a form:**
40
+
41
+ | List length / need | Component | Why |
42
+ | --- | --- | --- |
43
+ | Short, always-visible list, no search needed | `Select` | Native `<select>` wrapper — lightest option, but the popup is OS-painted and can't be themed |
44
+ | New build, want themed/custom-rendered rows (icons, descriptions), no huge list | `SelectV2` | Fully React-rendered popup — **prefer this for new work** over `Select` |
45
+ | Long list needing search + chips + select-all + infinite scroll | `SearchSelect` | The full-featured picker; scales via consumer-driven `pagination`, not DOM virtualization — see gotcha below |
46
+ | Search-as-you-type with avatars/colour swatches/a pinned "add new" row | `SelectSearch` | Lighter than `SearchSelect`; reach for it for that specific row-content need |
47
+
48
+ Default when unsure: `SelectV2` for a themed field, `Select` if the native popup is genuinely fine.
49
+
50
+ ### `Slider` is an image carousel, not a numeric range input
51
+
52
+ `Slider` auto-advances a set of images/content on a timer — no numeric value, min/max, or step. The
53
+ actual range-input slider is Chakra's own, re-exported from the `Primitives` barrel as `RangeSlider`
54
+ specifically because this library's `Slider` already owns the name.
55
+
56
+ **Apply:** for a numeric/range form control, import `RangeSlider` from the `Primitives` barrel —
57
+ never `Slider`.
58
+
59
+ ### Which "switch" — `ToggleSwitch` / `SegmentedControl` / `Switch`
60
+
61
+ | Choosing | Component | Why |
62
+ | --- | --- | --- |
63
+ | A real on/off toggle | `ToggleSwitch` | `role="switch"` + `aria-checked`, full keyboard support |
64
+ | One of 2-5 named options | `SegmentedControl` | `role="radiogroup"`, keyboard-navigable, supports per-option disabling |
65
+ | — | `Switch` | Despite the name, a two-label segmented control (`leftText`/`rightText`) — no role, no keyboard handling at all (mouse-only). Kept only for backward compatibility; don't reach for it in new code |
66
+
67
+ **Apply:** if the choice is "on vs off," it's never `Switch` — use `ToggleSwitch`. For 2+ named
68
+ options, prefer `SegmentedControl` even over `Switch`.
69
+
70
+ ### Circular charts — `ApexPieChart` vs `ApexPolarCharts`
71
+
72
+ | Need | Component | Why not the other |
73
+ | --- | --- | --- |
74
+ | Proportional share of a whole — slices sum to 100% | `ApexPieChart` | The default "part of a whole" chart; donut variants support a center total label |
75
+ | Compare independent magnitudes on a shared radial grid — values need not sum to anything | `ApexPolarCharts` | Reads like a circular bar chart, not a pie; picking Pie here makes unrelated values look like they must add to 100% |
76
+
77
+ ### Which "button" — `Button` / `ButtonGroupIcon` / `Buttons`
78
+
79
+ | Need | Component | Why not the others |
80
+ | --- | --- | --- |
81
+ | A single themed, interactive button — any variant/size/colorScheme, dark-mode aware | `Button` | The only one of the three that reads design tokens at all |
82
+ | A themed row of icon + text + icon, optionally a dropdown menu on the right | `ButtonGroupIcon` | The real "group" component despite `Buttons`' plural name suggesting otherwise |
83
+ | *(avoid)* | `Buttons` (plural) | Legacy single `<button>` hardcoded to Tailwind `bg-purple-600`, not theme-aware, not exported from the package root — see gotcha below |
84
+
85
+ ### Which "card" — `Card` / `ProductCard` / `ProductDetails` / `PaymentCard`
86
+
87
+ | Need | Component | Why not the others |
88
+ | --- | --- | --- |
89
+ | Generic bordered/padded container, no commerce semantics | `Card` | Plain layout wrapper — its `header`/`footer`/divider props are dead, compose your own layout in `children` |
90
+ | Compact product tile for a grid/listing page | `ProductCard` | Fixed size presets, single-image hover-swap, no gallery |
91
+ | Full product detail page layout (gallery + description + variant picker) | `ProductDetails` | No card chrome of its own; same variant-list shape as `ProductCard` but named `price`, not `options` |
92
+ | Subscription/pricing-tier card (plans, billing cycle, feature list) | `PaymentCard` | Takes a `Plan` object, unrelated to `options`/`productImage` |
93
+
94
+ ### Managing organizations — `OrganizationDetails` vs `OrgSwitcher`
95
+
96
+ | Doing | Component | Why not the other |
97
+ | --- | --- | --- |
98
+ | Quickly changing which org is active for the current session (navbar/header) | `OrgSwitcher` | Compact trigger + searchable popover; no create/rename/delete — session-scoped |
99
+ | Managing the org list — rename, delete, accept/decline invites, create new, set a persisted default | `OrganizationDetails` | Full admin panel with bundled CRUD modals; `default`/`onSetDefault` is a persisted preference, not OrgSwitcher's session-scoped `value`/`onChange` |
100
+
101
+ ### Plan/upgrade cluster — `UpgradeButton` / `PlanPill` / `PlanBadge` / `LimitReachedModal`
102
+
103
+ | Doing | Component | Why not the others |
104
+ | --- | --- | --- |
105
+ | A prominent, animated "upgrade now" CTA button | `UpgradeButton` | Shimmer/hover-lift button with size variants |
106
+ | Showing a plan-state badge and you already have label/tone/copy decided | `PlanPill` | Presentational only — no resolution logic |
107
+ | Showing the top-bar plan-name/"upgrade" badge from raw org plan data | `PlanBadge` | Wraps `PlanPill` with `resolvePlanBadge()`; renders nothing if `canManageBilling` is falsy |
108
+ | Blocking a user who hit a plan limit, with an explanation and upgrade path | `LimitReachedModal` | Full modal, fully controlled, reuses `UpgradeButton` as its own CTA |
109
+
110
+ ### Top-of-app navigation — `NavigationBar` / `Header` / `SideBar` / `AppSwitcher` / `WorkspaceWindow`
111
+
112
+ | Need | Component | Why not the others |
113
+ | --- | --- | --- |
114
+ | Top bar: back control + user-avatar profile/logout dropdown | `NavigationBar` | No page-nav links at all — `navMenu` is only the avatar dropdown's own items |
115
+ | Top bar: horizontal page links with active-state highlighting + submenus | `Header` | Desktop submenus are hover-only, see gotcha below |
116
+ | Collapsible/dockable left rail — primary in-app navigation + secondary panel | `SideBar` | The persistent nav shell, not for switching between whole apps |
117
+ | Cross-app launcher (CRM/HRMS/Tickets/Billing/...) | `AppSwitcher` | Two-column popover grid of separate app origins — `SideBar`'s `otherApps` is the legacy predecessor; don't wire both into one shell |
118
+ | Floating Jira-style dialog to view/edit one record without leaving the page | `WorkspaceWindow` | Modal-based floating panel, not page navigation; pairs with `WorkspaceTray` |
119
+
120
+ ### File pickers — `FileUpload` vs `FileUploader`
121
+
122
+ | Need | Component | Why |
123
+ | --- | --- | --- |
124
+ | Real `File`/Blob objects to actually upload (FormData/API) | `FileUpload` | Controlled; `onFilesUploaded` carries real `File[]` and validates accept/size with rejection messages |
125
+ | Self-contained "add photos, see thumbnails, remove" list with no server upload | `FileUploader` | Manages its own state; its `onFilesChange` metadata discards the real `File` — see gotcha below |
126
+
127
+ Both export a type named `FileUploaderProps` — the one re-exported from the package root (`src/index.ts`) describes `FileUpload`, not `FileUploader`. Check which folder a type came from before trusting the name.
128
+
129
+ ### Inline file preview — `PdfViewer` vs `FilePreview`
130
+
131
+ | Need | Component | Why |
132
+ | --- | --- | --- |
133
+ | Always-visible inline PDF panel in the page flow | `PdfViewer` | Non-modal, PDF-only, small open/download toolbar |
134
+ | Click-to-open lightbox over mixed/unknown file types | `FilePreview` | Controlled modal; auto-detects image/pdf/video/other, adds zoom/rotate for images, graceful fallback for unsupported types |
135
+
136
+ Both render a PDF through the identical unstyled `<embed type="application/pdf">` with no error handling if the browser can't render it inline — neither tells you when that happens.
137
+
138
+ ---
139
+
140
+ ## Known gotchas (silent failures)
141
+
142
+ ### `Drawer` / `Modal` / `ProfileCard` drop any child that isn't a named slot
143
+
144
+ All three match children by exact type (`child.type === XHeader/XBody/XFooter`) and render only
145
+ those matches — nothing else in `children` is ever read. Two consequences: a sibling among the
146
+ slots (a nested `Modal`, `AlertDialog`, a confirm dialog, a portal after the footer) silently never
147
+ mounts; and a slot wrapped in a `<>...</>` fragment is dropped too, because the matching doesn't
148
+ unwrap fragments — a fragment's `.type` is `Fragment`, never the slot component.
149
+
150
+ **Apply:** put a confirm dialog **outside** the `Drawer`/`Modal`/`ProfileCard`, as a sibling in a
151
+ wrapping fragment — never among the header/body/footer slots. When a ternary picks between bodies,
152
+ branch into a variable rendered inside one body slot, rather than returning fragment-wrapped slots
153
+ per branch.
154
+
155
+ ### `Select`'s `onChange` never fires for the built-in placeholder
156
+
157
+ `Select` resolves the changed value against its `options` list and calls `onChange` only on a hit.
158
+ The built-in `placeholder` renders as its own empty-value option, which isn't in `options` — so
159
+ picking it resolves to no match and nothing fires. An "Any / All / None" reset built on the
160
+ placeholder alone is a dead control; the value snaps back and no filter clears.
161
+
162
+ **Apply:** fine for a plain pick-one-of-N. For a clearable filter, add an explicit
163
+ `{ id: "", label: "Any" }` entry to `options` instead of relying on the placeholder.
164
+
165
+ ### `MultiSelect` is an email-chip input, not a picker
166
+
167
+ Despite the name, `MultiSelect` takes **no `options` prop at all**. Typed text is validated as an
168
+ email address and rejected if it doesn't match — there is no way to choose from a product/entity
169
+ list.
170
+
171
+ **Apply:** use `SearchSelect` with `isMultiple` to pick multiple values from an options list.
172
+
173
+ ### `RadioButton` has a closed prop list — no `...rest`, no `name`
174
+
175
+ It forwards only a fixed set of props (`label`, `colorScheme`, `isChecked`, `onChange`,
176
+ `isDisabled`, `size`, `value`, `defaultChecked`, plus label/tooltip props) to the underlying radio
177
+ — a `data-*` hook, `aria-describedby`, or a `ref` cannot reach it.
178
+
179
+ **Apply:** it still joins an external `RadioGroup` correctly (grouping comes from context, no
180
+ `name` prop needed) — don't avoid it just for grouping. Reach for the library's Chakra escape
181
+ hatch only when you need something outside that closed list.
182
+
183
+ ### `Table`'s `onRowClick` is dead if every column has a `node` renderer
184
+
185
+ Row-click is gated **per column**, not per row: a column supplying a custom `node` renderer
186
+ swallows the click on that cell. Give every column a `node` and `onRowClick` becomes dead code —
187
+ accepted, typed, never called.
188
+
189
+ **Apply:** leave at least one column without a `node`, or put an explicit control inside a `node`
190
+ renderer instead of relying on row click.
191
+
192
+ ### `InputTextArea`'s `width` defaults to the number `500`, and no `id` means no label
193
+
194
+ `width` defaults to `500`, forwarded straight through — `500` isn't a sizing-scale key, so it
195
+ renders a literal `500px`, not a max and not responsive. It only shows up on a narrow screen.
196
+ Separately, `id` feeds both the visible label and the field itself with no fallback — omit it and
197
+ the label is associated with nothing; the field has no accessible name.
198
+
199
+ **Apply:** pass `width="100%"` **and** `id` at every call site.
200
+
201
+ ### `error` without `errorMessage` renders the literal word "Error" — and erases `helperText`
202
+
203
+ Every field that shows validation errors (`TextInput`, `InputTextArea`, `Select`, `MultiSelect`,
204
+ `SelectV2`, `SearchSelect`, `SelectSearch`, `Search`, `Checkbox`, the `DatePicker` variants,
205
+ `PhoneNumberInput`) falls back to the literal word **"Error"** when `error` is `true` but
206
+ `errorMessage` is empty. Worse, `helperText` only renders when `!error` — so the guidance
207
+ disappears exactly when it's needed.
208
+
209
+ **Apply:** never pass `error` without `errorMessage`. Gate `error` on a `touched` flag so a field
210
+ whose defaults arrive asynchronously doesn't open already red.
211
+
212
+ ### A wrapper presetting a prop must destructure with a default, not rely on JSX prop order
213
+
214
+ Wrapping a library component to preset a prop (e.g. `Table`'s `variant`) as
215
+ `<Table variant="studio" {...props} />` silently reverts to the library's own default the moment a
216
+ caller passes `variant={undefined}` — a later spread always wins in JSX, even with `undefined`,
217
+ and the library component resolves that `undefined` via its own default parameter.
218
+
219
+ **Apply:**
220
+ ```tsx
221
+ const AppTable = ({ variant = 'studio', ...props }: TableProps) => <Table variant={variant} {...props} />;
222
+ ```
223
+ Applies to any library prop with a default value, not just `Table`'s `variant`.
224
+
225
+ ### `FormWrapper` has a closed prop list — no `...rest`
226
+
227
+ It destructures exactly `{ icon, text, children }` and forwards nothing else to either the outer
228
+ wrapper or the bordered content `Box` — a `data-testid`, `id`, a margin override, or an `onClick` on
229
+ the wrapper all silently disappear, and TypeScript won't catch it since excess-property checks don't
230
+ apply to spreads.
231
+
232
+ **Apply:** wrap `FormWrapper` in your own `Box` when you need margin, a test hook, or an id on the
233
+ section — don't expect anything but `icon`/`text`/`children` to reach the DOM.
234
+
235
+ ### `ContactForm`'s `apiKey` prop is a POST URL, not an auth token
236
+
237
+ Despite the name, `apiKey` is passed straight into `fetch(apiKey, { method: "POST" })` as the submit
238
+ endpoint — never sent as a header or credential. A real API key/secret fails silently as an invalid
239
+ URL, surfaced only as a generic "Failed to send message" alert. There's no `headers` prop, so an
240
+ authenticated endpoint can't be reached through this component at all.
241
+
242
+ **Apply:** pass the full POST URL, never a token. If the endpoint needs auth headers, proxy through
243
+ your own backend instead.
244
+
245
+ ### `ContactForm` can't tell its parent the submission result
246
+
247
+ It does its own internal `fetch` and renders its own success/error alert from local state — there is
248
+ no `onSuccess`, `onSubmit`, or `onError` prop (a dead `// onSubmit(formData)` line is the only trace
249
+ one ever existed). A call site can't redirect, toast, or update its own state when the enquiry sends.
250
+ Separately, the email field is validated for format but its "required" check is commented out, so a
251
+ blank email submits successfully with no error shown.
252
+
253
+ **Apply:** if the parent needs to react to success, this component can't provide it. Don't rely on
254
+ `email` being enforced as required — validate it yourself first if that matters.
255
+
256
+ ### `VerifyEmailOtp` can't accept alphanumeric codes
257
+
258
+ It wraps Chakra's `PinInput` without forwarding a `type`, so Chakra's `type="number"` default
259
+ applies — any letter typed is silently rejected (the character never appears, no error shown).
260
+ `VerifyEmailOtpProps` has no `type` field and no `...rest` escape hatch. Its `description` text also
261
+ always gets a hardcoded second line appended — "your new Pixel Account" — with no prop to remove it.
262
+
263
+ **Apply:** only use this component for numeric-only OTPs with product copy that matches that exact
264
+ trailing phrase. Otherwise build the card from `PinInput`/`PinInputs` plus your own text.
265
+
266
+ ### `ApexLineChart` only ever renders one line, frozen at mount
267
+
268
+ `data`/`series` changes after the first render are silently ignored unless the component remounts
269
+ (no effect syncs later prop changes into state); `series` only reads index 0 for the line's name
270
+ despite the plural name; `variant="realtime"` replaces your data with random numbers on an interval
271
+ rather than animating it. Its `legendStyle` prop also type-checks but has no effect, unlike the
272
+ identical prop on `ApexPieChart`/`ApexPolarCharts`.
273
+
274
+ **Apply:** remount (`key`) `ApexLineChart` when the underlying data changes. Don't use
275
+ `variant="realtime"` expecting it to reflect a live feed.
276
+
277
+ ### `ApexPieChart`'s `showDataLabels` can be silently overridden by chart height
278
+
279
+ With the default `labelPlacement="auto"`, a **numeric** `height` under 240 forces labels off even
280
+ with `showDataLabels={true}` — no warning. Slices under `minLabelPercent` (default 8%) render blank
281
+ label text rather than being hidden as a unit.
282
+
283
+ **Apply:** pass `labelPlacement="inside"`/`"outside"` explicitly for small numeric-height charts;
284
+ lower `minLabelPercent` when every slice needs a visible value.
285
+
286
+ ### `ApexBarChart` and `ApexAreaChart` silently drop `data` when `series` is also passed
287
+
288
+ `series` always wins over `data` with no warning, on both components — a natural mistake when
289
+ migrating from single- to multi-series. Separately, `ApexBarChart`'s `barColor` array only paints one
290
+ color per bar when `distributed={true}`; with the default `false`, every bar takes `barColor[0]` and
291
+ the rest of the array is silently unused. `ApexRadialChart`'s `hollowSize` has its own unrelated trap
292
+ — it's silently overridden to a fixed `"52%"` whenever `variant="multi"`.
293
+
294
+ **Apply:** never pass `data` and `series` together on `ApexBarChart`/`ApexAreaChart`. Set
295
+ `distributed` whenever `ApexBarChart`'s `barColor` has more than one color. Don't expect
296
+ `ApexRadialChart`'s `hollowSize` to apply under `variant="multi"`.
297
+
298
+ ### `Skeletons` / `ProgressBar` have closed prop lists — no `borderRadius`, no margin, no `...rest`
299
+
300
+ Both `Pick<>` a fixed key set from their Chakra equivalents and forward nothing else — there is no
301
+ way to round a skeleton's corners, add margin, or attach a ref/`data-*` through either component.
302
+
303
+ **Apply:** for rounding, spacing, or a ref, use the Primitives barrel's raw Chakra `Skeleton`/
304
+ `Progress` instead.
305
+
306
+ ### `Skeletons`' `isLoaded` only works for `type="skeleton"`
307
+
308
+ `type="circle"`/`"text"` never receive `isLoaded` (or `children`/`bg`/`color`/`fadeDuration`) —
309
+ passing them compiles and is silently dropped; the shimmer never stops no matter what `isLoaded` is
310
+ set to.
311
+
312
+ **Apply:** for `circle`/`text`, control visibility by conditionally rendering the `Skeletons` element
313
+ itself, not via `isLoaded`.
314
+
315
+ ### `Notification`'s `onClick` only reaches the title text, and its status dot has two gates
316
+
317
+ `onClick` is wired solely to the title text — the card, avatar, and description are not clickable
318
+ despite the generic prop name. Separately, `warningColor`/`errorColor`/`successColor` only take
319
+ effect when `showStatus` is also `true`, and populating `notification.status` (e.g. `"blocked"`) has
320
+ no effect at all — the dot's color comes purely from `dueDate`/`endDate` math.
321
+
322
+ **Apply:** for a fully clickable card, wrap it yourself with your own `onClick`. Always pair the
323
+ three color overrides with `showStatus`; don't use `status` to drive dot color.
324
+
325
+ ### `FeedbackForm` shows a success toast and resets even with no `onSubmit`/`submitUrl`
326
+
327
+ Both props are optional, and when neither is provided, submit still falls through to the success
328
+ toast and form reset — validation, spinner, and reset all work end-to-end while the payload is never
329
+ sent or captured anywhere. Separately, `defaultValues` only seeds state at mount (no resync if it
330
+ arrives later from an async fetch), and its toast is Chakra's raw `useToast`, not this library's
331
+ `Toaster` — the same portal issue documented for `Toaster`/`Modal` can silently hide it when this
332
+ form is embedded in a `Modal`.
333
+
334
+ **Apply:** always pass `onSubmit` or `submitUrl` — treat a bare `<FeedbackForm />` as a bug, not a
335
+ minimal valid usage. Key the element to force a remount if `defaultValues` arrives late. Verify the
336
+ toast actually appears if embedding inside a `Modal`.
337
+
338
+ ### `Checkbox`'s `error` never sets `isInvalid`, and `variant` is a no-op
339
+
340
+ `error` doesn't set `isInvalid`/`aria-invalid`, and `errorMessage`/`helperText` aren't linked via
341
+ `aria-describedby` — confirmed by three `it.failing` cases in `Checkbox.a11y.test.tsx`. Separately,
342
+ `variant` is typed and accepted but never destructured or read; `Checkbox.styles.ts` defines no
343
+ `variants` key, so no value changes anything.
344
+
345
+ **Apply:** pass `isInvalid` explicitly alongside `error` — `error` alone never registers as invalid.
346
+ Don't expect `variant` to change a `Checkbox`'s look.
347
+
348
+ ### `Toggle`/`TableToggle` has no `aria-pressed`, and its tooltip text can silently mismatch its `aria-label`
349
+
350
+ Confirmed by three `it.failing` cases in `TableToggle.a11y.test.tsx` — a tooltip reading "Table View"
351
+ on a button whose `aria-label` is "Grid View" is a real, reachable state, not a hypothetical.
352
+
353
+ **Apply:** keep each button's tooltip text and `aria-label` in sync yourself; the component doesn't
354
+ enforce or derive one from the other.
355
+
356
+ ### `Slider`'s pagination dots can desync from the visible slide
357
+
358
+ The main track sorts `images` by `order`; the pagination dots map over the unsorted array. Passing
359
+ `images` out of `order` sequence makes the active dot point at the wrong slide.
360
+
361
+ **Apply:** pre-sort `images` by `order` before passing them in.
362
+
363
+ ### `TextLabel`'s `isInformation` alone renders no icon — it also needs `informationMessage`
364
+
365
+ The info-tooltip icon is gated on `isInformation && informationMessage` — both must be truthy or
366
+ nothing renders, not even a bare icon. `TextLabel` is the shared label engine behind most fields in
367
+ the library (`TextInput`, `NumberInput`, `PhoneNumberInput`, `RadioButton`, `PinInput`,
368
+ `InputSwitch`, `SelectV2`, the `DatePicker` family, `InputTextArea`, `SelectSearch`, `Search`,
369
+ `SearchSelect`, `MultiSelect`, `Select`), so the same silent no-op repeats at every one of them.
370
+
371
+ **Apply:** always pass `isInformation` and `informationMessage` together; never treat
372
+ `isInformation` alone as "use a default message."
373
+
374
+ ### Any field's label silently renders as an unassociated `<span>` if you omit `id`
375
+
376
+ `TextLabel` (the shared label engine behind nearly every field, see above) only renders a real
377
+ `<label htmlFor>` when given an `id` — omit it and the visible label text renders but is never
378
+ programmatically associated with its control, on any of the ~17 components that use it.
379
+
380
+ **Apply:** always pass `id` when you want a real, accessible `<label>`. (`MultiSelect` omits it on
381
+ purpose and wires `aria-label` instead — that's the pattern to copy if you skip `id` deliberately.)
382
+
383
+ ### `ErrorComponent`'s `error` prop is the message text itself — the opposite of `error`+`errorMessage`
384
+
385
+ Every other field in the library pairs a boolean `error` with a string `errorMessage`.
386
+ `ErrorComponent` (used internally by `Input`/`PinInputs`) instead takes `error: string` directly as
387
+ the message, with no internal truthy-check — passing `error=""` still draws the full icon next to
388
+ blank text. It also has no `id`, so unlike `ErrorMessage` it can't be wired to `aria-describedby`.
389
+
390
+ **Apply:** treat `ErrorComponent` as `Input`/`PinInputs`-specific, not a general error row; guard it
391
+ with a truthy-message check yourself, and use `ErrorMessage` for any other field.
392
+
393
+ ### `FormattedDescription`'s single-`*italic*` marker strips the asterisks but applies no italic style
394
+
395
+ `**bold**` works; a lone `*word*` silently renders as plain text with the markers removed, reading
396
+ as though the formatting was simply ignored.
397
+
398
+ **Apply:** don't rely on single-asterisk emphasis in `content` strings — use `**bold**` or plain text.
399
+
400
+ ### `Timeline`'s `onEditNote` editor doesn't auto-close without `editNoteLoading` — unlike add-note
401
+
402
+ Add-note has a back-compat fallback that closes its editor immediately if `addNoteLoading` is never
403
+ wired. Edit-note has no equivalent fallback — its only close path is an effect watching
404
+ `editNoteLoading` transition `true → false`. Wire `onEditNote` without `editNoteLoading` and Save
405
+ looks like it does nothing: the form stays open with no error or feedback.
406
+
407
+ **Apply:** always pass `editNoteLoading` alongside `onEditNote`, even a client-only flag flipped
408
+ right after the call resolves.
409
+
410
+ ### `Timeline`'s `events` prop is dead — only `timelineEvents` renders
411
+
412
+ `events` is typed and accepted, reads as a plausible prop name, and is never used by the component.
413
+
414
+ **Apply:** always use `timelineEvents`; treat `events`/the exported `TimelineEvent` type as vestigial.
415
+
416
+ ### `Timeline` drops events with an unparseable `created_at`, with no visible trace
417
+
418
+ An event whose formatted date resolves to `"Invalid Date"` is excluded from every date group — not
419
+ shown in a fallback bucket, just gone. The only signal is a `console.warn` inside the formatter.
420
+
421
+ **Apply:** validate/normalize `created_at` before handing events to `Timeline` — a bad timestamp is
422
+ silent, total content loss for that row.
423
+
424
+ ### `Reorder`'s `onReorder` fires even when nothing moved, and its real props aren't in its exported type
425
+
426
+ A drag that ends back at its starting index still has a drop target and still calls `onReorder` with
427
+ a new array reference in the same order. Separately, the component supports `showRemoveIcon`/
428
+ `onRemove` in practice, but the exported `ReorderListProps` type declares only
429
+ `label`/`items`/`onReorder` — neither `ReorderListProps` nor `ReorderItem` is exported from
430
+ `src/index.ts` at all, so there's no public named type to check either way.
431
+
432
+ **Apply:** compare source/destination index (or diff the array) before persisting a reorder, if a
433
+ no-op write matters. `showRemoveIcon`/`onRemove` do work — pass them despite the type gap.
434
+
435
+ ### `Divider` and `Trail`'s pieces aren't exported from the package at all
436
+
437
+ Neither `src/Components/Divider/` nor `src/Components/Trail/` appears in `src/index.ts`, though both
438
+ still compile into `dist/` and are deep-import-reachable. The library's own `Divider` is always
439
+ vertical, fixed size/color, zero props — a different thing from the general-purpose (horizontal,
440
+ styleable) `Divider` re-exported from the `Primitives` barrel. `Trail/TrailWorks` is a hardcoded
441
+ 2-row demo table, not a reusable grid.
442
+
443
+ **Apply:** for a divider in a consuming app, use the `Divider` from `Primitives`, not this library's
444
+ own. For a real data grid, use `Table` — nothing under `Trail/` is meant for reuse.
445
+
446
+ ### `KanbanActions` is exported but still not wired into `KanbanBoard`
447
+
448
+ `KanbanBoard`'s header select/edit/create bar is driven by its own `kanbanSelect`/`kanbanEdit`/
449
+ `kanbanCreate` props, via a different internal component. `KanbanActions` is a separate, standalone
450
+ component (exported from the package root as of 2.4.2-beta.39) that a consumer must render and wire
451
+ up itself — its `options`-driven buttons always render with no permission gating, unlike
452
+ `KanbanBoard`'s own header actions, which respect `permissions.isEditable`/`isCreatable`.
453
+
454
+ **Apply:** use `KanbanBoard`'s own `kanbanSelect`/`kanbanEdit`/`kanbanCreate` props for the board's
455
+ built-in header actions. Reach for `KanbanActions` only when building a custom toolbar outside
456
+ `KanbanBoard`, and gate it yourself — it has no permissions awareness of its own.
457
+
458
+ ### `KanbanBoard`'s `permissions.isEditable: false` disables card drag but not column-reorder drag
459
+
460
+ Card `Draggable`s get `isDragDisabled={!canDrag}`; the column-reorder `Draggable` (active when
461
+ `enableColumnReorder` is true) never checks it — a "read-only" board still lets users reorder whole
462
+ columns.
463
+
464
+ **Apply:** also set `enableColumnReorder={false}` to fully lock a read-only board.
465
+
466
+ ### `KanbanBoard`'s `collapsedColumns` only seeds initial state — not a live controlled prop
467
+
468
+ It seeds a `useState` lazy initializer once, on mount. Without the `preferences` feature wired, a
469
+ later render passing a different `collapsedColumns` value does nothing, despite the name implying a
470
+ controlled value.
471
+
472
+ **Apply:** to force a column open/closed post-mount without `preferences`, remount the board (change
473
+ its `key`) rather than re-passing the prop.
474
+
475
+ ### `KanbanBoard`'s `account.customNode` silently drops delete/open/expand for that one card
476
+
477
+ An item with `customNode` set renders that function instead of `AccountCard`, so `onDelete`,
478
+ `onOpen`, `isDeletable`, and expand/collapse never apply — even though they read as board-wide
479
+ props. Mixing plain and `customNode` items in one column produces inconsistent per-card behavior.
480
+
481
+ **Apply:** don't expect board-wide card actions to reach a `customNode` card; wire them inside your
482
+ custom render instead.
483
+
484
+ ### `KanbanBoard`'s `AccountCard` only renders string-typed fields, and mangles camelCase labels
485
+
486
+ A numeric field on an `Account` (explicitly allowed by its index signature) is silently never shown
487
+ in the card's field list. The auto-generated label only splits on `_` — a snake_case key
488
+ (`account_name`) renders as "Account Name," but an idiomatic camelCase key (`nextFollowUp`)
489
+ collapses into one mashed word ("Nextfollowup").
490
+
491
+ **Apply:** use snake_case keys on `Account` objects, and keep numeric display values as strings.
492
+
493
+ ### `KanbanBoard`'s `onColumnDelete` receives the deleted column's **card** ids, not the column's id
494
+
495
+ Despite the callback parameter being named `colId`-adjacent, what's actually passed is
496
+ `columns[colId].items.map(item => item.id)` — the cards that were in the column, never the column's
497
+ own id.
498
+
499
+ **Apply:** track which column was being deleted another way (e.g. hover/selection state captured
500
+ before the click) if you need the column id itself.
501
+
502
+ ### `isRequired` is decorative on some fields, native on others — same prop name, different behavior
503
+
504
+ `TextInput`, `PhoneNumberInput`, and the exported `PinInput` pass `isRequired` only to the label
505
+ (draws a `*`) — the field itself never gets `required`/`aria-required` (confirmed by an `it.failing`
506
+ case in `TextInput.a11y.test.tsx`). `NumberInput` and the internal `Input.tsx` do propagate it
507
+ natively. A form relying on `isRequired` for native HTML5/AT validation works on some fields and
508
+ silently doesn't on others.
509
+
510
+ **Apply:** don't rely on `isRequired` for native form validation — validate required fields yourself
511
+ regardless of which component you're using.
512
+
513
+ ### `PhoneNumberInput` and `NoteTextArea` type a `ref` prop that never attaches
514
+
515
+ Both are plain function components, not `forwardRef` — a `ref` passed to a plain function component
516
+ is stripped before the body runs, so the destructured ref param is always `undefined`.
517
+ `NoteTextArea` compounds this: even where it does forward a ref, it only reaches the secondary title
518
+ input, never the primary `Textarea`.
519
+
520
+ **Apply:** don't rely on a `ref` into either component; `NumberInput`/`InputTextArea` forward refs
521
+ correctly if you need that pattern.
522
+
523
+ ### `NoteTextArea`'s `saveButtonLoading` going `true → false` clears the draft even on a failed save
524
+
525
+ The effect that resets note/title/files fires whenever `saveButtonLoading` goes falsy — there's no
526
+ separate success/failure signal, so a parent that turns off the loading flag after a failed save
527
+ silently discards everything the user typed.
528
+
529
+ **Apply:** don't flip `saveButtonLoading` back to `false` on failure without your own recovery path
530
+ (e.g. keep the draft in your own state and re-seed it).
531
+
532
+ ### `PinInput` and `PinInputs` are two unrelated implementations — only one is real
533
+
534
+ The component published as `PinInput` from `index.ts` is Chakra-native, themed, supports OTP paste
535
+ and `type: "alphanumeric" | "number"`. `PinInputs` (plural) is a separate, hand-rolled,
536
+ always-numeric implementation that is **not exported** and not referenced anywhere else in the repo
537
+ — a dead-code candidate, not an alternate API. It still compiles into `dist/`, so the deep-import
538
+ pattern this repo otherwise supports would silently pull in the unmaintained one.
539
+
540
+ **Apply:** always use `PinInput` (singular); never deep-import `PinInputs`.
541
+
542
+ ### `InputSwitch`'s checked/unchecked track color is silently replaced by a caller-supplied `sx`
543
+
544
+ The component's own `sx` (sets track background from `isChecked`) is spread over first, then
545
+ `{...props}` — any `sx` a caller passes wins outright, so the switch stops changing color on toggle.
546
+
547
+ **Apply:** don't pass `sx` to override styling on `InputSwitch`; if you must, re-include the
548
+ checked/unchecked background logic yourself.
549
+
550
+ ### `TextInput`'s `placeholder` defaults to the literal word `"Placeholder"`, not empty
551
+
552
+ Omit the prop and real users see the actual text "Placeholder" in the field.
553
+
554
+ **Apply:** always pass an explicit `placeholder` (or an empty string) at every `TextInput` call site.
555
+
556
+ ### The internal `Input.tsx` silently ignores six declared props
557
+
558
+ `disabled`, `autoComplete`, `autoFocus`, `inputClassName`, `labelClassName`, and `errorClassName`
559
+ are all typed on `InputProps` but never read — passing them, `disabled` especially, compiles cleanly
560
+ and does nothing. It also has no `id` field, so its label always renders as an unassociated `<span>`.
561
+
562
+ **Apply:** this is an internal component (not exported) reachable only via deep import — prefer
563
+ `TextInput` for anything public-facing, which doesn't have this gap.
564
+
565
+ ### `AlertDialog`'s `colorScheme`/`size`/`status`/`variant`/`addRole` are dead props
566
+
567
+ Typed (`Pick`ed from Chakra's `AlertProps`) but never destructured — Cancel/Confirm are hardcoded
568
+ red/primary at `size="sm"` regardless of what you pass.
569
+
570
+ **Apply:** style Cancel/Confirm via `button1Style`/`button2Style`, not `colorScheme`/`size`/`status`/
571
+ `variant`.
572
+
573
+ ### `AlertDialog` can always be dismissed via Escape or an overlay click, not just its buttons
574
+
575
+ `closeOnOverlayClick`/`closeOnEsc` aren't exposed as props, so Chakra's `true`/`true` defaults apply
576
+ unconditionally — `onClose` fires the same way for Escape/overlay-click as for the Cancel button.
577
+
578
+ **Apply:** don't treat `onClose` as "the user explicitly chose Cancel" — that distinction isn't
579
+ available through this component.
580
+
581
+ ### `ToolTip`'s `overflowOnly` silently no-ops on non-single-element children
582
+
583
+ The truncation ref only attaches when `children` passes `React.isValidElement` — a bare string, a
584
+ Fragment, or multiple children skip that branch, so the tooltip always shows instead of
585
+ only-when-truncated (the opposite of the prop's contract).
586
+
587
+ **Apply:** give `overflowOnly`/`OverflowToolTip` exactly one real element as `children` (e.g. a
588
+ single `Text noOfLines`), never a Fragment or bare text.
589
+
590
+ ### `Toaster`'s `showToast({ children })` is a dead prop, and its two `onClose`s are different functions
591
+
592
+ `children` type-checks (Picked from Chakra's `ToastProps`) but is never read — only `title`/
593
+ `description`/`actions` render. Separately, the `onClose` you pass to `showToast` is wired to
594
+ Chakra's `onCloseComplete` (fires after the exit animation, on any dismiss path); the `onClose` your
595
+ `actions` render-prop receives is a different, immediate per-toast dismiss function.
596
+
597
+ **Apply:** pass `description`, not `children`. Don't assume your `onClose` fires the instant the
598
+ user clicks close — it fires after the exit transition completes.
599
+
600
+ ### Every `Toaster` status announces at `aria-live="polite"`, including `error`
601
+
602
+ No urgency bump for errors, and status is conveyed by icon + colour alone with no text equivalent —
603
+ confirmed by two intentionally-`it.failing` tests in `Toaster.a11y.test.tsx`.
604
+
605
+ **Apply:** don't rely on an error toast interrupting a screen reader; pair a critical failure with
606
+ another signal (e.g. an inline field error).
607
+
608
+ ### `Button`'s `loadingText` defaults to `"Loading"`, not Chakra's spinner-only style
609
+
610
+ `loadingText` defaults to the literal string `"Loading"`, so every `isLoading` button shows that
611
+ text next to the spinner instead of Chakra's native behavior (hide content, spinner only) — even
612
+ icon-only buttons, where it can break the expected square aspect ratio. Passing
613
+ `loadingText={undefined}` does not restore the native look; the default parameter still applies.
614
+
615
+ **Apply:** pass `loadingText=""` explicitly to get a spinner-only loading state.
616
+
617
+ ### `ButtonGroupIcon`'s dropdown needs `rightIcon` **and** `rightIconDropdown` both set
618
+
619
+ The `Menu`/`dropdownOptions` branch only renders inside `rightIcon && rightIconDropdown`. Supplying
620
+ `dropdownOptions` alone, or `rightIconDropdown` without `rightIcon`, silently renders nothing on the
621
+ right side. Separately, `onButtongroupClick` is wired to Chakra `ButtonGroup`'s own `onClick` on the
622
+ wrapping div — native DOM bubbling means it fires on every click inside the group (left icon, center
623
+ button, right icon/dropdown), not just a "clicked outside the buttons" signal.
624
+
625
+ **Apply:** always set `rightIcon` + `rightIconDropdown={true}` together for the dropdown. Don't use
626
+ `onButtongroupClick` to detect background clicks — inspect `event.target` if you need to distinguish.
627
+
628
+ ### `Buttons` (plural) is not a group wrapper, and not theme-aware
629
+
630
+ Despite the plural name suggesting a group, `Buttons` renders one plain `<button>` hardcoded to
631
+ Tailwind's `bg-purple-600` — it ignores brand/dark-mode entirely and isn't exported from the package
632
+ root.
633
+
634
+ **Apply:** use `Button` for a single themed button or `ButtonGroupIcon` for a themed group; there is
635
+ no good reason to reach for `Buttons`.
636
+
637
+ ### `Card` silently drops `header`, `footer`, and all three divider props
638
+
639
+ `CardProps` declares `header`, `footer`, `dividercolor`, `dividersize`, `dividervariant`, but none
640
+ are destructured by `Card` — passing them compiles cleanly and renders nothing. Padding is also
641
+ hardcoded (`p={4}`), so it can't be tuned via props either.
642
+
643
+ **Apply:** put header/footer content inside `children`; use `sx` for padding overrides.
644
+
645
+ ### `ProductCard`'s variant selection goes stale after an `options` update, and `options={[]}` crashes it
646
+
647
+ Both `ProductCard` and its internal `ProductPrice` capture `options[0]` into state only once, at
648
+ mount, with no resync effect — a later re-render with refreshed `options` (new stock/price) is
649
+ silently ignored, so Add to Cart/Notify Me act on stale data. An empty array crashes on
650
+ `selected.label`. Separately, `description` and `avalabilitys` are typed and accepted but never
651
+ read by the component.
652
+
653
+ **Apply:** treat `options` as effectively static per mount (remount via `key` if it changes), and
654
+ never pass `[]`. Don't rely on `description`/`avalabilitys` — there's currently no way to show either.
655
+
656
+ ### `ProductTags` (shared by `ProductCard`/`ProductDetails`) silently renders zero tags past 4
657
+
658
+ The row-layout helper only handles 1-4 entries — 5 or more tags renders nothing at all, no
659
+ truncation or "+N more" affordance.
660
+
661
+ **Apply:** cap `tags` at 4 entries at the call site until the component adds an overflow case.
662
+
663
+ ### `PaymentCard`'s `onHover` never fires its `"card"` variant, and the CTA hides unless `isRenewal`
664
+
665
+ `onHover`'s type promises `"card" | "button"`, but no hover handler exists on the outer plan card —
666
+ only the CTA button wires hover. Separately, the CTA (and its callbacks) disappears whenever
667
+ `isActive` is true unless `isRenewal` is also set, regardless of `plan.buttonText`.
668
+
669
+ **Apply:** don't build "card" hover analytics on this prop. Pass `isRenewal` to show a CTA on the
670
+ current/active plan.
671
+
672
+ ### `OrganizationDetails`' `defaultOrg === 1` silently overrides an explicit `canDelete: true`
673
+
674
+ `isProtected` is computed as `item.defaultOrg === 1 || canProtect` — `defaultOrg` short-circuits the
675
+ `canDelete`/role check unconditionally. An org that is both the user's default and marked
676
+ `canDelete: true` still renders a disabled delete button, with only a tooltip explaining why.
677
+
678
+ **Apply:** don't rely on `canDelete` alone to guarantee delete is enabled — check `defaultOrg` too.
679
+
680
+ ### `OrganizationDetails`, `CustomModulesTable`'s create/edit/delete modals show no error UI on rejection
681
+
682
+ `onCreateOrganization`/`onDeleteOrganization`/`onEditOrganization` (and `CustomModulesTable`'s
683
+ `onUpdateModule`/`onDeleteModule`) are `await`ed and the modal only resets on success — a rejection
684
+ is an unhandled promise rejection with zero visible feedback.
685
+
686
+ **Apply:** wrap your own handler in try/catch and show your own error toast; the library never does
687
+ it for you.
688
+
689
+ ### `OrgSwitcher`'s `onChange` doesn't fire on re-selecting the already-active org, and has a closed prop list
690
+
691
+ Re-clicking the current org closes the popover but skips `onChange` entirely (`org.id !== value` gate)
692
+ — don't rely on it for a side effect that must run on every click (analytics, refetch). Separately,
693
+ the trigger has no `...rest`/`ref` escape hatch: a `data-testid`, `id`, or positioning `ref` can't
694
+ reach it.
695
+
696
+ **Apply:** don't depend on `onChange` firing for a repeat pick. There's no supported way to attach
697
+ test hooks or a ref to the trigger.
698
+
699
+ ### `UpgradeButton`'s gold icon accent silently falls back to the label color on low contrast
700
+
701
+ The gold accent is only used when it clears AA contrast against both gradient stops; a custom
702
+ `gradient` prop can flip it to the label's own ink color with no signal.
703
+
704
+ **Apply:** don't assume the icon stays gold with a custom `gradient` — check contrast yourself if the
705
+ gold accent is load-bearing for your design.
706
+
707
+ ### `PlanPill`/`PlanBadge` always render as a real, focusable `<button>` — even with no `onClick`
708
+
709
+ `as="button"`, `cursor="pointer"`, and the hover-lift are unconditional. Omitting the optional
710
+ `onClick` does not get you a static/informational pill — it stays tabbable and screen-reader
711
+ -announced as a button regardless.
712
+
713
+ **Apply:** there is currently no way to get a non-interactive plan badge from this component.
714
+
715
+ ### `LimitReachedModal`'s `onUpgrade` never triggers `onClose`, and needs both `limit` and `used` to show usage
716
+
717
+ Clicking the CTA calls only `onUpgrade` — confirmed by the component's own test. Separately, the
718
+ inline usage line renders only when **both** `limit` and `used` are non-nullish; passing just one
719
+ silently omits the whole line.
720
+
721
+ **Apply:** close the modal yourself inside your `onUpgrade` handler if upgrading should dismiss it.
722
+ Always pass `limit`/`used` together, or neither.
723
+
724
+ ### `CustomModulesTable`'s `ModuleItem.module_id` is the one snake_case field on an otherwise camelCase type
725
+
726
+ A loosely-typed API response cast straight to `ModuleItem[]` can leave `module_id: undefined` with
727
+ no compile error, colliding React `key`s.
728
+
729
+ **Apply:** map the API field explicitly to `module_id` — don't assume this type is uniformly
730
+ camelCase like its sibling payload type (`UpdateModulePayload.moduleId`).
731
+
732
+ ### `RolesPermission`'s permission matrix silently reroutes every column for an "Automation" row
733
+
734
+ Any `permissions[]` row whose `module` case-insensitively equals `"automation"` collapses every
735
+ column onto a single `automation` boolean — only the Read cell renders/toggles, and clicking it
736
+ calls `onPermissionChange(module, "automation")`, not `"read"`. Separately, `roles_id` (typed
737
+ `string`) is coerced via `Number()` before `onDeleteRole` fires — a UUID or ObjectId silently
738
+ becomes `NaN`.
739
+
740
+ **Apply:** if a row's `module` can be `"automation"`, expect only its Read checkbox to work, toggling
741
+ `automation` — create/edit/delete/import/export are unreachable for that row. Only pass
742
+ numeric-string `roles_id` values.
743
+
744
+ ### Several delete/deactivate modals close before their async handler can be awaited
745
+
746
+ `RolesPermission`'s `DeleteRoleModal` and `UserDetails`' `DeactivateConfirmModal` call their
747
+ handlers fire-and-forget (typed plain `() => void`) and close synchronously in the same tick — the
748
+ opposite failure mode from the create/edit modals above, whose handlers are genuinely awaited.
749
+
750
+ **Apply:** any `isLoading`/spinner wiring for delete/deactivate can never be seen — handle
751
+ loading/error UI outside these two modals (e.g. a toast).
752
+
753
+ ### `UserDetails`' Change Role and Resend Invitation buttons silently no-op when `userId` is null
754
+
755
+ Only Deactivate actually disables itself when `selectedUser.userId` is null — the other two stay
756
+ visually enabled and do nothing on click. Separately, `ChangeRoleModal` pre-selects the current role
757
+ by case-insensitive **label text** match, not an id — any mismatch (whitespace, a renamed role)
758
+ silently opens the modal with nothing pre-selected, no error shown.
759
+
760
+ **Apply:** always populate `selectedUser.userId` when those two actions should be usable. Keep
761
+ `currentRole` as the exact display label kept in sync with `roleOptions[].label`.
762
+
763
+ ### `FileUploader`'s `onFilesChange` discards the real `File`, and its `acceptTypes`/`maxFiles` enforce nothing
764
+
765
+ `FileUploader` hands back lightweight `{id, name, size, previewUrl}` metadata — the original `File`
766
+ is discarded in `handleFiles`, so it can never back an actual upload. `acceptTypes` only sets the
767
+ native picker's `accept` attribute; drag-and-drop ignores it completely and no code path rejects a
768
+ wrong-type file. Exceeding `maxFiles` silently truncates the list with no error.
769
+
770
+ **Apply:** need real file bytes or enforced validation → use `FileUpload`, not `FileUploader`.
771
+
772
+ ### `FileUpload`'s default `maxSizeKB` is 5 — that's 5 **kilobytes**, not megabytes
773
+
774
+ Left at its default, `FileUpload` rejects virtually every real file, and the auto-generated
775
+ hint/error text literally reads "0.00 MB" because the KB→MB conversion divides an already-tiny value.
776
+
777
+ **Apply:** always pass an explicit `maxSizeKB` in KB (e.g. `5000` for ~5MB).
778
+
779
+ ### `DatePicker`'s `pickerType` does nothing when `isRange` is set, and no variant has a seconds control
780
+
781
+ `RangeDatePicker` never reads `pickerType` — whether time inputs show is controlled entirely by
782
+ whether `dateFormat` contains time tokens. Separately, every time-capable picker caps at minute
783
+ granularity regardless of `dateFormat` — a format containing `ss` compiles and parses but seconds
784
+ are never user-editable.
785
+
786
+ **Apply:** for a range picker, control the time row via `dateFormat`, never `pickerType`. Don't
787
+ request second-precision input from any DatePicker variant.
788
+
789
+ ### `RangeDatePicker` loses a picked range if you click outside instead of Apply
790
+
791
+ Unlike `SingleDatePicker`, its outside-click handler doesn't call `finalize()` — only the Apply
792
+ button or Escape commits a completed range via `onChange`. Clicking anywhere else outside the
793
+ popover after picking both ends discards the selection silently.
794
+
795
+ **Apply:** don't assume outside-click commits a range the way it does for `SingleDatePicker`.
796
+
797
+ ### `TimeOnlyPicker`'s label is never associated with its field, and `name` is a no-op
798
+
799
+ Passing `id`/`label` does not produce an accessible `<label for>` — the internal label call omits
800
+ `id`, so it always renders as an unassociated `<span>`. `name` (and `minDate`/`maxDate`/
801
+ `disableFutureDates`/`disablePastDates`/`autoComplete`) are also silently dropped — the rendered
802
+ `<input>` never gets a `name` attribute, breaking plain `<form>`/`FormData` submission.
803
+
804
+ **Apply:** don't rely on `TimeOnlyPicker` for native form submission or label accessibility; read its
805
+ value via `onChange` rather than form `name`.
806
+
807
+ ### `Editor`'s `config` prop can silently break dark mode, and its `key` prop can never reach Jodit
808
+
809
+ `Editor` computes `config.theme`/`config.popupRoot` itself to fix Jodit's dark-mode/popup theming,
810
+ then spreads your `config` on top — any `theme`/`popupRoot` key you pass wins and silently disables
811
+ the fix. Separately, `key` is typed as if readable, but React reserves and strips it before the
812
+ component sees `props`, so it's always `undefined` internally and can't force a remount. `editorRef`
813
+ is also `null` until Jodit's lazy-loaded chunk resolves — a mount-time effect reading it gets nothing.
814
+
815
+ **Apply:** never set `theme`/`popupRoot` inside the `config` you pass to `Editor`. To force a
816
+ remount, wrap `<Editor>` itself in a keyed parent, not via `Editor`'s own `key` prop.
817
+
818
+ ### `SelectV2`, `SearchSelect`, and `SelectSearch` all search `option.label` only
819
+
820
+ None of the three checks a rendered secondary field (`option.description`, a custom `view` node,
821
+ `option.email` on a profile row) — typing text that's visibly on-screen in a secondary field returns
822
+ no match.
823
+
824
+ **Apply:** if a secondary field needs to be searchable, fold it into `option.label` yourself, or
825
+ pre-filter `options` before passing them in.
826
+
827
+ ### `SearchSelect` never virtualizes, and `chip.maxChips={0}` is swallowed by a falsy fallback
828
+
829
+ Despite the prop name, `virtualization` does nothing — every filtered option renders as a real DOM
830
+ node; the list scales only via consumer-driven `pagination`. Separately,
831
+ `selectedValues.slice(0, chip?.maxChips || selectedValues.length)` treats a literal `0` as "no limit
832
+ set" (falsy), so every chip renders anyway instead of zero.
833
+
834
+ **Apply:** for a dataset large enough to need real virtualization, page it in via `pagination` rather
835
+ than setting `virtualization={true}`. Pass `1` or higher to `chip.maxChips`; there's no supported way
836
+ to hide all chips via this prop.
837
+
838
+ ### `SelectSearch`'s Enter key requires an exact full-label match, not the keyboard-highlighted option
839
+
840
+ Typing a partial query and pressing Enter without arrowing down first does not pick the
841
+ visually-highlighted top option — it only fires if the typed text exactly equals an option's full
842
+ label. `SelectV2`/`SearchSelect` both correctly select the highlighted option on Enter; `SelectSearch`
843
+ doesn't. Two more props (`isSearchEnabled`, `BottomIconStyle`) are typed but never read, and
844
+ `initialSelectedOption` only seeds selection at mount with no resync if the real value arrives later.
845
+
846
+ **Apply:** tell users to arrow down before Enter with this component specifically. Don't pass
847
+ `initialSelectedOption` before the real value is known (or key the component to force a remount).
848
+
849
+ ### `FieldSelectModal`'s "Select all" ignores the active search filter, and resets on any parent re-render
850
+
851
+ The header checkbox (and its indeterminate state) always operates on the complete `fields` list, not
852
+ the search-filtered subset — clicking it while filtered silently selects/clears fields the user can't
853
+ see. Separately, an effect re-seeds selection whenever `fields`/`defaultSelected` changes
854
+ **reference**, so an inline array literal for either prop silently wipes in-progress picks on the
855
+ next parent re-render.
856
+
857
+ **Apply:** clear the search before using "Select all." Memoize `fields`/`defaultSelected` in the
858
+ parent before passing them down.
859
+
860
+ ### `Dropdown`'s `ButtonText`/`text` are mutually exclusive per `dropdownType`, silently
861
+
862
+ The `"button"` trigger renders `ButtonText` only; the `"text"` trigger renders `text` only — pairing
863
+ the wrong prop with the active `dropdownType` renders an icon-only or bare-chevron trigger with no
864
+ visible label, and the `aria-label` fallback then substitutes "Open menu" as the accessible name too.
865
+ Separately, `buttonProps.sx` fully replaces the built-in trigger style rather than merging, silently
866
+ dropping the hover transition.
867
+
868
+ **Apply:** pair `ButtonText` with the default/`"button"` type and `text` with `dropdownType="text"`.
869
+ Fold custom styling into `dropDownButtonStyle`, not `buttonProps.sx`.
870
+
871
+ ### `Search`'s default `shortcut` grabs a page-global Ctrl+K with no way to opt out
872
+
873
+ Every mounted `Search` registers its own `window` Ctrl+K listener by default — the type only permits
874
+ the literal `"Ctrl+K"` or `undefined`, and `undefined` still resolves to the same default via JS
875
+ parameter defaulting. Two instances on one visible view race for the keypress.
876
+
877
+ **Apply:** avoid mounting more than one `Search` per visible view/route — there's currently no way to
878
+ scope or disable the hotkey per-instance.
879
+
880
+ ### `Header`'s desktop submenus open on hover only — no keyboard or click trigger
881
+
882
+ Dropdown children are gated on local hover state (`onMouseEnter`/`onMouseLeave`), with no `onFocus`.
883
+ A keyboard user tabbing to a parent item can never open its children on the desktop layout — the
884
+ identical data renders as a click-toggled accordion on mobile.
885
+
886
+ **Apply:** don't put anything a keyboard user must reach behind `children` on desktop; use `rightSlot`
887
+ (real focusable buttons) for critical actions until this gets a keyboard path.
888
+
889
+ ### `WorkspaceWindow`'s `state="maximized"` is indistinguishable from `"medium"`
890
+
891
+ The component only branches on `state === "minimized"` — size is always the same fixed constant, and
892
+ `onMedium`/`onMaximize` are accepted callbacks that are never invoked anywhere in the component.
893
+
894
+ **Apply:** treat `state` as effectively two-valued (open vs. `"minimized"`); don't wire a maximize
895
+ control expecting `onMaximize` to fire.
896
+
897
+ ### `FilterSidebar`'s `selected` without `onChange` makes every filter silently inert
898
+
899
+ Passing `selected` alone (uncontrolled companion `onChange` omitted) computes the next filter state
900
+ on every click and discards it — checkboxes visibly never check, forever, with no error. Separately,
901
+ `onApply`, `headerPadding`, and `sliderMode` are all typed and accepted but have zero effect —
902
+ `FilterSection.checkboxes` doesn't exist either; radio-vs-checkbox mode is actually decided by
903
+ `type === "radio" || section.radio`.
904
+
905
+ **Apply:** always pass `selected` and `onChange` together, or omit `selected` and let `FilterSidebar`
906
+ own its state. Don't reach for `onApply`/`headerPadding`/`sliderMode`/`FilterSection.checkboxes` —
907
+ none of them do anything.
908
+
909
+ ### `Breadcrumbs`' `isLastChild` prop is accepted but never read
910
+
911
+ It's declared on the type but omitted from the component's destructure entirely.
912
+
913
+ **Apply:** don't pass it expecting it to mark or style the final crumb — there's nothing it can do.
914
+
915
+ ### `Accordion`'s `items[].buttonProps`/`itemProps` replace, not merge, the expanded/hover highlight
916
+
917
+ Both spread after the built-in `bg`/`_hover` that encode `isExpanded` state — passing `bg` or
918
+ `_hover` there to tweak one item's style silently kills that item's expanded/active indication.
919
+
920
+ **Apply:** style around the defaults via `customStyles` (merged through `sx`) rather than
921
+ `buttonProps`/`itemProps` when the highlight must survive.
922
+
923
+ ### `Table`'s `LeftFilterPane` Clear All only re-applies filters in `"sidebar"` mode
924
+
925
+ `handleClear` calls `onClear` unconditionally, but only calls `onApply(cleared)` when
926
+ `filterMode === "sidebar"` — in `"modal"` mode, Clear All visually unchecks every filter but never
927
+ tells the parent the selection changed, so a consumer whose `onClear` doesn't itself reset
928
+ applied/query state keeps serving pre-clear filtered data.
929
+
930
+ **Apply:** when using `filterMode="modal"`, drive your data refetch from `onClear`, not `onApply` —
931
+ don't assume `onApply` fires on every Clear All.
932
+
933
+ ### `ScrollToTop` watches one `parentElement` hop, not "the nearest scrollable ancestor"
934
+
935
+ It reads `scrollTop` off its immediate DOM parent only, with no upward search for an `overflow:
936
+ auto/scroll` element. Wrap it in one extra layout `<div>` and the button silently never appears — no
937
+ error, no warning, `scrollTop` on a non-scrolling parent just stays `0` forever.
938
+
939
+ **Apply:** `ScrollToTop`'s JSX parent must be the actual scroll container, or pass `useWindow` when
940
+ the page itself scrolls.
941
+
942
+ ### `ProfilePhotoViewer`'s PDF detection breaks the moment a file is picked, and `photoUrl` is read once
943
+
944
+ PDF detection is a literal `.endsWith(".pdf")` check — picking a file through the built-in editor
945
+ replaces the value with a base64 data URI that never ends in `.pdf`, so a freshly-picked PDF renders
946
+ as a broken image instead of the intended file badge (only the original URL prop is detected
947
+ correctly). Separately, `photoUrl` only seeds state at mount — a later re-render with a new
948
+ `photoUrl` (list virtualization, route change without remount) keeps showing the old photo.
949
+
950
+ **Apply:** don't use the built-in edit flow for PDF documents; detect kind from `File.type` in your
951
+ own handler instead. Use `key={photoUrl}` to force a remount when the photo identity changes.
952
+
953
+ ### `FilePreview` infers file kind from `fileName`, not `fileUrl`, and never resets zoom/rotation on its own
954
+
955
+ Once `fileName` is set, `fileUrl`'s own extension is never consulted — a friendly display name with
956
+ no extension forces the "preview unavailable" fallback even when `fileUrl` points at a perfectly
957
+ renderable file. Separately, cycling `fileUrl` while the modal stays open (a gallery next/prev)
958
+ carries the previous image's zoom/rotation into the new one.
959
+
960
+ **Apply:** keep the real extension on `fileName`, or pass `fileType` explicitly to skip inference.
961
+ Remount via `key={fileUrl}` when swapping the file in place instead of just changing the prop.
962
+
963
+ ### `StageProgress`'s `tooltipThreshold`/`minStageWidth` no-op under `variant="stepper"`, and a stale `value` blanks the tracker
964
+
965
+ Both props stop having any effect the moment a tracker switches to the stepper variant. Separately,
966
+ if `value` matches no `stage.id` (e.g. `stages` was filtered/re-derived and went stale), every stage
967
+ silently renders as `"upcoming"` — no stage is ever active or completed, with no error. The match is
968
+ also a strict `===`: a numeric `stage.id` compared against a string `value` (or vice versa) never
969
+ matches either, even when the "same" stage is clearly intended.
970
+
971
+ **Apply:** don't rely on either prop once on the stepper variant. Re-validate `value` against the
972
+ current `stages` list whenever it's filtered, and keep `id`/`value` the same primitive type at every
973
+ call site.
974
+
975
+ ### `Table`'s `isVisiblity`, `tableSettings`, `handleExportChange`/`exportOptions`/`exportLabel`, and `onColumnFilter` are dead props — now `@deprecated`
976
+
977
+ Grepped account-frontend, tickets, crm-frontend, hrms and social-frontend: zero consumers set any of
978
+ these six. All six are now marked `@deprecated` in `TableProps.tsx` rather than removed outright, in
979
+ case an app outside those five repos relies on one. None of these do anything in the current
980
+ implementation, despite being typed on `TableProps` (and some documented on the demo page):
981
+
982
+ - `isVisiblity` — `Table`'s own destructure never lists it, so a consumer's value is dropped. It's
983
+ hardcoded `true` into both `Pagination` call sites regardless, and `Pagination` doesn't read it
984
+ either. It is a misspelling of `isVisibility`, but do not rename it (breaking change) — and do not
985
+ expect it to do anything if you do.
986
+ - `tableSettings` (`{filters, filterSelected, onFilterSelection}`) — `Table` passes it to
987
+ `TableSettings`, but `TableSettings`'s function signature never destructures it.
988
+ - `handleExportChange` / `exportOptions` / `exportLabel` — `Table` renders no export UI at all; none
989
+ of the three are read anywhere, despite `src/Pages/table.tsx` documenting them as if live.
990
+ - `onColumnFilter` — commented out of `Table`'s own destructure (`// onColumnFilter`).
991
+
992
+ **Apply:** don't reach for any of these expecting an effect. Column visibility is driven by
993
+ `isTableSettings` (shows the Settings gear) + `preferences` (server persistence) + the Manage
994
+ Columns tab — not by `isVisiblity`/`tableSettings`.
995
+
996
+ ### `Table`'s `preferences` prop is silent-by-default, not required
997
+
998
+ Omitting `preferences` (or leaving `preferences.url` empty, the default) does not throw or disable
999
+ the table — the persistence hooks both early-return when the base URL is falsy. The table works
1000
+ fully in memory; it just never persists column order/visibility, density, or grouping across
1001
+ reloads. When you do wire a `url`, `token` is sent as a **raw** `Authorization` header value — do
1002
+ not prefix it with `"Bearer "` yourself expecting the hook to strip it.
1003
+
1004
+ **Apply:** treat `preferences` as opt-in persistence, not a required config block. If settings
1005
+ aren't surviving a refresh, check `preferences.url` is actually set before assuming a bug.
1006
+
1007
+ ### `SearchSelect`'s `height` prop only resizes the `insideSelect` segment, not the field
1008
+
1009
+ Despite the name, `height` is read only to size the nested `insideSelect` trigger. The main
1010
+ control's height always comes from `size`'s token set — passing `height` with no `insideSelect`
1011
+ configured has no visible effect at all.
1012
+
1013
+ **Apply:** to change the main field's height, change `size`; `height` only matters when
1014
+ `insideSelect` is also passed.
1015
+
1016
+ ### `SearchSelect`'s `pagination.limit` also drives a "has more" guess, not just page size
1017
+
1018
+ `hasMore` is computed as `options.length % pagination.limit === 0` — there is no real end-of-data
1019
+ signal from the consumer. A total result count that happens to be an exact multiple of `limit`
1020
+ looks indistinguishable from "more pages exist," firing one extra, empty `onScroll` call.
1021
+
1022
+ **Apply:** if exact pagination boundaries matter, pad or report a real "no more results" state some
1023
+ other way; don't rely on `hasMore` being accurate at a page boundary.
1024
+
1025
+ ### `RolesPermission`'s `RoleData.permission`/`designation`/`makeSuperAdmin`/`automation`/`trackLocation`/`show_records` are dead weight in this component
1026
+
1027
+ None of these fields are read by `RolesPermission` — the roles list only renders
1028
+ `roleName`/`createdBy`/`created_at`/`roles_id`. They exist solely to be round-tripped unchanged
1029
+ through `onViewRole`/`onEditRole` so the consumer can prefill its own edit form. Setting them has no
1030
+ visible effect inside this component.
1031
+
1032
+ **Apply:** treat these fields as pass-through-only storage — populate them for your own edit form,
1033
+ not to change anything `RolesPermission` itself renders.
1034
+
1035
+ ### `OrganizationDetails`' `OrganizationItem.uiInvite` is never read
1036
+
1037
+ Active vs. invited organizations are decided purely by which array (`activeOrganizations` vs
1038
+ `invitedOrganizations`) an item is placed in — `uiInvite` is carried on the type but
1039
+ `OrganizationDetails` never inspects it.
1040
+
1041
+ **Apply:** don't rely on `uiInvite` to control which section an item renders in — move the item
1042
+ between the two arrays instead.
1043
+
1044
+ ### `OrganizationDetails`' `onSetDefault`/`onAcceptInvite`/`onDeclineInvite` are fire-and-forget despite their `Promise<void>` signature
1045
+
1046
+ Unlike `onCreateOrganization`/`onEditOrganization`/`onDeleteOrganization` (all awaited), these three
1047
+ are called without `await` — the `switchingOrgIds`/`respondingOrgIds` spinner arrays are entirely
1048
+ consumer-managed state, not driven by this component resolving the promise.
1049
+
1050
+ **Apply:** don't assume symmetry with the awaited callbacks in the same props interface; manage your
1051
+ own loading state for these three around the promise you return.
1052
+
1053
+ ### `OrganizationDetails`' `CreateOrgFormValues.default`/`defaultOrg` are dead fields — now `@deprecated`
1054
+
1055
+ The built-in `CreateOrgModal`'s internal state and submit handler never set or forward them, and the
1056
+ public `onCreateOrganization` callback's parameter type doesn't declare them at all — populating
1057
+ them in a custom create form has no effect on the built-in flow. account-frontend, the only real
1058
+ consumer of `OrganizationDetails`, never reads either field. Both are now `@deprecated` in
1059
+ `OrganizationDetailsProps.tsx`.
1060
+
1061
+ **Apply:** don't rely on these two fields to pre-mark a newly created org as default.
1062
+
1063
+ ### `SideBar`'s `selectedSubMenu` prop is accepted but never read — now `@deprecated`
1064
+
1065
+ `SidebarProps.selectedSubMenu` is threaded through `SideBar` → `MenuItems` → `MenuItemBox`, but the
1066
+ component's destructure never includes it — passing it has no effect of any kind. Zero consumers set
1067
+ it; now `@deprecated` in `SideBarProps.tsx`.
1068
+
1069
+ **Apply:** don't pass `selectedSubMenu` expecting it to highlight a submenu row.
1070
+
1071
+ ### `KanbanBoard`'s `kanbanSelect`/`onOpen` don't check `permissions` — decision: accepted as-is
1072
+
1073
+ Looked like an asymmetry with the gated `kanbanEdit`/`kanbanCreate`/`onDelete`, but on inspection
1074
+ `kanbanSelect` is a header filter dropdown (`options`/`onSelectChange`/`value`) — a view-level
1075
+ affordance, not a mutation trigger — and `onOpen` (opening a card) is a view action too. Both are
1076
+ already covered by the existing `permissions.isViewable` gate: the whole board (including the
1077
+ header) returns `null` before rendering when `isViewable` is `false`, so a viewer who can't see the
1078
+ board can't reach either. Gating them a second time against `isEditable`/`isCreatable`/`isDeletable`
1079
+ would be wrong — filtering/opening isn't an edit, create, or delete. No code change made.
1080
+
1081
+ **Apply:** if you need `kanbanSelect` or `onOpen` gated on something narrower than view access, gate
1082
+ it yourself (e.g. `isSelect: canEdit`); the component won't do it for you.
1083
+
1084
+ ### `SideBar`'s `locked` menu-item flag — decision: fixed to actually block interaction
1085
+
1086
+ Previously `locked` only swapped in a padlock icon; the click handler checked `disabled`, not
1087
+ `locked`, so a `locked: true` item still fully navigated. Zero consumers set `locked: true` in
1088
+ account-frontend, tickets, crm-frontend, hrms, social-frontend or crm-mobile, so there was no
1089
+ working behavior to preserve — the misleading name was a trap waiting for the first adopter. As of
1090
+ this release, `locked` blocks clicks/expansion the same way `disabled` does, in both the expanded
1091
+ sidebar (`MenuItemBox`) and the collapsed-sidebar flyout (`MenuPopoverContent`), for both top-level
1092
+ and submenu items. `disabled` is unchanged and still works independently.
1093
+
1094
+ **Apply:** `locked: true` alone now prevents interaction; you no longer need to also set
1095
+ `disabled: true`.
1096
+
1097
+ ### `KanbanBoard`'s `permissions.isViewable: false` hides everything, including header actions
1098
+
1099
+ Not just the columns — the select/edit/create header bar disappears too, since the whole component
1100
+ returns `null` before rendering anything.
1101
+
1102
+ **Apply:** there's no prop for hiding only the board body while keeping header actions visible.