@titan-design/react-ui 0.6.0 → 0.8.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 (258) hide show
  1. package/dist/bodymap.js +12 -7
  2. package/dist/bodymap.js.map +1 -1
  3. package/dist/bodymap.mjs +12 -7
  4. package/dist/bodymap.mjs.map +1 -1
  5. package/dist/index.d.mts +956 -128
  6. package/dist/index.d.ts +956 -128
  7. package/dist/index.js +2873 -981
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.mjs +2826 -982
  10. package/dist/index.mjs.map +1 -1
  11. package/dist/{pages-MO0JCySL.d.mts → pages-DCFBqp79.d.mts} +289 -57
  12. package/dist/{pages-D7Jlssvp.d.ts → pages-_fI3-x7Z.d.ts} +289 -57
  13. package/dist/pages.d.mts +1 -1
  14. package/dist/pages.d.ts +1 -1
  15. package/dist/pages.js +1659 -799
  16. package/dist/pages.js.map +1 -1
  17. package/dist/pages.mjs +1660 -800
  18. package/dist/pages.mjs.map +1 -1
  19. package/dist/theme/index.d.mts +16 -82
  20. package/dist/theme/index.d.ts +16 -82
  21. package/dist/theme/index.js +13 -115
  22. package/dist/theme/index.js.map +1 -1
  23. package/dist/theme/index.mjs +13 -115
  24. package/dist/theme/index.mjs.map +1 -1
  25. package/dist/theme/tokens-css.js +14 -6
  26. package/dist/theme/tokens-css.js.map +1 -1
  27. package/dist/theme/tokens-css.mjs +14 -6
  28. package/dist/theme/tokens-css.mjs.map +1 -1
  29. package/package.json +1 -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/CircularTimer/CircularTimer.stories.tsx +90 -0
  34. package/src/components/custom/CircularTimer/CircularTimer.test.tsx +62 -0
  35. package/src/components/custom/CircularTimer/CircularTimer.tsx +112 -0
  36. package/src/components/custom/CircularTimer/index.ts +1 -0
  37. package/src/components/custom/DateTime/DateTime.stories.tsx +1 -1
  38. package/src/components/custom/EmptyState/EmptyState.stories.tsx +1 -1
  39. package/src/components/custom/Gauge/Gauge.stories.tsx +1 -1
  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/Sidebar/Sidebar.stories.tsx +1 -1
  43. package/src/components/custom/Table/Table.stories.tsx +1 -1
  44. package/src/components/custom/TimerReadout/TimerReadout.stories.tsx +62 -0
  45. package/src/components/custom/TimerReadout/TimerReadout.test.tsx +72 -0
  46. package/src/components/custom/TimerReadout/TimerReadout.tsx +75 -0
  47. package/src/components/custom/TimerReadout/index.ts +1 -0
  48. package/src/components/custom/Treemap/Treemap.stories.tsx +1 -1
  49. package/src/components/custom/Typography/Typography.stories.tsx +1 -1
  50. package/src/components/custom/Workout/ActiveWorkoutPage.stories.tsx +21 -13
  51. package/src/components/custom/Workout/ActiveWorkoutPage.test.tsx +16 -13
  52. package/src/components/custom/Workout/ActiveWorkoutPage.tsx +9 -15
  53. package/src/components/custom/Workout/BaseBadge.stories.tsx +1 -1
  54. package/src/components/custom/Workout/BodyMap.stories.tsx +1 -1
  55. package/src/components/custom/Workout/BodyMapDetailPanel.stories.tsx +1 -1
  56. package/src/components/custom/Workout/CapacityBandChart.stories.tsx +1 -1
  57. package/src/components/custom/Workout/DeviationBar.stories.tsx +1 -1
  58. package/src/components/custom/Workout/ExerciseCard.stories.tsx +51 -66
  59. package/src/components/custom/Workout/ExerciseCard.test.tsx +146 -143
  60. package/src/components/custom/Workout/ExerciseCard.tsx +176 -198
  61. package/src/components/custom/Workout/ExerciseCardHeading.stories.tsx +99 -0
  62. package/src/components/custom/Workout/ExerciseCardHeading.test.tsx +72 -0
  63. package/src/components/custom/Workout/ExerciseCardHeading.tsx +43 -0
  64. package/src/components/custom/Workout/ExerciseCardUnified.stories.tsx +151 -0
  65. package/src/components/custom/Workout/ExerciseDetailPage.stories.tsx +5 -3
  66. package/src/components/custom/Workout/ExerciseDetailPage.test.tsx +4 -4
  67. package/src/components/custom/Workout/ExerciseDetailPage.tsx +4 -5
  68. package/src/components/custom/Workout/ExerciseHeading.stories.tsx +81 -0
  69. package/src/components/custom/Workout/ExerciseHeading.test.tsx +77 -0
  70. package/src/components/custom/Workout/ExerciseHeading.tsx +85 -0
  71. package/src/components/custom/Workout/ExerciseIndicator.stories.tsx +110 -0
  72. package/src/components/custom/Workout/ExerciseIndicator.test.tsx +93 -0
  73. package/src/components/custom/Workout/ExerciseIndicator.tsx +120 -0
  74. package/src/components/custom/Workout/FatigueMeter.stories.tsx +51 -0
  75. package/src/components/custom/Workout/FatigueMeter.test.tsx +85 -0
  76. package/src/components/custom/Workout/FatigueMeter.tsx +86 -0
  77. package/src/components/custom/Workout/InputBar.stories.tsx +1 -1
  78. package/src/components/custom/Workout/IntensityBar.stories.tsx +1 -1
  79. package/src/components/custom/Workout/LiveAuraFrame.stories.tsx +153 -0
  80. package/src/components/custom/Workout/LiveAuraFrame.test.tsx +74 -0
  81. package/src/components/custom/Workout/LiveAuraFrame.tsx +105 -0
  82. package/src/components/custom/Workout/MesoCard.stories.tsx +1 -1
  83. package/src/components/custom/Workout/MesoProgressBar.stories.tsx +1 -1
  84. package/src/components/custom/Workout/MesoStatusCard.stories.tsx +1 -1
  85. package/src/components/custom/Workout/MetricTiles.stories.tsx +60 -0
  86. package/src/components/custom/Workout/MetricTiles.test.tsx +58 -0
  87. package/src/components/custom/Workout/MetricTiles.tsx +48 -0
  88. package/src/components/custom/Workout/MuscleGroupChip.stories.tsx +1 -1
  89. package/src/components/custom/Workout/PlaceholderStrip.stories.tsx +1 -1
  90. package/src/components/custom/Workout/PrBadge.stories.tsx +1 -1
  91. package/src/components/custom/Workout/PrHistoryModal.stories.tsx +1 -1
  92. package/src/components/custom/Workout/ProgramPlanningPage.stories.tsx +4 -16
  93. package/src/components/custom/Workout/ProgramPlanningPage.tsx +8 -6
  94. package/src/components/custom/Workout/README.md +193 -4
  95. package/src/components/custom/Workout/ReadinessCheck.stories.tsx +1 -1
  96. package/src/components/custom/Workout/RestTimer.stories.tsx +133 -3
  97. package/src/components/custom/Workout/RestTimer.test.tsx +73 -0
  98. package/src/components/custom/Workout/RestTimer.tsx +155 -59
  99. package/src/components/custom/Workout/RowInventory.stories.tsx +405 -0
  100. package/src/components/custom/Workout/S3FullRail.stories.tsx +34 -0
  101. package/src/components/custom/Workout/S3SessionPace.stories.tsx +95 -0
  102. package/src/components/custom/Workout/S3SessionRailHeading.stories.tsx +61 -0
  103. package/src/components/custom/Workout/S3SetTypes.stories.tsx +176 -0
  104. package/src/components/custom/Workout/S3WorkoutExpansion.stories.tsx +240 -0
  105. package/src/components/custom/Workout/ScheduleTiles.stories.tsx +40 -0
  106. package/src/components/custom/Workout/ScheduleTiles.test.tsx +34 -0
  107. package/src/components/custom/Workout/ScheduleTiles.tsx +70 -0
  108. package/src/components/custom/Workout/SegmentedBar.stories.tsx +99 -0
  109. package/src/components/custom/Workout/SegmentedBar.test.tsx +77 -0
  110. package/src/components/custom/Workout/SegmentedBar.tsx +172 -0
  111. package/src/components/custom/Workout/SegmentedProgressBar.stories.tsx +50 -0
  112. package/src/components/custom/Workout/SegmentedProgressBar.test.tsx +80 -0
  113. package/src/components/custom/Workout/SegmentedProgressBar.tsx +67 -0
  114. package/src/components/custom/Workout/SessionHeader.stories.tsx +121 -0
  115. package/src/components/custom/Workout/SessionHeader.test.tsx +122 -0
  116. package/src/components/custom/Workout/SessionHeader.tsx +152 -0
  117. package/src/components/custom/Workout/SessionRail.stories.tsx +153 -0
  118. package/src/components/custom/Workout/SessionRail.test.tsx +86 -0
  119. package/src/components/custom/Workout/SessionRail.tsx +126 -0
  120. package/src/components/custom/Workout/SetBar.stories.tsx +124 -0
  121. package/src/components/custom/Workout/SetBar.test.tsx +123 -0
  122. package/src/components/custom/Workout/SetBar.tsx +171 -0
  123. package/src/components/custom/Workout/SetRow.stories.tsx +50 -100
  124. package/src/components/custom/Workout/SetRow.test.tsx +94 -166
  125. package/src/components/custom/Workout/SetRow.tsx +169 -232
  126. package/src/components/custom/Workout/SetStrip.stories.tsx +154 -0
  127. package/src/components/custom/Workout/SetStrip.test.tsx +109 -0
  128. package/src/components/custom/Workout/SetStrip.tsx +71 -0
  129. package/src/components/custom/Workout/SetTableHeader.stories.tsx +66 -0
  130. package/src/components/custom/Workout/SetTableHeader.test.tsx +47 -0
  131. package/src/components/custom/Workout/SetTableHeader.tsx +88 -0
  132. package/src/components/custom/Workout/SetsRepsLoad.stories.tsx +47 -0
  133. package/src/components/custom/Workout/SetsRepsLoad.test.tsx +44 -0
  134. package/src/components/custom/Workout/SetsRepsLoad.tsx +52 -0
  135. package/src/components/custom/Workout/Sparkline.stories.tsx +1 -1
  136. package/src/components/custom/Workout/StatusDot.stories.tsx +1 -1
  137. package/src/components/custom/Workout/StatusPill.stories.tsx +59 -0
  138. package/src/components/custom/Workout/StatusPill.test.tsx +63 -0
  139. package/src/components/custom/Workout/StatusPill.tsx +88 -0
  140. package/src/components/custom/Workout/StrengthTrendChart.stories.tsx +1 -1
  141. package/src/components/custom/Workout/SupersetWrapper.stories.tsx +1 -1
  142. package/src/components/custom/Workout/TempoBar.stories.tsx +70 -1
  143. package/src/components/custom/Workout/TempoBar.test.tsx +119 -4
  144. package/src/components/custom/Workout/TempoBar.tsx +107 -22
  145. package/src/components/custom/Workout/TempoDisplay.stories.tsx +12 -1
  146. package/src/components/custom/Workout/TempoDisplay.tsx +23 -33
  147. package/src/components/custom/Workout/TrainingStatusPage.stories.tsx +1 -1
  148. package/src/components/custom/Workout/VelocityStrip.modalities.stories.tsx +254 -0
  149. package/src/components/custom/Workout/VelocityStrip.responsive.stories.tsx +145 -0
  150. package/src/components/custom/Workout/VelocityStrip.stories.tsx +262 -56
  151. package/src/components/custom/Workout/VelocityStrip.test.tsx +440 -141
  152. package/src/components/custom/Workout/VelocityStrip.tsx +776 -141
  153. package/src/components/custom/Workout/VolumeLandmarkBar.stories.tsx +73 -0
  154. package/src/components/custom/Workout/VolumeLandmarkBar.test.tsx +119 -0
  155. package/src/components/custom/Workout/VolumeLandmarkBar.tsx +154 -0
  156. package/src/components/custom/Workout/WeekRow.stories.tsx +1 -1
  157. package/src/components/custom/Workout/WeightBadge.stories.tsx +1 -1
  158. package/src/components/custom/Workout/WorkoutCard.stories.tsx +2 -6
  159. package/src/components/custom/Workout/WorkoutCard.test.tsx +13 -46
  160. package/src/components/custom/Workout/WorkoutPill.stories.tsx +1 -1
  161. package/src/components/custom/Workout/ZoneTrack.stories.tsx +139 -0
  162. package/src/components/custom/Workout/ZoneTrack.test.tsx +234 -0
  163. package/src/components/custom/Workout/ZoneTrack.tsx +373 -0
  164. package/src/components/custom/Workout/index.ts +55 -2
  165. package/src/components/custom/Workout/metricText.stories.tsx +69 -0
  166. package/src/components/custom/Workout/metricText.tsx +34 -0
  167. package/src/components/custom/Workout/paceTone.test.ts +29 -0
  168. package/src/components/custom/Workout/paceTone.ts +27 -0
  169. package/src/components/custom/Workout/setHeadingKit.tsx +177 -0
  170. package/src/components/custom/index.ts +2 -0
  171. package/src/components/custom/stepper/Stepper.stories.tsx +1 -1
  172. package/src/components/icons/icons.stories.tsx +67 -2
  173. package/src/components/icons/icons.test.tsx +32 -2
  174. package/src/components/icons/icons.tsx +108 -0
  175. package/src/components/shell/BrandLockup.stories.tsx +3 -3
  176. package/src/components/shell/DashboardShell.stories.tsx +65 -0
  177. package/src/components/shell/DashboardShell.test.tsx +42 -0
  178. package/src/components/shell/DashboardShell.tsx +74 -0
  179. package/src/components/shell/DeviceIndicator.stories.tsx +2 -2
  180. package/src/components/shell/DeviceMenu.stories.tsx +5 -5
  181. package/src/components/shell/DeviceRow.stories.tsx +3 -3
  182. package/src/components/shell/NavItem.stories.tsx +52 -0
  183. package/src/components/shell/NavItem.test.tsx +35 -0
  184. package/src/components/shell/NavItem.tsx +75 -0
  185. package/src/components/shell/README.md +30 -0
  186. package/src/components/shell/SessionRailSpecimen.stories.tsx +753 -0
  187. package/src/components/shell/SessionStatePill.stories.tsx +3 -3
  188. package/src/components/shell/SessionStatePill.tsx +1 -1
  189. package/src/components/shell/SideNav.stories.tsx +81 -0
  190. package/src/components/shell/SideNav.test.tsx +51 -0
  191. package/src/components/shell/SideNav.tsx +74 -0
  192. package/src/components/shell/TopBar.stories.tsx +5 -5
  193. package/src/components/shell/index.ts +5 -0
  194. package/src/components/ui/alert/Alert.stories.tsx +86 -3
  195. package/src/components/ui/alert/Alert.test.tsx +52 -0
  196. package/src/components/ui/alert/Alert.tsx +54 -20
  197. package/src/components/ui/autocomplete/Autocomplete.stories.tsx +1 -1
  198. package/src/components/ui/avatar/Avatar.stories.tsx +1 -1
  199. package/src/components/ui/badge/Badge.stories.tsx +1 -1
  200. package/src/components/ui/breadcrumbs/Breadcrumbs.stories.tsx +1 -1
  201. package/src/components/ui/button/Button.stories.tsx +1 -1
  202. package/src/components/ui/card/Card.stories.tsx +1 -1
  203. package/src/components/ui/checkbox/Checkbox.stories.tsx +1 -1
  204. package/src/components/ui/chip/Chip.stories.tsx +1 -1
  205. package/src/components/ui/collapse/Collapse.stories.tsx +1 -1
  206. package/src/components/ui/data-row/DataRow.stories.tsx +1 -1
  207. package/src/components/ui/divider/Divider.stories.tsx +1 -1
  208. package/src/components/ui/drawer/Drawer.stories.tsx +1 -1
  209. package/src/components/ui/form-field/FormField.stories.tsx +1 -1
  210. package/src/components/ui/help-tip/HelpTip.stories.tsx +1 -1
  211. package/src/components/ui/icon-box/IconBox.stories.tsx +1 -1
  212. package/src/components/ui/index.ts +1 -0
  213. package/src/components/ui/indicator/Indicator.stories.tsx +2 -2
  214. package/src/components/ui/indicator/Indicator.test.tsx +1 -0
  215. package/src/components/ui/indicator/Indicator.tsx +6 -1
  216. package/src/components/ui/input/Input.stories.tsx +1 -1
  217. package/src/components/ui/link/Link.stories.tsx +1 -1
  218. package/src/components/ui/list-item/ListItem.stories.tsx +1 -1
  219. package/src/components/ui/menu/Menu.stories.tsx +1 -1
  220. package/src/components/ui/modal/Modal.stories.tsx +1 -1
  221. package/src/components/ui/pill/Pill.stories.tsx +1 -1
  222. package/src/components/ui/popover/Popover.stories.tsx +1 -1
  223. package/src/components/ui/progress/Progress.stories.tsx +1 -1
  224. package/src/components/ui/progress/Progress.tsx +47 -22
  225. package/src/components/ui/radio/Radio.stories.tsx +1 -1
  226. package/src/components/ui/section/Section.stories.tsx +1 -1
  227. package/src/components/ui/select/Select.stories.tsx +1 -1
  228. package/src/components/ui/skeleton/Skeleton.stories.tsx +1 -1
  229. package/src/components/ui/spinner/Spinner.stories.tsx +1 -1
  230. package/src/components/ui/stack/Stack.stories.tsx +1 -1
  231. package/src/components/ui/surface/Surface.stories.tsx +1 -1
  232. package/src/components/ui/switch/Switch.stories.tsx +1 -1
  233. package/src/components/ui/tabs/Tabs.stories.tsx +1 -1
  234. package/src/components/ui/tile/Tile.stories.tsx +79 -0
  235. package/src/components/ui/tile/Tile.test.tsx +48 -0
  236. package/src/components/ui/tile/Tile.tsx +64 -0
  237. package/src/components/ui/tile/index.ts +2 -0
  238. package/src/components/ui/toast/Toast.stories.tsx +1 -1
  239. package/src/components/ui/toolbar-button/ToolbarButton.stories.tsx +1 -1
  240. package/src/components/ui/tooltip/Tooltip.stories.tsx +1 -1
  241. package/src/examples/react-hook-form/ReactHookForm.stories.tsx +1 -1
  242. package/src/hooks/index.ts +2 -0
  243. package/src/hooks/useTimer.test.ts +150 -0
  244. package/src/hooks/useTimer.ts +77 -0
  245. package/src/index.ts +3 -0
  246. package/src/pages.ts +1 -1
  247. package/src/stories/PresetShowcase.stories.tsx +1 -1
  248. package/src/stories/ThemePresets.stories.tsx +1 -1
  249. package/src/theme/ColorSystem.stories.tsx +1 -1
  250. package/src/theme/Colors.stories.tsx +5 -8
  251. package/src/theme/config.ts +4 -0
  252. package/src/theme/elevation.stories.tsx +1 -1
  253. package/src/theme/global.css +5 -1
  254. package/src/theme/shadows.stories.tsx +1 -1
  255. package/src/theme/tokens/primitives.ts +11 -107
  256. package/src/theme/tokens/semantic.ts +8 -0
  257. package/src/theme/workout-tokens.ts +11 -7
  258. package/tailwind.config.js +5 -0
