@titan-design/react-ui 0.12.1 → 0.14.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 (531) hide show
  1. package/README.md +60 -47
  2. package/dist/bodymap.js +856 -736
  3. package/dist/bodymap.js.map +1 -1
  4. package/dist/bodymap.mjs +858 -738
  5. package/dist/bodymap.mjs.map +1 -1
  6. package/dist/index.d.mts +1431 -237
  7. package/dist/index.d.ts +1431 -237
  8. package/dist/index.js +6506 -4781
  9. package/dist/index.js.map +1 -1
  10. package/dist/index.mjs +6280 -4642
  11. package/dist/index.mjs.map +1 -1
  12. package/dist/{pages-B1hqnGIC.d.ts → pages-CsjsUn0G.d.ts} +51 -16
  13. package/dist/{pages-CvsFqNtx.d.mts → pages-ZbT_pD_U.d.mts} +51 -16
  14. package/dist/pages.d.mts +1 -1
  15. package/dist/pages.d.ts +1 -1
  16. package/dist/pages.js +1919 -1937
  17. package/dist/pages.js.map +1 -1
  18. package/dist/pages.mjs +1927 -1945
  19. package/dist/pages.mjs.map +1 -1
  20. package/dist/theme/index.d.mts +225 -140
  21. package/dist/theme/index.d.ts +225 -140
  22. package/dist/theme/index.js +298 -319
  23. package/dist/theme/index.js.map +1 -1
  24. package/dist/theme/index.mjs +283 -315
  25. package/dist/theme/index.mjs.map +1 -1
  26. package/dist/theme/tokens-css.js +145 -24
  27. package/dist/theme/tokens-css.js.map +1 -1
  28. package/dist/theme/tokens-css.mjs +145 -24
  29. package/dist/theme/tokens-css.mjs.map +1 -1
  30. package/dist/theme/tokens.d.mts +128 -11
  31. package/dist/theme/tokens.d.ts +128 -11
  32. package/dist/theme/tokens.js +126 -26
  33. package/dist/theme/tokens.js.map +1 -1
  34. package/dist/theme/tokens.mjs +124 -27
  35. package/dist/theme/tokens.mjs.map +1 -1
  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/docs/render-testing-pattern.md +130 -0
  40. package/package.json +1 -1
  41. package/src/arch/Architecture.stories.tsx +3 -1
  42. package/src/arch/arch-graph.freshness.test.ts +52 -0
  43. package/src/arch/arch-graph.json +4989 -1583
  44. package/src/components/custom/ActiveWork/CoChangeChip.stories.tsx +44 -0
  45. package/src/components/custom/ActiveWork/CoChangeChip.test.tsx +29 -0
  46. package/src/components/custom/ActiveWork/CoChangeChip.tsx +48 -0
  47. package/src/components/custom/ActiveWork/Eyebrow.stories.tsx +25 -0
  48. package/src/components/custom/ActiveWork/Eyebrow.test.tsx +16 -0
  49. package/src/components/custom/ActiveWork/Eyebrow.tsx +26 -0
  50. package/src/components/custom/ActiveWork/FileActivityDetail.stories.tsx +50 -0
  51. package/src/components/custom/ActiveWork/FileActivityDetail.test.tsx +66 -0
  52. package/src/components/custom/ActiveWork/FileActivityDetail.tsx +202 -0
  53. package/src/components/custom/ActiveWork/FileActivityRow.stories.tsx +70 -0
  54. package/src/components/custom/ActiveWork/FileActivityRow.test.tsx +67 -0
  55. package/src/components/custom/ActiveWork/FileActivityRow.tsx +130 -0
  56. package/src/components/custom/ActiveWork/FileHistoryExplorer.stories.tsx +84 -0
  57. package/src/components/custom/ActiveWork/FileHistoryExplorer.test.tsx +99 -0
  58. package/src/components/custom/ActiveWork/FileHistoryExplorer.tsx +138 -0
  59. package/src/components/custom/ActiveWork/FilePathLabel.stories.tsx +39 -0
  60. package/src/components/custom/ActiveWork/FilePathLabel.test.tsx +53 -0
  61. package/src/components/custom/ActiveWork/FilePathLabel.tsx +63 -0
  62. package/src/components/custom/ActiveWork/InitiativeBrief.stories.tsx +50 -0
  63. package/src/components/custom/ActiveWork/InitiativeBrief.test.tsx +62 -0
  64. package/src/components/custom/ActiveWork/InitiativeBrief.tsx +182 -0
  65. package/src/components/custom/ActiveWork/InitiativeCard.stories.tsx +73 -0
  66. package/src/components/custom/ActiveWork/InitiativeCard.test.tsx +68 -0
  67. package/src/components/custom/ActiveWork/InitiativeCard.tsx +136 -0
  68. package/src/components/custom/ActiveWork/InitiativeHeader.stories.tsx +59 -0
  69. package/src/components/custom/ActiveWork/InitiativeHeader.test.tsx +40 -0
  70. package/src/components/custom/ActiveWork/InitiativeHeader.tsx +73 -0
  71. package/src/components/custom/ActiveWork/InitiativeReader.stories.tsx +145 -0
  72. package/src/components/custom/ActiveWork/OpenLoops.stories.tsx +58 -0
  73. package/src/components/custom/ActiveWork/OpenLoops.test.tsx +61 -0
  74. package/src/components/custom/ActiveWork/OpenLoops.tsx +107 -0
  75. package/src/components/custom/ActiveWork/PortfolioOverview.stories.tsx +101 -0
  76. package/src/components/custom/ActiveWork/PortfolioOverview.test.tsx +81 -0
  77. package/src/components/custom/ActiveWork/PortfolioOverview.tsx +83 -0
  78. package/src/components/custom/ActiveWork/README.md +305 -0
  79. package/src/components/custom/ActiveWork/SessionDetail.stories.tsx +71 -0
  80. package/src/components/custom/ActiveWork/SessionDetail.test.tsx +84 -0
  81. package/src/components/custom/ActiveWork/SessionDetail.tsx +180 -0
  82. package/src/components/custom/ActiveWork/SessionList.stories.tsx +69 -0
  83. package/src/components/custom/ActiveWork/SessionList.test.tsx +78 -0
  84. package/src/components/custom/ActiveWork/SessionList.tsx +103 -0
  85. package/src/components/custom/ActiveWork/SessionListItem.stories.tsx +64 -0
  86. package/src/components/custom/ActiveWork/SessionListItem.test.tsx +62 -0
  87. package/src/components/custom/ActiveWork/SessionListItem.tsx +152 -0
  88. package/src/components/custom/ActiveWork/SessionReader.stories.tsx +113 -0
  89. package/src/components/custom/ActiveWork/SeverityLabel.stories.tsx +51 -0
  90. package/src/components/custom/ActiveWork/SeverityLabel.test.tsx +68 -0
  91. package/src/components/custom/ActiveWork/SeverityLabel.tsx +97 -0
  92. package/src/components/custom/ActiveWork/TaskRow.stories.tsx +63 -0
  93. package/src/components/custom/ActiveWork/TaskRow.test.tsx +112 -0
  94. package/src/components/custom/ActiveWork/TaskRow.tsx +176 -0
  95. package/src/components/custom/ActiveWork/TaskTable.stories.tsx +123 -0
  96. package/src/components/custom/ActiveWork/TaskTable.test.tsx +233 -0
  97. package/src/components/custom/ActiveWork/TaskTable.tsx +321 -0
  98. package/src/components/custom/ActiveWork/active-work-depth.test.tsx +102 -0
  99. package/src/components/custom/ActiveWork/file-history-fixture.ts +91 -0
  100. package/src/components/custom/ActiveWork/format-time.test.ts +23 -0
  101. package/src/components/custom/ActiveWork/format-time.ts +32 -0
  102. package/src/components/custom/ActiveWork/index.ts +19 -0
  103. package/src/components/custom/ActiveWork/initiative-fixture.ts +104 -0
  104. package/src/components/custom/ActiveWork/session-fixture.ts +267 -0
  105. package/src/components/custom/ActiveWork/session-linkers.ts +56 -0
  106. package/src/components/custom/ActiveWork/task-list-fixture.ts +97 -0
  107. package/src/components/custom/CircularTimer/CircularTimer.stories.tsx +12 -6
  108. package/src/components/custom/DateTime/DateTime.stories.tsx +2 -1
  109. package/src/components/custom/DateTime/DateTime.test.tsx +3 -1
  110. package/src/components/custom/EmptyState/EmptyState.stories.tsx +22 -9
  111. package/src/components/custom/EmptyState/EmptyState.test.tsx +7 -13
  112. package/src/components/custom/EmptyState/EmptyState.tsx +4 -18
  113. package/src/components/custom/Fatigue/DualGhostSpark.stories.tsx +4 -3
  114. package/src/components/custom/Fatigue/FatigueLights.stories.tsx +2 -2
  115. package/src/components/custom/Fatigue/GhostSpark.stories.tsx +4 -3
  116. package/src/components/custom/Fatigue/LiveFatigueCard.stories.tsx +2 -2
  117. package/src/components/custom/Fatigue/LiveFatigueCard.tsx +8 -4
  118. package/src/components/custom/Fatigue/LiveFatiguePanel.stories.tsx +116 -6
  119. package/src/components/custom/Fatigue/LiveFatiguePanel.test.tsx +134 -0
  120. package/src/components/custom/Fatigue/LiveFatiguePanel.tsx +54 -83
  121. package/src/components/custom/Fatigue/README.md +40 -3
  122. package/src/components/custom/Fatigue/RomProgressionChart.stories.tsx +2 -2
  123. package/src/components/custom/Fatigue/SilverRedPalette.stories.tsx +2 -1
  124. package/src/components/custom/Fatigue/VelocityHero.stories.tsx +4 -3
  125. package/src/components/custom/Fatigue/VerdictHero.stories.tsx +2 -2
  126. package/src/components/custom/Fatigue/fatigue-mock.test.ts +0 -5
  127. package/src/components/custom/Fatigue/fatigue-mock.ts +2 -10
  128. package/src/components/custom/Fatigue/fatigue-tokens.ts +12 -0
  129. package/src/components/custom/Fatigue/index.ts +17 -5
  130. package/src/components/custom/Fatigue/panel-layout.test.ts +149 -0
  131. package/src/components/custom/Fatigue/panel-layout.ts +185 -0
  132. package/src/components/custom/Gauge/Gauge.stories.tsx +6 -3
  133. package/src/components/custom/Gauge/Gauge.test.tsx +1 -1
  134. package/src/components/custom/Gauge/Gauge.tsx +7 -2
  135. package/src/components/custom/Metric/Metric.stories.tsx +10 -1
  136. package/src/components/custom/Metric/Metric.test.tsx +1 -3
  137. package/src/components/custom/Metric/Metric.tsx +5 -20
  138. package/src/components/custom/Prose/MarkdownProse.stories.tsx +88 -0
  139. package/src/components/custom/Prose/MarkdownProse.test.tsx +87 -0
  140. package/src/components/custom/Prose/MarkdownProse.tsx +201 -0
  141. package/src/components/custom/Prose/README.md +58 -0
  142. package/src/components/custom/Prose/index.ts +1 -0
  143. package/src/components/custom/Scatter/Scatter.stories.tsx +55 -14
  144. package/src/components/custom/Scatter/Scatter.test.tsx +2 -2
  145. package/src/components/custom/Scatter/Scatter.tsx +122 -18
  146. package/src/components/custom/Sidebar/Sidebar.stories.tsx +41 -8
  147. package/src/components/custom/Sidebar/Sidebar.test.tsx +5 -1
  148. package/src/components/custom/Sidebar/Sidebar.tsx +16 -33
  149. package/src/components/custom/Table/Table.stories.tsx +99 -16
  150. package/src/components/custom/Table/Table.test.tsx +273 -86
  151. package/src/components/custom/Table/Table.tsx +159 -67
  152. package/src/components/custom/Table/column-fit.test.ts +75 -0
  153. package/src/components/custom/Table/column-fit.ts +116 -0
  154. package/src/components/custom/Table/index.ts +9 -0
  155. package/src/components/custom/TimerReadout/TimerReadout.stories.tsx +8 -6
  156. package/src/components/custom/Treemap/Treemap.stories.tsx +15 -12
  157. package/src/components/custom/Treemap/Treemap.test.tsx +1 -1
  158. package/src/components/custom/Treemap/Treemap.tsx +11 -3
  159. package/src/components/custom/Typography/Typography.stories.tsx +28 -1
  160. package/src/components/custom/Typography/Typography.test.tsx +34 -0
  161. package/src/components/custom/Typography/Typography.tsx +6 -0
  162. package/src/components/custom/Typography/index.ts +1 -8
  163. package/src/components/custom/Workout/ActiveWorkoutPage.stories.tsx +11 -2
  164. package/src/components/custom/Workout/BaseBadge.stories.tsx +27 -11
  165. package/src/components/custom/Workout/BaseBadge.test.tsx +31 -11
  166. package/src/components/custom/Workout/BaseBadge.tsx +6 -2
  167. package/src/components/custom/Workout/BodyMap.stories.tsx +4 -1
  168. package/src/components/custom/Workout/BodyMap.tsx +8 -4
  169. package/src/components/custom/Workout/BodyMapDetailPanel.stories.tsx +28 -6
  170. package/src/components/custom/Workout/BodyMapDetailPanel.test.tsx +11 -15
  171. package/src/components/custom/Workout/BodyMapDetailPanel.tsx +50 -12
  172. package/src/components/custom/Workout/CapacityBandChart.stories.tsx +12 -9
  173. package/src/components/custom/Workout/CapacityBandChart.test.tsx +24 -51
  174. package/src/components/custom/Workout/CapacityBandChart.tsx +144 -111
  175. package/src/components/custom/Workout/DeviationBar.stories.tsx +1 -1
  176. package/src/components/custom/Workout/DeviationBar.test.tsx +10 -4
  177. package/src/components/custom/Workout/DeviationBar.tsx +24 -16
  178. package/src/components/custom/Workout/DualVelocityStrip.stories.tsx +183 -0
  179. package/src/components/custom/Workout/DualVelocityStrip.test.tsx +32 -18
  180. package/src/components/custom/Workout/ExerciseCard.stories.tsx +12 -11
  181. package/src/components/custom/Workout/ExerciseCard.test.tsx +52 -22
  182. package/src/components/custom/Workout/ExerciseCard.tsx +99 -183
  183. package/src/components/custom/Workout/ExerciseCardHeading.stories.tsx +95 -12
  184. package/src/components/custom/Workout/ExerciseCardHeading.test.tsx +189 -1
  185. package/src/components/custom/Workout/ExerciseCardHeading.tsx +167 -18
  186. package/src/components/custom/Workout/ExerciseDetailPage.stories.tsx +9 -1
  187. package/src/components/custom/Workout/ExerciseDetailPage.tsx +3 -2
  188. package/src/components/custom/Workout/ExerciseHeading.stories.tsx +8 -8
  189. package/src/components/custom/Workout/ExerciseHeading.tsx +194 -46
  190. package/src/components/custom/Workout/ExerciseIndicator.stories.tsx +12 -9
  191. package/src/components/custom/Workout/ExerciseIndicator.test.tsx +27 -11
  192. package/src/components/custom/Workout/ExerciseIndicator.tsx +14 -15
  193. package/src/components/custom/Workout/FatigueMeter.stories.tsx +5 -5
  194. package/src/components/custom/Workout/InputBar.stories.tsx +4 -5
  195. package/src/components/custom/Workout/InputBar.tsx +4 -2
  196. package/src/components/custom/Workout/IntensityBar.stories.tsx +1 -1
  197. package/src/components/custom/Workout/IntensityBar.test.tsx +5 -1
  198. package/src/components/custom/Workout/IntensityBar.tsx +8 -3
  199. package/src/components/custom/Workout/LiveAuraFrame.stories.tsx +5 -4
  200. package/src/components/custom/Workout/MesoCard.stories.tsx +4 -1
  201. package/src/components/custom/Workout/MesoCard.test.tsx +7 -18
  202. package/src/components/custom/Workout/MesoCard.tsx +14 -10
  203. package/src/components/custom/Workout/MesoProgressBar.stories.tsx +1 -1
  204. package/src/components/custom/Workout/MesoProgressBar.test.tsx +18 -11
  205. package/src/components/custom/Workout/MesoProgressBar.tsx +15 -13
  206. package/src/components/custom/Workout/MesoStatusCard.stories.tsx +2 -1
  207. package/src/components/custom/Workout/MesoStatusCard.test.tsx +14 -44
  208. package/src/components/custom/Workout/MesoStatusCard.tsx +20 -33
  209. package/src/components/custom/Workout/MetricTiles.stories.tsx +3 -2
  210. package/src/components/custom/Workout/MuscleGroupChip.stories.tsx +2 -8
  211. package/src/components/custom/Workout/MuscleGroupChip.test.tsx +23 -31
  212. package/src/components/custom/Workout/MuscleGroupChip.tsx +28 -67
  213. package/src/components/custom/Workout/PlaceholderStrip.stories.tsx +9 -4
  214. package/src/components/custom/Workout/PlaceholderStrip.test.tsx +17 -10
  215. package/src/components/custom/Workout/PlaceholderStrip.tsx +9 -8
  216. package/src/components/custom/Workout/PrBadge.stories.tsx +2 -1
  217. package/src/components/custom/Workout/PrBadge.test.tsx +3 -9
  218. package/src/components/custom/Workout/PrBadge.tsx +13 -17
  219. package/src/components/custom/Workout/PrHistoryModal.stories.tsx +16 -3
  220. package/src/components/custom/Workout/PrHistoryModal.test.tsx +13 -36
  221. package/src/components/custom/Workout/PrHistoryModal.tsx +8 -4
  222. package/src/components/custom/Workout/ProgramPlanningPage.stories.tsx +6 -1
  223. package/src/components/custom/Workout/README.md +68 -17
  224. package/src/components/custom/Workout/ReadinessCheck.stories.tsx +3 -2
  225. package/src/components/custom/Workout/ReadinessCheck.test.tsx +12 -18
  226. package/src/components/custom/Workout/ReadinessCheck.tsx +22 -4
  227. package/src/components/custom/Workout/RestTimer.stories.tsx +16 -4
  228. package/src/components/custom/Workout/RestTimer.tsx +4 -2
  229. package/src/components/custom/Workout/ScheduleTiles.stories.tsx +3 -2
  230. package/src/components/custom/Workout/ScheduleTiles.test.tsx +3 -4
  231. package/src/components/custom/Workout/ScheduleTiles.tsx +4 -7
  232. package/src/components/custom/Workout/SegmentedBar.stories.tsx +21 -17
  233. package/src/components/custom/Workout/SegmentedBar.tsx +10 -5
  234. package/src/components/custom/Workout/SegmentedProgressBar.stories.tsx +5 -5
  235. package/src/components/custom/Workout/SessionHeader.stories.tsx +6 -6
  236. package/src/components/custom/Workout/SessionHeader.tsx +12 -12
  237. package/src/components/custom/Workout/SessionRail.stories.tsx +12 -11
  238. package/src/components/custom/Workout/SessionRail.tsx +7 -9
  239. package/src/components/custom/Workout/SetBar.stories.tsx +10 -6
  240. package/src/components/custom/Workout/SetBar.test.tsx +49 -4
  241. package/src/components/custom/Workout/SetBar.tsx +38 -12
  242. package/src/components/custom/Workout/SetRow.stories.tsx +3 -2
  243. package/src/components/custom/Workout/SetRow.test.tsx +16 -2
  244. package/src/components/custom/Workout/SetRow.tsx +61 -23
  245. package/src/components/custom/Workout/SetStrip.stories.tsx +63 -7
  246. package/src/components/custom/Workout/SetStrip.test.tsx +25 -0
  247. package/src/components/custom/Workout/SetStrip.tsx +24 -4
  248. package/src/components/custom/Workout/SetTableHeader.stories.tsx +6 -6
  249. package/src/components/custom/Workout/SetTableHeader.tsx +9 -12
  250. package/src/components/custom/Workout/SetsRepsLoad.stories.tsx +7 -7
  251. package/src/components/custom/Workout/SetsRepsLoad.tsx +24 -12
  252. package/src/components/custom/Workout/Sparkline.stories.tsx +14 -11
  253. package/src/components/custom/Workout/Sparkline.test.tsx +37 -19
  254. package/src/components/custom/Workout/Sparkline.tsx +14 -18
  255. package/src/components/custom/Workout/StatusDot.stories.tsx +1 -1
  256. package/src/components/custom/Workout/StatusDot.test.tsx +44 -5
  257. package/src/components/custom/Workout/StatusDot.tsx +93 -63
  258. package/src/components/custom/Workout/StatusPill.stories.tsx +1 -1
  259. package/src/components/custom/Workout/StatusPill.test.tsx +6 -15
  260. package/src/components/custom/Workout/StatusPill.tsx +27 -38
  261. package/src/components/custom/Workout/StrengthTrendChart.stories.tsx +11 -4
  262. package/src/components/custom/Workout/StrengthTrendChart.test.tsx +15 -37
  263. package/src/components/custom/Workout/StrengthTrendChart.tsx +39 -36
  264. package/src/components/custom/Workout/SupersetWrapper.stories.tsx +27 -64
  265. package/src/components/custom/Workout/SupersetWrapper.test.tsx +16 -14
  266. package/src/components/custom/Workout/SupersetWrapper.tsx +17 -21
  267. package/src/components/custom/Workout/TempoDisplay.stories.tsx +26 -10
  268. package/src/components/custom/Workout/TempoDisplay.test.tsx +18 -4
  269. package/src/components/custom/Workout/TempoDisplay.tsx +2 -0
  270. package/src/components/custom/Workout/TrainingStatusPage.stories.tsx +9 -1
  271. package/src/components/custom/Workout/VelocityStrip.compact.stories.tsx +4 -1
  272. package/src/components/custom/Workout/VelocityStrip.dual.stories.tsx +10 -6
  273. package/src/components/custom/Workout/VelocityStrip.expanded.stories.tsx +5 -2
  274. package/src/components/custom/Workout/VelocityStrip.hero.stories.tsx +44 -1
  275. package/src/components/custom/Workout/VelocityStrip.stories.tsx +12 -6
  276. package/src/components/custom/Workout/VelocityStrip.test.tsx +48 -6
  277. package/src/components/custom/Workout/VelocityStrip.tsx +26 -14
  278. package/src/components/custom/Workout/VolumeLandmarkBar.stories.tsx +6 -7
  279. package/src/components/custom/Workout/VolumeLandmarkBar.tsx +15 -6
  280. package/src/components/custom/Workout/WeekRow.stories.tsx +4 -1
  281. package/src/components/custom/Workout/WeekRow.test.tsx +18 -15
  282. package/src/components/custom/Workout/WeekRow.tsx +23 -16
  283. package/src/components/custom/Workout/WeightBadge.stories.tsx +2 -1
  284. package/src/components/custom/Workout/WeightBadge.test.tsx +50 -19
  285. package/src/components/custom/Workout/WeightBadge.tsx +28 -27
  286. package/src/components/custom/Workout/WorkoutCard.stories.tsx +6 -1
  287. package/src/components/custom/Workout/WorkoutCard.test.tsx +18 -0
  288. package/src/components/custom/Workout/WorkoutCard.tsx +35 -57
  289. package/src/components/custom/Workout/WorkoutPill.stories.tsx +5 -2
  290. package/src/components/custom/Workout/WorkoutPill.test.tsx +39 -7
  291. package/src/components/custom/Workout/WorkoutPill.tsx +88 -57
  292. package/src/components/custom/Workout/ZoneTrack.stories.tsx +10 -7
  293. package/src/components/custom/Workout/ZoneTrack.tsx +10 -9
  294. package/src/components/custom/Workout/exerciseRowState.ts +29 -0
  295. package/src/components/custom/Workout/index.ts +17 -2
  296. package/src/components/custom/Workout/metricText.stories.tsx +15 -13
  297. package/src/components/custom/Workout/metricText.tsx +8 -2
  298. package/src/components/custom/Workout/setHeadingKit.tsx +219 -36
  299. package/src/components/custom/Workout/velocity-story-kit.tsx +2 -2
  300. package/src/components/custom/charts/README.md +66 -0
  301. package/src/components/custom/charts/SetBarChart.test.tsx +46 -1
  302. package/src/components/custom/charts/SetBarChart.tsx +56 -9
  303. package/src/components/custom/charts/SparkBars.stories.tsx +55 -0
  304. package/src/components/custom/charts/SparkBars.test.tsx +69 -0
  305. package/src/components/custom/charts/SparkBars.tsx +85 -0
  306. package/src/components/custom/charts/flatBarGeometry.test.ts +41 -0
  307. package/src/components/custom/charts/flatBarGeometry.ts +32 -0
  308. package/src/components/custom/charts/index.ts +3 -0
  309. package/src/components/custom/index.ts +3 -0
  310. package/src/components/custom/stepper/Stepper.stories.tsx +13 -10
  311. package/src/components/custom/stepper/Stepper.test.tsx +1 -7
  312. package/src/components/custom/stepper/Stepper.tsx +21 -34
  313. package/src/components/icons/icons.stories.tsx +1 -1
  314. package/src/components/icons/icons.tsx +51 -0
  315. package/src/components/shell/AppShell.stories.tsx +150 -0
  316. package/src/components/shell/AppShell.test.tsx +70 -0
  317. package/src/components/shell/AppShell.tsx +90 -0
  318. package/src/components/shell/BrandLockup.stories.tsx +66 -5
  319. package/src/components/shell/BrandLockup.test.tsx +34 -1
  320. package/src/components/shell/BrandLockup.tsx +27 -11
  321. package/src/components/shell/NavItem.stories.tsx +4 -4
  322. package/src/components/shell/NavItem.test.tsx +17 -0
  323. package/src/components/shell/NavItem.tsx +17 -5
  324. package/src/components/shell/README.md +89 -26
  325. package/src/components/shell/SideNav.stories.tsx +38 -7
  326. package/src/components/shell/SideNav.test.tsx +16 -8
  327. package/src/components/shell/SideNav.tsx +17 -17
  328. package/src/components/shell/TopBar.stories.tsx +44 -19
  329. package/src/components/shell/TopBar.test.tsx +34 -12
  330. package/src/components/shell/TopBar.tsx +61 -40
  331. package/src/components/shell/brands.tsx +66 -0
  332. package/src/components/shell/index.ts +9 -8
  333. package/src/components/shell/{DeviceIndicator.stories.tsx → workout/DeviceIndicator.stories.tsx} +2 -2
  334. package/src/components/shell/{DeviceIndicator.tsx → workout/DeviceIndicator.tsx} +2 -2
  335. package/src/components/shell/{DeviceMenu.stories.tsx → workout/DeviceMenu.stories.tsx} +2 -2
  336. package/src/components/shell/{DeviceMenu.tsx → workout/DeviceMenu.tsx} +3 -3
  337. package/src/components/shell/{DeviceRow.stories.tsx → workout/DeviceRow.stories.tsx} +2 -2
  338. package/src/components/shell/{DeviceRow.tsx → workout/DeviceRow.tsx} +3 -3
  339. package/src/components/shell/{SessionStatePill.stories.tsx → workout/SessionStatePill.stories.tsx} +2 -2
  340. package/src/components/shell/{SessionStatePill.tsx → workout/SessionStatePill.tsx} +5 -3
  341. package/src/components/shell/workout/WorkoutShell.stories.tsx +71 -0
  342. package/src/components/shell/{DashboardShell.test.tsx → workout/WorkoutShell.test.tsx} +19 -8
  343. package/src/components/shell/workout/WorkoutShell.tsx +77 -0
  344. package/src/components/shell/workout/WorkoutTopBar.stories.tsx +58 -0
  345. package/src/components/shell/workout/WorkoutTopBar.test.tsx +39 -0
  346. package/src/components/shell/workout/WorkoutTopBar.tsx +52 -0
  347. package/src/components/shell/workout/index.ts +9 -0
  348. package/src/components/shell/workout/workoutNavItems.tsx +16 -0
  349. package/src/components/ui/README.md +110 -0
  350. package/src/components/ui/alert/Alert.stories.tsx +15 -5
  351. package/src/components/ui/alert/Alert.tsx +24 -3
  352. package/src/components/ui/autocomplete/Autocomplete.stories.tsx +11 -13
  353. package/src/components/ui/autocomplete/Autocomplete.test.tsx +7 -25
  354. package/src/components/ui/autocomplete/Autocomplete.tsx +21 -28
  355. package/src/components/ui/avatar/Avatar.stories.tsx +1 -1
  356. package/src/components/ui/avatar/Avatar.tsx +2 -10
  357. package/src/components/ui/badge/Badge.stories.tsx +83 -28
  358. package/src/components/ui/badge/Badge.test.tsx +19 -3
  359. package/src/components/ui/badge/Badge.tsx +48 -55
  360. package/src/components/ui/breadcrumbs/Breadcrumbs.stories.tsx +1 -1
  361. package/src/components/ui/breadcrumbs/Breadcrumbs.tsx +4 -16
  362. package/src/components/ui/button/Button.stories.tsx +46 -12
  363. package/src/components/ui/button/Button.tsx +44 -37
  364. package/src/components/ui/card/Card.stories.tsx +90 -94
  365. package/src/components/ui/card/Card.test.tsx +80 -6
  366. package/src/components/ui/card/Card.tsx +150 -203
  367. package/src/components/ui/checkbox/Checkbox.stories.tsx +1 -1
  368. package/src/components/ui/checkbox/Checkbox.tsx +7 -27
  369. package/src/components/ui/chip/Chip.stories.tsx +37 -13
  370. package/src/components/ui/chip/Chip.test.tsx +10 -6
  371. package/src/components/ui/chip/Chip.tsx +76 -91
  372. package/src/components/ui/collapse/Collapse.stories.tsx +23 -23
  373. package/src/components/ui/collapse/Collapse.tsx +6 -11
  374. package/src/components/ui/data-row/DataRow.stories.tsx +14 -3
  375. package/src/components/ui/data-row/DataRow.test.tsx +5 -15
  376. package/src/components/ui/data-row/DataRow.tsx +18 -7
  377. package/src/components/ui/divider/Divider.stories.tsx +1 -1
  378. package/src/components/ui/divider/Divider.tsx +1 -5
  379. package/src/components/ui/drawer/Drawer.stories.tsx +5 -16
  380. package/src/components/ui/drawer/Drawer.tsx +13 -27
  381. package/src/components/ui/floating-overlay-depth.test.tsx +143 -0
  382. package/src/components/ui/form-field/FormField.stories.tsx +6 -20
  383. package/src/components/ui/form-field/FormField.test.tsx +1 -5
  384. package/src/components/ui/form-field/FormField.tsx +10 -46
  385. package/src/components/ui/help-tip/HelpTip.stories.tsx +8 -19
  386. package/src/components/ui/help-tip/HelpTip.test.tsx +1 -3
  387. package/src/components/ui/help-tip/HelpTip.tsx +21 -22
  388. package/src/components/ui/help-tip/index.ts +7 -1
  389. package/src/components/ui/icon-box/IconBox.stories.tsx +1 -1
  390. package/src/components/ui/icon-box/IconBox.test.tsx +1 -7
  391. package/src/components/ui/icon-box/IconBox.tsx +10 -18
  392. package/src/components/ui/indicator/Indicator.stories.tsx +5 -4
  393. package/src/components/ui/indicator/Indicator.tsx +20 -14
  394. package/src/components/ui/input/Input.stories.tsx +3 -11
  395. package/src/components/ui/input/Input.test.tsx +2 -10
  396. package/src/components/ui/input/Input.tsx +10 -25
  397. package/src/components/ui/input/index.ts +7 -1
  398. package/src/components/ui/link/Link.stories.tsx +19 -7
  399. package/src/components/ui/list-item/ListItem.stories.tsx +17 -5
  400. package/src/components/ui/list-item/ListItem.tsx +2 -9
  401. package/src/components/ui/menu/Menu.stories.tsx +21 -15
  402. package/src/components/ui/menu/Menu.test.tsx +2 -11
  403. package/src/components/ui/menu/Menu.tsx +12 -14
  404. package/src/components/ui/menu/index.ts +8 -1
  405. package/src/components/ui/modal/Modal.stories.tsx +2 -2
  406. package/src/components/ui/modal/Modal.tsx +31 -19
  407. package/src/components/ui/pill/Pill.stories.tsx +111 -23
  408. package/src/components/ui/pill/Pill.test.tsx +101 -3
  409. package/src/components/ui/pill/Pill.tsx +168 -49
  410. package/src/components/ui/pill/index.ts +1 -1
  411. package/src/components/ui/popover/Popover.stories.tsx +6 -8
  412. package/src/components/ui/popover/Popover.test.tsx +1 -6
  413. package/src/components/ui/popover/Popover.tsx +20 -15
  414. package/src/components/ui/popover/index.ts +7 -1
  415. package/src/components/ui/progress/Progress.stories.tsx +3 -12
  416. package/src/components/ui/progress/Progress.test.tsx +1 -5
  417. package/src/components/ui/progress/Progress.tsx +9 -6
  418. package/src/components/ui/radio/Radio.stories.tsx +42 -21
  419. package/src/components/ui/radio/Radio.test.tsx +6 -2
  420. package/src/components/ui/radio/Radio.tsx +23 -22
  421. package/src/components/ui/section/Section.stories.tsx +12 -21
  422. package/src/components/ui/section/Section.test.tsx +1 -6
  423. package/src/components/ui/section/Section.tsx +1 -3
  424. package/src/components/ui/section/index.ts +1 -5
  425. package/src/components/ui/select/Select.stories.tsx +3 -13
  426. package/src/components/ui/select/Select.test.tsx +2 -11
  427. package/src/components/ui/select/Select.tsx +16 -15
  428. package/src/components/ui/skeleton/Skeleton.stories.tsx +3 -11
  429. package/src/components/ui/skeleton/Skeleton.tsx +3 -14
  430. package/src/components/ui/skeleton/index.ts +1 -7
  431. package/src/components/ui/spinner/Spinner.stories.tsx +1 -1
  432. package/src/components/ui/spinner/Spinner.tsx +4 -5
  433. package/src/components/ui/stack/Stack.stories.tsx +8 -8
  434. package/src/components/ui/stack/Stack.tsx +1 -1
  435. package/src/components/ui/surface/Surface.stories.tsx +92 -33
  436. package/src/components/ui/surface/Surface.test.tsx +88 -28
  437. package/src/components/ui/surface/Surface.tsx +37 -87
  438. package/src/components/ui/surface/SurfaceContext.ts +22 -62
  439. package/src/components/ui/surface/index.ts +8 -0
  440. package/src/components/ui/surface/resolveSurface.ts +98 -0
  441. package/src/components/ui/surface/surface.contract.test.ts +6 -1
  442. package/src/components/ui/switch/Switch.stories.tsx +1 -1
  443. package/src/components/ui/switch/Switch.tsx +7 -6
  444. package/src/components/ui/tabs/Tabs.stories.tsx +1 -1
  445. package/src/components/ui/tabs/Tabs.tsx +8 -21
  446. package/src/components/ui/tabs/index.ts +1 -7
  447. package/src/components/ui/tile/Tile.stories.tsx +1 -1
  448. package/src/components/ui/tile/Tile.tsx +3 -0
  449. package/src/components/ui/toast/Toast.stories.tsx +1 -1
  450. package/src/components/ui/toast/Toast.test.tsx +2 -8
  451. package/src/components/ui/toast/Toast.tsx +49 -57
  452. package/src/components/ui/toast/index.ts +0 -1
  453. package/src/components/ui/toolbar-button/ToolbarButton.stories.tsx +92 -71
  454. package/src/components/ui/toolbar-button/ToolbarButton.test.tsx +3 -18
  455. package/src/components/ui/toolbar-button/ToolbarButton.tsx +38 -49
  456. package/src/components/ui/tooltip/Tooltip.stories.tsx +12 -3
  457. package/src/components/ui/tooltip/Tooltip.test.tsx +21 -3
  458. package/src/components/ui/tooltip/Tooltip.tsx +55 -36
  459. package/src/components/ui/tooltip/index.ts +1 -1
  460. package/src/components/ui/trigger/TriggerSurface.test.tsx +215 -0
  461. package/src/components/ui/trigger/TriggerSurface.tsx +81 -0
  462. package/src/components/ui/trigger/index.ts +2 -0
  463. package/src/stories/PresetShowcase.stories.tsx +101 -48
  464. package/src/test/no-device-internals.test.ts +3 -3
  465. package/src/test/no-raw-color.test.ts +39 -0
  466. package/src/theme/Alpha.stories.tsx +103 -0
  467. package/src/theme/ChoosingTokens.stories.tsx +48 -0
  468. package/src/theme/ColorPalettes.stories.tsx +62 -45
  469. package/src/theme/ColorPrimitives.stories.tsx +35 -35
  470. package/src/theme/Depth.stories.tsx +132 -65
  471. package/src/theme/DepthCalibration.stories.tsx +23 -21
  472. package/src/theme/ProposedTokensVW82.stories.tsx +414 -0
  473. package/src/theme/ThemeProvider.test.tsx +4 -4
  474. package/src/theme/barrel.ts +7 -6
  475. package/src/theme/color-stories.coverage.test.ts +1 -1
  476. package/src/theme/color-utils.ts +41 -29
  477. package/src/theme/config.completeness.test.ts +1 -1
  478. package/src/theme/config.ts +40 -0
  479. package/src/theme/elevation.test.ts +82 -56
  480. package/src/theme/elevation.ts +77 -561
  481. package/src/theme/global.css +45 -5
  482. package/src/theme/grey-ramp.test.ts +24 -8
  483. package/src/theme/lift.test.ts +39 -0
  484. package/src/theme/lift.ts +102 -0
  485. package/src/theme/materials.test.ts +5 -2
  486. package/src/theme/materials.ts +38 -4
  487. package/src/theme/native-theming-guard.test.ts +5 -5
  488. package/src/theme/presets/apply.ts +4 -0
  489. package/src/theme/presets/audiobook.ts +5 -2
  490. package/src/theme/presets/default.ts +4 -0
  491. package/src/theme/presets/index.ts +14 -1
  492. package/src/theme/presets/types.ts +1 -1
  493. package/src/theme/semantic-contrast.test.ts +13 -4
  494. package/src/theme/status-distinctness.test.ts +66 -0
  495. package/src/theme/subtle-tone-weight.test.ts +163 -0
  496. package/src/theme/surface-planes.test.ts +37 -0
  497. package/src/theme/surface-planes.ts +68 -0
  498. package/src/theme/tailwind-var-opacity.test.ts +163 -0
  499. package/src/theme/token-export-guard.test.ts +1 -3
  500. package/src/theme/tokens/primitives.test.ts +15 -7
  501. package/src/theme/tokens/primitives.ts +98 -33
  502. package/src/theme/tokens/semantic-hex-guard.test.ts +322 -0
  503. package/src/theme/tokens/semantic.ts +124 -54
  504. package/src/theme/wash-ladder.test.ts +58 -0
  505. package/src/theme/workout-tokens.ts +1 -7
  506. package/src/types/jest-axe.d.ts +2 -6
  507. package/src/types/raw-md.d.ts +5 -0
  508. package/src/utils/colors.alpha-adoption.test.ts +408 -0
  509. package/src/utils/colors.ts +4 -4
  510. package/src/utils/form.ts +1 -3
  511. package/src/utils/index.ts +2 -7
  512. package/src/utils/number-format.ts +17 -0
  513. package/src/utils/workout-format.ts +15 -6
  514. package/src/web-jsx/jsx-runtime.ts +1 -5
  515. package/tailwind.config.js +55 -9
  516. package/src/components/custom/Workout/ExerciseCardUnified.stories.tsx +0 -151
  517. package/src/components/custom/Workout/RowInventory.stories.tsx +0 -408
  518. package/src/components/custom/Workout/S3FullRail.stories.tsx +0 -46
  519. package/src/components/custom/Workout/S3SessionPace.stories.tsx +0 -95
  520. package/src/components/custom/Workout/S3SessionRailHeading.stories.tsx +0 -61
  521. package/src/components/custom/Workout/S3SetTypes.stories.tsx +0 -176
  522. package/src/components/custom/Workout/S3WorkoutExpansion.stories.tsx +0 -240
  523. package/src/components/shell/DashboardShell.stories.tsx +0 -65
  524. package/src/components/shell/DashboardShell.tsx +0 -75
  525. package/src/components/shell/SessionRailSpecimen.stories.tsx +0 -753
  526. package/src/theme/elevation.stories.tsx +0 -346
  527. package/src/utils/useTheme.ts +0 -72
  528. /package/src/components/shell/{DeviceIndicator.test.tsx → workout/DeviceIndicator.test.tsx} +0 -0
  529. /package/src/components/shell/{DeviceMenu.test.tsx → workout/DeviceMenu.test.tsx} +0 -0
  530. /package/src/components/shell/{DeviceRow.test.tsx → workout/DeviceRow.test.tsx} +0 -0
  531. /package/src/components/shell/{SessionStatePill.test.tsx → workout/SessionStatePill.test.tsx} +0 -0
