@12-apps/ui 1.0.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (448) hide show
  1. package/components-catalog.md +14 -0
  2. package/package.json +42 -27
  3. package/src/__tests__/data-grid.test.tsx +125 -0
  4. package/src/__tests__/package-wiring.test.ts +12 -8
  5. package/src/__tests__/social-login-button.test.tsx +5 -5
  6. package/src/__tests__/viewport.test.ts +50 -0
  7. package/src/charts/index.ts +8 -0
  8. package/src/components/data-display/Alert/Alert.md +1 -1
  9. package/src/components/data-display/Alert/Alert.stories.tsx +5 -7
  10. package/src/components/data-display/Alert/Alert.styles.tsx +255 -0
  11. package/src/components/data-display/Alert/Alert.test.stories.tsx +11 -13
  12. package/src/components/data-display/Alert/Alert.tsx +135 -328
  13. package/src/components/data-display/AlertDialog/AlertDialog.stories.tsx +3 -1
  14. package/src/components/data-display/AlertDialog/AlertDialog.tsx +191 -78
  15. package/src/components/data-display/AlertDialog/AlertDialog.types.ts +8 -1
  16. package/src/components/data-display/AsyncStateContainer/AsyncStateContainer.test.stories.tsx +5 -5
  17. package/src/components/data-display/AsyncStateContainer/AsyncStateContainer.tsx +44 -35
  18. package/src/components/data-display/Avatar/Avatar.stories.tsx +4 -1
  19. package/src/components/data-display/Avatar/Avatar.test.stories.tsx +5 -3
  20. package/src/components/data-display/Avatar/Avatar.tsx +154 -450
  21. package/src/components/data-display/Avatar/Avatar.view.tsx +396 -0
  22. package/src/components/data-display/Badge/Badge.animations.ts +67 -0
  23. package/src/components/data-display/Badge/Badge.helpers.ts +74 -0
  24. package/src/components/data-display/Badge/Badge.stories.tsx +14 -16
  25. package/src/components/data-display/Badge/Badge.styles.ts +261 -0
  26. package/src/components/data-display/Badge/Badge.test.stories.tsx +32 -31
  27. package/src/components/data-display/Badge/Badge.tsx +151 -557
  28. package/src/components/data-display/Badge/Badge.variants.ts +106 -0
  29. package/src/components/data-display/Badge/BadgeContent.tsx +107 -0
  30. package/src/components/data-display/Banner/Banner.stories.tsx +5 -1
  31. package/src/components/data-display/Banner/Banner.styles.ts +120 -0
  32. package/src/components/data-display/Banner/Banner.tsx +179 -224
  33. package/src/components/data-display/Chart/Chart.md +48 -1
  34. package/src/components/data-display/Chart/Chart.tsx +82 -500
  35. package/src/components/data-display/Chart/Chart.types.ts +2 -0
  36. package/src/components/data-display/Chart/ChartComposables.tsx +121 -0
  37. package/src/components/data-display/Chart/ChartSpec.types.ts +70 -0
  38. package/src/components/data-display/Chart/SpecChart.stories.tsx +150 -0
  39. package/src/components/data-display/Chart/SpecChart.test.stories.tsx +56 -0
  40. package/src/components/data-display/Chart/SpecChart.tsx +53 -0
  41. package/src/components/data-display/Chart/__tests__/SpecChart.test.tsx +60 -0
  42. package/src/components/data-display/Chart/__tests__/chart-format.test.ts +43 -0
  43. package/src/components/data-display/Chart/__tests__/chart-spec.test.ts +119 -0
  44. package/src/components/data-display/Chart/chart-format.ts +26 -0
  45. package/src/components/data-display/Chart/chart-internals.ts +148 -0
  46. package/src/components/data-display/Chart/chart-renderers.tsx +338 -0
  47. package/src/components/data-display/Chart/chart-spec-registry.ts +74 -0
  48. package/src/components/data-display/Chart/chart-spec.ts +171 -0
  49. package/src/components/data-display/Chart/index.ts +30 -0
  50. package/src/components/data-display/Chip/Chip.helpers.tsx +131 -0
  51. package/src/components/data-display/Chip/Chip.stories.tsx +2 -1
  52. package/src/components/data-display/Chip/Chip.test.stories.tsx +11 -8
  53. package/src/components/data-display/Chip/Chip.tsx +31 -94
  54. package/src/components/data-display/DataGrid/DataGrid.body.tsx +141 -0
  55. package/src/components/data-display/DataGrid/DataGrid.cells.tsx +238 -0
  56. package/src/components/data-display/DataGrid/DataGrid.model.ts +315 -0
  57. package/src/components/data-display/DataGrid/DataGrid.rows.ts +112 -0
  58. package/src/components/data-display/DataGrid/DataGrid.states.tsx +102 -0
  59. package/src/components/data-display/DataGrid/DataGrid.test.stories.tsx +6 -12
  60. package/src/components/data-display/DataGrid/DataGrid.tsx +129 -725
  61. package/src/components/data-display/DataViews/DataViewsGrid.tsx +187 -0
  62. package/src/components/data-display/DataViews/DataViewsTableBase.tsx +400 -0
  63. package/src/components/data-display/DataViews/ManageViewsDialog.tsx +140 -0
  64. package/src/components/data-display/DataViews/SaveViewModal.tsx +289 -0
  65. package/src/components/data-display/DataViews/__tests__/DataViewsGrid.test.tsx +271 -0
  66. package/src/components/data-display/DataViews/__tests__/DataViewsTableBase.test.tsx +134 -0
  67. package/src/components/data-display/DataViews/__tests__/SaveViewModal.test.tsx +83 -0
  68. package/src/components/data-display/DataViews/__tests__/data-views-filter.test.ts +115 -0
  69. package/src/components/data-display/DataViews/__tests__/data-views-preview.test.ts +53 -0
  70. package/src/components/data-display/DataViews/__tests__/range-pill.test.tsx +114 -0
  71. package/src/components/data-display/DataViews/base-card.stories.tsx +136 -0
  72. package/src/components/data-display/DataViews/base-card.tsx +278 -0
  73. package/src/components/data-display/DataViews/data-views-filter-panel.tsx +184 -0
  74. package/src/components/data-display/DataViews/data-views-filter.ts +138 -0
  75. package/src/components/data-display/DataViews/data-views-grid-helpers.tsx +248 -0
  76. package/src/components/data-display/DataViews/data-views-grid-parts.tsx +400 -0
  77. package/src/components/data-display/DataViews/data-views-inline-bar.tsx +257 -0
  78. package/src/components/data-display/DataViews/data-views-layout-context.tsx +176 -0
  79. package/src/components/data-display/DataViews/data-views-pagination.tsx +31 -0
  80. package/src/components/data-display/DataViews/data-views-preview.ts +53 -0
  81. package/src/components/data-display/DataViews/data-views-range-pill.tsx +277 -0
  82. package/src/components/data-display/DataViews/data-views-table-parts.tsx +150 -0
  83. package/src/components/data-display/DataViews/data-views-toolbar.tsx +149 -0
  84. package/src/components/data-display/DataViews/data-views-types.ts +312 -0
  85. package/src/components/data-display/DataViews/data-views-view-mutations.ts +68 -0
  86. package/src/components/data-display/DataViews/index.ts +33 -0
  87. package/src/components/data-display/DataViews/use-data-views-state.ts +349 -0
  88. package/src/components/data-display/DateTimeDisplay/DateTimeDisplay.hooks.ts +104 -0
  89. package/src/components/data-display/DateTimeDisplay/DateTimeDisplay.tsx +68 -118
  90. package/src/components/data-display/DescriptionItem/DescriptionItem.stories.tsx +1 -1
  91. package/src/components/data-display/DescriptionItem/DescriptionItem.tsx +52 -34
  92. package/src/components/data-display/EmptyState/EmptyState.test.stories.tsx +6 -6
  93. package/src/components/data-display/EmptyState/EmptyState.tsx +218 -135
  94. package/src/components/data-display/ErrorState/ErrorState.test.stories.tsx +2 -2
  95. package/src/components/data-display/ErrorState/ErrorState.tsx +83 -55
  96. package/src/components/data-display/HoverCard/HoverCard.stories.tsx +3 -1
  97. package/src/components/data-display/HoverCard/HoverCard.test.stories.tsx +5 -5
  98. package/src/components/data-display/InteractiveTooltip/InteractiveTooltip.hooks.ts +99 -0
  99. package/src/components/data-display/InteractiveTooltip/InteractiveTooltip.styles.ts +87 -0
  100. package/src/components/data-display/InteractiveTooltip/InteractiveTooltip.tsx +28 -155
  101. package/src/components/data-display/LazyImage/LazyImage.hooks.ts +203 -0
  102. package/src/components/data-display/LazyImage/LazyImage.md +1 -1
  103. package/src/components/data-display/LazyImage/LazyImage.stories.tsx +3 -3
  104. package/src/components/data-display/LazyImage/LazyImage.tsx +144 -243
  105. package/src/components/data-display/Lightbox/Lightbox.constants.ts +53 -0
  106. package/src/components/data-display/Lightbox/Lightbox.helpers.ts +39 -0
  107. package/src/components/data-display/Lightbox/Lightbox.hooks.ts +259 -0
  108. package/src/components/data-display/Lightbox/Lightbox.test.stories.tsx +28 -35
  109. package/src/components/data-display/Lightbox/Lightbox.tsx +98 -658
  110. package/src/components/data-display/Lightbox/LightboxControls.tsx +152 -0
  111. package/src/components/data-display/Lightbox/LightboxCurrentMedia.tsx +50 -0
  112. package/src/components/data-display/Lightbox/LightboxMedia.tsx +76 -0
  113. package/src/components/data-display/Lightbox/LightboxOverlay.tsx +83 -0
  114. package/src/components/data-display/Lightbox/LightboxStage.tsx +97 -0
  115. package/src/components/data-display/Lightbox/LightboxThumbnails.tsx +83 -0
  116. package/src/components/data-display/Lightbox/useLightbox.ts +80 -0
  117. package/src/components/data-display/LoadingState/LoadingState.helpers.ts +52 -0
  118. package/src/components/data-display/LoadingState/LoadingState.tsx +117 -87
  119. package/src/components/data-display/MapPreview/MapControlBar.tsx +116 -0
  120. package/src/components/data-display/MapPreview/MapDecorations.tsx +155 -0
  121. package/src/components/data-display/MapPreview/MapLayers.tsx +70 -0
  122. package/src/components/data-display/MapPreview/MapMarkers.tsx +84 -0
  123. package/src/components/data-display/MapPreview/MapOverlays.tsx +68 -0
  124. package/src/components/data-display/MapPreview/MapPreview.constants.ts +19 -0
  125. package/src/components/data-display/MapPreview/MapPreview.helpers.ts +63 -0
  126. package/src/components/data-display/MapPreview/MapPreview.hooks.ts +265 -0
  127. package/src/components/data-display/MapPreview/MapPreview.test.stories.tsx +14 -10
  128. package/src/components/data-display/MapPreview/MapPreview.tsx +52 -882
  129. package/src/components/data-display/MapPreview/MapPreview.types.ts +8 -1
  130. package/src/components/data-display/MapPreview/MapSearchBar.tsx +64 -0
  131. package/src/components/data-display/MapPreview/MapTiles.tsx +70 -0
  132. package/src/components/data-display/MapPreview/StaticMapView.tsx +63 -0
  133. package/src/components/data-display/MapPreview/mapProjection.ts +52 -0
  134. package/src/components/data-display/MapPreview/mapSurface.ts +37 -0
  135. package/src/components/data-display/MapPreview/useMapPreview.ts +62 -0
  136. package/src/components/data-display/Popover/Popover.test.stories.tsx +13 -19
  137. package/src/components/data-display/Progress/Progress.helpers.ts +37 -0
  138. package/src/components/data-display/Progress/Progress.styles.ts +101 -0
  139. package/src/components/data-display/Progress/Progress.tsx +185 -213
  140. package/src/components/data-display/SectionOnboarding/SectionOnboarding.stories.tsx +1 -1
  141. package/src/components/data-display/SectionOnboarding/SectionOnboarding.tsx +1 -1
  142. package/src/components/data-display/StatCard/StatCard.md +117 -0
  143. package/src/components/data-display/StatCard/StatCard.stories.tsx +167 -0
  144. package/src/components/data-display/StatCard/StatCard.test.stories.tsx +240 -0
  145. package/src/components/data-display/StatCard/StatCard.tsx +236 -0
  146. package/src/components/data-display/StatCard/StatCard.types.ts +62 -0
  147. package/src/components/data-display/StatCard/index.ts +7 -0
  148. package/src/components/data-display/Stepper/Stepper.test.stories.tsx +12 -19
  149. package/src/components/data-display/Stepper/Stepper.tsx +1 -1
  150. package/src/components/data-display/Table/Table.helpers.ts +31 -0
  151. package/src/components/data-display/Table/Table.hooks.ts +161 -0
  152. package/src/components/data-display/Table/Table.stories.tsx +3 -1
  153. package/src/components/data-display/Table/Table.styles.ts +223 -0
  154. package/src/components/data-display/Table/Table.test.stories.tsx +4 -4
  155. package/src/components/data-display/Table/Table.tsx +291 -748
  156. package/src/components/data-display/Table/TableParts.hooks.tsx +112 -0
  157. package/src/components/data-display/Table/TableParts.tsx +298 -0
  158. package/src/components/data-display/Table/TableStates.tsx +21 -0
  159. package/src/components/data-display/Timeline/Timeline.stories.tsx +10 -12
  160. package/src/components/data-display/Timeline/Timeline.test.stories.tsx +30 -44
  161. package/src/components/data-display/Timeline/Timeline.tsx +23 -284
  162. package/src/components/data-display/Timeline/TimelineRow.tsx +346 -0
  163. package/src/components/data-display/TimingDiagram/TimingDiagram.tsx +38 -311
  164. package/src/components/data-display/TimingDiagram/TimingDiagram.views.tsx +346 -0
  165. package/src/components/data-display/Tooltip/Tooltip.stories.tsx +4 -1
  166. package/src/components/data-display/Tooltip/Tooltip.test.stories.tsx +44 -58
  167. package/src/components/data-display/Tooltip/Tooltip.tsx +67 -62
  168. package/src/components/data-display/index.ts +1 -0
  169. package/src/components/feedback/ConfirmAction/ConfirmAction.hooks.ts +96 -0
  170. package/src/components/feedback/ConfirmAction/ConfirmAction.md +140 -0
  171. package/src/components/feedback/ConfirmAction/ConfirmAction.parts.tsx +154 -0
  172. package/src/components/feedback/ConfirmAction/ConfirmAction.stories.tsx +146 -0
  173. package/src/components/feedback/ConfirmAction/ConfirmAction.test.stories.tsx +114 -0
  174. package/src/components/feedback/ConfirmAction/ConfirmAction.tsx +46 -0
  175. package/src/components/feedback/ConfirmAction/ConfirmAction.types.ts +111 -0
  176. package/src/components/feedback/ConfirmAction/ConfirmButton.tsx +18 -0
  177. package/src/components/feedback/ConfirmAction/__tests__/confirm-action.test.tsx +288 -0
  178. package/src/components/feedback/ConfirmAction/index.ts +16 -0
  179. package/src/components/feedback/ConfirmAction/with-confirmation.tsx +112 -0
  180. package/src/components/feedback/Dialog/Dialog.styles.ts +4 -2
  181. package/src/components/feedback/Dialog/Dialog.tsx +26 -1
  182. package/src/components/feedback/Dialog/__tests__/dialog-content-spacing.test.tsx +66 -0
  183. package/src/components/feedback/Modal/Modal.md +1 -1
  184. package/src/components/feedback/Modal/Modal.stories.tsx +2 -2
  185. package/src/components/feedback/Sonner/Sonner.tsx +104 -288
  186. package/src/components/feedback/Sonner/Sonner.types.ts +7 -0
  187. package/src/components/feedback/Sonner/SonnerToast.tsx +216 -0
  188. package/src/components/feedback/StackedModal/StackedModal.hooks.ts +226 -0
  189. package/src/components/feedback/StackedModal/StackedModal.parts.tsx +311 -0
  190. package/src/components/feedback/StackedModal/StackedModal.stories.tsx +13 -15
  191. package/src/components/feedback/StackedModal/StackedModal.styles.ts +193 -0
  192. package/src/components/feedback/StackedModal/StackedModal.tsx +100 -619
  193. package/src/components/feedback/StackedModal/StackedModal.types.ts +17 -3
  194. package/src/components/feedback/StackedModal/__tests__/stacked-modal-viewport.test.tsx +104 -0
  195. package/src/components/feedback/StackedModal/modal-stack.tsx +119 -0
  196. package/src/components/feedback/Toast/Toast.tsx +92 -81
  197. package/src/components/feedback/TutorialOverlay/TutorialOverlay.geometry.ts +65 -0
  198. package/src/components/feedback/TutorialOverlay/TutorialOverlay.hooks.ts +185 -0
  199. package/src/components/feedback/TutorialOverlay/TutorialOverlay.test.stories.tsx +2 -2
  200. package/src/components/feedback/TutorialOverlay/TutorialOverlay.tsx +156 -414
  201. package/src/components/feedback/TutorialOverlay/TutorialStepBody.tsx +255 -0
  202. package/src/components/feedback/index.ts +1 -0
  203. package/src/components/form/AddressAutocomplete/AddressAutocomplete.helpers.ts +58 -0
  204. package/src/components/form/AddressAutocomplete/AddressAutocomplete.hooks.ts +93 -0
  205. package/src/components/form/AddressAutocomplete/AddressAutocomplete.mapper.ts +57 -0
  206. package/src/components/form/AddressAutocomplete/AddressAutocomplete.stories.tsx +4 -2
  207. package/src/components/form/AddressAutocomplete/AddressAutocomplete.test.stories.tsx +20 -16
  208. package/src/components/form/AddressAutocomplete/AddressAutocomplete.tsx +26 -829
  209. package/src/components/form/AddressAutocomplete/AddressAutocomplete.types.ts +11 -0
  210. package/src/components/form/AddressAutocomplete/AddressAutocompleteField.tsx +86 -0
  211. package/src/components/form/AddressAutocomplete/AddressFallbackField.tsx +64 -0
  212. package/src/components/form/AddressAutocomplete/AddressInputField.tsx +80 -0
  213. package/src/components/form/AddressAutocomplete/AddressOption.tsx +83 -0
  214. package/src/components/form/AddressAutocomplete/AddressSuggestionsPaper.tsx +24 -0
  215. package/src/components/form/AddressAutocomplete/AddressTextField.tsx +43 -0
  216. package/src/components/form/AddressAutocomplete/mockPlaces.ts +208 -0
  217. package/src/components/form/AddressAutocomplete/useAddressPredictions.ts +136 -0
  218. package/src/components/form/AddressAutocomplete/useAddressSelection.ts +113 -0
  219. package/src/components/form/AddressAutocomplete/useCurrentLocation.ts +116 -0
  220. package/src/components/form/AddressAutocomplete/useGoogleMapsAPI.ts +75 -0
  221. package/src/components/form/Button/Button.helpers.ts +36 -0
  222. package/src/components/form/Button/Button.stories.tsx +4 -1
  223. package/src/components/form/Button/Button.styles.ts +225 -0
  224. package/src/components/form/Button/Button.test.stories.tsx +25 -21
  225. package/src/components/form/Button/Button.tsx +45 -252
  226. package/src/components/form/Calendar/Calendar.dates.ts +100 -0
  227. package/src/components/form/Calendar/Calendar.helpers.ts +32 -0
  228. package/src/components/form/Calendar/Calendar.hooks.ts +278 -0
  229. package/src/components/form/Calendar/Calendar.keyboard.ts +32 -0
  230. package/src/components/form/Calendar/Calendar.selection.ts +156 -0
  231. package/src/components/form/Calendar/Calendar.test.stories.tsx +33 -34
  232. package/src/components/form/Calendar/Calendar.tsx +63 -551
  233. package/src/components/form/Calendar/Calendar.types.ts +16 -0
  234. package/src/components/form/Calendar/CalendarDay.tsx +127 -0
  235. package/src/components/form/Calendar/CalendarDayCell.tsx +52 -0
  236. package/src/components/form/Calendar/CalendarMonth.tsx +128 -0
  237. package/src/components/form/CepField/CepField.md +138 -0
  238. package/src/components/form/CepField/CepField.stories.tsx +138 -0
  239. package/src/components/form/CepField/CepField.test.stories.tsx +281 -0
  240. package/src/components/form/CepField/CepField.tsx +211 -0
  241. package/src/components/form/CepField/CepField.types.ts +73 -0
  242. package/src/components/form/CepField/index.ts +2 -0
  243. package/src/components/form/Checkbox/Checkbox.helpers.ts +28 -0
  244. package/src/components/form/Checkbox/Checkbox.tsx +19 -16
  245. package/src/components/form/CodeEditor/CodeEditor.helpers.ts +45 -0
  246. package/src/components/form/CodeEditor/CodeEditor.hooks.ts +104 -0
  247. package/src/components/form/CodeEditor/CodeEditor.monaco.ts +109 -0
  248. package/src/components/form/CodeEditor/CodeEditor.test.stories.tsx +17 -18
  249. package/src/components/form/CodeEditor/CodeEditor.tsx +81 -330
  250. package/src/components/form/CodeEditor/CodeEditorToolbar.tsx +168 -0
  251. package/src/components/form/Command/Command.hooks.ts +207 -0
  252. package/src/components/form/Command/Command.parts.tsx +58 -0
  253. package/src/components/form/Command/Command.styles.ts +83 -0
  254. package/src/components/form/Command/Command.tsx +61 -270
  255. package/src/components/form/CreatableSelect/CreatableSelect.md +1 -1
  256. package/src/components/form/CreatableSelect/CreatableSelect.test.stories.tsx +1 -1
  257. package/src/components/form/CreatableSelect/CreatableSelect.tsx +152 -71
  258. package/src/components/form/CreatableSelect/CreatableSelect.types.ts +13 -0
  259. package/src/components/form/HeaderButton/HeaderButton.tsx +80 -0
  260. package/src/components/form/HeaderButton/index.ts +2 -0
  261. package/src/components/form/Input/Input.stories.tsx +5 -1
  262. package/src/components/form/Input/Input.styles.ts +176 -0
  263. package/src/components/form/Input/Input.test.stories.tsx +30 -23
  264. package/src/components/form/Input/Input.tsx +71 -211
  265. package/src/components/form/Input/Input.types.ts +11 -0
  266. package/src/components/form/InputOTP/InputOTP.test.stories.tsx +9 -17
  267. package/src/components/form/Menubar/Menubar.test.stories.tsx +4 -8
  268. package/src/components/form/PasswordStrength/PasswordStrength.helpers.tsx +117 -0
  269. package/src/components/form/PasswordStrength/PasswordStrength.test.stories.tsx +3 -3
  270. package/src/components/form/PasswordStrength/PasswordStrength.tsx +202 -255
  271. package/src/components/form/PhoneInput/PhoneInput.hooks.ts +134 -0
  272. package/src/components/form/PhoneInput/PhoneInput.test.stories.tsx +4 -4
  273. package/src/components/form/PhoneInput/PhoneInput.tsx +279 -292
  274. package/src/components/form/PhoneInput/countries.ts +54 -0
  275. package/src/components/form/PhoneInput/phone.ts +47 -0
  276. package/src/components/form/RadioGroup/RadioGroup.test.stories.tsx +9 -9
  277. package/src/components/form/RichTextEditor/RichTextEditor.dom.ts +124 -0
  278. package/src/components/form/RichTextEditor/RichTextEditor.format.ts +61 -0
  279. package/src/components/form/RichTextEditor/RichTextEditor.hooks.ts +142 -0
  280. package/src/components/form/RichTextEditor/RichTextEditor.test.stories.tsx +5 -12
  281. package/src/components/form/RichTextEditor/RichTextEditor.tsx +98 -410
  282. package/src/components/form/RichTextEditor/RichTextEditorToolbar.tsx +187 -0
  283. package/src/components/form/SearchPalette/SearchPalette.parts.tsx +22 -0
  284. package/src/components/form/SearchPalette/SearchPalette.tsx +13 -9
  285. package/src/components/form/Select/Select.test.stories.tsx +35 -27
  286. package/src/components/form/Slider/Slider.test.stories.tsx +9 -11
  287. package/src/components/form/Switch/Switch.md +2 -1
  288. package/src/components/form/Switch/Switch.test.stories.tsx +6 -6
  289. package/src/components/form/Textarea/Textarea.styles.ts +143 -0
  290. package/src/components/form/Textarea/Textarea.test.stories.tsx +20 -26
  291. package/src/components/form/Textarea/Textarea.tsx +114 -535
  292. package/src/components/form/Textarea/TextareaRichEditor.tsx +377 -0
  293. package/src/components/form/Toggle/Toggle.styles.ts +211 -0
  294. package/src/components/form/Toggle/Toggle.test.stories.tsx +19 -27
  295. package/src/components/form/Toggle/Toggle.tsx +10 -185
  296. package/src/components/form/UploadButton/UploadButton.hooks.ts +323 -0
  297. package/src/components/form/UploadButton/UploadButton.parts.tsx +210 -0
  298. package/src/components/form/UploadButton/UploadButton.stories.tsx +2 -1
  299. package/src/components/form/UploadButton/UploadButton.test.stories.tsx +123 -4
  300. package/src/components/form/UploadButton/UploadButton.tsx +76 -305
  301. package/src/components/form/UploadButton/UploadButton.types.ts +16 -0
  302. package/src/components/form/index.ts +1 -0
  303. package/src/components/form/total-form/Fields/CepField.tsx +143 -0
  304. package/src/components/form/total-form/Fields/ToggleField.tsx +61 -0
  305. package/src/components/form/total-form/Fields/index.ts +4 -0
  306. package/src/components/form/total-form/FormContainer.tsx +3 -3
  307. package/src/components/form/total-form/SubmitButton.tsx +25 -2
  308. package/src/components/form/total-form/total-form.test.tsx +118 -1
  309. package/src/components/layout/Accordion/Accordion.md +1 -1
  310. package/src/components/layout/Accordion/Accordion.stories.tsx +5 -1
  311. package/src/components/layout/Accordion/Accordion.styles.ts +80 -0
  312. package/src/components/layout/Accordion/Accordion.test.stories.tsx +32 -50
  313. package/src/components/layout/Accordion/Accordion.tsx +2 -75
  314. package/src/components/layout/Card/Card.helpers.ts +30 -0
  315. package/src/components/layout/Card/Card.stories.tsx +9 -11
  316. package/src/components/layout/Card/Card.styles.ts +182 -0
  317. package/src/components/layout/Card/Card.test.stories.tsx +46 -46
  318. package/src/components/layout/Card/Card.tsx +24 -241
  319. package/src/components/layout/CardGrid/CardGrid.md +96 -0
  320. package/src/components/layout/CardGrid/CardGrid.tsx +140 -0
  321. package/src/components/layout/CardGrid/__tests__/CardGrid.test.tsx +92 -0
  322. package/src/components/layout/CardGrid/index.ts +2 -0
  323. package/src/components/layout/Collapsible/Collapsible.helpers.ts +83 -0
  324. package/src/components/layout/Collapsible/Collapsible.test.stories.tsx +7 -3
  325. package/src/components/layout/Collapsible/Collapsible.tsx +111 -107
  326. package/src/components/layout/Container/Container.test.stories.tsx +11 -16
  327. package/src/components/layout/ContentToolbar/ColumnsMenu.tsx +1 -1
  328. package/src/components/layout/ContentToolbar/ContentToolbar.tsx +120 -44
  329. package/src/components/layout/ContentToolbar/ContentToolbar.types.ts +9 -0
  330. package/src/components/layout/ContentToolbar/FilterTrigger.tsx +1 -1
  331. package/src/components/layout/ContentToolbar/MultiSelectDropdown.tsx +58 -43
  332. package/src/components/layout/ContentToolbar/MultiSelectTriggers.tsx +139 -0
  333. package/src/components/layout/ContentToolbar/SavedViewsMenu.tsx +10 -3
  334. package/src/components/layout/ContentToolbar/SortByDropdown.tsx +35 -11
  335. package/src/components/layout/ContentToolbar/ViewSelector.tsx +5 -6
  336. package/src/components/layout/ContentToolbar/__tests__/MultiSelectDropdown.test.tsx +21 -0
  337. package/src/components/layout/Dashboard/Dashboard.test.stories.tsx +27 -1
  338. package/src/components/layout/Dashboard/Dashboard.tsx +27 -8
  339. package/src/components/layout/Dashboard/DashboardParts.tsx +12 -19
  340. package/src/components/layout/Dashboard/index.ts +2 -1
  341. package/src/components/layout/Drawer/Drawer.stories.tsx +8 -10
  342. package/src/components/layout/Drawer/Drawer.test.stories.tsx +18 -14
  343. package/src/components/layout/Drawer/Drawer.tsx +67 -53
  344. package/src/components/layout/Resizable/Resizable.helpers.ts +133 -0
  345. package/src/components/layout/Resizable/Resizable.hooks.ts +68 -0
  346. package/src/components/layout/Resizable/Resizable.tsx +38 -153
  347. package/src/components/layout/ScrollArea/ScrollArea.helpers.ts +51 -0
  348. package/src/components/layout/ScrollArea/ScrollArea.styles.ts +248 -0
  349. package/src/components/layout/ScrollArea/ScrollArea.tsx +183 -374
  350. package/src/components/layout/ScrollArea/ScrollAreaContent.tsx +70 -0
  351. package/src/components/layout/ScrollArea/ScrollViewport.tsx +90 -0
  352. package/src/components/layout/Separator/Separator.styles.ts +128 -0
  353. package/src/components/layout/Separator/Separator.test.stories.tsx +3 -12
  354. package/src/components/layout/Separator/Separator.tsx +6 -132
  355. package/src/components/layout/SettingsLayout/SettingsLayout.parts.tsx +2 -1
  356. package/src/components/layout/SettingsLayout/SettingsLayout.stories.tsx +6 -8
  357. package/src/components/layout/Sidebar/Sidebar.stories.tsx +10 -12
  358. package/src/components/layout/Sidebar/Sidebar.test.stories.tsx +35 -37
  359. package/src/components/layout/Skeleton/Skeleton.helpers.ts +33 -0
  360. package/src/components/layout/Skeleton/Skeleton.styles.ts +114 -0
  361. package/src/components/layout/Skeleton/Skeleton.test.stories.tsx +3 -3
  362. package/src/components/layout/Skeleton/Skeleton.tsx +67 -155
  363. package/src/components/layout/TableFilter/TableFilter.tsx +2 -1
  364. package/src/components/navigation/Breadcrumbs/BreadcrumbEntry.tsx +305 -0
  365. package/src/components/navigation/Breadcrumbs/Breadcrumbs.md +2 -1
  366. package/src/components/navigation/Breadcrumbs/Breadcrumbs.stories.tsx +12 -14
  367. package/src/components/navigation/Breadcrumbs/Breadcrumbs.styles.tsx +212 -0
  368. package/src/components/navigation/Breadcrumbs/Breadcrumbs.test.stories.tsx +62 -61
  369. package/src/components/navigation/Breadcrumbs/Breadcrumbs.tsx +116 -429
  370. package/src/components/navigation/CommandPalette/CommandPalette.helpers.ts +82 -0
  371. package/src/components/navigation/CommandPalette/CommandPalette.hooks.ts +202 -0
  372. package/src/components/navigation/CommandPalette/CommandPalette.stories.tsx +3 -1
  373. package/src/components/navigation/CommandPalette/CommandPalette.test.stories.tsx +3 -5
  374. package/src/components/navigation/CommandPalette/CommandPalette.tsx +108 -341
  375. package/src/components/navigation/CommandPalette/CommandPaletteResults.tsx +182 -0
  376. package/src/components/navigation/CommandPalette/ShortcutChip.tsx +18 -0
  377. package/src/components/navigation/ContextMenu/ContextMenu.md +3 -1
  378. package/src/components/navigation/ContextMenu/ContextMenu.stories.tsx +4 -1
  379. package/src/components/navigation/ContextMenu/ContextMenu.test.stories.tsx +19 -24
  380. package/src/components/navigation/ContextMenu/ContextMenu.tsx +70 -54
  381. package/src/components/navigation/DropdownMenu/DropdownMenu.md +3 -1
  382. package/src/components/navigation/DropdownMenu/DropdownMenu.stories.tsx +17 -19
  383. package/src/components/navigation/DropdownMenu/DropdownMenu.test.stories.tsx +26 -26
  384. package/src/components/navigation/DropdownMenu/DropdownMenu.tsx +189 -111
  385. package/src/components/navigation/NavigationMenu/NavigationMegaSection.tsx +66 -0
  386. package/src/components/navigation/NavigationMenu/NavigationMenu.md +7 -2
  387. package/src/components/navigation/NavigationMenu/NavigationMenu.shell.tsx +218 -0
  388. package/src/components/navigation/NavigationMenu/NavigationMenu.styles.ts +223 -0
  389. package/src/components/navigation/NavigationMenu/NavigationMenu.tsx +119 -808
  390. package/src/components/navigation/NavigationMenu/NavigationMenuItem.hooks.ts +126 -0
  391. package/src/components/navigation/NavigationMenu/NavigationMenuItem.tsx +352 -0
  392. package/src/components/navigation/NavigationMenu/NavigationStandardBody.tsx +148 -0
  393. package/src/components/navigation/NavigationMenu/stories/NavigationMenu.stories.tsx +15 -17
  394. package/src/components/navigation/NavigationMenu/stories/NavigationMenu.test.stories.tsx +27 -23
  395. package/src/components/navigation/NavigationMenu/stories/NavigationMenuHorizontal.stories.tsx +11 -13
  396. package/src/components/navigation/NavigationMenu/stories/NavigationMenuVertical.stories.tsx +9 -11
  397. package/src/components/navigation/Pagination/Pagination.helpers.tsx +85 -0
  398. package/src/components/navigation/Pagination/Pagination.md +2 -1
  399. package/src/components/navigation/Pagination/Pagination.stories.tsx +4 -6
  400. package/src/components/navigation/Pagination/Pagination.styles.ts +135 -0
  401. package/src/components/navigation/Pagination/Pagination.tsx +178 -313
  402. package/src/components/navigation/Pagination/PaginationParts.tsx +81 -0
  403. package/src/components/navigation/Tabs/Tabs.md +3 -1
  404. package/src/components/navigation/Tabs/Tabs.stories.tsx +21 -23
  405. package/src/components/navigation/Tabs/Tabs.styles.ts +163 -0
  406. package/src/components/navigation/Tabs/Tabs.test.stories.tsx +37 -37
  407. package/src/components/navigation/Tabs/Tabs.tsx +192 -361
  408. package/src/components/navigation/Tabs/TabsPanel.tsx +100 -0
  409. package/src/components/typography/Blockquote/Blockquote.tsx +1 -1
  410. package/src/components/typography/Code/Code.test.stories.tsx +5 -5
  411. package/src/components/typography/Code/Code.tsx +74 -49
  412. package/src/components/typography/Heading/Heading.test.stories.tsx +8 -8
  413. package/src/components/typography/Paragraph/Paragraph.test.stories.tsx +5 -12
  414. package/src/components/typography/Text/Text.tsx +84 -77
  415. package/src/components/utility/AnimatedIcon/AnimatedIcon.md +4 -4
  416. package/src/components/utility/AnimatedIcon/AnimatedIcon.stories.tsx +19 -21
  417. package/src/components/utility/AnimatedIcon/AnimatedIcon.test.stories.tsx +19 -12
  418. package/src/components/utility/AspectRatio/AspectRatio.test.stories.tsx +9 -9
  419. package/src/components/utility/InfiniteScroll/InfiniteScroll.hooks.ts +118 -0
  420. package/src/components/utility/InfiniteScroll/InfiniteScroll.parts.tsx +54 -0
  421. package/src/components/utility/InfiniteScroll/InfiniteScroll.test.stories.tsx +12 -9
  422. package/src/components/utility/InfiniteScroll/InfiniteScroll.tsx +29 -148
  423. package/src/components/utility/InstallPrompt/InstallPrompt.helpers.ts +124 -0
  424. package/src/components/utility/InstallPrompt/InstallPrompt.md +113 -0
  425. package/src/components/utility/InstallPrompt/InstallPrompt.stories.tsx +118 -0
  426. package/src/components/utility/InstallPrompt/InstallPrompt.styles.ts +50 -0
  427. package/src/components/utility/InstallPrompt/InstallPrompt.test.stories.tsx +83 -0
  428. package/src/components/utility/InstallPrompt/InstallPrompt.tsx +192 -0
  429. package/src/components/utility/InstallPrompt/InstallPrompt.types.ts +78 -0
  430. package/src/components/utility/InstallPrompt/__tests__/InstallPrompt.ios.test.tsx +65 -0
  431. package/src/components/utility/InstallPrompt/__tests__/usePwaInstall.test.tsx +271 -0
  432. package/src/components/utility/InstallPrompt/index.ts +10 -0
  433. package/src/components/utility/InstallPrompt/usePwaInstall.ts +171 -0
  434. package/src/components/utility/Transition/Transition.helpers.ts +40 -0
  435. package/src/components/utility/Transition/Transition.tsx +17 -68
  436. package/src/components/utility/VirtualList/VirtualList.hooks.ts +319 -0
  437. package/src/components/utility/VirtualList/VirtualList.test.stories.tsx +49 -38
  438. package/src/components/utility/VirtualList/VirtualList.tsx +110 -315
  439. package/src/components/utility/WorkflowStep/WorkflowStep.helpers.ts +151 -0
  440. package/src/components/utility/WorkflowStep/WorkflowStep.parts.tsx +371 -0
  441. package/src/components/utility/WorkflowStep/WorkflowStep.stories.tsx +9 -11
  442. package/src/components/utility/WorkflowStep/WorkflowStep.test.stories.tsx +7 -7
  443. package/src/components/utility/WorkflowStep/WorkflowStep.tsx +51 -449
  444. package/src/components/utility/WorkflowStep/WorkflowStepRow.tsx +96 -0
  445. package/src/components/utility/index.ts +1 -0
  446. package/src/mui/Link.ts +2 -0
  447. package/src/utils/index.ts +2 -1
  448. package/src/utils/viewport.ts +65 -0