@@ -5,7 +5,7 @@ import {
5
5
  countCompletedSets,
6
6
  deriveWorkoutProgress,
7
7
  findActiveExercise,
8
- statusToCardState,
8
+ isUpcomingExercise,
9
9
  groupExercises,
10
10
  type ActiveWorkoutExercise,
11
11
  type ActiveWorkoutPageProps,
@@ -29,8 +29,16 @@ const exercises: ActiveWorkoutExercise[] = [
29
29
  totalPlannedSets: 4,
30
30
  setVelocities: [[0.72], [0.68]],
31
31
  sets: [
32
- { mode: 'completed', setNumber: 1, reps: 8, weight: 195, rpe: 8, unit: 'lbs' },
33
- { mode: 'active', setNumber: 3, reps: null, weight: null, unit: 'lbs', isNextSet: true },
32
+ {
33
+ state: 'done',
34
+ setNumber: 1,
35
+ unit: 'lbs',
36
+ reps: 8,
37
+ weight: 195,
38
+ rpe: 8,
39
+ velocities: [0.72],
40
+ },
41
+ { state: 'todo', setNumber: 3, unit: 'lbs', target: { reps: 8, weight: 195 } },
34
42
  ],
35
43
  },
36
44
  {
@@ -107,16 +115,11 @@ describe('findActiveExercise', () => {
107
115
  })
108
116
  })