@@ -5,7 +5,7 @@ import { Input, InputGroup, PasswordInput } from './Input'
5
5
  const meta: Meta<typeof Input> = {
6
6
  title: 'Components/Molecules/Input',
7
7
  component: Input,
8
- tags: ['autodocs'],
8
+ tags: ['autodocs', 'status:stable', '!status:review'],
9
9
  argTypes: {
10
10
  variant: {
11
11
  control: 'select',
@@ -161,10 +161,7 @@ function SearchIcon() {
161
161
  export const WithLeftElement: Story = {
162
162
  render: () => (
163
163
  <View style={{ gap: 16, width: 300 }}>
164
- <Input
165
- placeholder="Search..."
166
- leftElement={<SearchIcon />}
167
- />
164
+ <Input placeholder="Search..." leftElement={<SearchIcon />} />
168
165
  </View>
169
166
  ),
170
167
  }
@@ -181,12 +178,7 @@ export const FormExample: Story = {
181
178
  helperText="Must be at least 8 characters"
182
179
  isRequired
183
180
  />
184
- <Input
185
- label="Bio"
186
- placeholder="Tell us about yourself..."
187
- multiline
188
- numberOfLines={3}
189
- />
181
+ <Input label="Bio" placeholder="Tell us about yourself..." multiline numberOfLines={3} />
190
182
  </InputGroup>
191
183
  ),
192
184
  }
@@ -25,13 +25,7 @@ describe('Input', () => {
25
25
  })
26
26
 
27
27
  it('displays error message when isInvalid', () => {
28
- render(
29
- <Input
30
- isInvalid
31
- errorMessage="Invalid input"
32
- helperText="This should not show"
33
- />
34
- )
28
+ render(<Input isInvalid errorMessage="Invalid input" helperText="This should not show" />)
35
29
  expect(screen.getByText('Invalid input')).toBeInTheDocument()
36
30
  expect(screen.queryByText('This should not show')).not.toBeInTheDocument()
37
31
  })
@@ -62,9 +56,7 @@ describe('Input', () => {
62
56
 
63
57
  describe('accessibility', () => {
64
58
  it('has no accessibility violations', async () => {
65
- const { container } = render(
66
- <Input label="Email" placeholder="Enter your email" />
67
- )
59
+ const { container } = render(<Input label="Email" placeholder="Enter your email" />)
68
60
 
69
61
  const results = await axe(container)
70
62
  expect(results).toHaveNoViolations()
@@ -50,7 +50,10 @@ const multilineSizeStyles: Record<InputSize, string> = {
50
50
  lg: 'min-h-[120px] px-4 py-3 text-lg',
51
51
  }
52
52
 
53
- const variantStyles: Record<InputVariant, { base: string; focus: string; hover: string; error: string }> = {
53
+ const variantStyles: Record<
54
+ InputVariant,
55
+ { base: string; focus: string; hover: string; error: string }
56
+ > = {
54
57
  outline: {
55
58
  base: 'border border-border-input rounded-md bg-transparent',
56
59
  hover: 'web:hover:border-border-input-hover',
@@ -146,11 +149,7 @@ export const Input = forwardRef<TextInput, InputProps>(function Input(
146
149
  isDisabled && 'opacity-40 cursor-not-allowed'
147
150
  )}
148
151
  >
149
- {leftElement && (
150
- <View className={cn('pl-3 pr-1', multiline && 'pt-3')}>
151
- {leftElement}
152
- </View>
153
- )}
152
+ {leftElement && <View className={cn('pl-3 pr-1', multiline && 'pt-3')}>{leftElement}</View>}
154
153
 
155
154
  <TextInput
156
155
  ref={ref}
@@ -176,23 +175,13 @@ export const Input = forwardRef<TextInput, InputProps>(function Input(
176
175
  />
177
176
 
178
177
  {rightElement && (
179
- <View className={cn('pl-1 pr-3', multiline && 'pt-3')}>
180
- {rightElement}
181
- </View>
178
+ <View className={cn('pl-1 pr-3', multiline && 'pt-3')}>{rightElement}</View>
182
179
  )}
183
180
  </View>
184
181
 
185
- {showHelper && (
186
- <Text className="mt-1.5 text-xs text-text-secondary">
187
- {helperText}
188
- </Text>
189
- )}
182
+ {showHelper && <Text className="mt-1.5 text-xs text-text-secondary">{helperText}</Text>}
190
183
 
191
- {showError && (
192
- <Text className="mt-1.5 text-xs text-status-error">
193
- {errorMessage}
194
- </Text>
195
- )}
184
+ {showError && <Text className="mt-1.5 text-xs text-status-error">{errorMessage}</Text>}
196
185
  </View>
197
186
  )
198
187
  })
@@ -206,11 +195,7 @@ export interface InputGroupProps {
206
195
  * Container for grouping related inputs.
207
196
  */
208
197
  export function InputGroup({ children, className }: InputGroupProps) {
209
- return (
210
- <View className={cn('flex-col gap-4', className)}>
211
- {children}
212
- </View>
213
- )
198
+ return <View className={cn('flex-col gap-4', className)}>{children}</View>
214
199
  }
215
200
 
216
201
  export interface PasswordInputProps extends Omit<InputProps, 'secureTextEntry' | 'rightElement'> {
@@ -264,7 +249,7 @@ export const PasswordInput = forwardRef<TextInput, PasswordInputProps>(function
264
249
  accessibilityLabel={isVisible ? 'Hide password' : 'Show password'}
265
250
  className="p-1 rounded active:opacity-70"
266
251
  >
267
- {isVisible ? (hideIcon || defaultHideIcon) : (showIcon || defaultShowIcon)}
252
+ {isVisible ? hideIcon || defaultHideIcon : showIcon || defaultShowIcon}
268
253
  </Pressable>
269
254
  }
270
255
  {...props}
@@ -1,2 +1,8 @@
1
1
  export { Input, InputGroup, PasswordInput } from './Input'
2
- export type { InputProps, InputGroupProps, PasswordInputProps, InputSize, InputVariant } from './Input'
2
+ export type {
3
+ InputProps,
4
+ InputGroupProps,
5
+ PasswordInputProps,
6
+ InputSize,
7
+ InputVariant,
8
+ } from './Input'
@@ -5,7 +5,7 @@ import { Link } from './Link'
5
5
  const meta: Meta<typeof Link> = {
6
6
  title: 'Components/Atoms/Link',
7
7
  component: Link,
8
- tags: ['autodocs'],
8
+ tags: ['autodocs', 'status:stable', '!status:review'],
9
9
  argTypes: {
10
10
  color: {
11
11
  control: 'select',
@@ -43,9 +43,15 @@ export const Default: Story = {
43
43
  export const AllColors: Story = {
44
44
  render: () => (
45
45
  <View style={{ flexDirection: 'row', gap: 16 }}>
46
- <Link color="default" onPress={() => {}}>Default</Link>
47
- <Link color="primary" onPress={() => {}}>Primary</Link>
48
- <Link color="secondary" onPress={() => {}}>Secondary</Link>
46
+ <Link color="default" onPress={() => {}}>
47
+ Default
48
+ </Link>
49
+ <Link color="primary" onPress={() => {}}>
50
+ Primary
51
+ </Link>
52
+ <Link color="secondary" onPress={() => {}}>
53
+ Secondary
54
+ </Link>
49
55
  </View>
50
56
  ),
51
57
  }
@@ -53,9 +59,15 @@ export const AllColors: Story = {
53
59
  export const UnderlineStyles: Story = {
54
60
  render: () => (
55
61
  <View style={{ flexDirection: 'row', gap: 16 }}>
56
- <Link underline="always" onPress={() => {}}>Always</Link>
57
- <Link underline="hover" onPress={() => {}}>Hover</Link>
58
- <Link underline="none" onPress={() => {}}>None</Link>
62
+ <Link underline="always" onPress={() => {}}>
63
+ Always
64
+ </Link>
65
+ <Link underline="hover" onPress={() => {}}>
66
+ Hover
67
+ </Link>
68
+ <Link underline="none" onPress={() => {}}>
69
+ None
70
+ </Link>
59
71
  </View>
60
72
  ),
61
73
  }
@@ -7,11 +7,23 @@ import {
7
7
  ListItemTrailing,
8
8
  ListItemDivider,
9
9
  } from './ListItem'
10
+ import { greyRamp } from '../../../theme/tokens/primitives'
10
11
 
11
12
  function UserIcon({ size = 20 }: { size?: number; className?: string }) {
12
13
  return (
13
- <View style={{ width: size, height: size, borderRadius: size / 2, backgroundColor: '#6366f1', justifyContent: 'center', alignItems: 'center' }}>
14
- <Text style={{ color: '#fff', fontSize: size * 0.5, fontWeight: '600' }}>U</Text>
14
+ <View
15
+ style={{
16
+ width: size,
17
+ height: size,
18
+ borderRadius: size / 2,
19
+ backgroundColor: 'var(--color-avatar-background)',
20
+ justifyContent: 'center',
21
+ alignItems: 'center',
22
+ }}
23
+ >
24
+ <Text style={{ color: 'var(--color-avatar-text)', fontSize: size * 0.5, fontWeight: '600' }}>
25
+ U
26
+ </Text>
15
27
  </View>
16
28
  )
17
29
  }
@@ -41,13 +53,13 @@ function LockIcon({ size = 20 }: { size?: number; className?: string }) {
41
53
  }
42
54
 
43
55
  function ChevronRight({ size = 16 }: { size?: number }) {
44
- return <Text style={{ color: '#9ca3af', fontSize: size }}>{'>'}</Text>
56
+ return <Text style={{ color: greyRamp[400], fontSize: size }}>{'>'}</Text>
45
57
  }
46
58
 
47
59
  const meta: Meta<typeof ListItem> = {
48
60
  title: 'Components/Molecules/ListItem',
49
61
  component: ListItem,
50
- tags: ['autodocs'],
62
+ tags: ['autodocs', 'status:stable', '!status:review'],
51
63
  }
52
64
 
53
65
  export default meta
@@ -124,7 +136,7 @@ export const SettingsList: Story = {
124
136
  <ListItemIcon icon={WifiIcon} />
125
137
  <ListItemContent title="Wi-Fi" subtitle="HomeNetwork" />
126
138
  <ListItemTrailing>
127
- <Text style={{ color: '#22c55e', fontSize: 12 }}>Connected</Text>
139
+ <Text style={{ color: 'var(--color-status-success)', fontSize: 12 }}>Connected</Text>
128
140
  </ListItemTrailing>
129
141
  </ListItem>
130
142
  </View>
@@ -50,9 +50,7 @@ export function ListItemContent({ title, subtitle, className, ...props }: ListIt
50
50
  return (
51
51
  <View className={cn('flex-1 justify-center', className)} {...props}>
52
52
  <Text className="text-sm font-medium text-text-primary">{title}</Text>
53
- {subtitle && (
54
- <Text className="text-xs text-text-secondary mt-0.5">{subtitle}</Text>
55
- )}
53
+ {subtitle && <Text className="text-xs text-text-secondary mt-0.5">{subtitle}</Text>}
56
54
  </View>
57
55
  )
58
56
  }
@@ -80,10 +78,5 @@ export interface ListItemDividerProps extends ViewProps {
80
78
  }
81
79
 
82
80
  export function ListItemDivider({ inset = true, className, ...props }: ListItemDividerProps) {
83
- return (
84
- <View
85
- className={cn('h-px bg-divider', inset ? 'ml-14' : '', className)}
86
- {...props}
87
- />
88
- )
81
+ return <View className={cn('h-px bg-divider', inset ? 'ml-14' : '', className)} {...props} />
89
82
  }
@@ -68,21 +68,15 @@ export const WithGroups: Story = {
68
68
  }
69
69
 
70
70
  function EditIcon({ size = 14 }: { size?: number }) {
71
- return (
72
- <Text style={{ fontSize: size, lineHeight: size }}>&#9998;</Text>
73
- )
71
+ return <Text style={{ fontSize: size, lineHeight: size }}>&#9998;</Text>
74
72
  }
75
73
 
76
74
  function TrashIcon({ size = 14 }: { size?: number }) {
77
- return (
78
- <Text style={{ fontSize: size, lineHeight: size }}>&#128465;</Text>
79
- )
75
+ return <Text style={{ fontSize: size, lineHeight: size }}>&#128465;</Text>
80
76
  }
81
77
 
82
78
  function CopyIcon({ size = 14 }: { size?: number }) {
83
- return (
84
- <Text style={{ fontSize: size, lineHeight: size }}>&#128203;</Text>
85
- )
79
+ return <Text style={{ fontSize: size, lineHeight: size }}>&#128203;</Text>
86
80
  }
87
81
 
88
82
  export const WithIcons: Story = {
@@ -94,10 +88,16 @@ export const WithIcons: Story = {
94
88
  </Button>
95
89
  </MenuTrigger>
96
90
  <MenuList>
97
- <MenuItem icon={<EditIcon />} onPress={() => {}}>Edit</MenuItem>
98
- <MenuItem icon={<CopyIcon />} onPress={() => {}}>Duplicate</MenuItem>
91
+ <MenuItem icon={<EditIcon />} onPress={() => {}}>
92
+ Edit
93
+ </MenuItem>
94
+ <MenuItem icon={<CopyIcon />} onPress={() => {}}>
95
+ Duplicate
96
+ </MenuItem>
99
97
  <MenuDivider />
100
- <MenuItem icon={<TrashIcon />} onPress={() => {}} isDestructive>Delete</MenuItem>
98
+ <MenuItem icon={<TrashIcon />} onPress={() => {}} isDestructive>
99
+ Delete
100
+ </MenuItem>
101
101
  </MenuList>
102
102
  </Menu>
103
103
  ),
@@ -115,7 +115,9 @@ export const DestructiveItem: Story = {
115
115
  <MenuItem onPress={() => {}}>Edit Profile</MenuItem>
116
116
  <MenuItem onPress={() => {}}>Change Password</MenuItem>
117
117
  <MenuDivider />
118
- <MenuItem onPress={() => {}} isDestructive>Delete Account</MenuItem>
118
+ <MenuItem onPress={() => {}} isDestructive>
119
+ Delete Account
120
+ </MenuItem>
119
121
  </MenuList>
120
122
  </Menu>
121
123
  ),
@@ -152,11 +154,15 @@ export const DisabledItems: Story = {
152
154
  </MenuTrigger>
153
155
  <MenuList>
154
156
  <MenuItem onPress={() => {}}>Undo</MenuItem>
155
- <MenuItem onPress={() => {}} isDisabled>Redo</MenuItem>
157
+ <MenuItem onPress={() => {}} isDisabled>
158
+ Redo
159
+ </MenuItem>
156
160
  <MenuDivider />
157
161
  <MenuItem onPress={() => {}}>Cut</MenuItem>
158
162
  <MenuItem onPress={() => {}}>Copy</MenuItem>
159
- <MenuItem onPress={() => {}} isDisabled>Paste</MenuItem>
163
+ <MenuItem onPress={() => {}} isDisabled>
164
+ Paste
165
+ </MenuItem>
160
166
  </MenuList>
161
167
  </Menu>
162
168
  ),
@@ -1,14 +1,7 @@
1
1
  import { describe, it, expect, vi } from 'vitest'
2
2
  import { render, screen, fireEvent } from '@testing-library/react'
3
3
  import { axe } from 'jest-axe'
4
- import {
5
- Menu,
6
- MenuTrigger,
7
- MenuList,
8
- MenuItem,
9
- MenuDivider,
10
- MenuGroup,
11
- } from './Menu'
4
+ import { Menu, MenuTrigger, MenuList, MenuItem, MenuDivider, MenuGroup } from './Menu'
12
5
 
13
6
  describe('Menu', () => {
14
7
  it('renders trigger element', () => {
@@ -198,9 +191,7 @@ describe('Menu', () => {
198
191
  <button>Options</button>
199
192
  </MenuTrigger>
200
193
  <MenuList>
201
- <MenuItem icon={<span data-testid="edit-icon">pencil</span>}>
202
- Edit
203
- </MenuItem>
194
+ <MenuItem icon={<span data-testid="edit-icon">pencil</span>}>Edit</MenuItem>
204
195
  </MenuList>
205
196
  </Menu>
206
197
  )
@@ -1,6 +1,8 @@
1
1
  import React, { useState, createContext, useContext } from 'react'
2
2
  import { View, Text, Pressable, type ViewProps } from 'react-native'
3
3
  import { cn } from '../../../utils/cn'
4
+ import { Surface } from '../surface'
5
+ import { TriggerSurface } from '../trigger'
4
6
 
5
7
  interface MenuContextType {
6
8
  isOpen: boolean
@@ -80,14 +82,14 @@ export function MenuTrigger({ children, className }: MenuTriggerProps) {
80
82
  const { isOpen, setIsOpen } = useContext(MenuContext)
81
83
 
82
84
  return (
83
- <Pressable
84
- onPress={() => setIsOpen(!isOpen)}
85
+ <TriggerSurface
86
+ handlers={{ onPress: () => setIsOpen(!isOpen) }}
85
87
  accessibilityRole="button"
86
88
  accessibilityState={{ expanded: isOpen }}
87
89
  className={className}
88
90
  >
89
91
  {children}
90
- </Pressable>
92
+ </TriggerSurface>
91
93
  )
92
94
  }
93
95
 
@@ -112,18 +114,19 @@ export function MenuList({ children, className }: MenuListProps) {
112
114
  className="fixed inset-0 z-40"
113
115
  style={{ position: 'absolute' }}
114
116
  />
115
- {/* Menu */}
116
- <View
117
+ {/* Menu — floating: overlay plane + lift, no ring. */}
118
+ <Surface
119
+ elevation={4}
120
+ rounded={false}
117
121
  className={cn(
118
122
  'absolute z-50 top-full left-0 mt-1 min-w-[160px]',
119
- 'bg-surface-elevated rounded-lg shadow-lg border border-hairline',
120
- 'py-1 overflow-hidden',
123
+ 'rounded-lg py-1 overflow-hidden',
121
124
  className
122
125
  )}
123
126
  accessibilityRole="menu"
124
127
  >
125
128
  {children}
126
- </View>
129
+ </Surface>
127
130
  </>
128
131
  )
129
132
  }
@@ -175,12 +178,7 @@ export function MenuItem({
175
178
  )}
176
179
  >
177
180
  {icon && <View className="mr-3">{icon}</View>}
178
- <Text
179
- className={cn(
180
- 'text-sm',
181
- isDestructive ? 'text-status-error' : 'text-text-primary'
182
- )}
183
- >
181
+ <Text className={cn('text-sm', isDestructive ? 'text-status-error' : 'text-text-primary')}>
184
182
  {children}
185
183
  </Text>
186
184
  </Pressable>
@@ -1,2 +1,9 @@
1
1
  export { Menu, MenuTrigger, MenuList, MenuItem, MenuDivider, MenuGroup } from './Menu'
2
- export type { MenuProps, MenuTriggerProps, MenuListProps, MenuItemProps, MenuDividerProps, MenuGroupProps } from './Menu'
2
+ export type {
3
+ MenuProps,
4
+ MenuTriggerProps,
5
+ MenuListProps,
6
+ MenuItemProps,
7
+ MenuDividerProps,
8
+ MenuGroupProps,
9
+ } from './Menu'
@@ -194,8 +194,8 @@ export const ScrollableContent: Story = {
194
194
  <Text className="text-text-primary font-semibold mb-1">Section {i + 1}</Text>
195
195
  <Text className="text-text-secondary text-sm">
196
196
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor
197
- incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
198
- nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
197
+ incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
198
+ exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
199
199
  </Text>
200
200
  </View>
201
201
  ))}
@@ -1,6 +1,14 @@
1
1
  import React, { createContext, useContext } from 'react'
2
- import { Modal as RNModal, View, Text, Pressable, ScrollView, type ModalProps as RNModalProps } from 'react-native'
2
+ import {
3
+ Modal as RNModal,
4
+ View,
5
+ Text,
6
+ Pressable,
7
+ ScrollView,
8
+ type ModalProps as RNModalProps,
9
+ } from 'react-native'
3
10
  import { cn } from '../../../utils/cn'
11
+ import { Surface } from '../surface'
4
12
 
5
13
  export type ModalSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'full'
6
14
  export type ModalScrollBehavior = 'inside' | 'outside'
@@ -84,6 +92,8 @@ export function Modal({
84
92
  onPress={handleBackdropPress}
85
93
  className={cn(
86
94
  'flex-1 items-center justify-center',
95
+ // VW-82: scrims stay raw — Tailwind v3 drops the `/n` modifier on a
96
+ // `var()` colour, so a translucent role has to be its own token (proposed).
87
97
  backdropBlur ? 'bg-black/30 web:backdrop-blur-sm' : 'bg-black/50',
88
98
  backdropClassName
89
99
  )}
@@ -102,10 +112,7 @@ export function Modal({
102
112
  {...props}
103
113
  >
104
114
  {scrollBehavior === 'outside' ? (
105
- <ScrollView
106
- contentContainerStyle={{ flexGrow: 1 }}
107
- keyboardShouldPersistTaps="handled"
108
- >
115
+ <ScrollView contentContainerStyle={{ flexGrow: 1 }} keyboardShouldPersistTaps="handled">
109
116
  {backdropContent}
110
117
  </ScrollView>
111
118
  ) : (
@@ -132,15 +139,14 @@ export function ModalContent({ children, className }: ModalContentProps) {
132
139
  // Prevent backdrop click from propagating
133
140
  onPress={(e) => e.stopPropagation()}
134
141
  >
135
- <View
136
- className={cn(
137
- 'bg-surface-elevated rounded-lg shadow-xl w-full',
138
- sizeStyles[size],
139
- className
140
- )}
142
+ {/* Floating: overlay plane + the deepest lift, no ring. */}
143
+ <Surface
144
+ elevation={5}
145
+ rounded={false}
146
+ className={cn('rounded-lg w-full', sizeStyles[size], className)}
141
147
  >
142
148
  {children}
143
- </View>
149
+ </Surface>
144
150
  </Pressable>
145
151
  )
146
152
  }
@@ -155,7 +161,12 @@ export interface ModalHeaderProps {
155
161
  */
156
162
  export function ModalHeader({ children, className }: ModalHeaderProps) {
157
163
  return (
158
- <View className={cn('flex-row items-center justify-between px-6 py-4 border-b border-divider', className)}>
164
+ <View
165
+ className={cn(
166
+ 'flex-row items-center justify-between px-6 py-4 border-b border-divider',
167
+ className
168
+ )}
169
+ >
159
170
  {children}
160
171
  </View>
161
172
  )
@@ -230,11 +241,7 @@ export function ModalBody({ children, maxHeight, className }: ModalBodyProps) {
230
241
  )
231
242
  }
232
243
 
233
- return (
234
- <View className={cn('px-6 py-4', className)}>
235
- {children}
236
- </View>
237
- )
244
+ return <View className={cn('px-6 py-4', className)}>{children}</View>
238
245
  }
239
246
 
240
247
  export interface ModalFooterProps {
@@ -247,7 +254,12 @@ export interface ModalFooterProps {
247
254
  */
248
255
  export function ModalFooter({ children, className }: ModalFooterProps) {
249
256
  return (
250
- <View className={cn('flex-row items-center justify-end gap-2 px-6 py-4 border-t border-divider', className)}>
257
+ <View
258
+ className={cn(
259
+ 'flex-row items-center justify-end gap-2 px-6 py-4 border-t border-divider',
260
+ className
261
+ )}
262
+ >
251
263
  {children}
252
264
  </View>
253
265
  )