@titan-design/react-ui 0.12.0 → 0.13.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 (509) hide show
  1. package/README.md +46 -47
  2. package/dist/bodymap.js +768 -701
  3. package/dist/bodymap.js.map +1 -1
  4. package/dist/bodymap.mjs +770 -703
  5. package/dist/bodymap.mjs.map +1 -1
  6. package/dist/index.d.mts +1320 -215
  7. package/dist/index.d.ts +1320 -215
  8. package/dist/index.js +5996 -4498
  9. package/dist/index.js.map +1 -1
  10. package/dist/index.mjs +5773 -4357
  11. package/dist/index.mjs.map +1 -1
  12. package/dist/{pages-CvsFqNtx.d.mts → pages-CpW3OB3g.d.mts} +21 -3
  13. package/dist/{pages-B1hqnGIC.d.ts → pages-_3Ajpiqu.d.ts} +21 -3
  14. package/dist/pages.d.mts +1 -1
  15. package/dist/pages.d.ts +1 -1
  16. package/dist/pages.js +1435 -1428
  17. package/dist/pages.js.map +1 -1
  18. package/dist/pages.mjs +1443 -1436
  19. package/dist/pages.mjs.map +1 -1
  20. package/dist/theme/index.d.mts +202 -1042
  21. package/dist/theme/index.d.ts +202 -1042
  22. package/dist/theme/index.js +215 -300
  23. package/dist/theme/index.js.map +1 -1
  24. package/dist/theme/index.mjs +202 -296
  25. package/dist/theme/index.mjs.map +1 -1
  26. package/dist/theme/tokens-css.js +62 -5
  27. package/dist/theme/tokens-css.js.map +1 -1
  28. package/dist/theme/tokens-css.mjs +62 -5
  29. package/dist/theme/tokens-css.mjs.map +1 -1
  30. package/dist/theme/tokens.d.mts +972 -0
  31. package/dist/theme/tokens.d.ts +972 -0
  32. package/dist/theme/tokens.js +904 -0
  33. package/dist/theme/tokens.js.map +1 -0
  34. package/dist/theme/tokens.mjs +880 -0
  35. package/dist/theme/tokens.mjs.map +1 -0
  36. package/docs/audits/2026-09-08-critique-addenda.md +51 -0
  37. package/docs/audits/2026-09-08-library-critique.md +212 -0
  38. package/docs/library-roadmap.md +99 -0
  39. package/package.json +7 -1
  40. package/src/arch/arch-graph.freshness.test.ts +52 -0
  41. package/src/arch/arch-graph.json +5021 -1617
  42. package/src/components/custom/ActiveWork/CoChangeChip.stories.tsx +44 -0
  43. package/src/components/custom/ActiveWork/CoChangeChip.test.tsx +29 -0
  44. package/src/components/custom/ActiveWork/CoChangeChip.tsx +48 -0
  45. package/src/components/custom/ActiveWork/Eyebrow.stories.tsx +25 -0
  46. package/src/components/custom/ActiveWork/Eyebrow.test.tsx +16 -0
  47. package/src/components/custom/ActiveWork/Eyebrow.tsx +26 -0
  48. package/src/components/custom/ActiveWork/FileActivityDetail.stories.tsx +50 -0
  49. package/src/components/custom/ActiveWork/FileActivityDetail.test.tsx +66 -0
  50. package/src/components/custom/ActiveWork/FileActivityDetail.tsx +202 -0
  51. package/src/components/custom/ActiveWork/FileActivityRow.stories.tsx +70 -0
  52. package/src/components/custom/ActiveWork/FileActivityRow.test.tsx +67 -0
  53. package/src/components/custom/ActiveWork/FileActivityRow.tsx +130 -0
  54. package/src/components/custom/ActiveWork/FileHistoryExplorer.stories.tsx +84 -0
  55. package/src/components/custom/ActiveWork/FileHistoryExplorer.test.tsx +99 -0
  56. package/src/components/custom/ActiveWork/FileHistoryExplorer.tsx +138 -0
  57. package/src/components/custom/ActiveWork/FilePathLabel.stories.tsx +39 -0
  58. package/src/components/custom/ActiveWork/FilePathLabel.test.tsx +53 -0
  59. package/src/components/custom/ActiveWork/FilePathLabel.tsx +63 -0
  60. package/src/components/custom/ActiveWork/InitiativeBrief.stories.tsx +50 -0
  61. package/src/components/custom/ActiveWork/InitiativeBrief.test.tsx +62 -0
  62. package/src/components/custom/ActiveWork/InitiativeBrief.tsx +181 -0
  63. package/src/components/custom/ActiveWork/InitiativeCard.stories.tsx +73 -0
  64. package/src/components/custom/ActiveWork/InitiativeCard.test.tsx +68 -0
  65. package/src/components/custom/ActiveWork/InitiativeCard.tsx +136 -0
  66. package/src/components/custom/ActiveWork/InitiativeHeader.stories.tsx +59 -0
  67. package/src/components/custom/ActiveWork/InitiativeHeader.test.tsx +40 -0
  68. package/src/components/custom/ActiveWork/InitiativeHeader.tsx +73 -0
  69. package/src/components/custom/ActiveWork/InitiativeReader.stories.tsx +145 -0
  70. package/src/components/custom/ActiveWork/OpenLoops.stories.tsx +58 -0
  71. package/src/components/custom/ActiveWork/OpenLoops.test.tsx +61 -0
  72. package/src/components/custom/ActiveWork/OpenLoops.tsx +107 -0
  73. package/src/components/custom/ActiveWork/PortfolioOverview.stories.tsx +101 -0
  74. package/src/components/custom/ActiveWork/PortfolioOverview.test.tsx +81 -0
  75. package/src/components/custom/ActiveWork/PortfolioOverview.tsx +83 -0
  76. package/src/components/custom/ActiveWork/README.md +305 -0
  77. package/src/components/custom/ActiveWork/SessionDetail.stories.tsx +71 -0
  78. package/src/components/custom/ActiveWork/SessionDetail.test.tsx +84 -0
  79. package/src/components/custom/ActiveWork/SessionDetail.tsx +180 -0
  80. package/src/components/custom/ActiveWork/SessionList.stories.tsx +69 -0
  81. package/src/components/custom/ActiveWork/SessionList.test.tsx +78 -0
  82. package/src/components/custom/ActiveWork/SessionList.tsx +103 -0
  83. package/src/components/custom/ActiveWork/SessionListItem.stories.tsx +64 -0
  84. package/src/components/custom/ActiveWork/SessionListItem.test.tsx +62 -0
  85. package/src/components/custom/ActiveWork/SessionListItem.tsx +152 -0
  86. package/src/components/custom/ActiveWork/SessionReader.stories.tsx +113 -0
  87. package/src/components/custom/ActiveWork/SeverityLabel.stories.tsx +51 -0
  88. package/src/components/custom/ActiveWork/SeverityLabel.test.tsx +68 -0
  89. package/src/components/custom/ActiveWork/SeverityLabel.tsx +97 -0
  90. package/src/components/custom/ActiveWork/TaskRow.stories.tsx +63 -0
  91. package/src/components/custom/ActiveWork/TaskRow.test.tsx +112 -0
  92. package/src/components/custom/ActiveWork/TaskRow.tsx +176 -0
  93. package/src/components/custom/ActiveWork/TaskTable.stories.tsx +123 -0
  94. package/src/components/custom/ActiveWork/TaskTable.test.tsx +233 -0
  95. package/src/components/custom/ActiveWork/TaskTable.tsx +321 -0
  96. package/src/components/custom/ActiveWork/active-work-depth.test.tsx +102 -0
  97. package/src/components/custom/ActiveWork/file-history-fixture.ts +91 -0
  98. package/src/components/custom/ActiveWork/format-time.test.ts +23 -0
  99. package/src/components/custom/ActiveWork/format-time.ts +32 -0
  100. package/src/components/custom/ActiveWork/index.ts +19 -0
  101. package/src/components/custom/ActiveWork/initiative-fixture.ts +104 -0
  102. package/src/components/custom/ActiveWork/session-fixture.ts +267 -0
  103. package/src/components/custom/ActiveWork/session-linkers.ts +56 -0
  104. package/src/components/custom/ActiveWork/task-list-fixture.ts +97 -0
  105. package/src/components/custom/CircularTimer/CircularTimer.stories.tsx +4 -3
  106. package/src/components/custom/DateTime/DateTime.stories.tsx +2 -1
  107. package/src/components/custom/DateTime/DateTime.test.tsx +3 -1
  108. package/src/components/custom/EmptyState/EmptyState.stories.tsx +22 -9
  109. package/src/components/custom/EmptyState/EmptyState.test.tsx +7 -13
  110. package/src/components/custom/EmptyState/EmptyState.tsx +4 -18
  111. package/src/components/custom/Fatigue/DualGhostSpark.stories.tsx +4 -3
  112. package/src/components/custom/Fatigue/FatigueLights.stories.tsx +2 -2
  113. package/src/components/custom/Fatigue/GhostSpark.stories.tsx +4 -3
  114. package/src/components/custom/Fatigue/LiveFatigueCard.stories.tsx +2 -2
  115. package/src/components/custom/Fatigue/LiveFatigueCard.tsx +8 -4
  116. package/src/components/custom/Fatigue/LiveFatiguePanel.stories.tsx +116 -6
  117. package/src/components/custom/Fatigue/LiveFatiguePanel.test.tsx +134 -0
  118. package/src/components/custom/Fatigue/LiveFatiguePanel.tsx +54 -83
  119. package/src/components/custom/Fatigue/README.md +40 -3
  120. package/src/components/custom/Fatigue/RomProgressionChart.stories.tsx +2 -2
  121. package/src/components/custom/Fatigue/SilverRedPalette.stories.tsx +2 -1
  122. package/src/components/custom/Fatigue/VelocityHero.stories.tsx +4 -3
  123. package/src/components/custom/Fatigue/VerdictHero.stories.tsx +2 -2
  124. package/src/components/custom/Fatigue/fatigue-mock.test.ts +0 -5
  125. package/src/components/custom/Fatigue/fatigue-mock.ts +2 -10
  126. package/src/components/custom/Fatigue/fatigue-tokens.ts +12 -0
  127. package/src/components/custom/Fatigue/index.ts +17 -5
  128. package/src/components/custom/Fatigue/panel-layout.test.ts +149 -0
  129. package/src/components/custom/Fatigue/panel-layout.ts +185 -0
  130. package/src/components/custom/Gauge/Gauge.stories.tsx +2 -2
  131. package/src/components/custom/Gauge/Gauge.test.tsx +1 -1
  132. package/src/components/custom/Gauge/Gauge.tsx +4 -1
  133. package/src/components/custom/Metric/Metric.stories.tsx +10 -1
  134. package/src/components/custom/Metric/Metric.test.tsx +1 -3
  135. package/src/components/custom/Metric/Metric.tsx +5 -20
  136. package/src/components/custom/Prose/MarkdownProse.stories.tsx +88 -0
  137. package/src/components/custom/Prose/MarkdownProse.test.tsx +87 -0
  138. package/src/components/custom/Prose/MarkdownProse.tsx +201 -0
  139. package/src/components/custom/Prose/README.md +58 -0
  140. package/src/components/custom/Prose/index.ts +1 -0
  141. package/src/components/custom/Scatter/Scatter.stories.tsx +46 -8
  142. package/src/components/custom/Scatter/Scatter.test.tsx +2 -2
  143. package/src/components/custom/Scatter/Scatter.tsx +116 -14
  144. package/src/components/custom/Sidebar/Sidebar.stories.tsx +40 -7
  145. package/src/components/custom/Sidebar/Sidebar.test.tsx +5 -1
  146. package/src/components/custom/Sidebar/Sidebar.tsx +16 -33
  147. package/src/components/custom/Table/Table.stories.tsx +98 -15
  148. package/src/components/custom/Table/Table.test.tsx +273 -86
  149. package/src/components/custom/Table/Table.tsx +159 -67
  150. package/src/components/custom/Table/column-fit.test.ts +75 -0
  151. package/src/components/custom/Table/column-fit.ts +116 -0
  152. package/src/components/custom/Table/index.ts +9 -0
  153. package/src/components/custom/TimerReadout/TimerReadout.stories.tsx +8 -6
  154. package/src/components/custom/Treemap/Treemap.stories.tsx +2 -2
  155. package/src/components/custom/Treemap/Treemap.test.tsx +1 -1
  156. package/src/components/custom/Treemap/Treemap.tsx +7 -2
  157. package/src/components/custom/Typography/Typography.stories.tsx +28 -1
  158. package/src/components/custom/Typography/Typography.test.tsx +34 -0
  159. package/src/components/custom/Typography/Typography.tsx +6 -0
  160. package/src/components/custom/Typography/index.ts +1 -8
  161. package/src/components/custom/Workout/ActiveWorkoutPage.stories.tsx +9 -1
  162. package/src/components/custom/Workout/BaseBadge.stories.tsx +19 -7
  163. package/src/components/custom/Workout/BaseBadge.test.tsx +31 -11
  164. package/src/components/custom/Workout/BaseBadge.tsx +3 -0
  165. package/src/components/custom/Workout/BodyMap.stories.tsx +4 -1
  166. package/src/components/custom/Workout/BodyMap.tsx +3 -1
  167. package/src/components/custom/Workout/BodyMapDetailPanel.stories.tsx +16 -4
  168. package/src/components/custom/Workout/BodyMapDetailPanel.test.tsx +11 -15
  169. package/src/components/custom/Workout/BodyMapDetailPanel.tsx +45 -9
  170. package/src/components/custom/Workout/CapacityBandChart.stories.tsx +10 -8
  171. package/src/components/custom/Workout/CapacityBandChart.test.tsx +24 -51
  172. package/src/components/custom/Workout/CapacityBandChart.tsx +139 -108
  173. package/src/components/custom/Workout/DeviationBar.stories.tsx +1 -1
  174. package/src/components/custom/Workout/DeviationBar.test.tsx +5 -2
  175. package/src/components/custom/Workout/DeviationBar.tsx +21 -16
  176. package/src/components/custom/Workout/DualVelocityStrip.stories.tsx +182 -0
  177. package/src/components/custom/Workout/DualVelocityStrip.test.tsx +3 -2
  178. package/src/components/custom/Workout/ExerciseCard.stories.tsx +8 -7
  179. package/src/components/custom/Workout/ExerciseCard.test.tsx +13 -3
  180. package/src/components/custom/Workout/ExerciseCard.tsx +42 -51
  181. package/src/components/custom/Workout/ExerciseCardHeading.stories.tsx +7 -7
  182. package/src/components/custom/Workout/ExerciseDetailPage.stories.tsx +9 -1
  183. package/src/components/custom/Workout/ExerciseHeading.stories.tsx +8 -8
  184. package/src/components/custom/Workout/ExerciseHeading.tsx +8 -5
  185. package/src/components/custom/Workout/ExerciseIndicator.stories.tsx +6 -4
  186. package/src/components/custom/Workout/ExerciseIndicator.test.tsx +27 -11
  187. package/src/components/custom/Workout/ExerciseIndicator.tsx +14 -15
  188. package/src/components/custom/Workout/FatigueMeter.stories.tsx +5 -5
  189. package/src/components/custom/Workout/InputBar.stories.tsx +4 -5
  190. package/src/components/custom/Workout/IntensityBar.stories.tsx +1 -1
  191. package/src/components/custom/Workout/IntensityBar.test.tsx +5 -1
  192. package/src/components/custom/Workout/IntensityBar.tsx +4 -2
  193. package/src/components/custom/Workout/LiveAuraFrame.stories.tsx +5 -4
  194. package/src/components/custom/Workout/MesoCard.stories.tsx +4 -1
  195. package/src/components/custom/Workout/MesoCard.test.tsx +7 -18
  196. package/src/components/custom/Workout/MesoCard.tsx +12 -9
  197. package/src/components/custom/Workout/MesoProgressBar.stories.tsx +1 -1
  198. package/src/components/custom/Workout/MesoProgressBar.test.tsx +18 -11
  199. package/src/components/custom/Workout/MesoProgressBar.tsx +15 -13
  200. package/src/components/custom/Workout/MesoStatusCard.stories.tsx +2 -1
  201. package/src/components/custom/Workout/MesoStatusCard.test.tsx +14 -44
  202. package/src/components/custom/Workout/MesoStatusCard.tsx +9 -23
  203. package/src/components/custom/Workout/MetricTiles.stories.tsx +3 -2
  204. package/src/components/custom/Workout/MuscleGroupChip.stories.tsx +2 -8
  205. package/src/components/custom/Workout/MuscleGroupChip.test.tsx +23 -31
  206. package/src/components/custom/Workout/MuscleGroupChip.tsx +28 -67
  207. package/src/components/custom/Workout/PlaceholderStrip.stories.tsx +1 -1
  208. package/src/components/custom/Workout/PlaceholderStrip.test.tsx +17 -10
  209. package/src/components/custom/Workout/PlaceholderStrip.tsx +9 -8
  210. package/src/components/custom/Workout/PrBadge.stories.tsx +2 -1
  211. package/src/components/custom/Workout/PrBadge.test.tsx +3 -9
  212. package/src/components/custom/Workout/PrBadge.tsx +13 -17
  213. package/src/components/custom/Workout/PrHistoryModal.stories.tsx +4 -1
  214. package/src/components/custom/Workout/PrHistoryModal.test.tsx +13 -36
  215. package/src/components/custom/Workout/PrHistoryModal.tsx +8 -4
  216. package/src/components/custom/Workout/ProgramPlanningPage.stories.tsx +6 -1
  217. package/src/components/custom/Workout/README.md +12 -7
  218. package/src/components/custom/Workout/ReadinessCheck.stories.tsx +3 -2
  219. package/src/components/custom/Workout/ReadinessCheck.test.tsx +12 -18
  220. package/src/components/custom/Workout/ReadinessCheck.tsx +19 -3
  221. package/src/components/custom/Workout/RestTimer.stories.tsx +3 -2
  222. package/src/components/custom/Workout/ScheduleTiles.stories.tsx +3 -2
  223. package/src/components/custom/Workout/ScheduleTiles.test.tsx +3 -4
  224. package/src/components/custom/Workout/ScheduleTiles.tsx +4 -7
  225. package/src/components/custom/Workout/SegmentedBar.stories.tsx +5 -5
  226. package/src/components/custom/Workout/SegmentedBar.tsx +6 -2
  227. package/src/components/custom/Workout/SegmentedProgressBar.stories.tsx +5 -5
  228. package/src/components/custom/Workout/SessionHeader.stories.tsx +6 -6
  229. package/src/components/custom/Workout/SessionHeader.tsx +12 -12
  230. package/src/components/custom/Workout/SessionRail.stories.tsx +12 -11
  231. package/src/components/custom/Workout/SessionRail.tsx +7 -9
  232. package/src/components/custom/Workout/SetBar.stories.tsx +10 -6
  233. package/src/components/custom/Workout/SetBar.test.tsx +49 -4
  234. package/src/components/custom/Workout/SetBar.tsx +38 -12
  235. package/src/components/custom/Workout/SetRow.stories.tsx +3 -2
  236. package/src/components/custom/Workout/SetRow.test.tsx +16 -2
  237. package/src/components/custom/Workout/SetRow.tsx +61 -23
  238. package/src/components/custom/Workout/SetStrip.stories.tsx +60 -5
  239. package/src/components/custom/Workout/SetStrip.test.tsx +25 -0
  240. package/src/components/custom/Workout/SetStrip.tsx +24 -4
  241. package/src/components/custom/Workout/SetTableHeader.stories.tsx +6 -6
  242. package/src/components/custom/Workout/SetTableHeader.tsx +9 -12
  243. package/src/components/custom/Workout/SetsRepsLoad.stories.tsx +7 -7
  244. package/src/components/custom/Workout/SetsRepsLoad.tsx +3 -5
  245. package/src/components/custom/Workout/Sparkline.stories.tsx +1 -1
  246. package/src/components/custom/Workout/Sparkline.test.tsx +37 -19
  247. package/src/components/custom/Workout/Sparkline.tsx +14 -18
  248. package/src/components/custom/Workout/StatusDot.stories.tsx +1 -1
  249. package/src/components/custom/Workout/StatusDot.test.tsx +44 -5
  250. package/src/components/custom/Workout/StatusDot.tsx +93 -63
  251. package/src/components/custom/Workout/StatusPill.stories.tsx +1 -1
  252. package/src/components/custom/Workout/StatusPill.test.tsx +6 -15
  253. package/src/components/custom/Workout/StatusPill.tsx +27 -38
  254. package/src/components/custom/Workout/StrengthTrendChart.stories.tsx +9 -3
  255. package/src/components/custom/Workout/StrengthTrendChart.test.tsx +15 -37
  256. package/src/components/custom/Workout/StrengthTrendChart.tsx +31 -30
  257. package/src/components/custom/Workout/SupersetWrapper.stories.tsx +27 -64
  258. package/src/components/custom/Workout/SupersetWrapper.test.tsx +16 -14
  259. package/src/components/custom/Workout/SupersetWrapper.tsx +17 -21
  260. package/src/components/custom/Workout/TempoDisplay.stories.tsx +22 -7
  261. package/src/components/custom/Workout/TempoDisplay.test.tsx +18 -4
  262. package/src/components/custom/Workout/TrainingStatusPage.stories.tsx +9 -1
  263. package/src/components/custom/Workout/VelocityStrip.compact.stories.tsx +4 -1
  264. package/src/components/custom/Workout/VelocityStrip.dual.stories.tsx +7 -4
  265. package/src/components/custom/Workout/VelocityStrip.expanded.stories.tsx +4 -1
  266. package/src/components/custom/Workout/VelocityStrip.hero.stories.tsx +4 -1
  267. package/src/components/custom/Workout/VelocityStrip.stories.tsx +12 -6
  268. package/src/components/custom/Workout/VelocityStrip.tsx +3 -0
  269. package/src/components/custom/Workout/VolumeLandmarkBar.stories.tsx +6 -7
  270. package/src/components/custom/Workout/VolumeLandmarkBar.tsx +15 -6
  271. package/src/components/custom/Workout/WeekRow.stories.tsx +4 -1
  272. package/src/components/custom/Workout/WeekRow.test.tsx +18 -15
  273. package/src/components/custom/Workout/WeekRow.tsx +23 -16
  274. package/src/components/custom/Workout/WeightBadge.stories.tsx +2 -1
  275. package/src/components/custom/Workout/WeightBadge.test.tsx +50 -19
  276. package/src/components/custom/Workout/WeightBadge.tsx +28 -27
  277. package/src/components/custom/Workout/WorkoutCard.stories.tsx +6 -1
  278. package/src/components/custom/Workout/WorkoutCard.test.tsx +18 -0
  279. package/src/components/custom/Workout/WorkoutCard.tsx +35 -57
  280. package/src/components/custom/Workout/WorkoutPill.stories.tsx +5 -2
  281. package/src/components/custom/Workout/WorkoutPill.test.tsx +39 -7
  282. package/src/components/custom/Workout/WorkoutPill.tsx +88 -57
  283. package/src/components/custom/Workout/ZoneTrack.stories.tsx +7 -6
  284. package/src/components/custom/Workout/ZoneTrack.tsx +10 -9
  285. package/src/components/custom/Workout/index.ts +5 -0
  286. package/src/components/custom/Workout/metricText.stories.tsx +6 -5
  287. package/src/components/custom/Workout/metricText.tsx +4 -0
  288. package/src/components/custom/Workout/setHeadingKit.tsx +207 -26
  289. package/src/components/custom/charts/README.md +61 -0
  290. package/src/components/custom/charts/SetBarChart.test.tsx +30 -1
  291. package/src/components/custom/charts/SetBarChart.tsx +42 -4
  292. package/src/components/custom/charts/SparkBars.stories.tsx +55 -0
  293. package/src/components/custom/charts/SparkBars.test.tsx +69 -0
  294. package/src/components/custom/charts/SparkBars.tsx +85 -0
  295. package/src/components/custom/charts/index.ts +3 -0
  296. package/src/components/custom/index.ts +3 -0
  297. package/src/components/custom/stepper/Stepper.stories.tsx +13 -10
  298. package/src/components/custom/stepper/Stepper.test.tsx +1 -7
  299. package/src/components/custom/stepper/Stepper.tsx +13 -28
  300. package/src/components/icons/icons.stories.tsx +1 -1
  301. package/src/components/icons/icons.tsx +51 -0
  302. package/src/components/shell/AppShell.stories.tsx +150 -0
  303. package/src/components/shell/AppShell.test.tsx +70 -0
  304. package/src/components/shell/AppShell.tsx +90 -0
  305. package/src/components/shell/BrandLockup.stories.tsx +66 -5
  306. package/src/components/shell/BrandLockup.test.tsx +34 -1
  307. package/src/components/shell/BrandLockup.tsx +27 -11
  308. package/src/components/shell/NavItem.stories.tsx +4 -4
  309. package/src/components/shell/NavItem.test.tsx +17 -0
  310. package/src/components/shell/NavItem.tsx +17 -5
  311. package/src/components/shell/README.md +90 -27
  312. package/src/components/shell/SideNav.stories.tsx +38 -7
  313. package/src/components/shell/SideNav.test.tsx +16 -8
  314. package/src/components/shell/SideNav.tsx +17 -17
  315. package/src/components/shell/TopBar.stories.tsx +44 -19
  316. package/src/components/shell/TopBar.test.tsx +34 -12
  317. package/src/components/shell/TopBar.tsx +61 -40
  318. package/src/components/shell/brands.tsx +66 -0
  319. package/src/components/shell/index.ts +9 -8
  320. package/src/components/shell/{DeviceIndicator.stories.tsx → workout/DeviceIndicator.stories.tsx} +2 -2
  321. package/src/components/shell/{DeviceIndicator.tsx → workout/DeviceIndicator.tsx} +2 -2
  322. package/src/components/shell/{DeviceMenu.stories.tsx → workout/DeviceMenu.stories.tsx} +2 -2
  323. package/src/components/shell/{DeviceMenu.tsx → workout/DeviceMenu.tsx} +3 -3
  324. package/src/components/shell/{DeviceRow.stories.tsx → workout/DeviceRow.stories.tsx} +2 -2
  325. package/src/components/shell/{DeviceRow.tsx → workout/DeviceRow.tsx} +3 -3
  326. package/src/components/shell/{SessionStatePill.stories.tsx → workout/SessionStatePill.stories.tsx} +2 -2
  327. package/src/components/shell/{SessionStatePill.tsx → workout/SessionStatePill.tsx} +5 -3
  328. package/src/components/shell/workout/WorkoutShell.stories.tsx +71 -0
  329. package/src/components/shell/{DashboardShell.test.tsx → workout/WorkoutShell.test.tsx} +19 -8
  330. package/src/components/shell/workout/WorkoutShell.tsx +77 -0
  331. package/src/components/shell/workout/WorkoutTopBar.stories.tsx +58 -0
  332. package/src/components/shell/workout/WorkoutTopBar.test.tsx +39 -0
  333. package/src/components/shell/workout/WorkoutTopBar.tsx +52 -0
  334. package/src/components/shell/workout/index.ts +9 -0
  335. package/src/components/shell/workout/workoutNavItems.tsx +16 -0
  336. package/src/components/ui/README.md +110 -0
  337. package/src/components/ui/alert/Alert.stories.tsx +1 -1
  338. package/src/components/ui/autocomplete/Autocomplete.stories.tsx +11 -13
  339. package/src/components/ui/autocomplete/Autocomplete.test.tsx +7 -25
  340. package/src/components/ui/autocomplete/Autocomplete.tsx +21 -28
  341. package/src/components/ui/avatar/Avatar.stories.tsx +1 -1
  342. package/src/components/ui/avatar/Avatar.tsx +2 -10
  343. package/src/components/ui/badge/Badge.stories.tsx +83 -28
  344. package/src/components/ui/badge/Badge.test.tsx +19 -3
  345. package/src/components/ui/badge/Badge.tsx +48 -55
  346. package/src/components/ui/breadcrumbs/Breadcrumbs.stories.tsx +1 -1
  347. package/src/components/ui/breadcrumbs/Breadcrumbs.tsx +4 -16
  348. package/src/components/ui/button/Button.stories.tsx +46 -12
  349. package/src/components/ui/button/Button.tsx +32 -25
  350. package/src/components/ui/card/Card.stories.tsx +90 -94
  351. package/src/components/ui/card/Card.test.tsx +80 -6
  352. package/src/components/ui/card/Card.tsx +150 -203
  353. package/src/components/ui/checkbox/Checkbox.stories.tsx +1 -1
  354. package/src/components/ui/checkbox/Checkbox.tsx +6 -26
  355. package/src/components/ui/chip/Chip.stories.tsx +37 -13
  356. package/src/components/ui/chip/Chip.test.tsx +10 -6
  357. package/src/components/ui/chip/Chip.tsx +76 -91
  358. package/src/components/ui/collapse/Collapse.stories.tsx +23 -23
  359. package/src/components/ui/collapse/Collapse.tsx +6 -11
  360. package/src/components/ui/data-row/DataRow.stories.tsx +9 -2
  361. package/src/components/ui/data-row/DataRow.test.tsx +5 -15
  362. package/src/components/ui/data-row/DataRow.tsx +18 -7
  363. package/src/components/ui/divider/Divider.stories.tsx +1 -1
  364. package/src/components/ui/divider/Divider.tsx +1 -5
  365. package/src/components/ui/drawer/Drawer.stories.tsx +5 -16
  366. package/src/components/ui/drawer/Drawer.tsx +13 -30
  367. package/src/components/ui/floating-overlay-depth.test.tsx +143 -0
  368. package/src/components/ui/form-field/FormField.stories.tsx +6 -20
  369. package/src/components/ui/form-field/FormField.test.tsx +1 -5
  370. package/src/components/ui/form-field/FormField.tsx +10 -46
  371. package/src/components/ui/help-tip/HelpTip.stories.tsx +8 -19
  372. package/src/components/ui/help-tip/HelpTip.test.tsx +1 -3
  373. package/src/components/ui/help-tip/HelpTip.tsx +21 -22
  374. package/src/components/ui/help-tip/index.ts +7 -1
  375. package/src/components/ui/icon-box/IconBox.stories.tsx +1 -1
  376. package/src/components/ui/icon-box/IconBox.test.tsx +1 -7
  377. package/src/components/ui/icon-box/IconBox.tsx +2 -12
  378. package/src/components/ui/indicator/Indicator.stories.tsx +1 -1
  379. package/src/components/ui/indicator/Indicator.tsx +20 -14
  380. package/src/components/ui/input/Input.stories.tsx +3 -11
  381. package/src/components/ui/input/Input.test.tsx +2 -10
  382. package/src/components/ui/input/Input.tsx +10 -25
  383. package/src/components/ui/input/index.ts +7 -1
  384. package/src/components/ui/link/Link.stories.tsx +19 -7
  385. package/src/components/ui/list-item/ListItem.stories.tsx +11 -2
  386. package/src/components/ui/list-item/ListItem.tsx +2 -9
  387. package/src/components/ui/menu/Menu.stories.tsx +21 -15
  388. package/src/components/ui/menu/Menu.test.tsx +2 -11
  389. package/src/components/ui/menu/Menu.tsx +12 -14
  390. package/src/components/ui/menu/index.ts +8 -1
  391. package/src/components/ui/modal/Modal.stories.tsx +2 -2
  392. package/src/components/ui/modal/Modal.tsx +29 -19
  393. package/src/components/ui/pill/Pill.stories.tsx +58 -23
  394. package/src/components/ui/pill/Pill.test.tsx +101 -3
  395. package/src/components/ui/pill/Pill.tsx +164 -49
  396. package/src/components/ui/pill/index.ts +1 -1
  397. package/src/components/ui/popover/Popover.stories.tsx +5 -7
  398. package/src/components/ui/popover/Popover.test.tsx +1 -6
  399. package/src/components/ui/popover/Popover.tsx +20 -15
  400. package/src/components/ui/popover/index.ts +7 -1
  401. package/src/components/ui/progress/Progress.stories.tsx +3 -12
  402. package/src/components/ui/progress/Progress.test.tsx +1 -5
  403. package/src/components/ui/radio/Radio.stories.tsx +42 -21
  404. package/src/components/ui/radio/Radio.test.tsx +6 -2
  405. package/src/components/ui/radio/Radio.tsx +23 -22
  406. package/src/components/ui/section/Section.stories.tsx +5 -14
  407. package/src/components/ui/section/Section.test.tsx +1 -6
  408. package/src/components/ui/section/Section.tsx +1 -3
  409. package/src/components/ui/section/index.ts +1 -5
  410. package/src/components/ui/select/Select.stories.tsx +3 -13
  411. package/src/components/ui/select/Select.test.tsx +2 -11
  412. package/src/components/ui/select/Select.tsx +14 -14
  413. package/src/components/ui/skeleton/Skeleton.stories.tsx +3 -11
  414. package/src/components/ui/skeleton/Skeleton.tsx +3 -14
  415. package/src/components/ui/skeleton/index.ts +1 -7
  416. package/src/components/ui/spinner/Spinner.stories.tsx +1 -1
  417. package/src/components/ui/spinner/Spinner.tsx +1 -4
  418. package/src/components/ui/stack/Stack.stories.tsx +1 -1
  419. package/src/components/ui/stack/Stack.tsx +1 -1
  420. package/src/components/ui/surface/Surface.stories.tsx +17 -5
  421. package/src/components/ui/surface/Surface.test.tsx +88 -28
  422. package/src/components/ui/surface/Surface.tsx +37 -87
  423. package/src/components/ui/surface/SurfaceContext.ts +22 -62
  424. package/src/components/ui/surface/index.ts +8 -0
  425. package/src/components/ui/surface/resolveSurface.ts +98 -0
  426. package/src/components/ui/surface/surface.contract.test.ts +6 -1
  427. package/src/components/ui/switch/Switch.stories.tsx +1 -1
  428. package/src/components/ui/switch/Switch.tsx +7 -6
  429. package/src/components/ui/tabs/Tabs.stories.tsx +1 -1
  430. package/src/components/ui/tabs/Tabs.tsx +7 -22
  431. package/src/components/ui/tabs/index.ts +1 -7
  432. package/src/components/ui/tile/Tile.stories.tsx +1 -1
  433. package/src/components/ui/tile/Tile.tsx +3 -0
  434. package/src/components/ui/toast/Toast.stories.tsx +1 -1
  435. package/src/components/ui/toast/Toast.test.tsx +2 -8
  436. package/src/components/ui/toast/Toast.tsx +43 -53
  437. package/src/components/ui/toast/index.ts +0 -1
  438. package/src/components/ui/toolbar-button/ToolbarButton.stories.tsx +92 -71
  439. package/src/components/ui/toolbar-button/ToolbarButton.test.tsx +3 -18
  440. package/src/components/ui/toolbar-button/ToolbarButton.tsx +25 -43
  441. package/src/components/ui/tooltip/Tooltip.stories.tsx +12 -3
  442. package/src/components/ui/tooltip/Tooltip.test.tsx +21 -3
  443. package/src/components/ui/tooltip/Tooltip.tsx +55 -36
  444. package/src/components/ui/tooltip/index.ts +1 -1
  445. package/src/components/ui/trigger/TriggerSurface.test.tsx +215 -0
  446. package/src/components/ui/trigger/TriggerSurface.tsx +81 -0
  447. package/src/components/ui/trigger/index.ts +2 -0
  448. package/src/stories/PresetShowcase.stories.tsx +100 -47
  449. package/src/test/no-device-internals.test.ts +3 -3
  450. package/src/theme/ChoosingTokens.stories.tsx +48 -0
  451. package/src/theme/ColorPalettes.stories.tsx +62 -45
  452. package/src/theme/ColorPrimitives.stories.tsx +35 -35
  453. package/src/theme/Depth.stories.tsx +132 -65
  454. package/src/theme/DepthCalibration.stories.tsx +24 -22
  455. package/src/theme/ThemeProvider.test.tsx +4 -4
  456. package/src/theme/barrel.ts +7 -6
  457. package/src/theme/color-stories.coverage.test.ts +1 -1
  458. package/src/theme/color-utils.ts +41 -29
  459. package/src/theme/config.completeness.test.ts +1 -1
  460. package/src/theme/config.ts +28 -0
  461. package/src/theme/elevation.test.ts +82 -56
  462. package/src/theme/elevation.ts +77 -561
  463. package/src/theme/global.css +30 -2
  464. package/src/theme/grey-ramp.test.ts +24 -8
  465. package/src/theme/lift.test.ts +39 -0
  466. package/src/theme/lift.ts +102 -0
  467. package/src/theme/materials.test.ts +5 -2
  468. package/src/theme/materials.ts +38 -4
  469. package/src/theme/native-theming-guard.test.ts +5 -5
  470. package/src/theme/presets/apply.ts +4 -0
  471. package/src/theme/presets/audiobook.ts +5 -2
  472. package/src/theme/presets/default.ts +4 -0
  473. package/src/theme/presets/index.ts +14 -1
  474. package/src/theme/presets/types.ts +1 -1
  475. package/src/theme/semantic-contrast.test.ts +13 -4
  476. package/src/theme/status-distinctness.test.ts +66 -0
  477. package/src/theme/surface-planes.test.ts +37 -0
  478. package/src/theme/surface-planes.ts +68 -0
  479. package/src/theme/token-export-guard.test.ts +102 -0
  480. package/src/theme/tokens/primitives.test.ts +15 -7
  481. package/src/theme/tokens/primitives.ts +67 -35
  482. package/src/theme/tokens/semantic.ts +71 -37
  483. package/src/theme/wash-ladder.test.ts +58 -0
  484. package/src/theme/workout-tokens.ts +1 -7
  485. package/src/types/jest-axe.d.ts +2 -6
  486. package/src/types/raw-md.d.ts +5 -0
  487. package/src/utils/colors.ts +4 -4
  488. package/src/utils/form.ts +1 -3
  489. package/src/utils/index.ts +2 -7
  490. package/src/utils/number-format.ts +17 -0
  491. package/src/utils/workout-format.ts +15 -6
  492. package/src/web-jsx/jsx-runtime.ts +1 -5
  493. package/tailwind.config.js +5 -0
  494. package/src/components/custom/Workout/ExerciseCardUnified.stories.tsx +0 -151
  495. package/src/components/custom/Workout/RowInventory.stories.tsx +0 -408
  496. package/src/components/custom/Workout/S3FullRail.stories.tsx +0 -46
  497. package/src/components/custom/Workout/S3SessionPace.stories.tsx +0 -95
  498. package/src/components/custom/Workout/S3SessionRailHeading.stories.tsx +0 -61
  499. package/src/components/custom/Workout/S3SetTypes.stories.tsx +0 -176
  500. package/src/components/custom/Workout/S3WorkoutExpansion.stories.tsx +0 -240
  501. package/src/components/shell/DashboardShell.stories.tsx +0 -65
  502. package/src/components/shell/DashboardShell.tsx +0 -75
  503. package/src/components/shell/SessionRailSpecimen.stories.tsx +0 -753
  504. package/src/theme/elevation.stories.tsx +0 -346
  505. package/src/utils/useTheme.ts +0 -72
  506. /package/src/components/shell/{DeviceIndicator.test.tsx → workout/DeviceIndicator.test.tsx} +0 -0
  507. /package/src/components/shell/{DeviceMenu.test.tsx → workout/DeviceMenu.test.tsx} +0 -0
  508. /package/src/components/shell/{DeviceRow.test.tsx → workout/DeviceRow.test.tsx} +0 -0
  509. /package/src/components/shell/{SessionStatePill.test.tsx → workout/SessionStatePill.test.tsx} +0 -0
