@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
@@ -1,9 +1,16 @@
1
1
  import React, { createContext, useContext, useState, useCallback, useEffect } 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'
4
5
 
5
6
  export type ToastStatus = 'success' | 'error' | 'warning' | 'info'
6
- export type ToastPosition = 'top' | 'top-right' | 'top-left' | 'bottom' | 'bottom-right' | 'bottom-left'
7
+ export type ToastPosition =
8
+ | 'top'
9
+ | 'top-right'
10
+ | 'top-left'
11
+ | 'bottom'
12
+ | 'bottom-right'
13
+ | 'bottom-left'
7
14
 
8
15
  export interface ToastConfig {
9
16
  /** Unique ID for the toast */
@@ -44,10 +51,10 @@ export interface ToastProviderProps {
44
51
  }
45
52
 
46
53
  const positionStyles: Record<ToastPosition, string> = {
47
- 'top': 'top-4 left-1/2 -translate-x-1/2',
54
+ top: 'top-4 left-1/2 -translate-x-1/2',
48
55
  'top-right': 'top-4 right-4',
49
56
  'top-left': 'top-4 left-4',
50
- 'bottom': 'bottom-4 left-1/2 -translate-x-1/2',
57
+ bottom: 'bottom-4 left-1/2 -translate-x-1/2',
51
58
  'bottom-right': 'bottom-4 right-4',
52
59
  'bottom-left': 'bottom-4 left-4',
53
60
  }
@@ -73,23 +80,26 @@ export function ToastProvider({
73
80
  }: ToastProviderProps) {
74
81
  const [toasts, setToasts] = useState<ToastConfig[]>([])
75
82
 
76
- const addToast = useCallback((config: Omit<ToastConfig, 'id'>) => {
77
- const id = `toast-${++toastIdCounter}`
78
- const newToast: ToastConfig = {
79
- id,
80
- duration: defaultDuration,
81
- isClosable: true,
82
- status: 'info',
83
- ...config,
84
- }
83
+ const addToast = useCallback(
84
+ (config: Omit<ToastConfig, 'id'>) => {
85
+ const id = `toast-${++toastIdCounter}`
86
+ const newToast: ToastConfig = {
87
+ id,
88
+ duration: defaultDuration,
89
+ isClosable: true,
90
+ status: 'info',
91
+ ...config,
92
+ }
85
93
 
86
- setToasts((prev) => {
87
- const updated = [newToast, ...prev]
88
- return updated.slice(0, maxToasts)
89
- })
94
+ setToasts((prev) => {
95
+ const updated = [newToast, ...prev]
96
+ return updated.slice(0, maxToasts)
97
+ })
90
98
 
91
- return id
92
- }, [defaultDuration, maxToasts])
99
+ return id
100
+ },
101
+ [defaultDuration, maxToasts]
102
+ )
93
103
 
94
104
  const removeToast = useCallback((id: string) => {
95
105
  setToasts((prev) => prev.filter((t) => t.id !== id))
@@ -104,10 +114,7 @@ export function ToastProvider({
104
114
  {children}
105
115
  {/* Toast Container */}
106
116
  <View
107
- className={cn(
108
- 'fixed z-[9999] flex flex-col gap-2',
109
- positionStyles[position]
110
- )}
117
+ className={cn('fixed z-[9999] flex flex-col gap-2', positionStyles[position])}
111
118
  pointerEvents="box-none"
112
119
  >
113
120
  {toasts.map((toast) => (
@@ -150,24 +157,26 @@ interface ToastItemProps extends ToastConfig {
150
157
  onClose: () => void
151
158
  }
152
159
 
160
+ // `-subtle` is the wash ladder's lightest rung. It replaces a `/10` opacity
161
+ // modifier, which emitted no rule at all against a var()-backed token (VW-308).
153
162
  const statusStyles: Record<ToastStatus, { bg: string; border: string; icon: string }> = {
154
163
  success: {
155
- bg: 'bg-status-success/10',
164
+ bg: 'bg-status-success-subtle',
156
165
  border: 'border-status-success',
157
166
  icon: '✓',
158
167
  },
159
168
  error: {
160
- bg: 'bg-status-error/10',
169
+ bg: 'bg-status-error-subtle',
161
170
  border: 'border-status-error',
162
171
  icon: '✕',
163
172
  },
164
173
  warning: {
165
- bg: 'bg-status-warning/10',
174
+ bg: 'bg-status-warning-subtle',
166
175
  border: 'border-status-warning',
167
176
  icon: '⚠',
168
177
  },
169
178
  info: {
170
- bg: 'bg-status-info/10',
179
+ bg: 'bg-status-info-subtle',
171
180
  border: 'border-status-info',
172
181
  icon: 'ℹ',
173
182
  },
@@ -200,12 +209,10 @@ function ToastItem({
200
209
  }, [duration, onClose])
201
210
 
202
211
  return (
203
- <View
204
- className={cn(
205
- 'min-w-[280px] max-w-[400px] rounded-lg border-l-4 shadow-lg',
206
- 'bg-surface-elevated',
207
- border
208
- )}
212
+ <Surface
213
+ elevation={5}
214
+ rounded={false}
215
+ className={cn('min-w-[280px] max-w-[400px] rounded-lg border-l-4', border)}
209
216
  accessibilityRole="alert"
210
217
  >
211
218
  <View className={cn('flex-row items-start p-3', bg)}>
@@ -216,14 +223,8 @@ function ToastItem({
216
223
 
217
224
  {/* Content */}
218
225
  <View className="flex-1">
219
- <Text className="text-sm font-semibold text-text-primary">
220
- {title}
221
- </Text>
222
- {description && (
223
- <Text className="text-sm text-text-secondary mt-0.5">
224
- {description}
225
- </Text>
226
- )}
226
+ <Text className="text-sm font-semibold text-text-primary">{title}</Text>
227
+ {description && <Text className="text-sm text-text-secondary mt-0.5">{description}</Text>}
227
228
  </View>
228
229
 
229
230
  {/* Close button */}
@@ -237,7 +238,7 @@ function ToastItem({
237
238
  </Pressable>
238
239
  )}
239
240
  </View>
240
- </View>
241
+ </Surface>
241
242
  )
242
243
  }
243
244
 
@@ -281,13 +282,10 @@ export function Toast({
281
282
  const { bg, border, icon } = statusStyles[status]
282
283
 
283
284
  return (
284
- <View
285
- className={cn(
286
- 'min-w-[280px] max-w-[400px] rounded-lg border-l-4 shadow-lg',
287
- 'bg-surface-elevated',
288
- border,
289
- className
290
- )}
285
+ <Surface
286
+ elevation={5}
287
+ rounded={false}
288
+ className={cn('min-w-[280px] max-w-[400px] rounded-lg border-l-4', border, className)}
291
289
  accessibilityRole="alert"
292
290
  {...props}
293
291
  >
@@ -301,14 +299,8 @@ export function Toast({
301
299
 
302
300
  {/* Content */}
303
301
  <View className="flex-1">
304
- <Text className="text-sm font-semibold text-text-primary">
305
- {title}
306
- </Text>
307
- {description && (
308
- <Text className="text-sm text-text-secondary mt-0.5">
309
- {description}
310
- </Text>
311
- )}
302
+ <Text className="text-sm font-semibold text-text-primary">{title}</Text>
303
+ {description && <Text className="text-sm text-text-secondary mt-0.5">{description}</Text>}
312
304
  </View>
313
305
 
314
306
  {/* Close button */}
@@ -322,6 +314,6 @@ export function Toast({
322
314
  </Pressable>
323
315
  )}
324
316
  </View>
325
- </View>
317
+ </Surface>
326
318
  )
327
319
  }
@@ -6,4 +6,3 @@ export type {
6
6
  ToastStatus,
7
7
  ToastPosition,
8
8
  } from './Toast'
9
-
@@ -6,7 +6,7 @@ import { ToolbarButton, ToolbarButtonGroup } from './ToolbarButton'
6
6
  const meta: Meta<typeof ToolbarButton> = {
7
7
  title: 'Components/Molecules/ToolbarButton',
8
8
  component: ToolbarButton,
9
- tags: ['autodocs'],
9
+ tags: ['autodocs', 'status:stable', '!status:review'],
10
10
  argTypes: {
11
11
  variant: {
12
12
  control: 'select',
@@ -40,19 +40,34 @@ type Story = StoryObj<typeof ToolbarButton>
40
40
  // These simulate MUI SvgIcon components at 20x20
41
41
  const SettingsIcon = ({ color }: { color?: string }) => (
42
42
  <View style={{ width: 20, height: 20, alignItems: 'center', justifyContent: 'center' }}>
43
- <Text className={color ? undefined : 'text-text-secondary'} style={{ fontSize: 16, ...(color ? { color } : {}) }}>⚙</Text>
43
+ <Text
44
+ className={color ? undefined : 'text-text-secondary'}
45
+ style={{ fontSize: 16, ...(color ? { color } : {}) }}
46
+ >
47
+
48
+ </Text>
44
49
  </View>
45
50
  )
46
51
 
47
52
  const FilterIcon = ({ color }: { color?: string }) => (
48
53
  <View style={{ width: 20, height: 20, alignItems: 'center', justifyContent: 'center' }}>
49
- <Text className={color ? undefined : 'text-text-secondary'} style={{ fontSize: 16, ...(color ? { color } : {}) }}>⏣</Text>
54
+ <Text
55
+ className={color ? undefined : 'text-text-secondary'}
56
+ style={{ fontSize: 16, ...(color ? { color } : {}) }}
57
+ >
58
+
59
+ </Text>
50
60
  </View>
51
61
  )
52
62
 
53
63
  const ViewIcon = ({ color }: { color?: string }) => (
54
64
  <View style={{ width: 20, height: 20, alignItems: 'center', justifyContent: 'center' }}>
55
- <Text className={color ? undefined : 'text-text-secondary'} style={{ fontSize: 16, ...(color ? { color } : {}) }}>◉</Text>
65
+ <Text
66
+ className={color ? undefined : 'text-text-secondary'}
67
+ style={{ fontSize: 16, ...(color ? { color } : {}) }}
68
+ >
69
+
70
+ </Text>
56
71
  </View>
57
72
  )
58
73
 
@@ -72,30 +87,19 @@ export const ActiveVsInactive: Story = {
72
87
  <Text className="text-text-secondary text-xs mb-1">
73
88
  isActive=true - sunken/dark look, ORANGE icon, white text
74
89
  </Text>
75
- <ToolbarButton
76
- label="Active (orange icon)"
77
- icon={<FilterIcon />}
78
- isActive={true}
79
- />
90
+ <ToolbarButton label="Active (orange icon)" icon={<FilterIcon />} isActive={true} />
80
91
  </View>
81
92
  <View>
82
93
  <Text className="text-text-secondary text-xs mb-1">
83
94
  isActive=undefined - sunken/dark look, white icon (default state)
84
95
  </Text>
85
- <ToolbarButton
86
- label="Default (white icon)"
87
- icon={<FilterIcon />}
88
- />
96
+ <ToolbarButton label="Default (white icon)" icon={<FilterIcon />} />
89
97
  </View>
90
98
  <View>
91
99
  <Text className="text-text-secondary text-xs mb-1">
92
100
  isActive=false - elevated/light look, gray icon
93
101
  </Text>
94
- <ToolbarButton
95
- label="Inactive (gray icon)"
96
- icon={<FilterIcon />}
97
- isActive={false}
98
- />
102
+ <ToolbarButton label="Inactive (gray icon)" icon={<FilterIcon />} isActive={false} />
99
103
  </View>
100
104
  </View>
101
105
  ),
@@ -109,8 +113,8 @@ export const Interactive: Story = {
109
113
  <Text className="text-text-secondary text-xs">
110
114
  Click to toggle. When active=true, icon turns orange:
111
115
  </Text>
112
- <ToolbarButton
113
- label="Toggle Me"
116
+ <ToolbarButton
117
+ label="Toggle Me"
114
118
  icon={<SettingsIcon />}
115
119
  isActive={active}
116
120
  onPress={() => setActive(!active)}
@@ -130,24 +134,19 @@ export const IconOnly: Story = {
130
134
  Icon-only buttons. Active button has orange icon:
131
135
  </Text>
132
136
  <View style={{ flexDirection: 'row', gap: 8 }}>
133
- <ToolbarButton
134
- label="Settings"
135
- icon={<SettingsIcon />}
137
+ <ToolbarButton
138
+ label="Settings"
139
+ icon={<SettingsIcon />}
136
140
  showLabel={false}
137
141
  isActive={false}
138
142
  />
139
- <ToolbarButton
140
- label="Filter (active)"
141
- icon={<FilterIcon />}
142
- showLabel={false}
143
- isActive={true}
144
- />
145
- <ToolbarButton
146
- label="View"
147
- icon={<ViewIcon />}
143
+ <ToolbarButton
144
+ label="Filter (active)"
145
+ icon={<FilterIcon />}
148
146
  showLabel={false}
149
- isActive={false}
147
+ isActive={true}
150
148
  />
149
+ <ToolbarButton label="View" icon={<ViewIcon />} showLabel={false} isActive={false} />
151
150
  </View>
152
151
  </View>
153
152
  ),
@@ -166,15 +165,15 @@ export const Disabled: Story = {
166
165
  Note: Orange icon IS shown when isActive=true (matching original XP behavior)
167
166
  </Text>
168
167
  <View style={{ flexDirection: 'row', gap: 8 }}>
169
- <ToolbarButton
170
- label="Disabled Active"
171
- icon={<SettingsIcon />}
168
+ <ToolbarButton
169
+ label="Disabled Active"
170
+ icon={<SettingsIcon />}
172
171
  isActive={true}
173
172
  isDisabled={true}
174
173
  />
175
- <ToolbarButton
176
- label="Disabled Inactive"
177
- icon={<SettingsIcon />}
174
+ <ToolbarButton
175
+ label="Disabled Inactive"
176
+ icon={<SettingsIcon />}
178
177
  isActive={false}
179
178
  isDisabled={true}
180
179
  />
@@ -193,16 +192,8 @@ export const HoverStates: Story = {
193
192
  Active: #3C3C3C → #4C4C4C | Inactive: #6E6E6E → #5D5D5D | Shadows: removed
194
193
  </Text>
195
194
  <View style={{ flexDirection: 'row', gap: 8 }}>
196
- <ToolbarButton
197
- label="Hover Me (Active)"
198
- icon={<SettingsIcon />}
199
- isActive={true}
200
- />
201
- <ToolbarButton
202
- label="Hover Me (Inactive)"
203
- icon={<SettingsIcon />}
204
- isActive={false}
205
- />
195
+ <ToolbarButton label="Hover Me (Active)" icon={<SettingsIcon />} isActive={true} />
196
+ <ToolbarButton label="Hover Me (Inactive)" icon={<SettingsIcon />} isActive={false} />
206
197
  </View>
207
198
  </View>
208
199
  ),
@@ -217,9 +208,24 @@ export const WithMenu: Story = {
217
208
  isActive={false}
218
209
  menuContent={
219
210
  <View style={{ paddingVertical: 8 }}>
220
- <Text className="text-text-primary" style={{ paddingHorizontal: 16, paddingVertical: 8 }}>Grid View</Text>
221
- <Text className="text-text-primary" style={{ paddingHorizontal: 16, paddingVertical: 8 }}>List View</Text>
222
- <Text className="text-text-primary" style={{ paddingHorizontal: 16, paddingVertical: 8 }}>Compact View</Text>
211
+ <Text
212
+ className="text-text-primary"
213
+ style={{ paddingHorizontal: 16, paddingVertical: 8 }}
214
+ >
215
+ Grid View
216
+ </Text>
217
+ <Text
218
+ className="text-text-primary"
219
+ style={{ paddingHorizontal: 16, paddingVertical: 8 }}
220
+ >
221
+ List View
222
+ </Text>
223
+ <Text
224
+ className="text-text-primary"
225
+ style={{ paddingHorizontal: 16, paddingVertical: 8 }}
226
+ >
227
+ Compact View
228
+ </Text>
223
229
  </View>
224
230
  }
225
231
  />
@@ -230,27 +236,27 @@ export const WithMenu: Story = {
230
236
  export const ButtonGroup: Story = {
231
237
  render: function Render() {
232
238
  const [activeIndex, setActiveIndex] = useState<number | null>(1)
233
-
239
+
234
240
  return (
235
241
  <View style={{ gap: 16 }}>
236
242
  <Text className="text-text-secondary text-xs mb-1">
237
243
  Click to select (one active at a time):
238
244
  </Text>
239
245
  <ToolbarButtonGroup gap="sm">
240
- <ToolbarButton
241
- label="Filter"
246
+ <ToolbarButton
247
+ label="Filter"
242
248
  icon={<FilterIcon />}
243
249
  isActive={activeIndex === 0}
244
250
  onPress={() => setActiveIndex(activeIndex === 0 ? null : 0)}
245
251
  />
246
- <ToolbarButton
247
- label="Settings"
252
+ <ToolbarButton
253
+ label="Settings"
248
254
  icon={<SettingsIcon />}
249
255
  isActive={activeIndex === 1}
250
256
  onPress={() => setActiveIndex(activeIndex === 1 ? null : 1)}
251
257
  />
252
- <ToolbarButton
253
- label="View"
258
+ <ToolbarButton
259
+ label="View"
254
260
  icon={<ViewIcon />}
255
261
  isActive={activeIndex === 2}
256
262
  onPress={() => setActiveIndex(activeIndex === 2 ? null : 2)}
@@ -265,7 +271,7 @@ export const ToolbarExample: Story = {
265
271
  render: function Render() {
266
272
  const [filterActive, setFilterActive] = useState(true)
267
273
  const [settingsActive, setSettingsActive] = useState(false)
268
-
274
+
269
275
  return (
270
276
  <View>
271
277
  <Text className="text-text-secondary text-xs mb-3">
@@ -290,8 +296,18 @@ export const ToolbarExample: Story = {
290
296
  isActive={false}
291
297
  menuContent={
292
298
  <View style={{ paddingVertical: 8 }}>
293
- <Text className="text-text-primary" style={{ paddingHorizontal: 16, paddingVertical: 8 }}>Grid</Text>
294
- <Text className="text-text-primary" style={{ paddingHorizontal: 16, paddingVertical: 8 }}>List</Text>
299
+ <Text
300
+ className="text-text-primary"
301
+ style={{ paddingHorizontal: 16, paddingVertical: 8 }}
302
+ >
303
+ Grid
304
+ </Text>
305
+ <Text
306
+ className="text-text-primary"
307
+ style={{ paddingHorizontal: 16, paddingVertical: 8 }}
308
+ >
309
+ List
310
+ </Text>
295
311
  </View>
296
312
  }
297
313
  />
@@ -304,7 +320,7 @@ export const ToolbarExample: Story = {
304
320
  export const CompactMode: Story = {
305
321
  render: function Render() {
306
322
  const [isCompact, setIsCompact] = useState(false)
307
-
323
+
308
324
  return (
309
325
  <View style={{ gap: 16 }}>
310
326
  <View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
@@ -333,12 +349,7 @@ export const CompactMode: Story = {
333
349
  showLabel={!isCompact}
334
350
  isActive={false}
335
351
  />
336
- <ToolbarButton
337
- label="View"
338
- icon={<ViewIcon />}
339
- showLabel={!isCompact}
340
- isActive={false}
341
- />
352
+ <ToolbarButton label="View" icon={<ViewIcon />} showLabel={!isCompact} isActive={false} />
342
353
  </ToolbarButtonGroup>
343
354
  </View>
344
355
  )
@@ -351,14 +362,24 @@ export const Variants: Story = {
351
362
  <View>
352
363
  <Text className="text-text-secondary text-xs mb-2">Neumorphic (with 3D inset shadows)</Text>
353
364
  <View style={{ flexDirection: 'row', gap: 8 }}>
354
- <ToolbarButton label="Inactive" icon={<SettingsIcon />} variant="raised" isActive={false} />
365
+ <ToolbarButton
366
+ label="Inactive"
367
+ icon={<SettingsIcon />}
368
+ variant="raised"
369
+ isActive={false}
370
+ />
355
371
  <ToolbarButton label="Active" icon={<SettingsIcon />} variant="raised" isActive={true} />
356
372
  </View>
357
373
  </View>
358
374
  <View>
359
375
  <Text className="text-text-secondary text-xs mb-2">Flat (no shadows)</Text>
360
376
  <View style={{ flexDirection: 'row', gap: 8 }}>
361
- <ToolbarButton label="Inactive" icon={<SettingsIcon />} variant="default" isActive={false} />
377
+ <ToolbarButton
378
+ label="Inactive"
379
+ icon={<SettingsIcon />}
380
+ variant="default"
381
+ isActive={false}
382
+ />
362
383
  <ToolbarButton label="Active" icon={<SettingsIcon />} variant="default" isActive={true} />
363
384
  </View>
364
385
  </View>
@@ -11,12 +11,7 @@ describe('ToolbarButton', () => {
11
11
  })
12
12
 
13
13
  it('renders icon when provided', () => {
14
- render(
15
- <ToolbarButton
16
- label="Settings"
17
- icon={<span data-testid="icon">gear</span>}
18
- />
19
- )
14
+ render(<ToolbarButton label="Settings" icon={<span data-testid="icon">gear</span>} />)
20
15
  expect(screen.getByTestId('icon')).toBeInTheDocument()
21
16
  })
22
17
 
@@ -108,24 +103,14 @@ describe('ToolbarButton', () => {
108
103
 
109
104
  describe('menu content', () => {
110
105
  it('shows menu when pressed with menuContent', () => {
111
- render(
112
- <ToolbarButton
113
- label="Options"
114
- menuContent={<span>Menu item</span>}
115
- />
116
- )
106
+ render(<ToolbarButton label="Options" menuContent={<span>Menu item</span>} />)
117
107
 
118
108
  fireEvent.click(screen.getByRole('button', { name: 'Options' }))
119
109
  expect(screen.getByText('Menu item')).toBeInTheDocument()
120
110
  })
121
111
 
122
112
  it('hides menu when pressed again', () => {
123
- render(
124
- <ToolbarButton
125
- label="Options"
126
- menuContent={<span>Menu item</span>}
127
- />
128
- )
113
+ render(<ToolbarButton label="Options" menuContent={<span>Menu item</span>} />)
129
114
 
130
115
  const button = screen.getByRole('button', { name: 'Options' })
131
116
  fireEvent.click(button)