@titan-design/react-ui 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (307) hide show
  1. package/dist/bodymap.js +241 -189
  2. package/dist/bodymap.js.map +1 -1
  3. package/dist/bodymap.mjs +241 -189
  4. package/dist/bodymap.mjs.map +1 -1
  5. package/dist/index.d.mts +1017 -130
  6. package/dist/index.d.ts +1017 -130
  7. package/dist/index.js +3058 -1090
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.mjs +2992 -1091
  10. package/dist/index.mjs.map +1 -1
  11. package/dist/{pages-MO0JCySL.d.mts → pages-8u_4WbL-.d.mts} +280 -57
  12. package/dist/{pages-D7Jlssvp.d.ts → pages-DaWiBOGa.d.ts} +280 -57
  13. package/dist/pages.d.mts +1 -1
  14. package/dist/pages.d.ts +1 -1
  15. package/dist/pages.js +1797 -1292
  16. package/dist/pages.js.map +1 -1
  17. package/dist/pages.mjs +1797 -1292
  18. package/dist/pages.mjs.map +1 -1
  19. package/dist/theme/index.d.mts +464 -268
  20. package/dist/theme/index.d.ts +464 -268
  21. package/dist/theme/index.js +303 -191
  22. package/dist/theme/index.js.map +1 -1
  23. package/dist/theme/index.mjs +295 -192
  24. package/dist/theme/index.mjs.map +1 -1
  25. package/dist/theme/tokens-css.js +160 -143
  26. package/dist/theme/tokens-css.js.map +1 -1
  27. package/dist/theme/tokens-css.mjs +160 -143
  28. package/dist/theme/tokens-css.mjs.map +1 -1
  29. package/package.json +3 -1
  30. package/src/arch/Architecture.stories.tsx +870 -0
  31. package/src/arch/annotations.json +48 -0
  32. package/src/arch/arch-graph.json +4301 -0
  33. package/src/components/custom/DateTime/DateTime.stories.tsx +83 -7
  34. package/src/components/custom/DateTime/DateTime.test.tsx +29 -3
  35. package/src/components/custom/DateTime/DateTime.tsx +55 -15
  36. package/src/components/custom/EmptyState/EmptyState.stories.tsx +1 -1
  37. package/src/components/custom/Gauge/Gauge.stories.tsx +1 -1
  38. package/src/components/custom/Gauge/Gauge.test.tsx +2 -2
  39. package/src/components/custom/Gauge/Gauge.tsx +6 -3
  40. package/src/components/custom/Metric/Metric.stories.tsx +1 -1
  41. package/src/components/custom/Scatter/Scatter.stories.tsx +1 -1
  42. package/src/components/custom/Scatter/Scatter.tsx +3 -5
  43. package/src/components/custom/Sidebar/Sidebar.stories.tsx +1 -1
  44. package/src/components/custom/Table/Table.stories.tsx +1 -1
  45. package/src/components/custom/TimerReadout/TimerReadout.stories.tsx +62 -0
  46. package/src/components/custom/TimerReadout/TimerReadout.test.tsx +72 -0
  47. package/src/components/custom/TimerReadout/TimerReadout.tsx +75 -0
  48. package/src/components/custom/TimerReadout/index.ts +1 -0
  49. package/src/components/custom/Treemap/Treemap.stories.tsx +1 -1
  50. package/src/components/custom/Treemap/Treemap.tsx +3 -5
  51. package/src/components/custom/Typography/Typography.stories.tsx +46 -28
  52. package/src/components/custom/Typography/Typography.test.tsx +13 -3
  53. package/src/components/custom/Typography/Typography.tsx +5 -0
  54. package/src/components/custom/Workout/ActiveWorkoutPage.stories.tsx +21 -13
  55. package/src/components/custom/Workout/ActiveWorkoutPage.test.tsx +16 -13
  56. package/src/components/custom/Workout/ActiveWorkoutPage.tsx +11 -16
  57. package/src/components/custom/Workout/BaseBadge.stories.tsx +1 -1
  58. package/src/components/custom/Workout/BodyMap.stories.tsx +1 -1
  59. package/src/components/custom/Workout/BodyMap.tsx +6 -3
  60. package/src/components/custom/Workout/BodyMapDetailPanel.stories.tsx +1 -1
  61. package/src/components/custom/Workout/BodyMapDetailPanel.tsx +6 -3
  62. package/src/components/custom/Workout/CapacityBandChart.stories.tsx +1 -1
  63. package/src/components/custom/Workout/CapacityBandChart.test.tsx +2 -2
  64. package/src/components/custom/Workout/CapacityBandChart.tsx +9 -6
  65. package/src/components/custom/Workout/DeviationBar.stories.tsx +1 -1
  66. package/src/components/custom/Workout/DeviationBar.test.tsx +1 -1
  67. package/src/components/custom/Workout/DeviationBar.tsx +7 -4
  68. package/src/components/custom/Workout/ExerciseCard.stories.tsx +51 -66
  69. package/src/components/custom/Workout/ExerciseCard.test.tsx +146 -143
  70. package/src/components/custom/Workout/ExerciseCard.tsx +176 -198
  71. package/src/components/custom/Workout/ExerciseCardHeading.stories.tsx +99 -0
  72. package/src/components/custom/Workout/ExerciseCardHeading.test.tsx +72 -0
  73. package/src/components/custom/Workout/ExerciseCardHeading.tsx +43 -0
  74. package/src/components/custom/Workout/ExerciseCardUnified.stories.tsx +151 -0
  75. package/src/components/custom/Workout/ExerciseDetailPage.stories.tsx +5 -3
  76. package/src/components/custom/Workout/ExerciseDetailPage.test.tsx +4 -4
  77. package/src/components/custom/Workout/ExerciseDetailPage.tsx +6 -6
  78. package/src/components/custom/Workout/ExerciseHeading.stories.tsx +81 -0
  79. package/src/components/custom/Workout/ExerciseHeading.test.tsx +77 -0
  80. package/src/components/custom/Workout/ExerciseHeading.tsx +85 -0
  81. package/src/components/custom/Workout/ExerciseIndicator.stories.tsx +110 -0
  82. package/src/components/custom/Workout/ExerciseIndicator.test.tsx +93 -0
  83. package/src/components/custom/Workout/ExerciseIndicator.tsx +120 -0
  84. package/src/components/custom/Workout/FatigueMeter.stories.tsx +51 -0
  85. package/src/components/custom/Workout/FatigueMeter.test.tsx +73 -0
  86. package/src/components/custom/Workout/FatigueMeter.tsx +82 -0
  87. package/src/components/custom/Workout/InputBar.stories.tsx +1 -1
  88. package/src/components/custom/Workout/InputBar.tsx +2 -1
  89. package/src/components/custom/Workout/IntensityBar.stories.tsx +1 -1
  90. package/src/components/custom/Workout/IntensityBar.test.tsx +8 -8
  91. package/src/components/custom/Workout/IntensityBar.tsx +10 -6
  92. package/src/components/custom/Workout/LiveAuraFrame.stories.tsx +153 -0
  93. package/src/components/custom/Workout/LiveAuraFrame.test.tsx +74 -0
  94. package/src/components/custom/Workout/LiveAuraFrame.tsx +105 -0
  95. package/src/components/custom/Workout/MesoCard.stories.tsx +1 -1
  96. package/src/components/custom/Workout/MesoCard.tsx +8 -3
  97. package/src/components/custom/Workout/MesoProgressBar.stories.tsx +1 -1
  98. package/src/components/custom/Workout/MesoProgressBar.test.tsx +1 -1
  99. package/src/components/custom/Workout/MesoProgressBar.tsx +3 -2
  100. package/src/components/custom/Workout/MesoStatusCard.stories.tsx +1 -1
  101. package/src/components/custom/Workout/MesoStatusCard.tsx +20 -13
  102. package/src/components/custom/Workout/MetricTiles.stories.tsx +60 -0
  103. package/src/components/custom/Workout/MetricTiles.test.tsx +58 -0
  104. package/src/components/custom/Workout/MetricTiles.tsx +48 -0
  105. package/src/components/custom/Workout/MuscleGroupChip.stories.tsx +1 -1
  106. package/src/components/custom/Workout/MuscleGroupChip.tsx +7 -4
  107. package/src/components/custom/Workout/PlaceholderStrip.stories.tsx +1 -1
  108. package/src/components/custom/Workout/PrBadge.stories.tsx +1 -1
  109. package/src/components/custom/Workout/PrBadge.tsx +5 -2
  110. package/src/components/custom/Workout/PrHistoryModal.stories.tsx +1 -1
  111. package/src/components/custom/Workout/PrHistoryModal.tsx +4 -3
  112. package/src/components/custom/Workout/ProgramPlanningPage.stories.tsx +4 -16
  113. package/src/components/custom/Workout/ProgramPlanningPage.tsx +10 -7
  114. package/src/components/custom/Workout/README.md +146 -4
  115. package/src/components/custom/Workout/ReadinessCheck.stories.tsx +1 -1
  116. package/src/components/custom/Workout/ReadinessCheck.tsx +7 -4
  117. package/src/components/custom/Workout/RestTimer.stories.tsx +1 -1
  118. package/src/components/custom/Workout/RestTimer.tsx +17 -11
  119. package/src/components/custom/Workout/RowInventory.stories.tsx +405 -0
  120. package/src/components/custom/Workout/S3FullRail.stories.tsx +34 -0
  121. package/src/components/custom/Workout/S3SessionPace.stories.tsx +95 -0
  122. package/src/components/custom/Workout/S3SessionRailHeading.stories.tsx +61 -0
  123. package/src/components/custom/Workout/S3SetTypes.stories.tsx +176 -0
  124. package/src/components/custom/Workout/S3WorkoutExpansion.stories.tsx +240 -0
  125. package/src/components/custom/Workout/ScheduleTiles.stories.tsx +40 -0
  126. package/src/components/custom/Workout/ScheduleTiles.test.tsx +34 -0
  127. package/src/components/custom/Workout/ScheduleTiles.tsx +70 -0
  128. package/src/components/custom/Workout/SegmentedBar.stories.tsx +99 -0
  129. package/src/components/custom/Workout/SegmentedBar.test.tsx +77 -0
  130. package/src/components/custom/Workout/SegmentedBar.tsx +172 -0
  131. package/src/components/custom/Workout/SegmentedProgressBar.stories.tsx +50 -0
  132. package/src/components/custom/Workout/SegmentedProgressBar.test.tsx +80 -0
  133. package/src/components/custom/Workout/SegmentedProgressBar.tsx +67 -0
  134. package/src/components/custom/Workout/SessionHeader.stories.tsx +121 -0
  135. package/src/components/custom/Workout/SessionHeader.test.tsx +122 -0
  136. package/src/components/custom/Workout/SessionHeader.tsx +152 -0
  137. package/src/components/custom/Workout/SessionRail.stories.tsx +153 -0
  138. package/src/components/custom/Workout/SessionRail.test.tsx +86 -0
  139. package/src/components/custom/Workout/SessionRail.tsx +126 -0
  140. package/src/components/custom/Workout/SetBar.stories.tsx +124 -0
  141. package/src/components/custom/Workout/SetBar.test.tsx +123 -0
  142. package/src/components/custom/Workout/SetBar.tsx +171 -0
  143. package/src/components/custom/Workout/SetRow.stories.tsx +50 -100
  144. package/src/components/custom/Workout/SetRow.test.tsx +94 -166
  145. package/src/components/custom/Workout/SetRow.tsx +170 -232
  146. package/src/components/custom/Workout/SetStrip.stories.tsx +154 -0
  147. package/src/components/custom/Workout/SetStrip.test.tsx +109 -0
  148. package/src/components/custom/Workout/SetStrip.tsx +71 -0
  149. package/src/components/custom/Workout/SetTableHeader.stories.tsx +66 -0
  150. package/src/components/custom/Workout/SetTableHeader.test.tsx +47 -0
  151. package/src/components/custom/Workout/SetTableHeader.tsx +88 -0
  152. package/src/components/custom/Workout/SetsRepsLoad.stories.tsx +47 -0
  153. package/src/components/custom/Workout/SetsRepsLoad.test.tsx +44 -0
  154. package/src/components/custom/Workout/SetsRepsLoad.tsx +52 -0
  155. package/src/components/custom/Workout/Sparkline.stories.tsx +1 -1
  156. package/src/components/custom/Workout/Sparkline.tsx +2 -1
  157. package/src/components/custom/Workout/StatusDot.stories.tsx +1 -1
  158. package/src/components/custom/Workout/StatusDot.test.tsx +2 -2
  159. package/src/components/custom/Workout/StatusDot.tsx +12 -9
  160. package/src/components/custom/Workout/StatusPill.stories.tsx +59 -0
  161. package/src/components/custom/Workout/StatusPill.test.tsx +63 -0
  162. package/src/components/custom/Workout/StatusPill.tsx +88 -0
  163. package/src/components/custom/Workout/StrengthTrendChart.stories.tsx +1 -1
  164. package/src/components/custom/Workout/StrengthTrendChart.tsx +9 -6
  165. package/src/components/custom/Workout/SupersetWrapper.stories.tsx +1 -1
  166. package/src/components/custom/Workout/SupersetWrapper.tsx +2 -1
  167. package/src/components/custom/Workout/TempoBar.stories.tsx +1 -1
  168. package/src/components/custom/Workout/TempoDisplay.stories.tsx +12 -1
  169. package/src/components/custom/Workout/TempoDisplay.tsx +29 -36
  170. package/src/components/custom/Workout/TrainingStatusPage.stories.tsx +1 -1
  171. package/src/components/custom/Workout/VelocityStrip.modalities.stories.tsx +254 -0
  172. package/src/components/custom/Workout/VelocityStrip.responsive.stories.tsx +145 -0
  173. package/src/components/custom/Workout/VelocityStrip.stories.tsx +129 -66
  174. package/src/components/custom/Workout/VelocityStrip.test.tsx +379 -144
  175. package/src/components/custom/Workout/VelocityStrip.tsx +508 -120
  176. package/src/components/custom/Workout/VolumeLandmarkBar.stories.tsx +73 -0
  177. package/src/components/custom/Workout/VolumeLandmarkBar.test.tsx +119 -0
  178. package/src/components/custom/Workout/VolumeLandmarkBar.tsx +154 -0
  179. package/src/components/custom/Workout/WeekRow.stories.tsx +1 -1
  180. package/src/components/custom/Workout/WeekRow.tsx +3 -2
  181. package/src/components/custom/Workout/WeightBadge.stories.tsx +1 -1
  182. package/src/components/custom/Workout/WeightBadge.tsx +6 -2
  183. package/src/components/custom/Workout/WorkoutCard.stories.tsx +2 -6
  184. package/src/components/custom/Workout/WorkoutCard.test.tsx +13 -46
  185. package/src/components/custom/Workout/WorkoutCard.tsx +5 -2
  186. package/src/components/custom/Workout/WorkoutPill.stories.tsx +1 -1
  187. package/src/components/custom/Workout/WorkoutPill.tsx +12 -8
  188. package/src/components/custom/Workout/ZoneTrack.stories.tsx +140 -0
  189. package/src/components/custom/Workout/ZoneTrack.test.tsx +200 -0
  190. package/src/components/custom/Workout/ZoneTrack.tsx +315 -0
  191. package/src/components/custom/Workout/icons.tsx +6 -67
  192. package/src/components/custom/Workout/index.ts +55 -2
  193. package/src/components/custom/Workout/metricText.stories.tsx +69 -0
  194. package/src/components/custom/Workout/metricText.tsx +34 -0
  195. package/src/components/custom/Workout/paceTone.test.ts +29 -0
  196. package/src/components/custom/Workout/paceTone.ts +27 -0
  197. package/src/components/custom/Workout/setHeadingKit.tsx +177 -0
  198. package/src/components/custom/index.ts +1 -0
  199. package/src/components/custom/stepper/Stepper.stories.tsx +1 -1
  200. package/src/components/icons/SvgIcon.tsx +50 -0
  201. package/src/components/icons/icons.stories.tsx +122 -0
  202. package/src/components/icons/icons.test.tsx +73 -0
  203. package/src/components/icons/icons.tsx +153 -0
  204. package/src/components/icons/index.ts +4 -0
  205. package/src/components/index.ts +6 -0
  206. package/src/components/shell/BrandLockup.stories.tsx +27 -0
  207. package/src/components/shell/BrandLockup.test.tsx +23 -0
  208. package/src/components/shell/BrandLockup.tsx +47 -0
  209. package/src/components/shell/DashboardShell.stories.tsx +65 -0
  210. package/src/components/shell/DashboardShell.test.tsx +42 -0
  211. package/src/components/shell/DashboardShell.tsx +74 -0
  212. package/src/components/shell/DeviceIndicator.stories.tsx +28 -0
  213. package/src/components/shell/DeviceIndicator.test.tsx +26 -0
  214. package/src/components/shell/DeviceIndicator.tsx +52 -0
  215. package/src/components/shell/DeviceMenu.stories.tsx +47 -0
  216. package/src/components/shell/DeviceMenu.test.tsx +40 -0
  217. package/src/components/shell/DeviceMenu.tsx +65 -0
  218. package/src/components/shell/DeviceRow.stories.tsx +38 -0
  219. package/src/components/shell/DeviceRow.test.tsx +37 -0
  220. package/src/components/shell/DeviceRow.tsx +58 -0
  221. package/src/components/shell/NavItem.stories.tsx +52 -0
  222. package/src/components/shell/NavItem.test.tsx +35 -0
  223. package/src/components/shell/NavItem.tsx +75 -0
  224. package/src/components/shell/README.md +116 -0
  225. package/src/components/shell/SessionRailSpecimen.stories.tsx +753 -0
  226. package/src/components/shell/SessionStatePill.stories.tsx +27 -0
  227. package/src/components/shell/SessionStatePill.test.tsx +25 -0
  228. package/src/components/shell/SessionStatePill.tsx +46 -0
  229. package/src/components/shell/SideNav.stories.tsx +81 -0
  230. package/src/components/shell/SideNav.test.tsx +51 -0
  231. package/src/components/shell/SideNav.tsx +74 -0
  232. package/src/components/shell/TopBar.stories.tsx +49 -0
  233. package/src/components/shell/TopBar.test.tsx +36 -0
  234. package/src/components/shell/TopBar.tsx +89 -0
  235. package/src/components/shell/index.ts +13 -0
  236. package/src/components/ui/alert/Alert.stories.tsx +1 -1
  237. package/src/components/ui/autocomplete/Autocomplete.stories.tsx +1 -1
  238. package/src/components/ui/avatar/Avatar.stories.tsx +1 -1
  239. package/src/components/ui/badge/Badge.stories.tsx +1 -1
  240. package/src/components/ui/breadcrumbs/Breadcrumbs.stories.tsx +1 -1
  241. package/src/components/ui/button/Button.stories.tsx +1 -1
  242. package/src/components/ui/card/Card.stories.tsx +1 -1
  243. package/src/components/ui/checkbox/Checkbox.stories.tsx +1 -1
  244. package/src/components/ui/chip/Chip.stories.tsx +1 -1
  245. package/src/components/ui/collapse/Collapse.stories.tsx +1 -1
  246. package/src/components/ui/data-row/DataRow.stories.tsx +1 -1
  247. package/src/components/ui/divider/Divider.stories.tsx +1 -1
  248. package/src/components/ui/drawer/Drawer.stories.tsx +1 -1
  249. package/src/components/ui/form-field/FormField.stories.tsx +1 -1
  250. package/src/components/ui/help-tip/HelpTip.stories.tsx +1 -1
  251. package/src/components/ui/icon-box/IconBox.stories.tsx +1 -1
  252. package/src/components/ui/index.ts +1 -0
  253. package/src/components/ui/indicator/Indicator.stories.tsx +38 -2
  254. package/src/components/ui/indicator/Indicator.test.tsx +20 -1
  255. package/src/components/ui/indicator/Indicator.tsx +50 -6
  256. package/src/components/ui/indicator/index.ts +1 -1
  257. package/src/components/ui/input/Input.stories.tsx +1 -1
  258. package/src/components/ui/link/Link.stories.tsx +1 -1
  259. package/src/components/ui/list-item/ListItem.stories.tsx +1 -1
  260. package/src/components/ui/menu/Menu.stories.tsx +1 -1
  261. package/src/components/ui/modal/Modal.stories.tsx +1 -1
  262. package/src/components/ui/pill/Pill.stories.tsx +1 -1
  263. package/src/components/ui/popover/Popover.stories.tsx +1 -1
  264. package/src/components/ui/progress/Progress.stories.tsx +1 -1
  265. package/src/components/ui/radio/Radio.stories.tsx +1 -1
  266. package/src/components/ui/section/Section.stories.tsx +1 -1
  267. package/src/components/ui/select/Select.stories.tsx +1 -1
  268. package/src/components/ui/skeleton/Skeleton.stories.tsx +1 -1
  269. package/src/components/ui/spinner/Spinner.stories.tsx +1 -1
  270. package/src/components/ui/spinner/Spinner.tsx +3 -2
  271. package/src/components/ui/stack/Stack.stories.tsx +1 -1
  272. package/src/components/ui/surface/Surface.stories.tsx +1 -1
  273. package/src/components/ui/switch/Switch.stories.tsx +1 -1
  274. package/src/components/ui/tabs/Tabs.stories.tsx +1 -1
  275. package/src/components/ui/tile/Tile.stories.tsx +79 -0
  276. package/src/components/ui/tile/Tile.test.tsx +48 -0
  277. package/src/components/ui/tile/Tile.tsx +64 -0
  278. package/src/components/ui/tile/index.ts +2 -0
  279. package/src/components/ui/toast/Toast.stories.tsx +1 -1
  280. package/src/components/ui/toolbar-button/ToolbarButton.stories.tsx +1 -1
  281. package/src/components/ui/toolbar-button/ToolbarButton.tsx +2 -1
  282. package/src/components/ui/tooltip/Tooltip.stories.tsx +1 -1
  283. package/src/examples/react-hook-form/ReactHookForm.stories.tsx +1 -1
  284. package/src/hooks/index.ts +2 -0
  285. package/src/hooks/useTimer.test.ts +150 -0
  286. package/src/hooks/useTimer.ts +77 -0
  287. package/src/index.ts +3 -0
  288. package/src/pages.ts +1 -1
  289. package/src/stories/PresetShowcase.stories.tsx +1 -1
  290. package/src/stories/ThemePresets.stories.tsx +1 -1
  291. package/src/theme/ColorSystem.stories.tsx +323 -0
  292. package/src/theme/Colors.stories.tsx +74 -9
  293. package/src/theme/barrel.ts +1 -0
  294. package/src/theme/config.ts +20 -3
  295. package/src/theme/elevation.stories.tsx +1 -1
  296. package/src/theme/extracted-colors-dataviz.ts +21 -0
  297. package/src/theme/extracted-colors-ui.ts +20 -0
  298. package/src/theme/global.css +69 -53
  299. package/src/theme/gradients.test.ts +25 -0
  300. package/src/theme/gradients.ts +36 -0
  301. package/src/theme/shadows.stories.tsx +1 -1
  302. package/src/theme/tokens/primitives.test.ts +232 -0
  303. package/src/theme/tokens/primitives.ts +238 -87
  304. package/src/theme/tokens/semantic.ts +101 -81
  305. package/src/theme/workout-tokens.ts +26 -21
  306. package/src/utils/avatar-color.ts +3 -3
  307. package/tailwind.config.js +15 -3