@@ -0,0 +1,58 @@
1
+ # `custom/Prose` — long-form text rendering
2
+
3
+ One component. It exists because the ActiveWork readers display markdown written
4
+ by humans and agents — briefs, session notes, open loops — and a `<Text>` per
5
+ paragraph loses headings, bullets, emphasis and, critically, the domain
6
+ references (`AW-124`, `#172`, a file path) that make that prose navigable.
7
+
8
+ This README is the **index**: **composes ↓** and **used-by ↑**, so the tree
9
+ navigates both ways. Counts come from
10
+ [`src/arch/arch-graph.json`](../../../arch/arch-graph.json).
11
+
12
+ ## Dependency map
13
+
14
+ | Member | Kind | Composes ↓ | Used-by ↑ |
15
+ | ------------------------------- | -------- | ------------------ | ---------------------------------------------------------- |
16
+ | `MarkdownProse` | molecule | `Typography`, `cn` | InitiativeBrief, OpenLoops, SessionDetail (all ActiveWork) |
17
+ | `parseProseBlocks` | pure fn | — | `MarkdownProse`, and its own tests |
18
+ | `ProseLinker` / `ProseLinkTone` | types | — | every consumer that supplies reference patterns |
19
+
20
+ Four in-repo consumers, zero external — `keep-internal` in the arch graph. The
21
+ parser is exported separately on purpose: block-splitting is the part worth
22
+ testing directly, and it is testable without rendering.
23
+
24
+ ## The two halves
25
+
26
+ **`parseProseBlocks(body)`** splits markdown into the five block kinds this
27
+ renderer understands (`h1` `h2` `h3` `li` `p`). Consecutive text lines join into
28
+ one paragraph and a blank line ends it; an indented line straight after a bullet
29
+ continues that bullet; deeper headings flatten to `h3`, because session prose
30
+ never needs more than three levels. It is pure, so it is unit-tested on its own.
31
+
32
+ **`MarkdownProse`** renders those blocks and inline-links references. `linkers`
33
+ is an ordered list of `{ id, pattern, tone, label, onPress }`; the renderer
34
+ combines the patterns into one tokenizer, which is why **a `ProseLinker.pattern`
35
+ must carry neither the `g` flag nor capture groups**. `tone` chooses how a
36
+ reference reads: `brand` for the domain's own ids, `link` for cross-references,
37
+ `muted` for asides. A linker with `onPress` becomes pressable and takes a link
38
+ role; without one it is styled text, not an interactive element.
39
+
40
+ ## Reuse audit
41
+
42
+ | Leaf | Should compose | Status |
43
+ | ---------------------- | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
44
+ | Headings and body copy | `Typography` | **Closed.** `h1`/`h2` → `h5`/`h6`, `h3` → `subtitle2`, paragraphs and bullets → `body2`. |
45
+ | Bold and code spans | `Typography` | **Open, deliberately.** Inline spans are raw `<Text>` with `font-semibold` / `font-mono`, because they nest inside a parent `<Text>` run where a `Typography` block would break the flow. |
46
+ | Bullet glyph | a shared list mark | **Open.** The `•` is drawn inline. One consumer family, so no primitive is justified yet — revisit at the second. |
47
+ | Colour | semantic tokens | **Closed.** `text-text-primary` / `text-brand-primary` throughout; the family is in the token-pure eslint error block. |
48
+ | Class merging | `cn()` | **Closed.** |
49
+
50
+ ## Watch list
51
+
52
+ - **The tokenizer contract is unenforced.** A `linkers` entry with a `g` flag or a
53
+ capture group breaks reference splitting at runtime with no type error. If a
54
+ third consumer arrives, validate in `MarkdownProse` rather than in each caller.
55
+ - **Markdown coverage is intentionally partial** — no tables, links, images,
56
+ blockquotes or nested lists. Widen it only against a real document that needs
57
+ it; the parser's value is that it is small enough to read.
58
+ - **Zero external consumers.** Prop changes are cheap while that holds.
@@ -0,0 +1 @@
1
+ export * from './MarkdownProse'
@@ -2,9 +2,9 @@ import type { Meta, StoryObj } from '@storybook/react-vite'
2
2
  import { Scatter, type ScatterDatum } from './Scatter'