109
117
 
110
- describe('statusToCardState', () => {
111
- it('keeps upcoming exercises upcoming regardless of focus', () => {
112
- expect(statusToCardState('upcoming', true)).toBe('upcoming')
113
- expect(statusToCardState('upcoming', false)).toBe('upcoming')
114
- })
115
-
116
- it('expands only the focused active/completed exercise', () => {
117
- expect(statusToCardState('active', true)).toBe('expanded')
118
- expect(statusToCardState('active', false)).toBe('collapsed')
119
- expect(statusToCardState('completed', true)).toBe('expanded')
118
+ describe('isUpcomingExercise', () => {
119
+ it('is true only for upcoming exercises', () => {
120
+ expect(isUpcomingExercise('upcoming')).toBe(true)
121
+ expect(isUpcomingExercise('active')).toBe(false)
122
+ expect(isUpcomingExercise('completed')).toBe(false)
120
123
  })
121
124
  })
122
125
 
@@ -1,7 +1,7 @@
1
1
  // Font mapping: font-heading=Space Grotesk, font-body=Nunito Sans (UI), font-sans=Inter (body)
2
2
  import { useMemo, useState } from 'react'
3
3
  import { View, Text, type ViewProps } from 'react-native'
4
- import { ExerciseCard, type ExerciseCardProps, type ExerciseCardState } from './ExerciseCard'
4
+ import { ExerciseCard, type ExerciseCardProps } from './ExerciseCard'
5
5
  import { InputBar } from './InputBar'
6
6
  import { RestTimer } from './RestTimer'
7
7
  import { SupersetWrapper } from './SupersetWrapper'
@@ -32,8 +32,6 @@ export interface ActiveWorkoutExercise {
32
32
  totalPlannedSets: number
33
33
  /** Collapsed summary (sets × reps @ weight) for a completed exercise. */
34
34
  summary?: ExerciseCardProps['summary']
35
- /** Estimated one-rep max badge. */
36
- e1rm?: ExerciseCardProps['e1rm']
37
35
  /** Flags a personal-record exercise. */
38
36
  isPR?: boolean
39
37
  /** Prescribed tempo, revealed when expanded. */
@@ -148,13 +146,9 @@ export function findActiveExercise(
148
146
  return exercises.find((exercise) => exercise.status === 'active') ?? null
149
147
  }
150
148
 
151
- /** Map an exercise's status + focus onto an `ExerciseCard` visual state (pure). */
152
- export function statusToCardState(
153
- status: ActiveExerciseStatus,
154
- focused: boolean
155
- ): ExerciseCardState {
156
- if (status === 'upcoming') return 'upcoming'
157
- return focused ? 'expanded' : 'collapsed'
149
+ /** Whether an exercise renders as the dimmed, not-yet-reached representation (pure). */
150
+ export function isUpcomingExercise(status: ActiveExerciseStatus): boolean {
151
+ return status === 'upcoming'
158
152
  }
159
153
 
160
154
  /** Project an exercise onto ExerciseCard props, wiring zoom focus (pure). */
@@ -165,18 +159,18 @@ export function toActiveCardProps(
165
159
  supersetPosition: ExerciseCardProps['supersetPosition'] = null,
166
160
  supersetColor?: string
167
161
  ): ExerciseCardProps {
168
- const state = statusToCardState(exercise.status, focused)
162
+ const upcoming = isUpcomingExercise(exercise.status)
169
163
  return {
170
164
  name: exercise.name,
171
- state,
172
- onToggle,
165
+ upcoming,
166
+ expanded: focused,
167
+ onExpandedChange: onToggle,
173
168
  summary: exercise.summary,
174
- e1rm: exercise.e1rm,
175
169
  isPR: exercise.isPR,
176
170
  tempo: exercise.tempo,
177
171
  setVelocities: exercise.setVelocities,
178
172
  totalPlannedSets: exercise.totalPlannedSets,
179
- sets: state === 'expanded' ? exercise.sets : undefined,
173
+ sets: focused ? exercise.sets : undefined,
180
174
  prescription: exercise.prescription,
181
175
  previousBest: exercise.previousBest,
182
176
  supersetPosition,
@@ -4,7 +4,7 @@ import { DumbbellIcon } from './icons'
4
4
  import { BaseBadge } from './BaseBadge'
5
5
 
6
6
  const meta: Meta<typeof BaseBadge> = {
7
- title: 'Custom/Workout/BaseBadge',
7
+ title: 'Components/Atoms/BaseBadge',
8
8
  component: BaseBadge,
9
9
  tags: ['autodocs'],
10
10
  argTypes: {
@@ -51,7 +51,7 @@ const backData: BodyMapData[] = [
51
51
  ]
52
52
 
53
53
  const meta: Meta<typeof BodyMap> = {
54
- title: 'Custom/Workout/BodyMap',
54
+ title: 'Workout/DataViz/BodyMap',
55
55
  component: BodyMap,
56
56
  tags: ['autodocs'],
57
57
  argTypes: {
@@ -21,7 +21,7 @@ const upcoming: UpcomingExercise[] = [
21
21
  ]
22
22
 
23
23
  const meta: Meta<typeof BodyMapDetailPanel> = {
24
- title: 'Custom/Workout/BodyMapDetailPanel',
24
+ title: 'Workout/DataViz/BodyMapDetailPanel',
25
25
  component: BodyMapDetailPanel,
26
26
  tags: ['autodocs'],
27
27
  decorators: [
@@ -39,7 +39,7 @@ const projection: CapacityBandProjection = {
39
39
  }
40
40
 
41
41
  const meta: Meta<typeof CapacityBandChart> = {
42
- title: 'Custom/Workout/CapacityBandChart',
42
+ title: 'Workout/DataViz/CapacityBandChart',
43
43
  component: CapacityBandChart,
44
44
  tags: ['autodocs'],
45
45
  argTypes: {
@@ -3,7 +3,7 @@ import { View } from 'react-native'
3
3
  import { DeviationBar } from './DeviationBar'
4
4
 
5
5
  const meta: Meta<typeof DeviationBar> = {
6
- title: 'Custom/Workout/DeviationBar',
6
+ title: 'Workout/DataViz/DeviationBar',
7
7
  component: DeviationBar,
8
8
  tags: ['autodocs'],
9
9
  argTypes: {
@@ -4,14 +4,31 @@ import { ExerciseCard } from './ExerciseCard'
4
4
  import type { SetRowProps } from './SetRow'
5
5
 
6
6
  const meta: Meta<typeof ExerciseCard> = {
7
- title: 'Custom/Workout/ExerciseCard',
7
+ title: 'Workout/ExerciseCard',
8
8
  component: ExerciseCard,
9
9
  tags: ['autodocs'],
10
+ parameters: {
11
+ docs: {
12
+ description: {
13
+ component:
14
+ '**Organism** (data-contract card). Three representations: `upcoming` (a dimmed, ' +
15
+ 'not-yet-reached row), collapsed (name + summary + per-set velocity strips), and expanded ' +
16
+ '— the unified card whose persistent header is the real ' +
17
+ '[ExerciseCardHeading](?path=/docs/workout-exercisecardheading--docs) over a SET · REPS · ' +
18
+ 'LBS · RPE body of [SetRow](?path=/docs/workout-setrow--docs)s (compact spotlight on the ' +
19
+ 'live set). Expand is controlled (`expanded` + `onExpandedChange`) or uncontrolled ' +
20
+ '(`defaultExpanded`); `upcoming` overrides expand.',
21
+ },
22
+ },
23
+ },
10
24
  argTypes: {
11
- state: {
25
+ upcoming: { control: 'boolean', description: 'Dimmed, not-yet-reached representation' },
26
+ expanded: { control: 'boolean', description: 'Controlled expand state' },
27
+ defaultExpanded: { control: 'boolean', description: 'Uncontrolled initial expand state' },
28
+ indicator: {
12
29
  control: 'select',
13
- options: ['collapsed', 'expanded', 'upcoming'],
14
- description: 'Card display state',
30
+ options: [undefined, 'pr', 'issue', 'info'],
31
+ description: 'Chip in the expanded header title line',
15
32
  },
16
33
  },
17
34
  decorators: [
@@ -26,76 +43,60 @@ const meta: Meta<typeof ExerciseCard> = {
26
43
  export default meta
27
44
  type Story = StoryObj<typeof ExerciseCard>
28
45
 
46
+ // Done · done · LIVE · todo — the unified body's full lifecycle.
29
47
  const sampleSets: SetRowProps[] = [
30
48
  {
31
- mode: 'completed',
49
+ state: 'done',
32
50
  setNumber: 1,
51
+ unit: 'lbs',
33
52
  reps: 8,
34
53
  weight: 135,
35
- unit: 'lbs',
36
54
  rpe: 7,
37
- previous: { reps: 8, weight: 130 },
38
55
  velocities: [1.1, 0.95, 0.82, 0.68, 0.55, 0.48, 0.42, 0.38],
39
56
  },
40
57
  {
41
- mode: 'completed',
58
+ state: 'done',
42
59
  setNumber: 2,
60
+ unit: 'lbs',
43
61
  reps: 8,
44
62
  weight: 135,
45
- unit: 'lbs',
46
63
  rpe: 8.5,
47
- previous: { reps: 8, weight: 135 },
48
- velocities: [0.95, 0.88, 0.78, 0.65, 0.52, 0.45, 0.40, 0.35],
64
+ velocities: [0.95, 0.88, 0.78, 0.65, 0.52, 0.45, 0.4, 0.35],
49
65
  },
50
66
  {
51
- mode: 'active',
67
+ state: 'live',
52
68
  setNumber: 3,
53
- reps: null,
54
- weight: null,
55
69
  unit: 'lbs',
56
- isNextSet: true,
57
- targets: { reps: 8, weight: 135 },
58
- previous: { reps: 8, weight: 135 },
59
- },
60
- {
61
- mode: 'active',
62
- setNumber: 4,
63
- reps: null,
64
- weight: null,
65
- unit: 'lbs',
66
- targets: { reps: 8, weight: 135 },
67
- previous: { reps: 8, weight: 135 },
70
+ target: { reps: 8, weight: 135 },
71
+ reps: 4,
72
+ weight: 135,
73
+ velocities: [0.92, 0.86, 0.8, 0.74],
68
74
  },
75
+ { state: 'todo', setNumber: 4, unit: 'lbs', target: { reps: 8, weight: 135 } },
69
76
  ]
70
77
 
71
78
  export const CollapsedWithVelocity: Story = {
72
79
  args: {
73
80
  name: 'Bench Press',
74
- state: 'collapsed',
75
- onToggle: () => {},
76
81
  summary: { sets: 4, reps: 8, weight: 135, unit: 'lbs' },
77
82
  setVelocities: [
78
83
  [1.1, 0.95, 0.82, 0.68, 0.55, 0.48, 0.42, 0.38],
79
- [0.95, 0.88, 0.78, 0.65, 0.52, 0.45, 0.40, 0.35],
84
+ [0.95, 0.88, 0.78, 0.65, 0.52, 0.45, 0.4, 0.35],
80
85
  ],
81
86
  totalPlannedSets: 4,
82
- e1rm: { value: 225, unit: 'lbs' },
83
87
  },
84
88
  }
85
89
 
86
90
  export const CollapsedWithPR: Story = {
87
91
  args: {
88
92
  name: 'Squat',
89
- state: 'collapsed',
90
- onToggle: () => {},
91
93
  summary: { sets: 3, reps: 5, weight: 275, unit: 'lbs' },
92
94
  setVelocities: [
93
95
  [0.65, 0.55, 0.45, 0.38, 0.32],
94
- [0.60, 0.50, 0.42, 0.35, 0.30],
95
- [0.58, 0.48, 0.40, 0.33, 0.28],
96
+ [0.6, 0.5, 0.42, 0.35, 0.3],
97
+ [0.58, 0.48, 0.4, 0.33, 0.28],
96
98
  ],
97
99
  totalPlannedSets: 3,
98
- e1rm: { value: 365, unit: 'lbs' },
99
100
  isPR: true,
100
101
  },
101
102
  }
@@ -103,50 +104,39 @@ export const CollapsedWithPR: Story = {
103
104
  export const ExpandedWithSets: Story = {
104
105
  args: {
105
106
  name: 'Bench Press',
106
- state: 'expanded',
107
- onToggle: () => {},
107
+ defaultExpanded: true,
108
108
  summary: { sets: 4, reps: 8, weight: 135, unit: 'lbs' },
109
+ indicator: 'info',
109
110
  sets: sampleSets,
110
- e1rm: { value: 225, unit: 'lbs' },
111
111
  },
112
112
  }
113
113
 
114
114
  export const ExpandedWithTempo: Story = {
115
115
  args: {
116
116
  name: 'Romanian Deadlift',
117
- state: 'expanded',
118
- onToggle: () => {},
117
+ defaultExpanded: true,
119
118
  summary: { sets: 3, reps: 10, weight: 185, unit: 'lbs' },
120
119
  tempo: [2, 1, 3, 0],
121
120
  sets: [
122
121
  {
123
- mode: 'completed',
122
+ state: 'done',
124
123
  setNumber: 1,
124
+ unit: 'lbs',
125
125
  reps: 10,
126
126
  weight: 185,
127
- unit: 'lbs',
128
127
  rpe: 7,
129
- previous: { reps: 10, weight: 175 },
128
+ velocities: [0.9, 0.82, 0.74, 0.66],
130
129
  },
131
130
  {
132
- mode: 'active',
131
+ state: 'live',
133
132
  setNumber: 2,
134
- reps: null,
135
- weight: null,
136
133
  unit: 'lbs',
137
- isNextSet: true,
138
- targets: { reps: 10, weight: 185 },
139
- previous: { reps: 10, weight: 185 },
140
- },
141
- {
142
- mode: 'active',
143
- setNumber: 3,
144
- reps: null,
145
- weight: null,
146
- unit: 'lbs',
147
- targets: { reps: 10, weight: 185 },
148
- previous: { reps: 10, weight: 185 },
134
+ target: { reps: 10, weight: 185 },
135
+ reps: 3,
136
+ weight: 185,
137
+ velocities: [0.88, 0.8, 0.72],
149
138
  },
139
+ { state: 'todo', setNumber: 3, unit: 'lbs', target: { reps: 10, weight: 185 } },
150
140
  ],
151
141
  },
152
142
  }
@@ -154,18 +144,15 @@ export const ExpandedWithTempo: Story = {
154
144
  export const Upcoming: Story = {
155
145
  args: {
156
146
  name: 'Lat Pulldown',
157
- state: 'upcoming',
158
- onToggle: () => {},
159
- prescription: '3\u00D78-12 @ RPE 8',
160
- previousBest: '135 lbs \u00D7 10',
147
+ upcoming: true,
148
+ prescription: '3×8-12 @ RPE 8',
149
+ previousBest: '135 lbs × 10',
161
150
  },
162
151
  }
163
152
 
164
153
  export const SupersetFirst: Story = {
165
154
  args: {
166
155
  name: 'Bench Press',
167
- state: 'collapsed',
168
- onToggle: () => {},
169
156
  summary: { sets: 3, reps: 8, weight: 185, unit: 'lbs' },
170
157
  supersetPosition: 'first',
171
158
  setVelocities: [[1.0, 0.9, 0.8]],
@@ -176,8 +163,6 @@ export const SupersetFirst: Story = {
176
163
  export const SupersetLast: Story = {
177
164
  args: {
178
165
  name: 'Barbell Row',
179
- state: 'collapsed',
180
- onToggle: () => {},
181
166
  summary: { sets: 3, reps: 8, weight: 155, unit: 'lbs' },
182
167
  supersetPosition: 'last',
183
168
  setVelocities: [[0.9, 0.8, 0.7]],