@titan-design/react-ui 0.12.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -47
- package/dist/bodymap.js +768 -701
- package/dist/bodymap.js.map +1 -1
- package/dist/bodymap.mjs +770 -703
- package/dist/bodymap.mjs.map +1 -1
- package/dist/index.d.mts +1320 -215
- package/dist/index.d.ts +1320 -215
- package/dist/index.js +5996 -4498
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5773 -4357
- package/dist/index.mjs.map +1 -1
- package/dist/{pages-CvsFqNtx.d.mts → pages-CpW3OB3g.d.mts} +21 -3
- package/dist/{pages-B1hqnGIC.d.ts → pages-_3Ajpiqu.d.ts} +21 -3
- package/dist/pages.d.mts +1 -1
- package/dist/pages.d.ts +1 -1
- package/dist/pages.js +1435 -1428
- package/dist/pages.js.map +1 -1
- package/dist/pages.mjs +1443 -1436
- package/dist/pages.mjs.map +1 -1
- package/dist/theme/index.d.mts +202 -1042
- package/dist/theme/index.d.ts +202 -1042
- package/dist/theme/index.js +215 -300
- package/dist/theme/index.js.map +1 -1
- package/dist/theme/index.mjs +202 -296
- package/dist/theme/index.mjs.map +1 -1
- package/dist/theme/tokens-css.js +62 -5
- package/dist/theme/tokens-css.js.map +1 -1
- package/dist/theme/tokens-css.mjs +62 -5
- package/dist/theme/tokens-css.mjs.map +1 -1
- package/dist/theme/tokens.d.mts +972 -0
- package/dist/theme/tokens.d.ts +972 -0
- package/dist/theme/tokens.js +904 -0
- package/dist/theme/tokens.js.map +1 -0
- package/dist/theme/tokens.mjs +880 -0
- package/dist/theme/tokens.mjs.map +1 -0
- package/docs/audits/2026-09-08-critique-addenda.md +51 -0
- package/docs/audits/2026-09-08-library-critique.md +212 -0
- package/docs/library-roadmap.md +99 -0
- package/package.json +7 -1
- package/src/arch/arch-graph.freshness.test.ts +52 -0
- package/src/arch/arch-graph.json +5021 -1617
- package/src/components/custom/ActiveWork/CoChangeChip.stories.tsx +44 -0
- package/src/components/custom/ActiveWork/CoChangeChip.test.tsx +29 -0
- package/src/components/custom/ActiveWork/CoChangeChip.tsx +48 -0
- package/src/components/custom/ActiveWork/Eyebrow.stories.tsx +25 -0
- package/src/components/custom/ActiveWork/Eyebrow.test.tsx +16 -0
- package/src/components/custom/ActiveWork/Eyebrow.tsx +26 -0
- package/src/components/custom/ActiveWork/FileActivityDetail.stories.tsx +50 -0
- package/src/components/custom/ActiveWork/FileActivityDetail.test.tsx +66 -0
- package/src/components/custom/ActiveWork/FileActivityDetail.tsx +202 -0
- package/src/components/custom/ActiveWork/FileActivityRow.stories.tsx +70 -0
- package/src/components/custom/ActiveWork/FileActivityRow.test.tsx +67 -0
- package/src/components/custom/ActiveWork/FileActivityRow.tsx +130 -0
- package/src/components/custom/ActiveWork/FileHistoryExplorer.stories.tsx +84 -0
- package/src/components/custom/ActiveWork/FileHistoryExplorer.test.tsx +99 -0
- package/src/components/custom/ActiveWork/FileHistoryExplorer.tsx +138 -0
- package/src/components/custom/ActiveWork/FilePathLabel.stories.tsx +39 -0
- package/src/components/custom/ActiveWork/FilePathLabel.test.tsx +53 -0
- package/src/components/custom/ActiveWork/FilePathLabel.tsx +63 -0
- package/src/components/custom/ActiveWork/InitiativeBrief.stories.tsx +50 -0
- package/src/components/custom/ActiveWork/InitiativeBrief.test.tsx +62 -0
- package/src/components/custom/ActiveWork/InitiativeBrief.tsx +181 -0
- package/src/components/custom/ActiveWork/InitiativeCard.stories.tsx +73 -0
- package/src/components/custom/ActiveWork/InitiativeCard.test.tsx +68 -0
- package/src/components/custom/ActiveWork/InitiativeCard.tsx +136 -0
- package/src/components/custom/ActiveWork/InitiativeHeader.stories.tsx +59 -0
- package/src/components/custom/ActiveWork/InitiativeHeader.test.tsx +40 -0
- package/src/components/custom/ActiveWork/InitiativeHeader.tsx +73 -0
- package/src/components/custom/ActiveWork/InitiativeReader.stories.tsx +145 -0
- package/src/components/custom/ActiveWork/OpenLoops.stories.tsx +58 -0
- package/src/components/custom/ActiveWork/OpenLoops.test.tsx +61 -0
- package/src/components/custom/ActiveWork/OpenLoops.tsx +107 -0
- package/src/components/custom/ActiveWork/PortfolioOverview.stories.tsx +101 -0
- package/src/components/custom/ActiveWork/PortfolioOverview.test.tsx +81 -0
- package/src/components/custom/ActiveWork/PortfolioOverview.tsx +83 -0
- package/src/components/custom/ActiveWork/README.md +305 -0
- package/src/components/custom/ActiveWork/SessionDetail.stories.tsx +71 -0
- package/src/components/custom/ActiveWork/SessionDetail.test.tsx +84 -0
- package/src/components/custom/ActiveWork/SessionDetail.tsx +180 -0
- package/src/components/custom/ActiveWork/SessionList.stories.tsx +69 -0
- package/src/components/custom/ActiveWork/SessionList.test.tsx +78 -0
- package/src/components/custom/ActiveWork/SessionList.tsx +103 -0
- package/src/components/custom/ActiveWork/SessionListItem.stories.tsx +64 -0
- package/src/components/custom/ActiveWork/SessionListItem.test.tsx +62 -0
- package/src/components/custom/ActiveWork/SessionListItem.tsx +152 -0
- package/src/components/custom/ActiveWork/SessionReader.stories.tsx +113 -0
- package/src/components/custom/ActiveWork/SeverityLabel.stories.tsx +51 -0
- package/src/components/custom/ActiveWork/SeverityLabel.test.tsx +68 -0
- package/src/components/custom/ActiveWork/SeverityLabel.tsx +97 -0
- package/src/components/custom/ActiveWork/TaskRow.stories.tsx +63 -0
- package/src/components/custom/ActiveWork/TaskRow.test.tsx +112 -0
- package/src/components/custom/ActiveWork/TaskRow.tsx +176 -0
- package/src/components/custom/ActiveWork/TaskTable.stories.tsx +123 -0
- package/src/components/custom/ActiveWork/TaskTable.test.tsx +233 -0
- package/src/components/custom/ActiveWork/TaskTable.tsx +321 -0
- package/src/components/custom/ActiveWork/active-work-depth.test.tsx +102 -0
- package/src/components/custom/ActiveWork/file-history-fixture.ts +91 -0
- package/src/components/custom/ActiveWork/format-time.test.ts +23 -0
- package/src/components/custom/ActiveWork/format-time.ts +32 -0
- package/src/components/custom/ActiveWork/index.ts +19 -0
- package/src/components/custom/ActiveWork/initiative-fixture.ts +104 -0
- package/src/components/custom/ActiveWork/session-fixture.ts +267 -0
- package/src/components/custom/ActiveWork/session-linkers.ts +56 -0
- package/src/components/custom/ActiveWork/task-list-fixture.ts +97 -0
- package/src/components/custom/CircularTimer/CircularTimer.stories.tsx +4 -3
- package/src/components/custom/DateTime/DateTime.stories.tsx +2 -1
- package/src/components/custom/DateTime/DateTime.test.tsx +3 -1
- package/src/components/custom/EmptyState/EmptyState.stories.tsx +22 -9
- package/src/components/custom/EmptyState/EmptyState.test.tsx +7 -13
- package/src/components/custom/EmptyState/EmptyState.tsx +4 -18
- package/src/components/custom/Fatigue/DualGhostSpark.stories.tsx +4 -3
- package/src/components/custom/Fatigue/FatigueLights.stories.tsx +2 -2
- package/src/components/custom/Fatigue/GhostSpark.stories.tsx +4 -3
- package/src/components/custom/Fatigue/LiveFatigueCard.stories.tsx +2 -2
- package/src/components/custom/Fatigue/LiveFatigueCard.tsx +8 -4
- package/src/components/custom/Fatigue/LiveFatiguePanel.stories.tsx +116 -6
- package/src/components/custom/Fatigue/LiveFatiguePanel.test.tsx +134 -0
- package/src/components/custom/Fatigue/LiveFatiguePanel.tsx +54 -83
- package/src/components/custom/Fatigue/README.md +40 -3
- package/src/components/custom/Fatigue/RomProgressionChart.stories.tsx +2 -2
- package/src/components/custom/Fatigue/SilverRedPalette.stories.tsx +2 -1
- package/src/components/custom/Fatigue/VelocityHero.stories.tsx +4 -3
- package/src/components/custom/Fatigue/VerdictHero.stories.tsx +2 -2
- package/src/components/custom/Fatigue/fatigue-mock.test.ts +0 -5
- package/src/components/custom/Fatigue/fatigue-mock.ts +2 -10
- package/src/components/custom/Fatigue/fatigue-tokens.ts +12 -0
- package/src/components/custom/Fatigue/index.ts +17 -5
- package/src/components/custom/Fatigue/panel-layout.test.ts +149 -0
- package/src/components/custom/Fatigue/panel-layout.ts +185 -0
- package/src/components/custom/Gauge/Gauge.stories.tsx +2 -2
- package/src/components/custom/Gauge/Gauge.test.tsx +1 -1
- package/src/components/custom/Gauge/Gauge.tsx +4 -1
- package/src/components/custom/Metric/Metric.stories.tsx +10 -1
- package/src/components/custom/Metric/Metric.test.tsx +1 -3
- package/src/components/custom/Metric/Metric.tsx +5 -20
- package/src/components/custom/Prose/MarkdownProse.stories.tsx +88 -0
- package/src/components/custom/Prose/MarkdownProse.test.tsx +87 -0
- package/src/components/custom/Prose/MarkdownProse.tsx +201 -0
- package/src/components/custom/Prose/README.md +58 -0
- package/src/components/custom/Prose/index.ts +1 -0
- package/src/components/custom/Scatter/Scatter.stories.tsx +46 -8
- package/src/components/custom/Scatter/Scatter.test.tsx +2 -2
- package/src/components/custom/Scatter/Scatter.tsx +116 -14
- package/src/components/custom/Sidebar/Sidebar.stories.tsx +40 -7
- package/src/components/custom/Sidebar/Sidebar.test.tsx +5 -1
- package/src/components/custom/Sidebar/Sidebar.tsx +16 -33
- package/src/components/custom/Table/Table.stories.tsx +98 -15
- package/src/components/custom/Table/Table.test.tsx +273 -86
- package/src/components/custom/Table/Table.tsx +159 -67
- package/src/components/custom/Table/column-fit.test.ts +75 -0
- package/src/components/custom/Table/column-fit.ts +116 -0
- package/src/components/custom/Table/index.ts +9 -0
- package/src/components/custom/TimerReadout/TimerReadout.stories.tsx +8 -6
- package/src/components/custom/Treemap/Treemap.stories.tsx +2 -2
- package/src/components/custom/Treemap/Treemap.test.tsx +1 -1
- package/src/components/custom/Treemap/Treemap.tsx +7 -2
- package/src/components/custom/Typography/Typography.stories.tsx +28 -1
- package/src/components/custom/Typography/Typography.test.tsx +34 -0
- package/src/components/custom/Typography/Typography.tsx +6 -0
- package/src/components/custom/Typography/index.ts +1 -8
- package/src/components/custom/Workout/ActiveWorkoutPage.stories.tsx +9 -1
- package/src/components/custom/Workout/BaseBadge.stories.tsx +19 -7
- package/src/components/custom/Workout/BaseBadge.test.tsx +31 -11
- package/src/components/custom/Workout/BaseBadge.tsx +3 -0
- package/src/components/custom/Workout/BodyMap.stories.tsx +4 -1
- package/src/components/custom/Workout/BodyMap.tsx +3 -1
- package/src/components/custom/Workout/BodyMapDetailPanel.stories.tsx +16 -4
- package/src/components/custom/Workout/BodyMapDetailPanel.test.tsx +11 -15
- package/src/components/custom/Workout/BodyMapDetailPanel.tsx +45 -9
- package/src/components/custom/Workout/CapacityBandChart.stories.tsx +10 -8
- package/src/components/custom/Workout/CapacityBandChart.test.tsx +24 -51
- package/src/components/custom/Workout/CapacityBandChart.tsx +139 -108
- package/src/components/custom/Workout/DeviationBar.stories.tsx +1 -1
- package/src/components/custom/Workout/DeviationBar.test.tsx +5 -2
- package/src/components/custom/Workout/DeviationBar.tsx +21 -16
- package/src/components/custom/Workout/DualVelocityStrip.stories.tsx +182 -0
- package/src/components/custom/Workout/DualVelocityStrip.test.tsx +3 -2
- package/src/components/custom/Workout/ExerciseCard.stories.tsx +8 -7
- package/src/components/custom/Workout/ExerciseCard.test.tsx +13 -3
- package/src/components/custom/Workout/ExerciseCard.tsx +42 -51
- package/src/components/custom/Workout/ExerciseCardHeading.stories.tsx +7 -7
- package/src/components/custom/Workout/ExerciseDetailPage.stories.tsx +9 -1
- package/src/components/custom/Workout/ExerciseHeading.stories.tsx +8 -8
- package/src/components/custom/Workout/ExerciseHeading.tsx +8 -5
- package/src/components/custom/Workout/ExerciseIndicator.stories.tsx +6 -4
- package/src/components/custom/Workout/ExerciseIndicator.test.tsx +27 -11
- package/src/components/custom/Workout/ExerciseIndicator.tsx +14 -15
- package/src/components/custom/Workout/FatigueMeter.stories.tsx +5 -5
- package/src/components/custom/Workout/InputBar.stories.tsx +4 -5
- package/src/components/custom/Workout/IntensityBar.stories.tsx +1 -1
- package/src/components/custom/Workout/IntensityBar.test.tsx +5 -1
- package/src/components/custom/Workout/IntensityBar.tsx +4 -2
- package/src/components/custom/Workout/LiveAuraFrame.stories.tsx +5 -4
- package/src/components/custom/Workout/MesoCard.stories.tsx +4 -1
- package/src/components/custom/Workout/MesoCard.test.tsx +7 -18
- package/src/components/custom/Workout/MesoCard.tsx +12 -9
- package/src/components/custom/Workout/MesoProgressBar.stories.tsx +1 -1
- package/src/components/custom/Workout/MesoProgressBar.test.tsx +18 -11
- package/src/components/custom/Workout/MesoProgressBar.tsx +15 -13
- package/src/components/custom/Workout/MesoStatusCard.stories.tsx +2 -1
- package/src/components/custom/Workout/MesoStatusCard.test.tsx +14 -44
- package/src/components/custom/Workout/MesoStatusCard.tsx +9 -23
- package/src/components/custom/Workout/MetricTiles.stories.tsx +3 -2
- package/src/components/custom/Workout/MuscleGroupChip.stories.tsx +2 -8
- package/src/components/custom/Workout/MuscleGroupChip.test.tsx +23 -31
- package/src/components/custom/Workout/MuscleGroupChip.tsx +28 -67
- package/src/components/custom/Workout/PlaceholderStrip.stories.tsx +1 -1
- package/src/components/custom/Workout/PlaceholderStrip.test.tsx +17 -10
- package/src/components/custom/Workout/PlaceholderStrip.tsx +9 -8
- package/src/components/custom/Workout/PrBadge.stories.tsx +2 -1
- package/src/components/custom/Workout/PrBadge.test.tsx +3 -9
- package/src/components/custom/Workout/PrBadge.tsx +13 -17
- package/src/components/custom/Workout/PrHistoryModal.stories.tsx +4 -1
- package/src/components/custom/Workout/PrHistoryModal.test.tsx +13 -36
- package/src/components/custom/Workout/PrHistoryModal.tsx +8 -4
- package/src/components/custom/Workout/ProgramPlanningPage.stories.tsx +6 -1
- package/src/components/custom/Workout/README.md +12 -7
- package/src/components/custom/Workout/ReadinessCheck.stories.tsx +3 -2
- package/src/components/custom/Workout/ReadinessCheck.test.tsx +12 -18
- package/src/components/custom/Workout/ReadinessCheck.tsx +19 -3
- package/src/components/custom/Workout/RestTimer.stories.tsx +3 -2
- package/src/components/custom/Workout/ScheduleTiles.stories.tsx +3 -2
- package/src/components/custom/Workout/ScheduleTiles.test.tsx +3 -4
- package/src/components/custom/Workout/ScheduleTiles.tsx +4 -7
- package/src/components/custom/Workout/SegmentedBar.stories.tsx +5 -5
- package/src/components/custom/Workout/SegmentedBar.tsx +6 -2
- package/src/components/custom/Workout/SegmentedProgressBar.stories.tsx +5 -5
- package/src/components/custom/Workout/SessionHeader.stories.tsx +6 -6
- package/src/components/custom/Workout/SessionHeader.tsx +12 -12
- package/src/components/custom/Workout/SessionRail.stories.tsx +12 -11
- package/src/components/custom/Workout/SessionRail.tsx +7 -9
- package/src/components/custom/Workout/SetBar.stories.tsx +10 -6
- package/src/components/custom/Workout/SetBar.test.tsx +49 -4
- package/src/components/custom/Workout/SetBar.tsx +38 -12
- package/src/components/custom/Workout/SetRow.stories.tsx +3 -2
- package/src/components/custom/Workout/SetRow.test.tsx +16 -2
- package/src/components/custom/Workout/SetRow.tsx +61 -23
- package/src/components/custom/Workout/SetStrip.stories.tsx +60 -5
- package/src/components/custom/Workout/SetStrip.test.tsx +25 -0
- package/src/components/custom/Workout/SetStrip.tsx +24 -4
- package/src/components/custom/Workout/SetTableHeader.stories.tsx +6 -6
- package/src/components/custom/Workout/SetTableHeader.tsx +9 -12
- package/src/components/custom/Workout/SetsRepsLoad.stories.tsx +7 -7
- package/src/components/custom/Workout/SetsRepsLoad.tsx +3 -5
- package/src/components/custom/Workout/Sparkline.stories.tsx +1 -1
- package/src/components/custom/Workout/Sparkline.test.tsx +37 -19
- package/src/components/custom/Workout/Sparkline.tsx +14 -18
- package/src/components/custom/Workout/StatusDot.stories.tsx +1 -1
- package/src/components/custom/Workout/StatusDot.test.tsx +44 -5
- package/src/components/custom/Workout/StatusDot.tsx +93 -63
- package/src/components/custom/Workout/StatusPill.stories.tsx +1 -1
- package/src/components/custom/Workout/StatusPill.test.tsx +6 -15
- package/src/components/custom/Workout/StatusPill.tsx +27 -38
- package/src/components/custom/Workout/StrengthTrendChart.stories.tsx +9 -3
- package/src/components/custom/Workout/StrengthTrendChart.test.tsx +15 -37
- package/src/components/custom/Workout/StrengthTrendChart.tsx +31 -30
- package/src/components/custom/Workout/SupersetWrapper.stories.tsx +27 -64
- package/src/components/custom/Workout/SupersetWrapper.test.tsx +16 -14
- package/src/components/custom/Workout/SupersetWrapper.tsx +17 -21
- package/src/components/custom/Workout/TempoDisplay.stories.tsx +22 -7
- package/src/components/custom/Workout/TempoDisplay.test.tsx +18 -4
- package/src/components/custom/Workout/TrainingStatusPage.stories.tsx +9 -1
- package/src/components/custom/Workout/VelocityStrip.compact.stories.tsx +4 -1
- package/src/components/custom/Workout/VelocityStrip.dual.stories.tsx +7 -4
- package/src/components/custom/Workout/VelocityStrip.expanded.stories.tsx +4 -1
- package/src/components/custom/Workout/VelocityStrip.hero.stories.tsx +4 -1
- package/src/components/custom/Workout/VelocityStrip.stories.tsx +12 -6
- package/src/components/custom/Workout/VelocityStrip.tsx +3 -0
- package/src/components/custom/Workout/VolumeLandmarkBar.stories.tsx +6 -7
- package/src/components/custom/Workout/VolumeLandmarkBar.tsx +15 -6
- package/src/components/custom/Workout/WeekRow.stories.tsx +4 -1
- package/src/components/custom/Workout/WeekRow.test.tsx +18 -15
- package/src/components/custom/Workout/WeekRow.tsx +23 -16
- package/src/components/custom/Workout/WeightBadge.stories.tsx +2 -1
- package/src/components/custom/Workout/WeightBadge.test.tsx +50 -19
- package/src/components/custom/Workout/WeightBadge.tsx +28 -27
- package/src/components/custom/Workout/WorkoutCard.stories.tsx +6 -1
- package/src/components/custom/Workout/WorkoutCard.test.tsx +18 -0
- package/src/components/custom/Workout/WorkoutCard.tsx +35 -57
- package/src/components/custom/Workout/WorkoutPill.stories.tsx +5 -2
- package/src/components/custom/Workout/WorkoutPill.test.tsx +39 -7
- package/src/components/custom/Workout/WorkoutPill.tsx +88 -57
- package/src/components/custom/Workout/ZoneTrack.stories.tsx +7 -6
- package/src/components/custom/Workout/ZoneTrack.tsx +10 -9
- package/src/components/custom/Workout/index.ts +5 -0
- package/src/components/custom/Workout/metricText.stories.tsx +6 -5
- package/src/components/custom/Workout/metricText.tsx +4 -0
- package/src/components/custom/Workout/setHeadingKit.tsx +207 -26
- package/src/components/custom/charts/README.md +61 -0
- package/src/components/custom/charts/SetBarChart.test.tsx +30 -1
- package/src/components/custom/charts/SetBarChart.tsx +42 -4
- package/src/components/custom/charts/SparkBars.stories.tsx +55 -0
- package/src/components/custom/charts/SparkBars.test.tsx +69 -0
- package/src/components/custom/charts/SparkBars.tsx +85 -0
- package/src/components/custom/charts/index.ts +3 -0
- package/src/components/custom/index.ts +3 -0
- package/src/components/custom/stepper/Stepper.stories.tsx +13 -10
- package/src/components/custom/stepper/Stepper.test.tsx +1 -7
- package/src/components/custom/stepper/Stepper.tsx +13 -28
- package/src/components/icons/icons.stories.tsx +1 -1
- package/src/components/icons/icons.tsx +51 -0
- package/src/components/shell/AppShell.stories.tsx +150 -0
- package/src/components/shell/AppShell.test.tsx +70 -0
- package/src/components/shell/AppShell.tsx +90 -0
- package/src/components/shell/BrandLockup.stories.tsx +66 -5
- package/src/components/shell/BrandLockup.test.tsx +34 -1
- package/src/components/shell/BrandLockup.tsx +27 -11
- package/src/components/shell/NavItem.stories.tsx +4 -4
- package/src/components/shell/NavItem.test.tsx +17 -0
- package/src/components/shell/NavItem.tsx +17 -5
- package/src/components/shell/README.md +90 -27
- package/src/components/shell/SideNav.stories.tsx +38 -7
- package/src/components/shell/SideNav.test.tsx +16 -8
- package/src/components/shell/SideNav.tsx +17 -17
- package/src/components/shell/TopBar.stories.tsx +44 -19
- package/src/components/shell/TopBar.test.tsx +34 -12
- package/src/components/shell/TopBar.tsx +61 -40
- package/src/components/shell/brands.tsx +66 -0
- package/src/components/shell/index.ts +9 -8
- package/src/components/shell/{DeviceIndicator.stories.tsx → workout/DeviceIndicator.stories.tsx} +2 -2
- package/src/components/shell/{DeviceIndicator.tsx → workout/DeviceIndicator.tsx} +2 -2
- package/src/components/shell/{DeviceMenu.stories.tsx → workout/DeviceMenu.stories.tsx} +2 -2
- package/src/components/shell/{DeviceMenu.tsx → workout/DeviceMenu.tsx} +3 -3
- package/src/components/shell/{DeviceRow.stories.tsx → workout/DeviceRow.stories.tsx} +2 -2
- package/src/components/shell/{DeviceRow.tsx → workout/DeviceRow.tsx} +3 -3
- package/src/components/shell/{SessionStatePill.stories.tsx → workout/SessionStatePill.stories.tsx} +2 -2
- package/src/components/shell/{SessionStatePill.tsx → workout/SessionStatePill.tsx} +5 -3
- package/src/components/shell/workout/WorkoutShell.stories.tsx +71 -0
- package/src/components/shell/{DashboardShell.test.tsx → workout/WorkoutShell.test.tsx} +19 -8
- package/src/components/shell/workout/WorkoutShell.tsx +77 -0
- package/src/components/shell/workout/WorkoutTopBar.stories.tsx +58 -0
- package/src/components/shell/workout/WorkoutTopBar.test.tsx +39 -0
- package/src/components/shell/workout/WorkoutTopBar.tsx +52 -0
- package/src/components/shell/workout/index.ts +9 -0
- package/src/components/shell/workout/workoutNavItems.tsx +16 -0
- package/src/components/ui/README.md +110 -0
- package/src/components/ui/alert/Alert.stories.tsx +1 -1
- package/src/components/ui/autocomplete/Autocomplete.stories.tsx +11 -13
- package/src/components/ui/autocomplete/Autocomplete.test.tsx +7 -25
- package/src/components/ui/autocomplete/Autocomplete.tsx +21 -28
- package/src/components/ui/avatar/Avatar.stories.tsx +1 -1
- package/src/components/ui/avatar/Avatar.tsx +2 -10
- package/src/components/ui/badge/Badge.stories.tsx +83 -28
- package/src/components/ui/badge/Badge.test.tsx +19 -3
- package/src/components/ui/badge/Badge.tsx +48 -55
- package/src/components/ui/breadcrumbs/Breadcrumbs.stories.tsx +1 -1
- package/src/components/ui/breadcrumbs/Breadcrumbs.tsx +4 -16
- package/src/components/ui/button/Button.stories.tsx +46 -12
- package/src/components/ui/button/Button.tsx +32 -25
- package/src/components/ui/card/Card.stories.tsx +90 -94
- package/src/components/ui/card/Card.test.tsx +80 -6
- package/src/components/ui/card/Card.tsx +150 -203
- package/src/components/ui/checkbox/Checkbox.stories.tsx +1 -1
- package/src/components/ui/checkbox/Checkbox.tsx +6 -26
- package/src/components/ui/chip/Chip.stories.tsx +37 -13
- package/src/components/ui/chip/Chip.test.tsx +10 -6
- package/src/components/ui/chip/Chip.tsx +76 -91
- package/src/components/ui/collapse/Collapse.stories.tsx +23 -23
- package/src/components/ui/collapse/Collapse.tsx +6 -11
- package/src/components/ui/data-row/DataRow.stories.tsx +9 -2
- package/src/components/ui/data-row/DataRow.test.tsx +5 -15
- package/src/components/ui/data-row/DataRow.tsx +18 -7
- package/src/components/ui/divider/Divider.stories.tsx +1 -1
- package/src/components/ui/divider/Divider.tsx +1 -5
- package/src/components/ui/drawer/Drawer.stories.tsx +5 -16
- package/src/components/ui/drawer/Drawer.tsx +13 -30
- package/src/components/ui/floating-overlay-depth.test.tsx +143 -0
- package/src/components/ui/form-field/FormField.stories.tsx +6 -20
- package/src/components/ui/form-field/FormField.test.tsx +1 -5
- package/src/components/ui/form-field/FormField.tsx +10 -46
- package/src/components/ui/help-tip/HelpTip.stories.tsx +8 -19
- package/src/components/ui/help-tip/HelpTip.test.tsx +1 -3
- package/src/components/ui/help-tip/HelpTip.tsx +21 -22
- package/src/components/ui/help-tip/index.ts +7 -1
- package/src/components/ui/icon-box/IconBox.stories.tsx +1 -1
- package/src/components/ui/icon-box/IconBox.test.tsx +1 -7
- package/src/components/ui/icon-box/IconBox.tsx +2 -12
- package/src/components/ui/indicator/Indicator.stories.tsx +1 -1
- package/src/components/ui/indicator/Indicator.tsx +20 -14
- package/src/components/ui/input/Input.stories.tsx +3 -11
- package/src/components/ui/input/Input.test.tsx +2 -10
- package/src/components/ui/input/Input.tsx +10 -25
- package/src/components/ui/input/index.ts +7 -1
- package/src/components/ui/link/Link.stories.tsx +19 -7
- package/src/components/ui/list-item/ListItem.stories.tsx +11 -2
- package/src/components/ui/list-item/ListItem.tsx +2 -9
- package/src/components/ui/menu/Menu.stories.tsx +21 -15
- package/src/components/ui/menu/Menu.test.tsx +2 -11
- package/src/components/ui/menu/Menu.tsx +12 -14
- package/src/components/ui/menu/index.ts +8 -1
- package/src/components/ui/modal/Modal.stories.tsx +2 -2
- package/src/components/ui/modal/Modal.tsx +29 -19
- package/src/components/ui/pill/Pill.stories.tsx +58 -23
- package/src/components/ui/pill/Pill.test.tsx +101 -3
- package/src/components/ui/pill/Pill.tsx +164 -49
- package/src/components/ui/pill/index.ts +1 -1
- package/src/components/ui/popover/Popover.stories.tsx +5 -7
- package/src/components/ui/popover/Popover.test.tsx +1 -6
- package/src/components/ui/popover/Popover.tsx +20 -15
- package/src/components/ui/popover/index.ts +7 -1
- package/src/components/ui/progress/Progress.stories.tsx +3 -12
- package/src/components/ui/progress/Progress.test.tsx +1 -5
- package/src/components/ui/radio/Radio.stories.tsx +42 -21
- package/src/components/ui/radio/Radio.test.tsx +6 -2
- package/src/components/ui/radio/Radio.tsx +23 -22
- package/src/components/ui/section/Section.stories.tsx +5 -14
- package/src/components/ui/section/Section.test.tsx +1 -6
- package/src/components/ui/section/Section.tsx +1 -3
- package/src/components/ui/section/index.ts +1 -5
- package/src/components/ui/select/Select.stories.tsx +3 -13
- package/src/components/ui/select/Select.test.tsx +2 -11
- package/src/components/ui/select/Select.tsx +14 -14
- package/src/components/ui/skeleton/Skeleton.stories.tsx +3 -11
- package/src/components/ui/skeleton/Skeleton.tsx +3 -14
- package/src/components/ui/skeleton/index.ts +1 -7
- package/src/components/ui/spinner/Spinner.stories.tsx +1 -1
- package/src/components/ui/spinner/Spinner.tsx +1 -4
- package/src/components/ui/stack/Stack.stories.tsx +1 -1
- package/src/components/ui/stack/Stack.tsx +1 -1
- package/src/components/ui/surface/Surface.stories.tsx +17 -5
- package/src/components/ui/surface/Surface.test.tsx +88 -28
- package/src/components/ui/surface/Surface.tsx +37 -87
- package/src/components/ui/surface/SurfaceContext.ts +22 -62
- package/src/components/ui/surface/index.ts +8 -0
- package/src/components/ui/surface/resolveSurface.ts +98 -0
- package/src/components/ui/surface/surface.contract.test.ts +6 -1
- package/src/components/ui/switch/Switch.stories.tsx +1 -1
- package/src/components/ui/switch/Switch.tsx +7 -6
- package/src/components/ui/tabs/Tabs.stories.tsx +1 -1
- package/src/components/ui/tabs/Tabs.tsx +7 -22
- package/src/components/ui/tabs/index.ts +1 -7
- package/src/components/ui/tile/Tile.stories.tsx +1 -1
- package/src/components/ui/tile/Tile.tsx +3 -0
- package/src/components/ui/toast/Toast.stories.tsx +1 -1
- package/src/components/ui/toast/Toast.test.tsx +2 -8
- package/src/components/ui/toast/Toast.tsx +43 -53
- package/src/components/ui/toast/index.ts +0 -1
- package/src/components/ui/toolbar-button/ToolbarButton.stories.tsx +92 -71
- package/src/components/ui/toolbar-button/ToolbarButton.test.tsx +3 -18
- package/src/components/ui/toolbar-button/ToolbarButton.tsx +25 -43
- package/src/components/ui/tooltip/Tooltip.stories.tsx +12 -3
- package/src/components/ui/tooltip/Tooltip.test.tsx +21 -3
- package/src/components/ui/tooltip/Tooltip.tsx +55 -36
- package/src/components/ui/tooltip/index.ts +1 -1
- package/src/components/ui/trigger/TriggerSurface.test.tsx +215 -0
- package/src/components/ui/trigger/TriggerSurface.tsx +81 -0
- package/src/components/ui/trigger/index.ts +2 -0
- package/src/stories/PresetShowcase.stories.tsx +100 -47
- package/src/test/no-device-internals.test.ts +3 -3
- package/src/theme/ChoosingTokens.stories.tsx +48 -0
- package/src/theme/ColorPalettes.stories.tsx +62 -45
- package/src/theme/ColorPrimitives.stories.tsx +35 -35
- package/src/theme/Depth.stories.tsx +132 -65
- package/src/theme/DepthCalibration.stories.tsx +24 -22
- package/src/theme/ThemeProvider.test.tsx +4 -4
- package/src/theme/barrel.ts +7 -6
- package/src/theme/color-stories.coverage.test.ts +1 -1
- package/src/theme/color-utils.ts +41 -29
- package/src/theme/config.completeness.test.ts +1 -1
- package/src/theme/config.ts +28 -0
- package/src/theme/elevation.test.ts +82 -56
- package/src/theme/elevation.ts +77 -561
- package/src/theme/global.css +30 -2
- package/src/theme/grey-ramp.test.ts +24 -8
- package/src/theme/lift.test.ts +39 -0
- package/src/theme/lift.ts +102 -0
- package/src/theme/materials.test.ts +5 -2
- package/src/theme/materials.ts +38 -4
- package/src/theme/native-theming-guard.test.ts +5 -5
- package/src/theme/presets/apply.ts +4 -0
- package/src/theme/presets/audiobook.ts +5 -2
- package/src/theme/presets/default.ts +4 -0
- package/src/theme/presets/index.ts +14 -1
- package/src/theme/presets/types.ts +1 -1
- package/src/theme/semantic-contrast.test.ts +13 -4
- package/src/theme/status-distinctness.test.ts +66 -0
- package/src/theme/surface-planes.test.ts +37 -0
- package/src/theme/surface-planes.ts +68 -0
- package/src/theme/token-export-guard.test.ts +102 -0
- package/src/theme/tokens/primitives.test.ts +15 -7
- package/src/theme/tokens/primitives.ts +67 -35
- package/src/theme/tokens/semantic.ts +71 -37
- package/src/theme/wash-ladder.test.ts +58 -0
- package/src/theme/workout-tokens.ts +1 -7
- package/src/types/jest-axe.d.ts +2 -6
- package/src/types/raw-md.d.ts +5 -0
- package/src/utils/colors.ts +4 -4
- package/src/utils/form.ts +1 -3
- package/src/utils/index.ts +2 -7
- package/src/utils/number-format.ts +17 -0
- package/src/utils/workout-format.ts +15 -6
- package/src/web-jsx/jsx-runtime.ts +1 -5
- package/tailwind.config.js +5 -0
- package/src/components/custom/Workout/ExerciseCardUnified.stories.tsx +0 -151
- package/src/components/custom/Workout/RowInventory.stories.tsx +0 -408
- package/src/components/custom/Workout/S3FullRail.stories.tsx +0 -46
- package/src/components/custom/Workout/S3SessionPace.stories.tsx +0 -95
- package/src/components/custom/Workout/S3SessionRailHeading.stories.tsx +0 -61
- package/src/components/custom/Workout/S3SetTypes.stories.tsx +0 -176
- package/src/components/custom/Workout/S3WorkoutExpansion.stories.tsx +0 -240
- package/src/components/shell/DashboardShell.stories.tsx +0 -65
- package/src/components/shell/DashboardShell.tsx +0 -75
- package/src/components/shell/SessionRailSpecimen.stories.tsx +0 -753
- package/src/theme/elevation.stories.tsx +0 -346
- package/src/utils/useTheme.ts +0 -72
- /package/src/components/shell/{DeviceIndicator.test.tsx → workout/DeviceIndicator.test.tsx} +0 -0
- /package/src/components/shell/{DeviceMenu.test.tsx → workout/DeviceMenu.test.tsx} +0 -0
- /package/src/components/shell/{DeviceRow.test.tsx → workout/DeviceRow.test.tsx} +0 -0
- /package/src/components/shell/{SessionStatePill.test.tsx → workout/SessionStatePill.test.tsx} +0 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { semanticColorsDark, semanticColorsLight } from './tokens/semantic'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Status and brand roles publish three wash rungs. They exist so a component can
|
|
6
|
+
* express a weight ramp without hand-mixing alpha: MesoProgressBar's segment
|
|
7
|
+
* track collapsed to one weight in three hues when only `-subtle` was available.
|
|
8
|
+
*
|
|
9
|
+
* A rung that drifts out of order silently flattens every consumer, and the
|
|
10
|
+
* consumer's own test cannot catch it — under the RNW vitest alias the rendered
|
|
11
|
+
* value is a `var(...)` reference, not an rgba triplet.
|
|
12
|
+
*/
|
|
13
|
+
const WASH_ROLES = [
|
|
14
|
+
'brand-primary',
|
|
15
|
+
'brand-secondary',
|
|
16
|
+
'status-success',
|
|
17
|
+
'status-error',
|
|
18
|
+
'status-error-vivid',
|
|
19
|
+
'status-warning',
|
|
20
|
+
'status-info',
|
|
21
|
+
] as const
|
|
22
|
+
|
|
23
|
+
const RUNGS = ['subtle', 'muted', 'strong'] as const
|
|
24
|
+
|
|
25
|
+
function alphaOf(value: string): number {
|
|
26
|
+
const parts = value.match(/rgba?\(([^)]+)\)/)?.[1].split(',')
|
|
27
|
+
if (!parts) return 1 // a solid ramp pin is fully opaque
|
|
28
|
+
return parts.length === 4 ? Number(parts[3].trim()) : 1
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
describe('wash ladder', () => {
|
|
32
|
+
for (const [mode, palette] of [
|
|
33
|
+
['dark', semanticColorsDark],
|
|
34
|
+
['light', semanticColorsLight],
|
|
35
|
+
] as const) {
|
|
36
|
+
describe(mode, () => {
|
|
37
|
+
for (const role of WASH_ROLES) {
|
|
38
|
+
it(`${role} publishes all three rungs`, () => {
|
|
39
|
+
for (const rung of RUNGS) {
|
|
40
|
+
expect(palette, `${role}-${rung} is missing`).toHaveProperty(`${role}-${rung}`)
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Light mode's `-subtle` is still a solid ramp tint rather than a wash, so its
|
|
48
|
+
// ladder is not comparable yet. AW-121 owns bringing light onto this model.
|
|
49
|
+
for (const role of WASH_ROLES) {
|
|
50
|
+
it(`${role} rungs ascend in weight (dark)`, () => {
|
|
51
|
+
const [subtle, muted, strong] = RUNGS.map((r) =>
|
|
52
|
+
alphaOf(semanticColorsDark[`${role}-${r}` as keyof typeof semanticColorsDark] as string)
|
|
53
|
+
)
|
|
54
|
+
expect(muted, `${role}-muted must outweigh -subtle`).toBeGreaterThan(subtle)
|
|
55
|
+
expect(strong, `${role}-strong must outweigh -muted`).toBeGreaterThan(muted)
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
})
|
|
@@ -48,13 +48,7 @@ export const WORKOUT_TOKENS = {
|
|
|
48
48
|
over2: ramp.red[700],
|
|
49
49
|
over3: ramp.red[800],
|
|
50
50
|
targetLine: 'rgba(33, 150, 243, 0.5)',
|
|
51
|
-
atTargetGlow:
|
|
52
|
-
'0 0 5px 1px rgba(33, 150, 243, 0.35), 0 0 10px 3px rgba(33, 150, 243, 0.15)',
|
|
53
|
-
},
|
|
54
|
-
|
|
55
|
-
// Placeholder strip
|
|
56
|
-
placeholder: {
|
|
57
|
-
fill: '#3A3A3A',
|
|
51
|
+
atTargetGlow: '0 0 5px 1px rgba(33, 150, 243, 0.35), 0 0 10px 3px rgba(33, 150, 243, 0.15)',
|
|
58
52
|
},
|
|
59
53
|
|
|
60
54
|
// Deviation bar
|
package/src/types/jest-axe.d.ts
CHANGED
|
@@ -5,12 +5,8 @@ declare module 'jest-axe' {
|
|
|
5
5
|
): Promise<{ violations: unknown[] }>
|
|
6
6
|
|
|
7
7
|
export const toHaveNoViolations: {
|
|
8
|
-
toHaveNoViolations(
|
|
9
|
-
results: { violations: unknown[] }
|
|
10
|
-
): { pass: boolean; message(): string }
|
|
8
|
+
toHaveNoViolations(results: { violations: unknown[] }): { pass: boolean; message(): string }
|
|
11
9
|
}
|
|
12
10
|
|
|
13
|
-
export function configureAxe(
|
|
14
|
-
options?: Record<string, unknown>
|
|
15
|
-
): typeof axe
|
|
11
|
+
export function configureAxe(options?: Record<string, unknown>): typeof axe
|
|
16
12
|
}
|
package/src/utils/colors.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Color utility functions for the design system
|
|
2
|
+
* Color utility functions for the design system.
|
|
3
3
|
*
|
|
4
|
-
* lighten
|
|
5
|
-
*
|
|
4
|
+
* `lighten`/`darken` are re-exported from `theme/color-utils`, which does the
|
|
5
|
+
* HSV math. They are hover/state adjustments, not a depth ladder — planes come
|
|
6
|
+
* from the grey ramp.
|
|
6
7
|
*/
|
|
7
8
|
|
|
8
9
|
export { lighten, darken } from '../theme/color-utils'
|
|
@@ -137,4 +138,3 @@ export function getLuminance(color: string): 'light' | 'dark' {
|
|
|
137
138
|
export function getContrastText(backgroundColor: string): string {
|
|
138
139
|
return getLuminance(backgroundColor) === 'light' ? '#000000' : '#FFFFFF'
|
|
139
140
|
}
|
|
140
|
-
|
package/src/utils/form.ts
CHANGED
|
@@ -160,9 +160,7 @@ export const validationRules = {
|
|
|
160
160
|
/**
|
|
161
161
|
* Compose multiple validation functions
|
|
162
162
|
*/
|
|
163
|
-
export function composeValidators(
|
|
164
|
-
...validators: Array<(value: any) => string | undefined>
|
|
165
|
-
) {
|
|
163
|
+
export function composeValidators(...validators: Array<(value: any) => string | undefined>) {
|
|
166
164
|
return (value: any): string | undefined => {
|
|
167
165
|
for (const validator of validators) {
|
|
168
166
|
const error = validator(value)
|
package/src/utils/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { cn } from './cn'
|
|
2
|
+
export { formatCompact, formatSignedCompact } from './number-format'
|
|
2
3
|
export {
|
|
3
4
|
getStatusColor,
|
|
4
5
|
getResultColor,
|
|
@@ -20,13 +21,7 @@ export {
|
|
|
20
21
|
validationRules,
|
|
21
22
|
composeValidators,
|
|
22
23
|
} from './form'
|
|
23
|
-
export type {
|
|
24
|
-
FieldState,
|
|
25
|
-
FieldWrapperProps,
|
|
26
|
-
FormValues,
|
|
27
|
-
FormErrors,
|
|
28
|
-
FormTouched,
|
|
29
|
-
} from './form'
|
|
24
|
+
export type { FieldState, FieldWrapperProps, FormValues, FormErrors, FormTouched } from './form'
|
|
30
25
|
export {
|
|
31
26
|
roundRpe,
|
|
32
27
|
rpeColor,
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compact integer formatting for dense readouts (stat tiles, sparkline
|
|
3
|
+
* captions) where a full-precision number would blow the column width.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/** 1234 → "1.2k", 1048576 → "1.0M", 42 → "42". Sign is preserved. */
|
|
7
|
+
export function formatCompact(n: number): string {
|
|
8
|
+
const abs = Math.abs(n)
|
|
9
|
+
if (abs >= 1_000_000) return (n / 1_000_000).toFixed(1) + 'M'
|
|
10
|
+
if (abs >= 1_000) return (n / 1_000).toFixed(1) + 'k'
|
|
11
|
+
return String(n)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** Like {@link formatCompact} but always signed: 514689 → "+514.7k", -20 → "-20". */
|
|
15
|
+
export function formatSignedCompact(n: number): string {
|
|
16
|
+
return (n >= 0 ? '+' : '') + formatCompact(n)
|
|
17
|
+
}
|
|
@@ -52,6 +52,20 @@ export function formatSignedPct(ratio: number): string {
|
|
|
52
52
|
return `${pct > 0 ? '+' : ''}${pct}%`
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Rep-range label, e.g. `"8–10"`. `"8"` when the bounds are equal or only one is
|
|
57
|
+
* given; `null` when neither is set. Shared by {@link formatPrescription} and the
|
|
58
|
+
* set strip's per-set prescribed-range label so the two never drift apart.
|
|
59
|
+
*/
|
|
60
|
+
export function formatRepsRange(repsLow?: number, repsHigh?: number): string | null {
|
|
61
|
+
if (repsLow != null && repsHigh != null) {
|
|
62
|
+
return repsLow === repsHigh ? `${repsLow}` : `${repsLow}–${repsHigh}`
|
|
63
|
+
}
|
|
64
|
+
if (repsLow != null) return `${repsLow}`
|
|
65
|
+
if (repsHigh != null) return `${repsHigh}`
|
|
66
|
+
return null
|
|
67
|
+
}
|
|
68
|
+
|
|
55
69
|
/** Structured prescription for the active exercise (from the plan). */
|
|
56
70
|
export interface PrescriptionInput {
|
|
57
71
|
repsLow?: number
|
|
@@ -67,12 +81,7 @@ export interface PrescriptionInput {
|
|
|
67
81
|
*/
|
|
68
82
|
export function formatPrescription(p: PrescriptionInput | null | undefined): string | null {
|
|
69
83
|
if (p == null) return null
|
|
70
|
-
|
|
71
|
-
if (p.repsLow != null && p.repsHigh != null) {
|
|
72
|
-
reps = p.repsLow === p.repsHigh ? `${p.repsLow}` : `${p.repsLow}–${p.repsHigh}`
|
|
73
|
-
} else if (p.repsLow != null) {
|
|
74
|
-
reps = `${p.repsLow}`
|
|
75
|
-
}
|
|
84
|
+
const reps = formatRepsRange(p.repsLow, p.repsHigh)
|
|
76
85
|
const weight = p.weightLbs != null ? `${p.weightLbs} lb` : null
|
|
77
86
|
const head = [reps, weight].filter((s): s is string => s != null).join(' @ ')
|
|
78
87
|
const rpe = p.rpe != null ? `RPE ${p.rpe}` : null
|
|
@@ -10,11 +10,7 @@
|
|
|
10
10
|
* native Metro). It is only inlined into the dist by tsup via
|
|
11
11
|
* an esbuild onResolve plugin.
|
|
12
12
|
*/
|
|
13
|
-
import {
|
|
14
|
-
jsx as reactJsx,
|
|
15
|
-
jsxs as reactJsxs,
|
|
16
|
-
Fragment,
|
|
17
|
-
} from 'react/jsx-runtime'
|
|
13
|
+
import { jsx as reactJsx, jsxs as reactJsxs, Fragment } from 'react/jsx-runtime'
|
|
18
14
|
import type { StyleProp } from 'react-native'
|
|
19
15
|
|
|
20
16
|
type JsxFn = typeof reactJsx
|
package/tailwind.config.js
CHANGED
|
@@ -183,6 +183,11 @@ module.exports = {
|
|
|
183
183
|
mono: ['var(--font-family-mono)', 'monospace'],
|
|
184
184
|
},
|
|
185
185
|
fontSize: {
|
|
186
|
+
// Micro steps. `2xs` carries a paired line-height like the rest of the
|
|
187
|
+
// scale (Typography's microLabel needs it); `3xs` is bare because a pill
|
|
188
|
+
// capsule takes its height from padding, not from the label's leading.
|
|
189
|
+
'3xs': '0.5625rem',
|
|
190
|
+
'2xs': ['0.625rem', { lineHeight: '0.875rem' }],
|
|
186
191
|
xs: ['0.75rem', { lineHeight: '1rem' }],
|
|
187
192
|
sm: ['0.875rem', { lineHeight: '1.25rem' }],
|
|
188
193
|
base: ['1rem', { lineHeight: '1.5rem' }],
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SHEET · Unified exercise card (page 2) — the LOCKED rail-expansion, hardened onto the
|
|
3
|
-
* REAL {@link ExerciseCard}. The collapsed rail item and the expanded card are ONE object: the
|
|
4
|
-
* persistent header is the real {@link ExerciseCardHeading}, and expanding reveals the body on the
|
|
5
|
-
* SAME surface — PREV dropped, done + upcoming sets share ONE muted treatment, the ACTIVE set
|
|
6
|
-
* stands out by brightness. Every per-row strip is the REAL {@link VelocityStrip} via its `set`
|
|
7
|
-
* descriptor: `mini` (flat 3px) for done/upcoming, and the `compact` velocity-height variant as
|
|
8
|
-
* the active-set SPOTLIGHT (option B, locked). No hand-built prototype strip remains.
|
|
9
|
-
*/
|
|
10
|
-
import type { Meta, StoryObj } from '@storybook/react-vite'
|
|
11
|
-
import { View, Text } from 'react-native'
|
|
12
|
-
import { ExerciseCard } from './ExerciseCard'
|
|
13
|
-
import { ExerciseCardHeading } from './ExerciseCardHeading'
|
|
14
|
-
import { VelocityStrip } from './VelocityStrip'
|
|
15
|
-
import { type SetRowProps } from './SetRow'
|
|
16
|
-
import { type SetStripSet } from './SetStrip'
|
|
17
|
-
import { INSET, BORDER_SUBTLE, T_PRIMARY, T_SECONDARY, Page, monoTag } from './setHeadingKit'
|
|
18
|
-
|
|
19
|
-
const INTER = 'Inter, sans-serif'
|
|
20
|
-
|
|
21
|
-
/** Per-rep mean velocity that DECAYS across a set (fast → slow). */
|
|
22
|
-
const decay = (n: number, start: number, span = 0.5) =>
|
|
23
|
-
Array.from({ length: n }, (_, r) => +(start - (span * r) / Math.max(1, n - 1)).toFixed(3))
|
|
24
|
-
|
|
25
|
-
// The exercise: a flat straight set (Cable Chest Press, 3 × 10 @ 90 lb).
|
|
26
|
-
const DONE = decay(10, 1.05)
|
|
27
|
-
const ACTIVE = decay(5, 0.95, 0.3)
|
|
28
|
-
|
|
29
|
-
// One data source drives both representations. Set 1 done · set 2 LIVE · set 3 upcoming.
|
|
30
|
-
const SETS: SetRowProps[] = [
|
|
31
|
-
{ state: 'done', setNumber: 1, unit: 'lbs', reps: 10, weight: 90, rpe: 7.5, velocities: DONE },
|
|
32
|
-
{
|
|
33
|
-
state: 'live',
|
|
34
|
-
setNumber: 2,
|
|
35
|
-
unit: 'lbs',
|
|
36
|
-
target: { reps: 10, weight: 90 },
|
|
37
|
-
reps: 5,
|
|
38
|
-
weight: 90,
|
|
39
|
-
velocities: ACTIVE,
|
|
40
|
-
},
|
|
41
|
-
{ state: 'todo', setNumber: 3, unit: 'lbs', target: { reps: 10, weight: 90 } },
|
|
42
|
-
]
|
|
43
|
-
|
|
44
|
-
// The header's per-set strip: the same lifecycle the card derives internally, built here
|
|
45
|
-
// so the collapsed rail item (ExerciseCardHeading) reads from the same source as the body.
|
|
46
|
-
const HEADER_STATES: SetStripSet[] = [
|
|
47
|
-
{ status: 'done', velocities: DONE },
|
|
48
|
-
{ status: 'active', velocities: ACTIVE, planned: 10 },
|
|
49
|
-
{ status: 'todo', planned: 10 },
|
|
50
|
-
]
|
|
51
|
-
|
|
52
|
-
const CARD_PROPS = {
|
|
53
|
-
name: 'Cable Chest Press',
|
|
54
|
-
summary: { sets: 3, reps: 10, weight: 90, unit: 'lbs' as const },
|
|
55
|
-
tempo: [2, 1, 2, 0] as [number, number, number, number],
|
|
56
|
-
indicator: 'info' as const,
|
|
57
|
-
sets: SETS,
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function Surface({ children, width = 260 }: { children: React.ReactNode; width?: number }) {
|
|
61
|
-
return (
|
|
62
|
-
<View style={{ width, backgroundColor: INSET, borderRadius: 8, overflow: 'hidden' }}>
|
|
63
|
-
{children}
|
|
64
|
-
</View>
|
|
65
|
-
)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const meta: Meta = {
|
|
69
|
-
title: 'Lab/Explorations/Unified Exercise Card',
|
|
70
|
-
parameters: { layout: 'fullscreen' },
|
|
71
|
-
}
|
|
72
|
-
export default meta
|
|
73
|
-
type Story = StoryObj
|
|
74
|
-
|
|
75
|
-
export const Unified: Story = {
|
|
76
|
-
name: 'One object · rail header → expanded body (real ExerciseCard)',
|
|
77
|
-
render: () => (
|
|
78
|
-
<Page
|
|
79
|
-
title="Unified exercise card — the rail heading IS the header"
|
|
80
|
-
note="The LOCKED rail-expansion, hardened onto the real ExerciseCard. Collapsed, it's the rail item (the real ExerciseCardHeading); expanded, the SAME surface reveals the table body — PREV dropped, done + upcoming sets share ONE muted treatment, the ACTIVE set stands out by brightness. Every per-row strip is the real VelocityStrip: `mini` for done/upcoming, the `compact` velocity-height variant as the active-set spotlight (B, locked). No hand-built prototype strip remains."
|
|
81
|
-
>
|
|
82
|
-
<View style={{ flexDirection: 'row', gap: 40, alignItems: 'flex-start', flexWrap: 'wrap' }}>
|
|
83
|
-
<View style={{ gap: 8 }}>
|
|
84
|
-
<Text style={{ ...monoTag, color: T_SECONDARY }}>
|
|
85
|
-
collapsed · rail item (ExerciseCardHeading)
|
|
86
|
-
</Text>
|
|
87
|
-
<Surface>
|
|
88
|
-
<ExerciseCardHeading
|
|
89
|
-
name={CARD_PROPS.name}
|
|
90
|
-
sets={3}
|
|
91
|
-
reps={10}
|
|
92
|
-
load={90}
|
|
93
|
-
unit="lbs"
|
|
94
|
-
tempo={CARD_PROPS.tempo}
|
|
95
|
-
indicator={CARD_PROPS.indicator}
|
|
96
|
-
setStates={HEADER_STATES}
|
|
97
|
-
/>
|
|
98
|
-
</Surface>
|
|
99
|
-
</View>
|
|
100
|
-
|
|
101
|
-
<View style={{ gap: 8 }}>
|
|
102
|
-
<Text style={{ ...monoTag, color: T_SECONDARY }}>
|
|
103
|
-
expanded · same header + revealed body
|
|
104
|
-
</Text>
|
|
105
|
-
<Surface>
|
|
106
|
-
<ExerciseCard {...CARD_PROPS} defaultExpanded />
|
|
107
|
-
</Surface>
|
|
108
|
-
</View>
|
|
109
|
-
</View>
|
|
110
|
-
|
|
111
|
-
<View style={{ height: 1, backgroundColor: BORDER_SUBTLE, marginVertical: 8 }} />
|
|
112
|
-
|
|
113
|
-
<View style={{ gap: 10, maxWidth: 320 }}>
|
|
114
|
-
<Text style={{ ...monoTag, color: T_SECONDARY }}>
|
|
115
|
-
the locked active-set spotlight · VelocityStrip variant="expanded" (bare)
|
|
116
|
-
</Text>
|
|
117
|
-
<View style={{ backgroundColor: INSET, borderRadius: 8, padding: 12 }}>
|
|
118
|
-
<VelocityStrip
|
|
119
|
-
variant="expanded"
|
|
120
|
-
showNumbers={false}
|
|
121
|
-
showInfo={false}
|
|
122
|
-
height={24}
|
|
123
|
-
scale="fixed"
|
|
124
|
-
set={{ type: 'straight', velocities: ACTIVE, planned: 10 }}
|
|
125
|
-
/>
|
|
126
|
-
</View>
|
|
127
|
-
<Text style={{ fontFamily: INTER, fontSize: 12.5, color: T_SECONDARY, lineHeight: 19 }}>
|
|
128
|
-
A small fixed-height (~24px) velocity-HEIGHT strip: bar height ∝ velocity against a fixed
|
|
129
|
-
1.15 m/s ceiling, planned reps as grey stubs, set-type aware — none of the full
|
|
130
|
-
variant's labels, info row, or mount animation. It reads as the same object as the
|
|
131
|
-
flat `mini` strips above it, just taller and brighter to mark the live set.
|
|
132
|
-
</Text>
|
|
133
|
-
</View>
|
|
134
|
-
|
|
135
|
-
<Text
|
|
136
|
-
style={{
|
|
137
|
-
fontFamily: INTER,
|
|
138
|
-
fontSize: 12.5,
|
|
139
|
-
color: T_PRIMARY,
|
|
140
|
-
lineHeight: 19,
|
|
141
|
-
maxWidth: 780,
|
|
142
|
-
marginTop: 6,
|
|
143
|
-
}}
|
|
144
|
-
>
|
|
145
|
-
The header is the same molecule collapsed and expanded — the card reads as one object, the
|
|
146
|
-
body flowing out of the rail row rather than a separate panel. The expanded card is the real
|
|
147
|
-
ExerciseCard; its header per-set strip is derived from the same rows the body renders.
|
|
148
|
-
</Text>
|
|
149
|
-
</Page>
|
|
150
|
-
),
|
|
151
|
-
}
|