3
3
 
4
4
  const meta: Meta<typeof Scatter> = {
5
- title: 'Components/DataViz/Scatter',
5
+ title: 'Custom/Charts/Scatter',
6
6
  component: Scatter,
7
- tags: ['autodocs'],
7
+ tags: ['autodocs', 'status:candidate', '!status:review'],
8
8
  argTypes: {
9
9
  width: { control: { type: 'range', min: 240, max: 800, step: 20 } },
10
10
  height: { control: { type: 'range', min: 180, max: 600, step: 20 } },
@@ -30,7 +30,14 @@ export const Default: Story = {
30
30
  width: 480,
31
31
  height: 340,
32
32
  diagonal: true,
33
- axis: { xLabel: 'Instability (I)', yLabel: 'Abstractness (A)', xMin: 0, xMax: 1, yMin: 0, yMax: 1 },
33
+ axis: {
34
+ xLabel: 'Instability (I)',
35
+ yLabel: 'Abstractness (A)',
36
+ xMin: 0,
37
+ xMax: 1,
38
+ yMin: 0,
39
+ yMax: 1,
40
+ },
34
41
  },
35
42
  }
36
43
 
@@ -39,7 +46,14 @@ export const NoDiagonal: Story = {
39
46
  data: mainSequence,
40
47
  width: 480,
41
48
  height: 340,
42
- axis: { xLabel: 'Instability (I)', yLabel: 'Abstractness (A)', xMin: 0, xMax: 1, yMin: 0, yMax: 1 },
49
+ axis: {
50
+ xLabel: 'Instability (I)',
51
+ yLabel: 'Abstractness (A)',
52
+ xMin: 0,
53
+ xMax: 1,
54
+ yMin: 0,
55
+ yMax: 1,
56
+ },
43
57
  },
44
58
  }