@@ -0,0 +1,59 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite'
2
+ import { View } from 'react-native'
3
+ import { StatusPill } from './StatusPill'
4
+
5
+ const meta: Meta<typeof StatusPill> = {
6
+ title: 'Workout/StatusPill',
7
+ component: StatusPill,
8
+ tags: ['autodocs'],
9
+ parameters: {
10
+ docs: {
11
+ description: {
12
+ component:
13
+ 'Auto-regulation verdict pill — a glowing status dot plus colored verdict text in a ' +
14
+ 'tinted capsule. Composes `StatusDot`; tint, border, text, and dot all derive from the ' +
15
+ 'same semantic status token (success / warning / error).',
16
+ },
17
+ },
18
+ },
19
+ argTypes: {
20
+ status: {
21
+ control: 'select',
22
+ options: ['productive', 'threshold', 'stop'],
23
+ description: 'Auto-regulation verdict',
24
+ },
25
+ label: {
26
+ control: 'text',
27
+ description: 'Overrides the default verdict text',
28
+ },
29
+ },
30
+ }
31
+
32
+ export default meta
33
+ type Story = StoryObj<typeof StatusPill>
34
+
35
+ export const Productive: Story = {
36
+ args: { status: 'productive' },
37
+ }
38
+
39
+ export const Threshold: Story = {
40
+ args: { status: 'threshold' },
41
+ }
42
+
43
+ export const Stop: Story = {
44
+ args: { status: 'stop' },
45
+ }
46
+
47
+ export const WithCustomLabel: Story = {
48
+ args: { status: 'stop', label: 'Stop · velocity loss 31%' },
49
+ }
50
+
51
+ export const AllStates: Story = {
52
+ render: () => (
53
+ <View style={{ gap: 10, alignItems: 'flex-start' }}>
54
+ <StatusPill status="productive" label="Productive · in the band" />
55
+ <StatusPill status="threshold" label="Threshold · VL20 reached" />
56
+ <StatusPill status="stop" label="Stop · velocity loss 31%" />
57
+ </View>
58
+ ),
59
+ }
@@ -0,0 +1,63 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { render, screen } from '@testing-library/react'
3
+ import { axe } from 'jest-axe'
4
+ import { StatusPill, statusPillColor, type StatusPillStatus } from './StatusPill'
5
+ import { getSemanticColors } from '../../../theme/tokens/semantic'
6
+ import { alpha } from '../../../utils/colors'
7
+
8
+ const t = getSemanticColors('dark')
9
+
10
+ const cases: Array<{
11
+ status: StatusPillStatus
12
+ token: 'status-success' | 'status-warning' | 'status-error'
13
+ label: string
14
+ }> = [
15
+ { status: 'productive', token: 'status-success', label: 'Productive' },
16
+ { status: 'threshold', token: 'status-warning', label: 'Threshold' },
17
+ { status: 'stop', token: 'status-error', label: 'Stop' },
18
+ ]
19
+
20
+ describe('StatusPill', () => {
21
+ it('renders the pill container', () => {
22
+ render(<StatusPill status="productive" />)
23
+ expect(screen.getByTestId('status-pill')).toBeInTheDocument()
24
+ })
25
+
26
+ it('composes a status dot', () => {
27
+ render(<StatusPill status="productive" />)
28
+ expect(screen.getByTestId('status-dot')).toBeInTheDocument()
29
+ })
30
+
31
+ describe('per-status mapping', () => {
32
+ cases.forEach(({ status, token, label }) => {
33
+ it(`maps ${status} to the ${token} color and default label`, () => {
34
+ render(<StatusPill status={status} />)
35
+ const text = screen.getByTestId('status-pill-label')
36
+ expect(text).toHaveTextContent(label)
37
+ expect(text).toHaveStyle({ color: t[token] })
38
+ })
39
+
40
+ it(`tints the ${status} capsule from the ${token} token`, () => {
41
+ render(<StatusPill status={status} />)
42
+ expect(screen.getByTestId('status-pill')).toHaveStyle({
43
+ backgroundColor: alpha(t[token], 0.14),
44
+ borderTopColor: alpha(t[token], 0.4),
45
+ })
46
+ })
47
+ })
48
+ })
49
+
50
+ it('exposes the resolved color via statusPillColor', () => {
51
+ expect(statusPillColor('stop')).toBe(t['status-error'])
52
+ })
53
+
54
+ it('renders a custom label override', () => {
55
+ render(<StatusPill status="stop" label="Stop · velocity loss 31%" />)
56
+ expect(screen.getByText('Stop · velocity loss 31%')).toBeInTheDocument()
57
+ })
58
+
59
+ it('has no a11y violations', async () => {
60
+ const { container } = render(<StatusPill status="threshold" />)
61
+ expect(await axe(container)).toHaveNoViolations()
62
+ })
63
+ })
@@ -0,0 +1,88 @@
1
+ // Font mapping: font-heading=Space Grotesk, font-body=Nunito Sans (UI), font-sans=Inter (body)
2
+ import { View, Text, type ViewProps } from 'react-native'
3
+ import { getSemanticColors } from '../../../theme/tokens/semantic'
4
+ import { alpha } from '../../../utils/colors'
5
+ import { StatusDot, type StatusDotVariant } from './StatusDot'
6
+
7
+ const t = getSemanticColors('dark')
8
+
9
+ /**
10
+ * Auto-regulation verdict — the human-readable read-once summary of a set's
11
+ * velocity-loss state.
12
+ * - `productive` — in the band, keep going (success)
13
+ * - `threshold` — VL20 reached, approaching fatigue (warning)
14
+ * - `stop` — VL28+, terminate the set (error)
15
+ */
16
+ export type StatusPillStatus = 'productive' | 'threshold' | 'stop'
17
+
18
+ export interface StatusPillProps extends ViewProps {
19
+ status: StatusPillStatus
20
+ /** Overrides the default verdict text for the status. */
21
+ label?: string
22
+ className?: string
23
+ }
24
+
25
+ const statusToken: Record<StatusPillStatus, 'status-success' | 'status-warning' | 'status-error'> =
26
+ {
27
+ productive: 'status-success',
28
+ threshold: 'status-warning',
29
+ stop: 'status-error',
30
+ }
31
+
32
+ const statusDotVariant: Record<StatusPillStatus, StatusDotVariant> = {
33
+ productive: 'success',
34
+ threshold: 'warning',
35
+ stop: 'error',
36
+ }
37
+
38
+ const defaultLabel: Record<StatusPillStatus, string> = {
39
+ productive: 'Productive',
40
+ threshold: 'Threshold',
41
+ stop: 'Stop',
42
+ }
43
+
44
+ /** Resolved semantic color for a verdict status. */
45
+ export function statusPillColor(status: StatusPillStatus): string {
46
+ return t[statusToken[status]]
47
+ }
48
+
49
+ /**
50
+ * Verdict pill: a glowing status dot + colored verdict text, in a tinted,
51
+ * bordered capsule. Composes {@link StatusDot} for the dot so the glow/color
52
+ * stays consistent with the atom. Tint and border are derived from the same
53
+ * semantic token via `alpha()` — no per-status raw hex.
54
+ */
55
+ export function StatusPill({ status, label, className, style, ...props }: StatusPillProps) {
56
+ const color = statusPillColor(status)
57
+ const text = label ?? defaultLabel[status]
58
+
59
+ return (
60
+ <View
61
+ testID="status-pill"
62
+ className={className}
63
+ style={[
64
+ {
65
+ flexDirection: 'row',
66
+ alignItems: 'center',
67
+ gap: 7,
68
+ alignSelf: 'flex-start',
69
+ paddingVertical: 7,
70
+ paddingHorizontal: 13,
71
+ borderRadius: 9,
72
+ backgroundColor: alpha(color, 0.14),
73
+ borderWidth: 1,
74
+ borderColor: alpha(color, 0.4),
75
+ },
76
+ style,
77
+ ]}
78
+ {...props}
79
+ >
80
+ <View accessibilityElementsHidden>
81
+ <StatusDot variant={statusDotVariant[status]} glow />
82
+ </View>
83
+ <Text testID="status-pill-label" style={{ fontSize: 13, fontWeight: '800', color }}>
84
+ {text}
85
+ </Text>
86
+ </View>
87
+ )
88
+ }
@@ -32,7 +32,7 @@ const decline: StrengthTrendDataPoint[] = [
32
32
  ]
