@titan-design/react-ui 0.12.1 → 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 +1319 -216
- package/dist/index.d.ts +1319 -216
- 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 +195 -134
- package/dist/theme/index.d.ts +195 -134
- 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 +73 -5
- package/dist/theme/tokens.d.ts +73 -5
- package/dist/theme/tokens.js +55 -7
- package/dist/theme/tokens.js.map +1 -1
- package/dist/theme/tokens.mjs +55 -8
- package/dist/theme/tokens.mjs.map +1 -1
- 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 +1 -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 +11 -6
- 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 +89 -26
- 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 +23 -21
- 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 +1 -3
- package/src/theme/tokens/primitives.test.ts +15 -7
- package/src/theme/tokens/primitives.ts +65 -33
- 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,81 @@
|
|
|
1
|
+
import React, { isValidElement, cloneElement } from 'react'
|
|
2
|
+
import { Pressable, type AccessibilityState } from 'react-native'
|
|
3
|
+
|
|
4
|
+
type Handler = (...args: never[]) => void
|
|
5
|
+
type Handlers = Record<string, Handler | undefined>
|
|
6
|
+
|
|
7
|
+
export interface TriggerSurfaceProps {
|
|
8
|
+
/** Pressable handlers (onPress, onHoverIn, …) for whichever element owns the interaction. */
|
|
9
|
+
handlers: Handlers
|
|
10
|
+
/** Role for the wrapper when it is the one handling the interaction. */
|
|
11
|
+
accessibilityRole?: 'button'
|
|
12
|
+
/** Merged onto whichever element ends up owning the interaction. */
|
|
13
|
+
accessibilityState?: AccessibilityState
|
|
14
|
+
className?: string
|
|
15
|
+
children: React.ReactNode
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
type ComposableChildProps = Handlers & { accessibilityState?: AccessibilityState }
|
|
19
|
+
|
|
20
|
+
function chain(childHandler: Handler | undefined, ownHandler: Handler | undefined): Handler {
|
|
21
|
+
return (...args: never[]) => {
|
|
22
|
+
childHandler?.(...args)
|
|
23
|
+
ownHandler?.(...args)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Give interaction handling to a composed child instead of wrapping it in a second Pressable.
|
|
29
|
+
*
|
|
30
|
+
* React Native Web lets only the innermost pressable in a chain handle a gesture:
|
|
31
|
+
* PressResponder calls `stopPropagation()` on the click that drives `onPress`,
|
|
32
|
+
* and `useHover` contains hover the same way. A trigger that wraps a `Pressable`
|
|
33
|
+
* child (a `Button`, say) in its own `Pressable` therefore never sees the
|
|
34
|
+
* interaction — in a browser the trigger looks completely dead.
|
|
35
|
+
*
|
|
36
|
+
* A component child may be a Pressable, so the handlers are cloned onto it and
|
|
37
|
+
* the wrapper drops the button role — that also leaves one `[role=button]`
|
|
38
|
+
* rather than an invalid button-inside-button pair. The wrapper stays a
|
|
39
|
+
* Pressable, out of the tab order, to still catch children that turn out not to
|
|
40
|
+
* be pressable. Host elements (`<button>`, `<span>`) cannot take these handlers
|
|
41
|
+
* and do not swallow the gesture, so for those the wrapper handles it.
|
|
42
|
+
*/
|
|
43
|
+
export function TriggerSurface({
|
|
44
|
+
handlers,
|
|
45
|
+
accessibilityRole,
|
|
46
|
+
accessibilityState,
|
|
47
|
+
className,
|
|
48
|
+
children,
|
|
49
|
+
}: TriggerSurfaceProps) {
|
|
50
|
+
const child = isValidElement(children) ? children : null
|
|
51
|
+
const childCanCompose = child !== null && typeof child.type !== 'string'
|
|
52
|
+
|
|
53
|
+
if (!childCanCompose) {
|
|
54
|
+
return (
|
|
55
|
+
<Pressable
|
|
56
|
+
accessibilityRole={accessibilityRole}
|
|
57
|
+
accessibilityState={accessibilityState}
|
|
58
|
+
className={className}
|
|
59
|
+
{...handlers}
|
|
60
|
+
>
|
|
61
|
+
{children}
|
|
62
|
+
</Pressable>
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const childElement = child as React.ReactElement<ComposableChildProps>
|
|
67
|
+
const composed: ComposableChildProps = {}
|
|
68
|
+
for (const [name, handler] of Object.entries(handlers)) {
|
|
69
|
+
composed[name] = chain(childElement.props[name], handler)
|
|
70
|
+
}
|
|
71
|
+
composed.accessibilityState = {
|
|
72
|
+
...childElement.props.accessibilityState,
|
|
73
|
+
...accessibilityState,
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
<Pressable focusable={false} tabIndex={-1} className={className} {...handlers}>
|
|
78
|
+
{cloneElement(childElement, composed)}
|
|
79
|
+
</Pressable>
|
|
80
|
+
)
|
|
81
|
+
}
|
|
@@ -70,9 +70,7 @@ function SideBySideShowcase() {
|
|
|
70
70
|
return (
|
|
71
71
|
<View className="gap-6 p-6 bg-background-default min-h-screen">
|
|
72
72
|
<View className="gap-2">
|
|
73
|
-
<Text className="text-3xl font-bold text-text-primary font-heading">
|
|
74
|
-
Preset Showcase
|
|
75
|
-
</Text>
|
|
73
|
+
<Text className="text-3xl font-bold text-text-primary font-heading">Preset Showcase</Text>
|
|
76
74
|
<Text className="text-text-secondary text-base">
|
|
77
75
|
Toggle between presets to see how the entire design system adapts.
|
|
78
76
|
</Text>
|
|
@@ -89,14 +87,14 @@ function SideBySideShowcase() {
|
|
|
89
87
|
Subheading (font-heading)
|
|
90
88
|
</Text>
|
|
91
89
|
<Text className="text-base text-text-primary font-body">
|
|
92
|
-
Body text using font-body. The quick brown fox jumps over the lazy dog. This
|
|
93
|
-
|
|
90
|
+
Body text using font-body. The quick brown fox jumps over the lazy dog. This demonstrates
|
|
91
|
+
how paragraph text renders under the current preset.
|
|
94
92
|
</Text>
|
|
95
93
|
<Text className="text-sm text-text-secondary font-body">
|
|
96
94
|
Secondary body text for captions and supporting content.
|
|
97
95
|
</Text>
|
|
98
96
|
<Text className="text-sm text-text-primary font-mono">
|
|
99
|
-
{
|
|
97
|
+
{"const monospace = 'font-mono rendering'"}
|
|
100
98
|
</Text>
|
|
101
99
|
</Section>
|
|
102
100
|
|
|
@@ -195,20 +193,40 @@ function SideBySideShowcase() {
|
|
|
195
193
|
{/* Toasts */}
|
|
196
194
|
<Section title="Toasts">
|
|
197
195
|
<View className="gap-3">
|
|
198
|
-
<Toast
|
|
199
|
-
|
|
196
|
+
<Toast
|
|
197
|
+
title="Operation successful"
|
|
198
|
+
description="Your changes have been saved."
|
|
199
|
+
status="success"
|
|
200
|
+
/>
|
|
201
|
+
<Toast
|
|
202
|
+
title="Something went wrong"
|
|
203
|
+
description="Please try again later."
|
|
204
|
+
status="error"
|
|
205
|
+
/>
|
|
200
206
|
<Toast title="Heads up" description="This action cannot be undone." status="warning" />
|
|
201
|
-
<Toast
|
|
207
|
+
<Toast
|
|
208
|
+
title="New update available"
|
|
209
|
+
description="Version 2.0 is ready to install."
|
|
210
|
+
status="info"
|
|
211
|
+
/>
|
|
202
212
|
</View>
|
|
203
213
|
</Section>
|
|
204
214
|
|
|
205
215
|
{/* Status Colors */}
|
|
206
216
|
<Section title="Status Colors">
|
|
207
217
|
<View className="flex-row gap-3 flex-wrap">
|
|
208
|
-
<Badge color="success" size="lg">
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
<Badge color="
|
|
218
|
+
<Badge color="success" size="lg">
|
|
219
|
+
Success
|
|
220
|
+
</Badge>
|
|
221
|
+
<Badge color="error" size="lg">
|
|
222
|
+
Error
|
|
223
|
+
</Badge>
|
|
224
|
+
<Badge color="warning" size="lg">
|
|
225
|
+
Warning
|
|
226
|
+
</Badge>
|
|
227
|
+
<Badge color="info" size="lg">
|
|
228
|
+
Info
|
|
229
|
+
</Badge>
|
|
212
230
|
</View>
|
|
213
231
|
</Section>
|
|
214
232
|
</View>
|
|
@@ -225,9 +243,7 @@ function TypographyShowcase() {
|
|
|
225
243
|
return (
|
|
226
244
|
<View className="gap-6 p-6 bg-background-default min-h-screen">
|
|
227
245
|
<View className="gap-2">
|
|
228
|
-
<Text className="text-3xl font-bold text-text-primary font-heading">
|
|
229
|
-
Typography
|
|
230
|
-
</Text>
|
|
246
|
+
<Text className="text-3xl font-bold text-text-primary font-heading">Typography</Text>
|
|
231
247
|
<Text className="text-text-secondary text-base">
|
|
232
248
|
How fonts and text styles change across presets.
|
|
233
249
|
</Text>
|
|
@@ -252,9 +268,9 @@ function TypographyShowcase() {
|
|
|
252
268
|
|
|
253
269
|
<Section title="Body Font (font-body)">
|
|
254
270
|
<Text className="text-base text-text-primary font-body">
|
|
255
|
-
Regular body text. Design systems provide a shared language for product teams.
|
|
256
|
-
|
|
257
|
-
|
|
271
|
+
Regular body text. Design systems provide a shared language for product teams. By
|
|
272
|
+
codifying decisions into reusable components and tokens, teams move faster while
|
|
273
|
+
maintaining visual consistency across every surface.
|
|
258
274
|
</Text>
|
|
259
275
|
<Text className="text-base font-semibold text-text-primary font-body">
|
|
260
276
|
Bold body text. Emphasis and hierarchy within paragraph content.
|
|
@@ -263,8 +279,8 @@ function TypographyShowcase() {
|
|
|
263
279
|
Italic body text. Used for quotations, citations, and emphasis.
|
|
264
280
|
</Text>
|
|
265
281
|
<Text className="text-sm text-text-secondary font-body">
|
|
266
|
-
Small / secondary text. Captions, labels, and supporting information
|
|
267
|
-
|
|
282
|
+
Small / secondary text. Captions, labels, and supporting information that supplements the
|
|
283
|
+
main content without competing for attention.
|
|
268
284
|
</Text>
|
|
269
285
|
<Text className="text-xs text-text-tertiary font-body">
|
|
270
286
|
Extra-small / tertiary text. Timestamps, metadata, fine print.
|
|
@@ -287,19 +303,14 @@ function TypographyShowcase() {
|
|
|
287
303
|
|
|
288
304
|
<Section title="Mixed Typography">
|
|
289
305
|
<Card className="p-5 gap-3">
|
|
290
|
-
<Text className="text-2xl font-bold text-text-primary font-heading">
|
|
291
|
-
Chapter One
|
|
292
|
-
</Text>
|
|
306
|
+
<Text className="text-2xl font-bold text-text-primary font-heading">Chapter One</Text>
|
|
293
307
|
<Text className="text-base text-text-secondary font-body">
|
|
294
|
-
It was a bright cold day in April, and the clocks were striking thirteen.
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
along with him.
|
|
299
|
-
</Text>
|
|
300
|
-
<Text className="text-xs text-text-tertiary font-mono">
|
|
301
|
-
George Orwell, 1984
|
|
308
|
+
It was a bright cold day in April, and the clocks were striking thirteen. Winston Smith,
|
|
309
|
+
his chin nuzzled into his breast in an effort to escape the vile wind, slipped quickly
|
|
310
|
+
through the glass doors of Victory Mansions, though not quickly enough to prevent a
|
|
311
|
+
swirl of gritty dust from entering along with him.
|
|
302
312
|
</Text>
|
|
313
|
+
<Text className="text-xs text-text-tertiary font-mono">George Orwell, 1984</Text>
|
|
303
314
|
</Card>
|
|
304
315
|
</Section>
|
|
305
316
|
</View>
|
|
@@ -332,9 +343,7 @@ function ColorPaletteShowcase() {
|
|
|
332
343
|
return (
|
|
333
344
|
<View className="gap-6 p-6 bg-background-default min-h-screen">
|
|
334
345
|
<View className="gap-2">
|
|
335
|
-
<Text className="text-3xl font-bold text-text-primary font-heading">
|
|
336
|
-
Color Palette
|
|
337
|
-
</Text>
|
|
346
|
+
<Text className="text-3xl font-bold text-text-primary font-heading">Color Palette</Text>
|
|
338
347
|
<Text className="text-text-secondary text-base">
|
|
339
348
|
Semantic color tokens rendered as swatches. Toggle presets to compare palettes.
|
|
340
349
|
</Text>
|
|
@@ -347,13 +356,21 @@ function ColorPaletteShowcase() {
|
|
|
347
356
|
<ColorSwatch label="brand-primary" className="bg-brand-primary" />
|
|
348
357
|
<ColorSwatch label="brand-primary-light" className="bg-brand-primary-light" />
|
|
349
358
|
<ColorSwatch label="brand-primary-dark" className="bg-brand-primary-dark" />
|
|
350
|
-
<ColorSwatch
|
|
359
|
+
<ColorSwatch
|
|
360
|
+
label="brand-primary-subtle"
|
|
361
|
+
className="bg-brand-primary-subtle"
|
|
362
|
+
textClass="text-text-primary"
|
|
363
|
+
/>
|
|
351
364
|
</View>
|
|
352
365
|
<View className="flex-row gap-3 flex-wrap mt-2">
|
|
353
366
|
<ColorSwatch label="brand-secondary" className="bg-brand-secondary" />
|
|
354
367
|
<ColorSwatch label="brand-secondary-light" className="bg-brand-secondary-light" />
|
|
355
368
|
<ColorSwatch label="brand-secondary-dark" className="bg-brand-secondary-dark" />
|
|
356
|
-
<ColorSwatch
|
|
369
|
+
<ColorSwatch
|
|
370
|
+
label="brand-secondary-subtle"
|
|
371
|
+
className="bg-brand-secondary-subtle"
|
|
372
|
+
textClass="text-text-primary"
|
|
373
|
+
/>
|
|
357
374
|
</View>
|
|
358
375
|
</Section>
|
|
359
376
|
|
|
@@ -372,7 +389,9 @@ function ColorPaletteShowcase() {
|
|
|
372
389
|
<Text className="text-xs font-mono font-medium text-text-primary">text-primary</Text>
|
|
373
390
|
</View>
|
|
374
391
|
<View className="rounded-lg p-3 min-w-[120px] min-h-[60px] justify-end bg-surface-elevated border border-hairline">
|
|
375
|
-
<Text className="text-xs font-mono font-medium text-text-secondary">
|
|
392
|
+
<Text className="text-xs font-mono font-medium text-text-secondary">
|
|
393
|
+
text-secondary
|
|
394
|
+
</Text>
|
|
376
395
|
</View>
|
|
377
396
|
<View className="rounded-lg p-3 min-w-[120px] min-h-[60px] justify-end bg-surface-elevated border border-hairline">
|
|
378
397
|
<Text className="text-xs font-mono font-medium text-text-tertiary">text-tertiary</Text>
|
|
@@ -382,26 +401,60 @@ function ColorPaletteShowcase() {
|
|
|
382
401
|
|
|
383
402
|
<Section title="Surface Colors">
|
|
384
403
|
<View className="flex-row gap-3 flex-wrap">
|
|
385
|
-
<ColorSwatch
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
404
|
+
<ColorSwatch
|
|
405
|
+
label="surface-base"
|
|
406
|
+
className="bg-surface-base border border-hairline"
|
|
407
|
+
textClass="text-text-primary"
|
|
408
|
+
/>
|
|
409
|
+
<ColorSwatch
|
|
410
|
+
label="surface-elevated"
|
|
411
|
+
className="bg-surface-elevated border border-hairline"
|
|
412
|
+
textClass="text-text-primary"
|
|
413
|
+
/>
|
|
414
|
+
<ColorSwatch
|
|
415
|
+
label="surface-raised"
|
|
416
|
+
className="bg-surface-raised border border-hairline"
|
|
417
|
+
textClass="text-text-primary"
|
|
418
|
+
/>
|
|
419
|
+
<ColorSwatch
|
|
420
|
+
label="surface-overlay"
|
|
421
|
+
className="bg-surface-overlay border border-hairline"
|
|
422
|
+
textClass="text-text-primary"
|
|
423
|
+
/>
|
|
424
|
+
<ColorSwatch
|
|
425
|
+
label="surface-input"
|
|
426
|
+
className="bg-surface-input border border-hairline"
|
|
427
|
+
textClass="text-text-primary"
|
|
428
|
+
/>
|
|
390
429
|
</View>
|
|
391
430
|
</Section>
|
|
392
431
|
|
|
393
432
|
<Section title="Background Colors">
|
|
394
433
|
<View className="flex-row gap-3 flex-wrap">
|
|
395
|
-
<ColorSwatch
|
|
396
|
-
|
|
397
|
-
|
|
434
|
+
<ColorSwatch
|
|
435
|
+
label="background-base"
|
|
436
|
+
className="bg-background-base border border-hairline"
|
|
437
|
+
textClass="text-text-primary"
|
|
438
|
+
/>
|
|
439
|
+
<ColorSwatch
|
|
440
|
+
label="background-default"
|
|
441
|
+
className="bg-background-default border border-hairline"
|
|
442
|
+
textClass="text-text-primary"
|
|
443
|
+
/>
|
|
444
|
+
<ColorSwatch
|
|
445
|
+
label="background-subtle"
|
|
446
|
+
className="bg-background-subtle border border-hairline"
|
|
447
|
+
textClass="text-text-primary"
|
|
448
|
+
/>
|
|
398
449
|
</View>
|
|
399
450
|
</Section>
|
|
400
451
|
|
|
401
452
|
<Section title="Border Colors">
|
|
402
453
|
<View className="flex-row gap-3 flex-wrap">
|
|
403
454
|
<View className="rounded-lg p-3 min-w-[120px] min-h-[60px] justify-end bg-surface-base border-2 border-hairline-default">
|
|
404
|
-
<Text className="text-xs font-mono font-medium text-text-primary">
|
|
455
|
+
<Text className="text-xs font-mono font-medium text-text-primary">
|
|
456
|
+
hairline-default
|
|
457
|
+
</Text>
|
|
405
458
|
</View>
|
|
406
459
|
<View className="rounded-lg p-3 min-w-[120px] min-h-[60px] justify-end bg-surface-base border-2 border-hairline-subtle">
|
|
407
460
|
<Text className="text-xs font-mono font-medium text-text-primary">hairline-subtle</Text>
|
|
@@ -21,13 +21,13 @@ describe('no-device-internals', () => {
|
|
|
21
21
|
// Dimension and ratio strings: the `\b` guard before `0x` means a digit
|
|
22
22
|
// followed by `x` never reads as a hex literal. These exact strings
|
|
23
23
|
// tripped an earlier, looser sweep.
|
|
24
|
-
{ code:
|
|
25
|
-
{ code:
|
|
24
|
+
{ code: '// icons render at 20x20' },
|
|
25
|
+
{ code: '// 200x400 intrinsic -> ~160x320 px' },
|
|
26
26
|
// SVG path coordinates — digit-only runs are not byte frames.
|
|
27
27
|
{ code: 'const d = "M12 2 22 12 12 22 2 12Z"' },
|
|
28
28
|
{ code: 'const d = "M7 7 17 17 12 22 12 2 17 7 7 17"' },
|
|
29
29
|
// Timestamps — `-` and `:` are not byte separators.
|
|
30
|
-
{ code:
|
|
30
|
+
{ code: '// datetime // 2024-01-15 14:30' },
|
|
31
31
|
// "cascade" in its CSS sense is ordinary styling vocabulary.
|
|
32
32
|
{ code: "// RN doesn't cascade text color, so hand-color the text" },
|
|
33
33
|
// Plain numbers and durations.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite'
|
|
2
|
+
import { View, Text } from 'react-native'
|
|
3
|
+
import tokensDoc from '../../TOKENS.md?raw'
|
|
4
|
+
import { Typography } from '../components/custom/Typography'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Rendered straight from `packages/ui/TOKENS.md` via Vite's `?raw`, deliberately
|
|
8
|
+
* as its markdown source rather than a hand-built React page. A prettier page
|
|
9
|
+
* would be a second copy of the rules that can drift from the file — and a token
|
|
10
|
+
* guide that disagrees with itself is worse than a plain one. The content is
|
|
11
|
+
* mostly aligned tables, which read fine in mono.
|
|
12
|
+
*/
|
|
13
|
+
function ChoosingTokens() {
|
|
14
|
+
return (
|
|
15
|
+
<View className="gap-4 p-6">
|
|
16
|
+
<Typography variant="h3" className="text-text-primary">
|
|
17
|
+
Choosing tokens
|
|
18
|
+
</Typography>
|
|
19
|
+
<Typography variant="body2" className="text-text-secondary">
|
|
20
|
+
The decision table to read before writing a component. Source of truth:{' '}
|
|
21
|
+
<Text className="font-mono text-text-primary">packages/ui/TOKENS.md</Text> — this page
|
|
22
|
+
renders that file, so the two cannot disagree.
|
|
23
|
+
</Typography>
|
|
24
|
+
<View className="rounded-lg bg-surface-raised p-4">
|
|
25
|
+
<Text className="font-mono text-xs leading-5 text-text-secondary">{tokensDoc}</Text>
|
|
26
|
+
</View>
|
|
27
|
+
</View>
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const meta: Meta<typeof ChoosingTokens> = {
|
|
32
|
+
title: 'Foundations/Choosing Tokens',
|
|
33
|
+
component: ChoosingTokens,
|
|
34
|
+
parameters: {
|
|
35
|
+
layout: 'fullscreen',
|
|
36
|
+
docs: {
|
|
37
|
+
description: {
|
|
38
|
+
component:
|
|
39
|
+
'Which palette for which meaning, how to resolve a colour in code, and the type/spacing ' +
|
|
40
|
+
'scales. Rendered from `packages/ui/TOKENS.md`.',
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
}
|
|
45
|
+
export default meta
|
|
46
|
+
type Story = StoryObj<typeof ChoosingTokens>
|
|
47
|
+
|
|
48
|
+
export const Default: Story = {}
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/react-vite'
|
|
2
2
|
import { View, Text } from 'react-native'
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
categoricalPalette,
|
|
5
|
+
getCategoricalColor,
|
|
6
|
+
CATEGORICAL_CVD_SAFE_MAX,
|
|
7
|
+
divergingScale,
|
|
8
|
+
sequentialEffort,
|
|
9
|
+
discreteRainbow,
|
|
10
|
+
bestTextColor,
|
|
11
|
+
greyRamp,
|
|
12
|
+
} from './tokens/primitives'
|
|
4
13
|
import { semanticColorsLight, semanticColorsDark } from './tokens/semantic'
|
|
5
14
|
import { WORKOUT_TOKENS } from './workout-tokens'
|
|
6
15
|
import { WORKOUT_PILL_DELOAD } from './extracted-colors-dataviz'
|
|
@@ -52,7 +61,12 @@ export default meta
|
|
|
52
61
|
* `Foundations/Color/Primitives`.
|
|
53
62
|
*/
|
|
54
63
|
const SURFACE_PLANES = [
|
|
55
|
-
{
|
|
64
|
+
{
|
|
65
|
+
step: 975,
|
|
66
|
+
hex: greyRamp[975],
|
|
67
|
+
lStar: 3.8,
|
|
68
|
+
role: 'Frame / bezel — chrome the ramp sits inside',
|
|
69
|
+
},
|
|
56
70
|
{ step: 950, hex: greyRamp[950], lStar: 9, role: 'Shell' },
|
|
57
71
|
{ step: 925, hex: greyRamp[925], lStar: 13.9, role: 'Main content plane' },
|
|
58
72
|
{ step: 900, hex: greyRamp[900], lStar: 17.2, role: 'Nav / rail' },
|
|
@@ -113,12 +127,12 @@ export const SurfaceRamp: StoryObj = {
|
|
|
113
127
|
<View style={{ padding: 24 }}>
|
|
114
128
|
<Text className="text-2xl font-bold text-text-primary mb-2">Surface Ramp (Dark Mode)</Text>
|
|
115
129
|
<SectionIntro>
|
|
116
|
-
The v0.10.0 surface foundation, and the assignment the most surfaces depend on. Depth is
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
130
|
+
The v0.10.0 surface foundation, and the assignment the most surfaces depend on. Depth is an{' '}
|
|
131
|
+
<Text className="font-semibold">ordered ramp</Text>, not a set of unrelated fills — planes
|
|
132
|
+
are spaced by perceptual lightness (L*) on a diminishing taper, so "one step up"
|
|
133
|
+
is the same visual distance anywhere in the stack. Listed darkest first. Several semantic
|
|
134
|
+
tokens deliberately share a plane (shown per row); that aliasing is what lets a component
|
|
135
|
+
say what it <Text className="italic">is</Text> rather than how deep it sits.
|
|
122
136
|
</SectionIntro>
|
|
123
137
|
|
|
124
138
|
<View style={{ gap: 14 }}>
|
|
@@ -132,9 +146,9 @@ export const SurfaceRamp: StoryObj = {
|
|
|
132
146
|
scales — the greys it is built from are in Foundations/Color/Primitives. To apply it at
|
|
133
147
|
runtime use <Text className="font-semibold text-text-primary"><Surface level></Text>{' '}
|
|
134
148
|
and <Text className="font-semibold text-text-primary">useOnSurfaceColor</Text> rather than
|
|
135
|
-
reading tokens directly — see Components/Atoms/Surface.
|
|
136
|
-
|
|
137
|
-
in Foundations/
|
|
149
|
+
reading tokens directly — see Components/Atoms/Surface. How a plane says it is ABOVE its
|
|
150
|
+
neighbour (tone, lift, hairline, material) and how the elevation levels map onto these steps
|
|
151
|
+
are in Foundations/Depth.
|
|
138
152
|
</Text>
|
|
139
153
|
</View>
|
|
140
154
|
),
|
|
@@ -188,16 +202,14 @@ export const CategoricalPalette: StoryObj = {
|
|
|
188
202
|
<SectionIntro>
|
|
189
203
|
Seven hues in one canonical order —{' '}
|
|
190
204
|
<Text className="font-semibold">blue → magenta → red → orange → green → cyan → amber</Text>{' '}
|
|
191
|
-
— expressed as references into the tonal ramps. The sequence is nested-stable: a chart
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
{CATEGORICAL_CVD_SAFE_MAX} (
|
|
195
|
-
|
|
196
|
-
wants a legend or a second encoding. Two variants ship:{' '}
|
|
205
|
+
— expressed as references into the tonal ramps. The sequence is nested-stable: a chart with
|
|
206
|
+
N series takes the first N colors and a series' index does not shift as N changes. The
|
|
207
|
+
worst-case deuteranopia/protanopia ΔE floor of 8 holds through the first{' '}
|
|
208
|
+
{CATEGORICAL_CVD_SAFE_MAX} (<Text className="font-semibold">CATEGORICAL_CVD_SAFE_MAX</Text>
|
|
209
|
+
); the 7th is extended and wants a legend or a second encoding. Two variants ship:{' '}
|
|
197
210
|
<Text className="font-semibold">default</Text> (vivid, for neutral/light surfaces, legible
|
|
198
|
-
under black text) and <Text className="font-semibold">dark</Text> (deeper, for white text
|
|
199
|
-
|
|
200
|
-
it.
|
|
211
|
+
under black text) and <Text className="font-semibold">dark</Text> (deeper, for white text on
|
|
212
|
+
a filled swatch). A third "light" variant was dropped — `default` doubles as it.
|
|
201
213
|
</SectionIntro>
|
|
202
214
|
|
|
203
215
|
<CategoricalRow name="Default (black text)" colors={categoricalPalette.default} />
|
|
@@ -394,8 +406,8 @@ export const FatigueRomPalette: StoryObj = {
|
|
|
394
406
|
</Text>{' '}
|
|
395
407
|
One scheme shared by the two live-quality readouts — the ROM progression bars and the
|
|
396
408
|
ghost-spark current line. Deliberately no greens and no ambers: those languages belong to
|
|
397
|
-
the verdict tones and the velocity-loss bands (stories 3 and 4), and reusing them here
|
|
398
|
-
|
|
409
|
+
the verdict tones and the velocity-loss bands (stories 3 and 4), and reusing them here would
|
|
410
|
+
make "fine" and "fast" look like the same claim. Every stop is a
|
|
399
411
|
reference into the tonal ramps.
|
|
400
412
|
</SectionIntro>
|
|
401
413
|
|
|
@@ -426,8 +438,8 @@ export const FatigueRomPalette: StoryObj = {
|
|
|
426
438
|
<Text className="text-text-secondary text-xs mb-3">
|
|
427
439
|
A controlled rep (grind signature below GRIND_THRESHOLD = {GRIND_THRESHOLD}) stays in the
|
|
428
440
|
silver family, dimming toward DRIFT_GREY with tempo deviation — a "drifting but not
|
|
429
|
-
failing" cue that never becomes a color. At or above the threshold the line runs
|
|
430
|
-
|
|
441
|
+
failing" cue that never becomes a color. At or above the threshold the line runs light
|
|
442
|
+
→ mid → deep by severity.
|
|
431
443
|
</Text>
|
|
432
444
|
<View style={{ flexDirection: 'row', gap: 32 }}>
|
|
433
445
|
<FatigueRampStrip
|
|
@@ -442,8 +454,8 @@ export const FatigueRomPalette: StoryObj = {
|
|
|
442
454
|
DRIFT_GREY is `neutral[600]` #4B5563, and the unified warm grey ramp assigns it no
|
|
443
455
|
destination — the 15-row fold maps the other greys but skips this one. It needs an
|
|
444
456
|
assignment before that migration lands. Note that the recovered spec records DRIFT_GREY as
|
|
445
|
-
`grey[500]` #1C1C1C; that is stale, `fatigue-tokens.ts` on main reads `neutral[600]`,
|
|
446
|
-
|
|
457
|
+
`grey[500]` #1C1C1C; that is stale, `fatigue-tokens.ts` on main reads `neutral[600]`, which
|
|
458
|
+
puts it in the expensive half of the fold rather than the cheap one.
|
|
447
459
|
</Text>
|
|
448
460
|
</View>
|
|
449
461
|
),
|
|
@@ -461,7 +473,9 @@ export const FatigueRomPalette: StoryObj = {
|
|
|
461
473
|
* buries. Columns are derived from the shipped tokens, so a new modifier shows
|
|
462
474
|
* up here without editing the story.
|
|
463
475
|
*/
|
|
464
|
-
|
|
476
|
+
// Wash rungs run subtle -> muted -> strong (0.12 / 0.30 / 0.50) so the matrix
|
|
477
|
+
// reads as the ramp it is.
|
|
478
|
+
const VARIANT_SUFFIXES = ['light', 'dark', 'subtle', 'muted', 'strong', 'hover', 'active'] as const
|
|
465
479
|
|
|
466
480
|
function variantsOf(base: string, palette: Record<string, string>) {
|
|
467
481
|
return [
|
|
@@ -513,12 +527,12 @@ export const StatusColors: StoryObj = {
|
|
|
513
527
|
<Text className="text-2xl font-bold text-text-primary mb-2">Status Colors</Text>
|
|
514
528
|
<SectionIntro>
|
|
515
529
|
Status roles and their modifiers. <Text className="font-semibold">status-error-vivid</Text>{' '}
|
|
516
|
-
is a separate role (not a modifier of status-error) reserved for destructive
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
530
|
+
is a separate role (not a modifier of status-error) reserved for destructive emphasis. It
|
|
531
|
+
used to be the one status family sourced from the `redVivid` support scale rather than the
|
|
532
|
+
OKLCH ramps; TD-07.14 deleted that scale, so the family now resolves to the same
|
|
533
|
+
red[600]/[500]/[700] steps as status-error. The two are therefore identical in value today —
|
|
534
|
+
the role is kept distinct because emphasis is meant to come from a glow derived from
|
|
535
|
+
red[500], not from a second, higher-chroma red.
|
|
522
536
|
</SectionIntro>
|
|
523
537
|
<VariantMatrix
|
|
524
538
|
bases={[
|
|
@@ -557,8 +571,8 @@ export const ResultColors: StoryObj = {
|
|
|
557
571
|
<Text className="text-2xl font-bold text-text-primary mb-2">Result / Outcome Colors</Text>
|
|
558
572
|
<SectionIntro>
|
|
559
573
|
Colors for indicating positive, negative, or neutral outcomes. Distinct from status: these
|
|
560
|
-
encode the <Text className="italic">direction of a change</Text> (did this get better?),
|
|
561
|
-
|
|
574
|
+
encode the <Text className="italic">direction of a change</Text> (did this get better?), not
|
|
575
|
+
a system state.
|
|
562
576
|
</SectionIntro>
|
|
563
577
|
<VariantMatrix
|
|
564
578
|
bases={['result-improve', 'result-degrade', 'result-inconclusive', 'result-neutral']}
|
|
@@ -574,11 +588,11 @@ export const TextAndBorderColors: StoryObj = {
|
|
|
574
588
|
<View style={{ padding: 24 }}>
|
|
575
589
|
<Text className="text-2xl font-bold text-text-primary mb-2">Text & Border Colors</Text>
|
|
576
590
|
<SectionIntro>
|
|
577
|
-
The dark-mode text and border roles. Today the border family is the grey grey ramp
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
591
|
+
The dark-mode text and border roles. Today the border family is the grey grey ramp assigned
|
|
592
|
+
to line-work, and text-tertiary and the link colors come from the neutral and blue support
|
|
593
|
+
scales — all three of which are pending migration (TD-07.14): the greys fold into one warm
|
|
594
|
+
grey ramp and the links move to the OKLCH blue. These are the roles that will move most,
|
|
595
|
+
because the mid-grey text steps shift furthest. Prefer{' '}
|
|
582
596
|
<Text className="font-semibold">useOnSurfaceColor</Text> for text sitting on a{' '}
|
|
583
597
|
<Text className="font-semibold"><Surface></Text> — it picks the right text role for
|
|
584
598
|
the plane instead of hardcoding one, which is also what makes the migration survivable.
|
|
@@ -782,7 +796,10 @@ export const RolesInUse: StoryObj = {
|
|
|
782
796
|
<Demo label="IntensityBar · effort">
|
|
783
797
|
<View style={{ flexDirection: 'row', gap: 2, width: 132 }}>
|
|
784
798
|
{sequentialEffort.map((hex, i) => (
|
|
785
|
-
<View
|
|
799
|
+
<View
|
|
800
|
+
key={i}
|
|
801
|
+
style={{ flex: 1, height: 20, backgroundColor: hex, borderRadius: 2 }}
|
|
802
|
+
/>
|
|
786
803
|
))}
|
|
787
804
|
</View>
|
|
788
805
|
</Demo>
|
|
@@ -832,10 +849,10 @@ export const LegacyDataVisualizationColors: StoryObj = {
|
|
|
832
849
|
</Text>
|
|
833
850
|
<SectionIntro>
|
|
834
851
|
<Text className="font-semibold">Do not use for new work.</Text> Paul Tol's
|
|
835
|
-
discrete-rainbow scale behind the `data-1..10` tokens — no longer consumed by any
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
852
|
+
discrete-rainbow scale behind the `data-1..10` tokens — no longer consumed by any component.
|
|
853
|
+
Use the Categorical Palette (story 2) for charts and qualitative series. This story exists
|
|
854
|
+
because the tokens are still shipped, and a shipped token without a swatch is the drift the
|
|
855
|
+
coverage test guards against; it goes away when the tokens do.
|
|
839
856
|
</SectionIntro>
|
|
840
857
|
|
|
841
858
|
<View style={{ gap: 16 }}>
|