45
59
 
@@ -50,7 +64,14 @@ export const Selected: Story = {
50
64
  height: 340,
51
65
  diagonal: true,
52
66
  selectedId: 'utils',
53
- axis: { xLabel: 'Instability (I)', yLabel: 'Abstractness (A)', xMin: 0, xMax: 1, yMin: 0, yMax: 1 },
67
+ axis: {
68
+ xLabel: 'Instability (I)',
69
+ yLabel: 'Abstractness (A)',
70
+ xMin: 0,
71
+ xMax: 1,
72
+ yMin: 0,
73
+ yMax: 1,
74
+ },
54
75
  },
55
76
  }
56
77
 
@@ -67,11 +88,21 @@ export const SinglePoint: Story = {
67
88
  /** An outlier far outside the main cluster, kept legible by an explicit domain. */
68
89
  export const Outlier: Story = {
69
90
  args: {
70
- data: [...mainSequence, { id: 'legacy', x: 0.98, y: 0.98, r: 16, color: '#F83030', label: 'legacy.ts' }],
91
+ data: [
92
+ ...mainSequence,
93
+ { id: 'legacy', x: 0.98, y: 0.98, r: 16, color: '#F83030', label: 'legacy.ts' },
94
+ ],
71
95
  width: 480,
72
96
  height: 340,
73
97
  diagonal: true,
74
- axis: { xLabel: 'Instability (I)', yLabel: 'Abstractness (A)', xMin: 0, xMax: 1, yMin: 0, yMax: 1 },
98
+ axis: {
99
+ xLabel: 'Instability (I)',
100
+ yLabel: 'Abstractness (A)',
101
+ xMin: 0,
102
+ xMax: 1,
103
+ yMin: 0,
104
+ yMax: 1,
105
+ },
75
106
  },
76
107
  }
77
108
 
@@ -80,6 +111,13 @@ export const Empty: Story = {
80
111
  data: [],
81
112
  width: 400,
82
113
  height: 300,
83
- axis: { xLabel: 'Instability (I)', yLabel: 'Abstractness (A)', xMin: 0, xMax: 1, yMin: 0, yMax: 1 },
114
+ axis: {
115
+ xLabel: 'Instability (I)',
116
+ yLabel: 'Abstractness (A)',
117
+ xMin: 0,
118
+ xMax: 1,
119
+ yMin: 0,
120
+ yMax: 1,
121
+ },
84
122
  },
85
123
  }