@@ -1,68 +1,24 @@
1
- import type {
2
- PaletteColor} from '@mui/material';
3
1
  import {
4
2
  alpha,
5
3
  Box,
6
4
  CircularProgress,
7
- keyframes,
8
5
  LinearProgress,
9
6
  Typography,
10
7
  } from '@mui/material';
11
- import type { Theme} from '@mui/material/styles';
12
8
  import { styled, useTheme } from '@mui/material/styles';
13
9
  import React from 'react';
14
10
 
11
+ import { resolveProgressProps } from './Progress.helpers';
12
+ import {
13
+ barEmphasisStyles,
14
+ barVariantStyles,
15
+ circularEmphasisStyles,
16
+ getColorFromTheme,
17
+ getSizeStyles,
18
+ pulseAnimation,
19
+ } from './Progress.styles';
15
20
  import type { ProgressProps, ProgressSize, ProgressVariant } from './Progress.types';
16
21
 
17
- // Define pulse animation
18
- const pulseAnimation = keyframes`
19
- 0% {
20
- opacity: 1;
21
- }
22
- 50% {
23
- opacity: 0.7;
24
- }
25
- 100% {
26
- opacity: 1;
27
- }
28
- `;
29
-
30
- const getColorFromTheme = (theme: Theme, color: string): PaletteColor => {
31
- const colorMap: Record<string, PaletteColor> = {
32
- primary: theme.palette.primary,
33
- secondary: theme.palette.secondary,
34
- success: theme.palette.success,
35
- warning: theme.palette.warning,
36
- error: theme.palette.error,
37
- danger: theme.palette.error, // Add danger alias
38
- };
39
-
40
- // Handle special case for neutral (grey) which is a Color, not PaletteColor
41
- if (color === 'neutral') {
42
- return {
43
- light: theme.palette.grey[300],
44
- main: theme.palette.grey[500],
45
- dark: theme.palette.grey[700],
46
- contrastText: theme.palette.getContrastText(theme.palette.grey[500]),
47
- };
48
- }
49
-
50
- const selectedColor = colorMap[color];
51
- // Ensure we always return a valid color object with main and dark properties
52
- return selectedColor || theme.palette.primary;
53
- };
54
-
55
- const getSizeStyles = (size: ProgressSize) => {
56
- const sizeMap: Record<ProgressSize, { height: number; circularSize: number; fontSize: string }> =
57
- {
58
- sm: { height: 4, circularSize: 32, fontSize: '0.75rem' },
59
- md: { height: 6, circularSize: 40, fontSize: '0.875rem' },
60
- lg: { height: 8, circularSize: 48, fontSize: '1rem' },
61
- };
62
-
63
- return sizeMap[size] || sizeMap.md;
64
- };
65
-
66
22
  const StyledLinearProgress = styled(LinearProgress, {
67
23
  shouldForwardProp: (prop) =>
68
24
  !['customVariant', 'customSize', 'customColor', 'glow', 'pulse'].includes(prop as string),
@@ -72,7 +28,7 @@ const StyledLinearProgress = styled(LinearProgress, {
72
28
  customColor?: string;
73
29
  glow?: boolean;
74
30
  pulse?: boolean;
75
- }>(({ theme, customVariant, customSize = 'md', customColor = 'primary', glow, pulse }) => {
31
+ }>(({ theme, customVariant, customSize, customColor = 'primary', glow, pulse }) => {
76
32
  const colorPalette = getColorFromTheme(theme, customColor);
77
33
  const sizeStyles = getSizeStyles(customSize);
78
34
 
@@ -84,41 +40,8 @@ const StyledLinearProgress = styled(LinearProgress, {
84
40
  '& .MuiLinearProgress-bar': {
85
41
  borderRadius: 'inherit',
86
42
  transition: 'all 0.3s ease',
87
-
88
- ...(customVariant === 'linear' && {
89
- backgroundColor: colorPalette.main,
90
- }),
91
-
92
- ...(customVariant === 'gradient' && {
93
- background: `linear-gradient(90deg, ${colorPalette.main} 0%, ${colorPalette.dark || colorPalette.main} 100%)`,
94
- }),
95
-
96
- ...(customVariant === 'glass' && {
97
- backgroundColor: alpha(colorPalette.main, 0.8),
98
- backdropFilter: 'blur(10px)',
99
- border: `1px solid ${alpha(colorPalette.main, 0.3)}`,
100
- }),
101
-
102
- // Glow effect
103
- ...(glow &&
104
- !pulse && {
105
- boxShadow: `0 0 10px 2px ${alpha(colorPalette.main, 0.4)}`,
106
- filter: 'brightness(1.1)',
107
- }),
108
-
109
- // Pulse animation
110
- ...(pulse &&
111
- !glow && {
112
- animation: `${pulseAnimation} 2s infinite`,
113
- }),
114
-
115
- // Both glow and pulse
116
- ...(glow &&
117
- pulse && {
118
- boxShadow: `0 0 10px 2px ${alpha(colorPalette.main, 0.4)}`,
119
- filter: 'brightness(1.1)',
120
- animation: `${pulseAnimation} 2s infinite`,
121
- }),
43
+ ...barVariantStyles(customVariant, colorPalette),
44
+ ...barEmphasisStyles(colorPalette, glow, pulse),
122
45
  },
123
46
  };
124
47
  });
@@ -134,25 +57,7 @@ const StyledCircularProgress = styled(CircularProgress, {
134
57
 
135
58
  return {
136
59
  color: colorPalette.main,
137
-
138
- // Glow effect
139
- ...(glow &&
140
- !pulse && {
141
- filter: `drop-shadow(0 0 8px ${alpha(colorPalette.main, 0.6)})`,
142
- }),
143
-
144
- // Pulse animation
145
- ...(pulse &&
146
- !glow && {
147
- animation: `${pulseAnimation} 2s infinite`,
148
- }),
149
-
150
- // Both glow and pulse
151
- ...(glow &&
152
- pulse && {
153
- filter: `drop-shadow(0 0 8px ${alpha(colorPalette.main, 0.6)})`,
154
- animation: `${pulseAnimation} 2s infinite`,
155
- }),
60
+ ...circularEmphasisStyles(colorPalette, glow, pulse),
156
61
  };
157
62
  });
158
63
 
@@ -198,135 +103,202 @@ const SegmentedProgress: React.FC<{
198
103
  );
199
104
  };
200
105
 
201
- export const Progress = React.forwardRef<HTMLDivElement, ProgressProps>(
106
+ interface ViewProps {
107
+ size: ProgressSize;
108
+ color: string;
109
+ glow: boolean;
110
+ pulse: boolean;
111
+ showLabel: boolean;
112
+ displayValue: number;
113
+ displayLabel: string;
114
+ /** Absent means indeterminate — the bar animates rather than reporting progress. */
115
+ value?: number;
116
+ dataTestId: string;
117
+ }
118
+
119
+ const ProgressLabel: React.FC<{ size: ProgressSize; label: string; testId: string }> = ({
120
+ size,
121
+ label,
122
+ testId,
123
+ }) => (
124
+ <Typography
125
+ variant="caption"
126
+ sx={{
127
+ display: 'block',
128
+ textAlign: 'center',
129
+ mt: 1,
130
+ fontSize: getSizeStyles(size).fontSize,
131
+ fontWeight: 600,
132
+ }}
133
+ data-testid={testId}
134
+ >
135
+ {label}
136
+ </Typography>
137
+ );
138
+
139
+ const CircularView = React.forwardRef<
140
+ HTMLDivElement,
141
+ ViewProps & { thickness: number; circularSize?: number }
142
+ >(
202
143
  (
203
144
  {
204
- variant = 'linear',
205
- size = 'md',
206
- color = 'primary',
207
- glow = false,
208
- pulse = false,
209
- showLabel = false,
210
- label,
211
- segments = 10,
212
- thickness = 4,
213
- circularSize,
145
+ size,
146
+ color,
147
+ glow,
148
+ pulse,
149
+ showLabel,
150
+ displayValue,
151
+ displayLabel,
214
152
  value,
215
- dataTestId = 'progress',
153
+ dataTestId,
154
+ thickness,
155
+ circularSize,
216
156
  ...props
217
157
  },
218
158
  ref,
219
159
  ) => {
220
160
  const sizeStyles = getSizeStyles(size);
221
- const finalCircularSize = circularSize || sizeStyles.circularSize;
222
-
223
- const displayValue = value || 0;
224
- const displayLabel = label || (showLabel ? `${Math.round(displayValue)}%` : '');
225
-
226
- if (variant === 'circular') {
227
- return (
228
- <Box ref={ref} sx={{ position: 'relative', display: 'inline-flex' }} data-testid={dataTestId}>
229
- <StyledCircularProgress
230
- variant={value !== undefined ? 'determinate' : 'indeterminate'}
231
- value={displayValue}
232
- size={finalCircularSize}
233
- thickness={thickness}
234
- customColor={color}
235
- glow={glow}
236
- pulse={pulse}
237
- data-testid={`${dataTestId}-circular`}
238
- {...props}
239
- />
240
- {showLabel && value !== undefined && (
241
- <Box
242
- sx={{
243
- top: 0,
244
- left: 0,
245
- bottom: 0,
246
- right: 0,
247
- position: 'absolute',
248
- display: 'flex',
249
- alignItems: 'center',
250
- justifyContent: 'center',
251
- }}
252
- >
253
- <Typography
254
- variant="caption"
255
- component="div"
256
- color="text.secondary"
257
- sx={{ fontSize: sizeStyles.fontSize, fontWeight: 600 }}
258
- data-testid={`${dataTestId}-label`}
259
- >
260
- {displayLabel}
261
- </Typography>
262
- </Box>
263
- )}
264
- </Box>
265
- );
266
- }
267
-
268
- if (variant === 'segmented') {
269
- return (
270
- <Box ref={ref} sx={{ width: '100%' }} data-testid={dataTestId} {...props}>
271
- <SegmentedProgress
272
- value={displayValue}
273
- segments={segments}
274
- color={color}
275
- size={size}
276
- glow={glow}
277
- pulse={pulse}
278
- dataTestId={dataTestId}
279
- />
280
- {showLabel && (
281
- <Typography
282
- variant="caption"
283
- sx={{
284
- display: 'block',
285
- textAlign: 'center',
286
- mt: 1,
287
- fontSize: sizeStyles.fontSize,
288
- fontWeight: 600,
289
- }}
290
- data-testid={`${dataTestId}-label`}
291
- >
292
- {displayLabel}
293
- </Typography>
294
- )}
295
- </Box>
296
- );
297
- }
298
161
 
299
162
  return (
300
- <Box ref={ref} sx={{ width: '100%' }} data-testid={dataTestId}>
301
- <StyledLinearProgress
163
+ <Box ref={ref} sx={{ position: 'relative', display: 'inline-flex' }} data-testid={dataTestId}>
164
+ <StyledCircularProgress
302
165
  variant={value !== undefined ? 'determinate' : 'indeterminate'}
303
166
  value={displayValue}
304
- customVariant={variant}
305
- customSize={size}
167
+ size={circularSize || sizeStyles.circularSize}
168
+ thickness={thickness}
306
169
  customColor={color}
307
170
  glow={glow}
308
171
  pulse={pulse}
309
- data-testid={`${dataTestId}-linear`}
172
+ data-testid={`${dataTestId}-circular`}
310
173
  {...props}
311
174
  />
312
- {showLabel && (
313
- <Typography
314
- variant="caption"
175
+ {showLabel && value !== undefined && (
176
+ <Box
315
177
  sx={{
316
- display: 'block',
317
- textAlign: 'center',
318
- mt: 1,
319
- fontSize: sizeStyles.fontSize,
320
- fontWeight: 600,
178
+ top: 0,
179
+ left: 0,
180
+ bottom: 0,
181
+ right: 0,
182
+ position: 'absolute',
183
+ display: 'flex',
184
+ alignItems: 'center',
185
+ justifyContent: 'center',
321
186
  }}
322
- data-testid={`${dataTestId}-label`}
323
187
  >
324
- {displayLabel}
325
- </Typography>
188
+ <Typography
189
+ variant="caption"
190
+ component="div"
191
+ color="text.secondary"
192
+ sx={{ fontSize: sizeStyles.fontSize, fontWeight: 600 }}
193
+ data-testid={`${dataTestId}-label`}
194
+ >
195
+ {displayLabel}
196
+ </Typography>
197
+ </Box>
326
198
  )}
327
199
  </Box>
328
200
  );
329
201
  },
330
202
  );
331
203
 
204
+ CircularView.displayName = 'ProgressCircularView';
205
+
206
+ const SegmentedView = React.forwardRef<HTMLDivElement, ViewProps & { segments: number }>(
207
+ (
208
+ { size, color, glow, pulse, showLabel, displayValue, displayLabel, dataTestId, segments, value: _value, ...props },
209
+ ref,
210
+ ) => (
211
+ <Box ref={ref} sx={{ width: '100%' }} data-testid={dataTestId} {...props}>
212
+ <SegmentedProgress
213
+ value={displayValue}
214
+ segments={segments}
215
+ color={color}
216
+ size={size}
217
+ glow={glow}
218
+ pulse={pulse}
219
+ dataTestId={dataTestId}
220
+ />
221
+ {showLabel && (
222
+ <ProgressLabel size={size} label={displayLabel} testId={`${dataTestId}-label`} />
223
+ )}
224
+ </Box>
225
+ ),
226
+ );
227
+
228
+ SegmentedView.displayName = 'ProgressSegmentedView';
229
+
230
+ const LinearView = React.forwardRef<HTMLDivElement, ViewProps & { variant: ProgressVariant }>(
231
+ (
232
+ { size, color, glow, pulse, showLabel, displayValue, displayLabel, value, dataTestId, variant, ...props },
233
+ ref,
234
+ ) => (
235
+ <Box ref={ref} sx={{ width: '100%' }} data-testid={dataTestId}>
236
+ <StyledLinearProgress
237
+ variant={value !== undefined ? 'determinate' : 'indeterminate'}
238
+ value={displayValue}
239
+ customVariant={variant}
240
+ customSize={size}
241
+ customColor={color}
242
+ glow={glow}
243
+ pulse={pulse}
244
+ data-testid={`${dataTestId}-linear`}
245
+ {...props}
246
+ />
247
+ {showLabel && (
248
+ <ProgressLabel size={size} label={displayLabel} testId={`${dataTestId}-label`} />
249
+ )}
250
+ </Box>
251
+ ),
252
+ );
253
+
254
+ LinearView.displayName = 'ProgressLinearView';
255
+
256
+ export const Progress = React.forwardRef<HTMLDivElement, ProgressProps>(
257
+ (rawProps, ref) => {
258
+ const {
259
+ variant,
260
+ size,
261
+ color,
262
+ glow,
263
+ pulse,
264
+ showLabel,
265
+ label,
266
+ segments,
267
+ thickness,
268
+ circularSize,
269
+ value,
270
+ dataTestId,
271
+ // LinearProgressProps carries a `ref` typed for its own element; the
272
+ // forwarded one below is the ref that matters.
273
+ ref: _ref,
274
+ ...props
275
+ } = resolveProgressProps(rawProps);
276
+ const displayValue = value || 0;
277
+ const shared = {
278
+ size,
279
+ color,
280
+ glow,
281
+ pulse,
282
+ showLabel,
283
+ displayValue,
284
+ displayLabel: label || (showLabel ? `${Math.round(displayValue)}%` : ''),
285
+ value,
286
+ dataTestId,
287
+ ...props,
288
+ };
289
+
290
+ if (variant === 'circular') {
291
+ return (
292
+ <CircularView ref={ref} {...shared} thickness={thickness} circularSize={circularSize} />
293
+ );
294
+ }
295
+
296
+ if (variant === 'segmented') {
297
+ return <SegmentedView ref={ref} {...shared} segments={segments} />;
298
+ }
299
+
300
+ return <LinearView ref={ref} {...shared} variant={variant} />;
301
+ },
302
+ );
303
+
332
304
  Progress.displayName = 'Progress';
@@ -1,4 +1,4 @@
1
- import { CreditCard } from '@mui/icons-material';
1
+ import CreditCard from '@mui/icons-material/CreditCard';
2
2
  import { Box, Chip, SvgIcon, TextField, Typography } from '@mui/material';
3
3
  import type { Meta, StoryObj } from '@storybook/react-vite';
4
4
  import { fn } from 'storybook/test';
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
 
3
- import { CheckCircle } from '@mui/icons-material';
3
+ import CheckCircle from '@mui/icons-material/CheckCircle';
4
4
  import { Box, Button, Collapse, Stack, Typography, useTheme } from '@mui/material';
5
5
  import React from 'react';
6
6
 
@@ -0,0 +1,117 @@
1
+ # StatCard
2
+
3
+ A KPI tile: one labelled figure, an optional period-over-period delta, an
4
+ optional leading icon, an optional hint line, and a loading state. It is the
5
+ single shared tile for dashboard KPI rows and summary bands, so surfaces stop
6
+ hand-rolling the label/value pattern.
7
+
8
+ ## Features
9
+
10
+ - **Pre-formatted values**: the tile never formats money, percentages or
11
+ locale — `value` and `delta.value` arrive as strings the caller already
12
+ shaped, so currency/locale rules stay with the data owner.
13
+ - **Direction separate from meaning**: `delta.direction` picks the arrow;
14
+ `delta.tone` picks the colour. A rising cost can render an up arrow and still
15
+ read as negative.
16
+ - **Semantic colour only**: `success.main` / `error.main` / `text.secondary`
17
+ from the MUI palette — no hardcoded hex, so themes and dark mode work.
18
+ - **Accessible**: the tile is a `role="group"` labelled by its own label; the
19
+ arrow is `aria-hidden` and the delta carries a direction-aware sentence that
20
+ callers can localize.
21
+ - **Loading state**: skeletons replace value and delta while the label stays put,
22
+ so a KPI grid does not reflow when data lands.
23
+
24
+ ## Props
25
+
26
+ | Prop | Type | Default | Description |
27
+ | ------------- | ----------------------- | ------- | --------------------------------------------------------------- |
28
+ | `label` | `string` | — | What the figure measures, e.g. `"Receita"`. |
29
+ | `value` | `ReactNode` | — | The figure, already formatted. |
30
+ | `delta` | `StatCardDelta` | — | Optional period-over-period change (see below). |
31
+ | `icon` | `ReactNode` | — | Optional leading icon beside the label (decorative). |
32
+ | `hint` | `string` | — | Optional clarifying line under the value, e.g. the range. |
33
+ | `loading` | `boolean` | `false` | Swaps value/delta for skeletons and marks the tile `aria-busy`. |
34
+ | `className` | `string` | — | Custom class on the tile root. |
35
+ | `dataTestId` | `string` | `'stat-card'` | Root test id; child ids derive from it. |
36
+
37
+ ### `StatCardDelta`
38
+
39
+ | Field | Type | Default | Description |
40
+ | ----------- | --------------------------------- | ------------------ | ----------------------------------------------------------------- |
41
+ | `value` | `string` | — | The pre-formatted change, e.g. `"+12,5%"`. |
42
+ | `direction` | `'up' \| 'down' \| 'neutral'` | — | Which way the metric moved (picks the arrow). |
43
+ | `tone` | `'positive' \| 'negative' \| 'neutral'` | derived from `direction` | How the movement should read (picks the colour). |
44
+ | `label` | `string` | — | Comparison context, e.g. `"vs. período anterior"`. |
45
+ | `ariaLabel` | `string` | generated (English) | Overrides the screen-reader sentence — pass a localized string. |
46
+
47
+ ## Usage
48
+
49
+ ### Basic
50
+
51
+ ```tsx
52
+ import { StatCard } from '@12-apps/ui/data-display/StatCard';
53
+
54
+ <StatCard label="Receita" value="R$ 12.480,00" />;
55
+ ```
56
+
57
+ ### With a period-over-period delta
58
+
59
+ ```tsx
60
+ <StatCard
61
+ label="Receita"
62
+ value="R$ 12.480,00"
63
+ delta={{ value: '+12,5%', direction: 'up', label: 'vs. período anterior' }}
64
+ />
65
+ ```
66
+
67
+ ### "Lower is better" metrics
68
+
69
+ Cost going up is not good news. Keep the honest arrow and override the tone:
70
+
71
+ ```tsx
72
+ <StatCard
73
+ label="Custo (CMV)"
74
+ value="R$ 4.900,00"
75
+ delta={{ value: '+9,4%', direction: 'up', tone: 'negative' }}
76
+ />
77
+ ```
78
+
79
+ ### Loading
80
+
81
+ ```tsx
82
+ <StatCard label="Receita" value={revenueLabel} delta={revenueDelta} loading={isPending} />
83
+ ```
84
+
85
+ ### A KPI row
86
+
87
+ ```tsx
88
+ <Box sx={{ display: 'grid', gap: 2, gridTemplateColumns: 'repeat(4, 1fr)' }}>
89
+ <StatCard label="Receita" value={revenue} dataTestId="kpi-revenue" />
90
+ <StatCard label="Custo (CMV)" value={cogs} dataTestId="kpi-cogs" />
91
+ <StatCard label="Lucro bruto" value={profit} dataTestId="kpi-profit" />
92
+ <StatCard label="Pedidos" value={orders} dataTestId="kpi-orders" />
93
+ </Box>
94
+ ```
95
+
96
+ ## Accessibility
97
+
98
+ - The root is a `role="group"` with `aria-labelledby` pointing at the label, so
99
+ assistive tech announces the tile as "Receita, group" rather than reading two
100
+ unrelated strings.
101
+ - The direction arrow is `aria-hidden` — it duplicates information the delta's
102
+ `aria-label` already carries, and would otherwise be announced twice.
103
+ - The delta's generated sentence ("Increase of +12,5% vs. período anterior") is
104
+ English. Non-English apps pass `delta.ariaLabel` to localize it.
105
+ - While `loading`, the tile sets `aria-busy="true"` and keeps its label, so the
106
+ metric is still identifiable before the number lands.
107
+
108
+ ## Best Practices
109
+
110
+ - Format on the way in. If two tiles disagree about decimal places, that belongs
111
+ to the caller's formatter, not to the tile.
112
+ - Set `tone` explicitly for any metric where lower is better (cost, refunds,
113
+ churn) — the default reading assumes higher is better.
114
+ - Give each tile in a grid its own `dataTestId` so tests target a specific KPI
115
+ instead of an index.
116
+ - Use `hint` for the measured window ("Últimos 30 dias"), not for the delta's
117
+ comparison text — that belongs in `delta.label`.