33
33
 
34
34
  const meta: Meta<typeof StrengthTrendChart> = {
35
- title: 'Custom/Workout/StrengthTrendChart',
35
+ title: 'Workout/DataViz/StrengthTrendChart',
36
36
  component: StrengthTrendChart,
37
37
  tags: ['autodocs'],
38
38
  argTypes: {
@@ -3,17 +3,20 @@ import { useEffect, useMemo, useState } from 'react'
3
3
  import { View, Text, Pressable, Animated, Easing, type ViewProps } from 'react-native'
4
4
  import { cn } from '../../../utils/cn'
5
5
  import { resolveColor } from '../../../theme/resolve-color'
6
+ import { getSemanticColors } from '../../../theme/tokens/semantic'
6
7
 
7
- const BRAND_PRIMARY = '#FF7900'
8
+ const sem = getSemanticColors('dark')
9
+
10
+ const BRAND_PRIMARY = sem['brand-primary']
8
11
  // Line/border color for the dashed projection, used where a className cannot
9
12
  // apply (passed as a prop into an inline style, and a per-edge borderTopColor).
10
13
  const PROJECTION_LINE_COLOR = resolveColor('text-tertiary')
11
- const STATUS_SUCCESS = '#14B8A6'
12
- const STATUS_ERROR = '#D14343'
13
- const STATUS_WARNING = '#FFB020'
14
+ const STATUS_SUCCESS = sem['status-success']
15
+ const STATUS_ERROR = sem['status-error']
16
+ const STATUS_WARNING = sem['status-warning']
14
17
  const GRID_LINE = 'rgba(255,255,255,0.06)'
15
- const SUCCESS_PILL_BG = 'rgba(20,184,166,0.10)'
16
- const SUCCESS_PILL_BORDER = 'rgba(20,184,166,0.20)'
18
+ const SUCCESS_PILL_BG = 'rgba(46,213,115,0.10)'
19
+ const SUCCESS_PILL_BORDER = 'rgba(46,213,115,0.20)'
17
20
  const ERROR_PILL_BG = 'rgba(209,67,67,0.10)'
18
21
  const ERROR_PILL_BORDER = 'rgba(209,67,67,0.20)'
19
22
 
@@ -4,7 +4,7 @@ import { SupersetWrapper } from './SupersetWrapper'
4
4
  import { ExerciseCard } from './ExerciseCard'
5
5
 
6
6
  const meta: Meta<typeof SupersetWrapper> = {
7
- title: 'Custom/Workout/SupersetWrapper',
7
+ title: 'Workout/SupersetWrapper',
8
8
  component: SupersetWrapper,
9
9
  tags: ['autodocs'],
10
10
  decorators: [
@@ -1,6 +1,7 @@
1
1
  // Font mapping: font-heading=Space Grotesk, font-body=Nunito Sans (UI), font-sans=Inter (body)
2
2
  import React from 'react'
3
3
  import { View, Text } from 'react-native'
4
+ import { getSemanticColors } from '../../../theme/tokens/semantic'
4
5
 
5
6
  export interface SupersetWrapperProps {
6
7
  label?: string
@@ -10,7 +11,7 @@ export interface SupersetWrapperProps {
10
11
 
11
12
  const DEFAULTS = {
12
13
  label: 'SS',
13
- color: '#FF7900',
14
+ color: getSemanticColors('dark')['brand-primary'],
14
15
  bgBase: '#101010',
15
16
  } as const
16
17
 
@@ -3,7 +3,7 @@ import { View } from 'react-native'
3
3
  import { TempoBar } from './TempoBar'
4
4
 
5
5
  const meta: Meta<typeof TempoBar> = {
6
- title: 'Custom/Workout/TempoBar',
6
+ title: 'Workout/TempoBar',
7
7
  component: TempoBar,
8
8
  tags: ['autodocs'],
9
9
  argTypes: {
@@ -5,9 +5,20 @@ import { TempoDisplay, type TempoLivePhase, type TempoLiveState } from './TempoD
5
5
 
6
6
  // tempo = [eccentric, pauseBottom, concentric, pauseTop]
7
7
  const meta: Meta<typeof TempoDisplay> = {
8
- title: 'Custom/Workout/TempoDisplay',
8
+ title: 'Workout/TempoDisplay',
9
9
  component: TempoDisplay,
10
10
  tags: ['autodocs'],
11
+ parameters: {
12
+ docs: {
13
+ description: {
14
+ component:
15
+ '**Molecule.** The eccentric/pause/concentric/pause tempo display. Composes ' +
16
+ '[MetricCell](?path=/docs/workout-metriccell--docs) ' +
17
+ '(shared value/separator cell). Used-by ↑ ' +
18
+ '[ExerciseHeading](?path=/docs/workout-exerciseheading--docs) (`showLabel={false}`).',
19
+ },
20
+ },
21
+ },
11
22
  argTypes: {
12
23
  tempo: {
13
24
  control: 'object',
@@ -3,7 +3,11 @@ import { useState, useCallback } from 'react'
3
3
  import { View, Text, Pressable, type ViewProps } from 'react-native'
4
4
  import { roundTempo } from '../../../utils/workout-format'
5
5
  import { alpha } from '../../../utils/colors'
6
+ import { getSemanticColors } from '../../../theme/tokens/semantic'
6
7
  import { getTempoFillPct, getTempoPacingState } from './TempoBar'
8
+ import { MetricCell } from './metricText'
9
+
10
+ const t = getSemanticColors('dark')
7
11
 
8
12
  /** The four tempo phases, in the order the display renders them. */
9
13
  export type TempoLivePhase = 'eccentric' | 'pauseBottom' | 'concentric' | 'pauseTop'
@@ -26,6 +30,8 @@ export interface TempoDisplayProps extends ViewProps {
26
30
  size?: 'sm' | 'md'
27
31
  /** Colored phases or mono (all gray) */
28
32
  colored?: boolean
33
+ /** Show the "TEMPO" caption before the values. Default true. */
34
+ showLabel?: boolean
29
35
  /** Show info tooltip on press */
30
36
  showInfo?: boolean
31
37
  /**
@@ -40,13 +46,13 @@ export interface TempoDisplayProps extends ViewProps {
40
46
 
41
47
  const INTER = 'Inter, sans-serif'
42
48
  const TEXT_TERTIARY = '#6B7280'
43
- const STATUS_ERROR = '#D14343' // status-error (red), shown when a phase runs behind pace
49
+ const STATUS_ERROR = t['status-error'] // shown when a phase runs behind pace
44
50
 
45
51
  // Phase colors: [eccentric, pauseBottom, concentric, pauseTop]
46
52
  const phaseColors = {
47
- eccentric: '#FFB020', // status-warning (amber)
53
+ eccentric: t['status-warning'],
48
54
  pauseBottom: TEXT_TERTIARY,
49
- concentric: '#14B8A6', // status-success (teal)
55
+ concentric: t['status-success'],
50
56
  pauseTop: TEXT_TERTIARY,
51
57
  dash: TEXT_TERTIARY,
52
58
  }
@@ -61,33 +67,17 @@ function TempoValue({
61
67
  fontSize: number
62
68
  }) {
63
69
  return (
64
- <Text
65
- style={{
66
- fontFamily: INTER,
67
- fontSize,
68
- color,
69
- fontWeight: '600',
70
- letterSpacing: 1,
71
- }}
72
- >
70
+ <MetricCell color={color} fontSize={fontSize}>
73
71
  {value}
74
- </Text>
72
+ </MetricCell>
75
73
  )
76
74
  }
77
75
 
78
76
  function TempoSeparator({ color, fontSize }: { color: string; fontSize: number }) {
79
77
  return (
80
- <Text
81
- style={{
82
- fontFamily: INTER,
83
- fontSize,
84
- color,
85
- fontWeight: '600',
86
- letterSpacing: 1,
87
- }}
88
- >
78
+ <MetricCell color={color} fontSize={fontSize}>
89
79
  -
90
- </Text>
80
+ </MetricCell>
91
81
  )
92
82
  }
93
83
 
@@ -167,6 +157,7 @@ export function TempoDisplay({
167
157
  tempo,
168
158
  size = 'md',
169
159
  colored = true,
160
+ showLabel = true,
170
161
  showInfo = true,
171
162
  live,
172
163
  onPress,
@@ -202,19 +193,21 @@ export function TempoDisplay({
202
193
  }}
203
194
  {...props}
204
195
  >
205
- <Text
206
- style={{
207
- fontFamily: INTER,
208
- fontSize: 9,
209
- fontWeight: '500',
210
- color: TEXT_TERTIARY,
211
- letterSpacing: 0.5,
212
- textTransform: 'uppercase',
213
- marginRight: 6,
214
- }}
215
- >
216
- TEMPO
217
- </Text>
196
+ {showLabel && (
197
+ <Text
198
+ style={{
199
+ fontFamily: INTER,
200
+ fontSize: 9,
201
+ fontWeight: '500',
202
+ color: TEXT_TERTIARY,
203
+ letterSpacing: 0.5,
204
+ textTransform: 'uppercase',
205
+ marginRight: 6,
206
+ }}
207
+ >
208
+ TEMPO
209
+ </Text>
210
+ )}
218
211
  <View style={{ flexDirection: 'row' }} testID="tempo-value">
219
212
  {live ? (
220
213
  <LiveTempoRow
@@ -181,7 +181,7 @@ const muscles: TrainingStatusMuscle[] = [
181
181
  ]
182
182
 
183
183
  const meta: Meta<typeof TrainingStatusPage> = {
184
- title: 'Custom/Workout/TrainingStatusPage',
184
+ title: 'Pages/Training Status',
185
185
  component: TrainingStatusPage,
186
186
  parameters: { layout: 'fullscreen' },
187
187
  tags: ['autodocs'],