@@ -68,7 +68,7 @@ describe('Scatter', () => {
68
68
  width={200}
69
69
  height={200}
70
70
  axis={{ xMin: 0, xMax: 1000, yMin: 0, yMax: 1000 }}
71
- />,
71
+ />
72
72
  )
73
73
  expect(screen.getByTestId('scatter-point-big')).toBeInTheDocument()
74
74
  })
@@ -83,7 +83,7 @@ describe('Scatter', () => {
83
83
 
84
84
  it('has no accessibility violations', async () => {
85
85
  const { container } = render(
86
- <Scatter {...base} diagonal axis={{ xLabel: 'I', yLabel: 'A' }} selectedId="b" />,
86
+ <Scatter {...base} diagonal axis={{ xLabel: 'I', yLabel: 'A' }} selectedId="b" />
87
87
  )
88
88
  expect(await axe(container)).toHaveNoViolations()
89
89
  })
@@ -86,8 +86,20 @@ function formatTick(v: number): string {
86
86
 
87
87
  /** A single straight segment drawn as one rotated View (SVG-free). */
88
88
  function LineSegment({
89
- x1, y1, x2, y2, color, testID,
90
- }: { x1: number; y1: number; x2: number; y2: number; color: string; testID: string }) {
89
+ x1,
90
+ y1,
91
+ x2,
92
+ y2,
93
+ color,
94
+ testID,
95
+ }: {
96
+ x1: number
97
+ y1: number
98
+ x2: number
99
+ y2: number
100
+ color: string
101
+ testID: string
102
+ }) {
91
103
  const dx = x2 - x1
92
104
  const dy = y2 - y1
93
105
  const length = Math.sqrt(dx * dx + dy * dy)
@@ -132,8 +144,16 @@ export function Scatter({
132
144
  }: ScatterProps) {
133
145
  const innerW = Math.max(1, width - PLOT_LEFT - PLOT_RIGHT)
134
146
  const innerH = Math.max(1, height - PLOT_TOP - PLOT_BOTTOM)
135
- const xd = domainOf(data.map((d) => d.x), axis.xMin, axis.xMax)
136
- const yd = domainOf(data.map((d) => d.y), axis.yMin, axis.yMax)
147
+ const xd = domainOf(
148
+ data.map((d) => d.x),
149
+ axis.xMin,
150
+ axis.xMax
151
+ )
152
+ const yd = domainOf(
153
+ data.map((d) => d.y),
154
+ axis.yMin,
155
+ axis.yMax
156
+ )
137
157
 
138
158
  const toX = (x: number) => PLOT_LEFT + ((x - xd.min) / (xd.max - xd.min)) * innerW
139
159
  const toY = (y: number) => PLOT_TOP + (1 - (y - yd.min) / (yd.max - yd.min)) * innerH
@@ -164,9 +184,25 @@ export function Scatter({
164
184
  key={`y-${i}`}
165
185
  accessibilityElementsHidden
166
186
  testID="scatter-gridline-y"
167
- style={{ position: 'absolute', left: PLOT_LEFT, width: innerW, top: y, height: 1, backgroundColor: GRID_LINE }}
187
+ style={{
188
+ position: 'absolute',
189
+ left: PLOT_LEFT,
190
+ width: innerW,
191
+ top: y,
192
+ height: 1,
193
+ backgroundColor: GRID_LINE,
194
+ }}
168
195
  >
169
- <Text className="text-[9px] text-text-tertiary" style={{ position: 'absolute', left: -PLOT_LEFT, top: -6, width: PLOT_LEFT - 6, textAlign: 'right' }}>
196
+ <Text
197
+ className="text-[9px] text-text-tertiary"
198
+ style={{
199
+ position: 'absolute',
200
+ left: -PLOT_LEFT,
201
+ top: -6,
202
+ width: PLOT_LEFT - 6,
203
+ textAlign: 'right',
204
+ }}
205
+ >
170
206
  {formatTick(t)}
171
207
  </Text>
172
208
  </View>
@@ -179,9 +215,25 @@ export function Scatter({
179
215
  key={`x-${i}`}
180
216
  accessibilityElementsHidden
181
217
  testID="scatter-gridline-x"
182
- style={{ position: 'absolute', top: PLOT_TOP, height: innerH, left: x, width: 1, backgroundColor: GRID_LINE }}
218
+ style={{
219
+ position: 'absolute',
220
+ top: PLOT_TOP,
221
+ height: innerH,
222
+ left: x,
223
+ width: 1,
224
+ backgroundColor: GRID_LINE,
225
+ }}
183
226
  >
184
- <Text className="text-[9px] text-text-tertiary" style={{ position: 'absolute', top: innerH + 4, left: -16, width: 32, textAlign: 'center' }}>
227
+ <Text
228
+ className="text-[9px] text-text-tertiary"
229
+ style={{
230
+ position: 'absolute',
231
+ top: innerH + 4,
232
+ left: -16,
233
+ width: 32,
234
+ textAlign: 'center',
235
+ }}
236
+ >
185
237
  {formatTick(t)}
186
238
  </Text>
187
239
  </View>
@@ -189,8 +241,28 @@ export function Scatter({
189
241
  })}
190
242
 
191
243
  {/* Axis frame (left + bottom). */}
192
- <View accessibilityElementsHidden style={{ position: 'absolute', left: PLOT_LEFT, top: PLOT_TOP, width: 1, height: innerH, backgroundColor: AXIS_LINE }} />
193
- <View accessibilityElementsHidden style={{ position: 'absolute', left: PLOT_LEFT, top: PLOT_TOP + innerH, width: innerW, height: 1, backgroundColor: AXIS_LINE }} />
244
+ <View
245
+ accessibilityElementsHidden
246
+ style={{
247
+ position: 'absolute',
248
+ left: PLOT_LEFT,
249
+ top: PLOT_TOP,
250
+ width: 1,
251
+ height: innerH,
252
+ backgroundColor: AXIS_LINE,
253
+ }}
254
+ />
255
+ <View
256
+ accessibilityElementsHidden
257
+ style={{
258
+ position: 'absolute',
259
+ left: PLOT_LEFT,
260
+ top: PLOT_TOP + innerH,
261
+ width: innerW,
262
+ height: 1,
263
+ backgroundColor: AXIS_LINE,
264
+ }}
265
+ />
194
266
 
195
267
  {diagonal && (
196
268
  <LineSegment
@@ -204,19 +276,44 @@ export function Scatter({
204
276
  )}
205
277
 
206
278
  {axis.xLabel && (
207
- <Text testID="scatter-x-label" className="text-[10px] font-semibold text-text-secondary" style={{ position: 'absolute', left: PLOT_LEFT, width: innerW, bottom: 2, textAlign: 'center' }}>
279
+ <Text
280
+ testID="scatter-x-label"
281
+ className="text-[10px] font-semibold text-text-secondary"
282
+ style={{
283
+ position: 'absolute',
284
+ left: PLOT_LEFT,
285
+ width: innerW,
286
+ bottom: 2,
287
+ textAlign: 'center',
288
+ }}
289
+ >
208
290
  {axis.xLabel}
209
291
  </Text>
210
292
  )}
211
293
  {axis.yLabel && (
212
- <Text testID="scatter-y-label" className="text-[10px] font-semibold text-text-secondary" style={{ position: 'absolute', left: -innerH / 2 + 6, top: PLOT_TOP + innerH / 2, width: innerH, textAlign: 'center', transformOrigin: '50% 50%', transform: [{ rotate: '-90deg' }] }}>
294
+ <Text
295
+ testID="scatter-y-label"
296
+ className="text-[10px] font-semibold text-text-secondary"
297
+ style={{
298
+ position: 'absolute',
299
+ left: -innerH / 2 + 6,
300
+ top: PLOT_TOP + innerH / 2,
301
+ width: innerH,
302
+ textAlign: 'center',
303
+ transformOrigin: '50% 50%',
304
+ transform: [{ rotate: '-90deg' }],
305
+ }}
306
+ >
213
307
  {axis.yLabel}
214
308
  </Text>
215
309
  )}
216
310
  </View>
217
311
 
218
312
  {/* Interactive point overlay (kept out of the image-role canvas). */}
219
- <View style={{ position: 'absolute', top: 0, left: 0, width, height }} testID="scatter-points">
313
+ <View
314
+ style={{ position: 'absolute', top: 0, left: 0, width, height }}
315
+ testID="scatter-points"
316
+ >
220
317
  {points.map((p) => {
221
318
  const selected = p.datum.id === selectedId
222
319
  const showLabel = p.datum.label && (selected || p.radius >= 10)
@@ -244,7 +341,12 @@ export function Scatter({
244
341
  <Text
245
342
  numberOfLines={1}
246
343
  className="text-[9px] font-semibold text-text-primary"
247
- style={{ position: 'absolute', left: p.radius * 2 + 3, top: p.radius - 6, width: 80 }}
344
+ style={{
345
+ position: 'absolute',
346
+ left: p.radius * 2 + 3,
347
+ top: p.radius - 6,
348
+ width: 80,
349
+ }}
248
350
  >
249
351
  {p.datum.label}
250
352
  </Text>
@@ -13,7 +13,16 @@ import {
13
13
  const meta: Meta<typeof Sidebar> = {
14
14
  title: 'Components/Organisms/Sidebar',
15
15
  component: Sidebar,
16
- tags: ['autodocs'],
16
+ tags: ['autodocs', 'status:candidate', '!status:review'],
17
+ parameters: {
18
+ docs: {
19
+ description: {
20
+ component:
21
+ 'Composes RN primitives only (View / Pressable / ScrollView) plus caller-supplied ' +
22
+ 'icon components. The seven parts share collapsed and active state through a context.',
23
+ },
24
+ },
25
+ },
17
26
  argTypes: {
18
27
  isCollapsed: {
19
28
  control: 'boolean',
@@ -46,27 +55,51 @@ type Story = StoryObj<typeof Sidebar>
46
55
 
47
56
  // Simple icon components for demos
48
57
  function HomeIcon({ size = 20, className }: { size?: number; className?: string }) {
49
- return <Text style={{ fontSize: size }} className={className}>&#8962;</Text>
58
+ return (
59
+ <Text style={{ fontSize: size }} className={className}>
60
+ &#8962;
61
+ </Text>
62
+ )
50
63
  }
51
64
 
52
65
  function ChartIcon({ size = 20, className }: { size?: number; className?: string }) {
53
- return <Text style={{ fontSize: size }} className={className}>&#9632;</Text>
66
+ return (
67
+ <Text style={{ fontSize: size }} className={className}>
68
+ &#9632;
69
+ </Text>
70
+ )
54
71
  }
55
72
 
56
73
  function UserIcon({ size = 20, className }: { size?: number; className?: string }) {
57
- return <Text style={{ fontSize: size }} className={className}>&#9786;</Text>
74
+ return (
75
+ <Text style={{ fontSize: size }} className={className}>
76
+ &#9786;
77
+ </Text>
78
+ )
58
79
  }
59
80
 
60
81
  function GearIcon({ size = 20, className }: { size?: number; className?: string }) {
61
- return <Text style={{ fontSize: size }} className={className}>&#9881;</Text>
82
+ return (
83
+ <Text style={{ fontSize: size }} className={className}>
84
+ &#9881;
85
+ </Text>
86
+ )
62
87
  }
63
88
 
64
89
  function MailIcon({ size = 20, className }: { size?: number; className?: string }) {
65
- return <Text style={{ fontSize: size }} className={className}>&#9993;</Text>
90
+ return (
91
+ <Text style={{ fontSize: size }} className={className}>
92
+ &#9993;
93
+ </Text>
94
+ )
66
95
  }
67
96
 
68
97
  function FileIcon({ size = 20, className }: { size?: number; className?: string }) {
69
- return <Text style={{ fontSize: size }} className={className}>&#128196;</Text>
98
+ return (
99
+ <Text style={{ fontSize: size }} className={className}>
100
+ &#128196;
101
+ </Text>
102
+ )
70
103
  }
71
104
 
72
105
  export const Default: Story = {
@@ -12,7 +12,11 @@ import {
12
12
  } from './Sidebar'
13
13
 
14
14
  function MockIcon({ size, className }: { size?: number; className?: string }) {
15
- return <span data-testid="mock-icon" data-size={size} className={className}>I</span>
15
+ return (
16
+ <span data-testid="mock-icon" data-size={size} className={className}>
17
+ I
18
+ </span>
19
+ )
16
20
  }
17
21
 
18
22
  function renderSidebar(props: Partial<React.ComponentProps<typeof Sidebar>> = {}) {
@@ -1,5 +1,12 @@
1
1
  import React, { createContext, useContext } from 'react'
2
- import { View, Text, Pressable, ScrollView, type ViewProps, type PressableProps } from 'react-native'
2
+ import {
3
+ View,
4
+ Text,
5
+ Pressable,
6
+ ScrollView,
7
+ type ViewProps,
8
+ type PressableProps,
9
+ } from 'react-native'
3
10
  import { cn } from '../../../utils/cn'
4
11
 
5
12
  interface SidebarContextType {
@@ -85,9 +92,7 @@ export interface SidebarHeaderProps {
85
92
  */
86
93
  export function SidebarHeader({ children, className }: SidebarHeaderProps) {
87
94
  return (
88
- <View className={cn('px-4 py-4 border-b border-hairline-subtle', className)}>
89
- {children}
90
- </View>
95
+ <View className={cn('px-4 py-4 border-b border-hairline-subtle', className)}>{children}</View>
91
96
  )
92
97
  }
93
98
 
@@ -101,10 +106,7 @@ export interface SidebarContentProps {
101
106
  */
102
107
  export function SidebarContent({ children, className }: SidebarContentProps) {
103
108
  return (
104
- <ScrollView
105
- className={cn('flex-1', className)}
106
- showsVerticalScrollIndicator={false}
107
- >
109
+ <ScrollView className={cn('flex-1', className)} showsVerticalScrollIndicator={false}>
108
110
  {children}
109
111
  </ScrollView>
110
112
  )
@@ -120,9 +122,7 @@ export interface SidebarFooterProps {
120
122
  */
121
123
  export function SidebarFooter({ children, className }: SidebarFooterProps) {
122
124
  return (
123
- <View className={cn('px-2 py-4 border-t border-hairline-subtle', className)}>
124
- {children}
125
- </View>
125
+ <View className={cn('px-2 py-4 border-t border-hairline-subtle', className)}>{children}</View>
126
126
  )
127
127
  }
128
128
 
@@ -146,9 +146,7 @@ export function SidebarSection({ title, children, className }: SidebarSectionPro
146
146
  {title}
147
147
  </Text>
148
148
  )}
149
- <View className="gap-0.5">
150
- {children}
151
- </View>
149
+ <View className="gap-0.5">{children}</View>
152
150
  </View>
153
151
  )
154
152
  }
@@ -209,12 +207,7 @@ export function SidebarItem({
209
207
  {...props}
210
208
  >
211
209
  {Icon && (
212
- <Icon
213
- size={20}
214
- className={cn(
215
- isActive ? 'text-brand-primary' : 'text-text-secondary'
216
- )}
217
- />
210
+ <Icon size={20} className={cn(isActive ? 'text-brand-primary' : 'text-text-secondary')} />
218
211
  )}
219
212
  {!isCollapsed && (
220
213
  <>
@@ -227,16 +220,8 @@ export function SidebarItem({
227
220
  >
228
221
  {label}
229
222
  </Text>
230
- {badge && (
231
- <View className="ml-auto">
232
- {badge}
233
- </View>
234
- )}
235
- {hasChildren && (
236
- <Text className="text-text-tertiary ml-1">
237
- {isExpanded ? '▼' : '▶'}
238
- </Text>
239
- )}
223
+ {badge && <View className="ml-auto">{badge}</View>}
224
+ {hasChildren && <Text className="text-text-tertiary ml-1">{isExpanded ? '▼' : '▶'}</Text>}
240
225
  </>
241
226
  )}
242
227
  </Pressable>
@@ -251,7 +236,5 @@ export interface SidebarDividerProps {
251
236
  * Divider between sidebar sections.
252
237
  */
253
238
  export function SidebarDivider({ className }: SidebarDividerProps) {
254
- return (
255
- <View className={cn('h-px mx-4 my-2 bg-hairline-subtle', className)} />
256
- )
239
+ return <View className={cn('h-px mx-4 my-2 bg-hairline-subtle', className)} />
257
240
  }