@titan-design/react-ui 0.12.1 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -47
- package/dist/bodymap.js +856 -736
- package/dist/bodymap.js.map +1 -1
- package/dist/bodymap.mjs +858 -738
- package/dist/bodymap.mjs.map +1 -1
- package/dist/index.d.mts +1431 -237
- package/dist/index.d.ts +1431 -237
- package/dist/index.js +6506 -4781
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +6280 -4642
- package/dist/index.mjs.map +1 -1
- package/dist/{pages-B1hqnGIC.d.ts → pages-CsjsUn0G.d.ts} +51 -16
- package/dist/{pages-CvsFqNtx.d.mts → pages-ZbT_pD_U.d.mts} +51 -16
- package/dist/pages.d.mts +1 -1
- package/dist/pages.d.ts +1 -1
- package/dist/pages.js +1919 -1937
- package/dist/pages.js.map +1 -1
- package/dist/pages.mjs +1927 -1945
- package/dist/pages.mjs.map +1 -1
- package/dist/theme/index.d.mts +225 -140
- package/dist/theme/index.d.ts +225 -140
- package/dist/theme/index.js +298 -319
- package/dist/theme/index.js.map +1 -1
- package/dist/theme/index.mjs +283 -315
- package/dist/theme/index.mjs.map +1 -1
- package/dist/theme/tokens-css.js +145 -24
- package/dist/theme/tokens-css.js.map +1 -1
- package/dist/theme/tokens-css.mjs +145 -24
- package/dist/theme/tokens-css.mjs.map +1 -1
- package/dist/theme/tokens.d.mts +128 -11
- package/dist/theme/tokens.d.ts +128 -11
- package/dist/theme/tokens.js +126 -26
- package/dist/theme/tokens.js.map +1 -1
- package/dist/theme/tokens.mjs +124 -27
- 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/docs/render-testing-pattern.md +130 -0
- package/package.json +1 -1
- package/src/arch/Architecture.stories.tsx +3 -1
- package/src/arch/arch-graph.freshness.test.ts +52 -0
- package/src/arch/arch-graph.json +4989 -1583
- 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 +182 -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 +12 -6
- 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 +6 -3
- package/src/components/custom/Gauge/Gauge.test.tsx +1 -1
- package/src/components/custom/Gauge/Gauge.tsx +7 -2
- 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 +55 -14
- package/src/components/custom/Scatter/Scatter.test.tsx +2 -2
- package/src/components/custom/Scatter/Scatter.tsx +122 -18
- package/src/components/custom/Sidebar/Sidebar.stories.tsx +41 -8
- 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 +99 -16
- 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 +15 -12
- package/src/components/custom/Treemap/Treemap.test.tsx +1 -1
- package/src/components/custom/Treemap/Treemap.tsx +11 -3
- 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 +11 -2
- package/src/components/custom/Workout/BaseBadge.stories.tsx +27 -11
- package/src/components/custom/Workout/BaseBadge.test.tsx +31 -11
- package/src/components/custom/Workout/BaseBadge.tsx +6 -2
- package/src/components/custom/Workout/BodyMap.stories.tsx +4 -1
- package/src/components/custom/Workout/BodyMap.tsx +8 -4
- package/src/components/custom/Workout/BodyMapDetailPanel.stories.tsx +28 -6
- package/src/components/custom/Workout/BodyMapDetailPanel.test.tsx +11 -15
- package/src/components/custom/Workout/BodyMapDetailPanel.tsx +50 -12
- package/src/components/custom/Workout/CapacityBandChart.stories.tsx +12 -9
- package/src/components/custom/Workout/CapacityBandChart.test.tsx +24 -51
- package/src/components/custom/Workout/CapacityBandChart.tsx +144 -111
- package/src/components/custom/Workout/DeviationBar.stories.tsx +1 -1
- package/src/components/custom/Workout/DeviationBar.test.tsx +10 -4
- package/src/components/custom/Workout/DeviationBar.tsx +24 -16
- package/src/components/custom/Workout/DualVelocityStrip.stories.tsx +183 -0
- package/src/components/custom/Workout/DualVelocityStrip.test.tsx +32 -18
- package/src/components/custom/Workout/ExerciseCard.stories.tsx +12 -11
- package/src/components/custom/Workout/ExerciseCard.test.tsx +52 -22
- package/src/components/custom/Workout/ExerciseCard.tsx +99 -183
- package/src/components/custom/Workout/ExerciseCardHeading.stories.tsx +95 -12
- package/src/components/custom/Workout/ExerciseCardHeading.test.tsx +189 -1
- package/src/components/custom/Workout/ExerciseCardHeading.tsx +167 -18
- package/src/components/custom/Workout/ExerciseDetailPage.stories.tsx +9 -1
- package/src/components/custom/Workout/ExerciseDetailPage.tsx +3 -2
- package/src/components/custom/Workout/ExerciseHeading.stories.tsx +8 -8
- package/src/components/custom/Workout/ExerciseHeading.tsx +194 -46
- package/src/components/custom/Workout/ExerciseIndicator.stories.tsx +12 -9
- 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/InputBar.tsx +4 -2
- 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 +8 -3
- 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 +14 -10
- 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 +20 -33
- 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 +9 -4
- 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 +16 -3
- 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 +68 -17
- 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 +22 -4
- package/src/components/custom/Workout/RestTimer.stories.tsx +16 -4
- package/src/components/custom/Workout/RestTimer.tsx +4 -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 +21 -17
- package/src/components/custom/Workout/SegmentedBar.tsx +10 -5
- 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 +63 -7
- 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 +24 -12
- package/src/components/custom/Workout/Sparkline.stories.tsx +14 -11
- 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 +11 -4
- package/src/components/custom/Workout/StrengthTrendChart.test.tsx +15 -37
- package/src/components/custom/Workout/StrengthTrendChart.tsx +39 -36
- 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 +26 -10
- package/src/components/custom/Workout/TempoDisplay.test.tsx +18 -4
- package/src/components/custom/Workout/TempoDisplay.tsx +2 -0
- 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 +10 -6
- package/src/components/custom/Workout/VelocityStrip.expanded.stories.tsx +5 -2
- package/src/components/custom/Workout/VelocityStrip.hero.stories.tsx +44 -1
- package/src/components/custom/Workout/VelocityStrip.stories.tsx +12 -6
- package/src/components/custom/Workout/VelocityStrip.test.tsx +48 -6
- package/src/components/custom/Workout/VelocityStrip.tsx +26 -14
- 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 +10 -7
- package/src/components/custom/Workout/ZoneTrack.tsx +10 -9
- package/src/components/custom/Workout/exerciseRowState.ts +29 -0
- package/src/components/custom/Workout/index.ts +17 -2
- package/src/components/custom/Workout/metricText.stories.tsx +15 -13
- package/src/components/custom/Workout/metricText.tsx +8 -2
- package/src/components/custom/Workout/setHeadingKit.tsx +219 -36
- package/src/components/custom/Workout/velocity-story-kit.tsx +2 -2
- package/src/components/custom/charts/README.md +66 -0
- package/src/components/custom/charts/SetBarChart.test.tsx +46 -1
- package/src/components/custom/charts/SetBarChart.tsx +56 -9
- 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/flatBarGeometry.test.ts +41 -0
- package/src/components/custom/charts/flatBarGeometry.ts +32 -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 +21 -34
- 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 +15 -5
- package/src/components/ui/alert/Alert.tsx +24 -3
- 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 +44 -37
- 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 +7 -27
- 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 +14 -3
- 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 -27
- 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 +10 -18
- package/src/components/ui/indicator/Indicator.stories.tsx +5 -4
- 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 +17 -5
- 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 +31 -19
- package/src/components/ui/pill/Pill.stories.tsx +111 -23
- package/src/components/ui/pill/Pill.test.tsx +101 -3
- package/src/components/ui/pill/Pill.tsx +168 -49
- package/src/components/ui/pill/index.ts +1 -1
- package/src/components/ui/popover/Popover.stories.tsx +6 -8
- 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/progress/Progress.tsx +9 -6
- 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 +12 -21
- 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 +16 -15
- 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 +4 -5
- package/src/components/ui/stack/Stack.stories.tsx +8 -8
- package/src/components/ui/stack/Stack.tsx +1 -1
- package/src/components/ui/surface/Surface.stories.tsx +92 -33
- 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 +8 -21
- 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 +49 -57
- 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 +38 -49
- 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 +101 -48
- package/src/test/no-device-internals.test.ts +3 -3
- package/src/test/no-raw-color.test.ts +39 -0
- package/src/theme/Alpha.stories.tsx +103 -0
- 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/ProposedTokensVW82.stories.tsx +414 -0
- 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 +40 -0
- package/src/theme/elevation.test.ts +82 -56
- package/src/theme/elevation.ts +77 -561
- package/src/theme/global.css +45 -5
- 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/subtle-tone-weight.test.ts +163 -0
- package/src/theme/surface-planes.test.ts +37 -0
- package/src/theme/surface-planes.ts +68 -0
- package/src/theme/tailwind-var-opacity.test.ts +163 -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 +98 -33
- package/src/theme/tokens/semantic-hex-guard.test.ts +322 -0
- package/src/theme/tokens/semantic.ts +124 -54
- 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.alpha-adoption.test.ts +408 -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 +55 -9
- 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
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/react-vite'
|
|
2
2
|
import { View } from 'react-native'
|
|
3
|
-
import {
|
|
4
|
-
Skeleton,
|
|
5
|
-
SkeletonText,
|
|
6
|
-
SkeletonCircle,
|
|
7
|
-
SkeletonCard,
|
|
8
|
-
SkeletonListItem,
|
|
9
|
-
} from './Skeleton'
|
|
3
|
+
import { Skeleton, SkeletonText, SkeletonCircle, SkeletonCard, SkeletonListItem } from './Skeleton'
|
|
10
4
|
|
|
11
5
|
const meta: Meta<typeof Skeleton> = {
|
|
12
6
|
title: 'Components/Atoms/Skeleton',
|
|
13
7
|
component: Skeleton,
|
|
14
|
-
tags: ['autodocs'],
|
|
8
|
+
tags: ['autodocs', 'status:stable', '!status:review'],
|
|
15
9
|
argTypes: {
|
|
16
10
|
variant: {
|
|
17
11
|
control: 'select',
|
|
@@ -64,9 +58,7 @@ export const RectVariant: Story = {
|
|
|
64
58
|
}
|
|
65
59
|
|
|
66
60
|
export const RoundedVariant: Story = {
|
|
67
|
-
render: () =>
|
|
68
|
-
<Skeleton variant="rounded" width={300} height={200} />
|
|
69
|
-
),
|
|
61
|
+
render: () => <Skeleton variant="rounded" width={300} height={200} />,
|
|
70
62
|
}
|
|
71
63
|
|
|
72
64
|
export const TextBlock: Story = {
|
|
@@ -136,11 +136,7 @@ export interface SkeletonCircleProps {
|
|
|
136
136
|
/**
|
|
137
137
|
* Circle skeleton for avatars.
|
|
138
138
|
*/
|
|
139
|
-
export function SkeletonCircle({
|
|
140
|
-
size = 40,
|
|
141
|
-
animation = 'pulse',
|
|
142
|
-
className,
|
|
143
|
-
}: SkeletonCircleProps) {
|
|
139
|
+
export function SkeletonCircle({ size = 40, animation = 'pulse', className }: SkeletonCircleProps) {
|
|
144
140
|
return (
|
|
145
141
|
<Skeleton
|
|
146
142
|
variant="circle"
|
|
@@ -179,12 +175,7 @@ export function SkeletonCard({
|
|
|
179
175
|
return (
|
|
180
176
|
<View className={cn('rounded-lg overflow-hidden bg-surface-elevated', className)}>
|
|
181
177
|
{hasImage && (
|
|
182
|
-
<Skeleton
|
|
183
|
-
variant="rect"
|
|
184
|
-
width="100%"
|
|
185
|
-
height={imageHeight}
|
|
186
|
-
animation={animation}
|
|
187
|
-
/>
|
|
178
|
+
<Skeleton variant="rect" width="100%" height={imageHeight} animation={animation} />
|
|
188
179
|
)}
|
|
189
180
|
<View className="p-4 gap-3">
|
|
190
181
|
<Skeleton variant="text" width="70%" animation={animation} />
|
|
@@ -218,9 +209,7 @@ export function SkeletonListItem({
|
|
|
218
209
|
}: SkeletonListItemProps) {
|
|
219
210
|
return (
|
|
220
211
|
<View className={cn('flex-row items-center gap-3 p-3', className)}>
|
|
221
|
-
{hasAvatar &&
|
|
222
|
-
<SkeletonCircle size={avatarSize} animation={animation} />
|
|
223
|
-
)}
|
|
212
|
+
{hasAvatar && <SkeletonCircle size={avatarSize} animation={animation} />}
|
|
224
213
|
<View className="flex-1">
|
|
225
214
|
<SkeletonText lines={lines} animation={animation} />
|
|
226
215
|
</View>
|
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
export {
|
|
2
|
-
Skeleton,
|
|
3
|
-
SkeletonText,
|
|
4
|
-
SkeletonCircle,
|
|
5
|
-
SkeletonCard,
|
|
6
|
-
SkeletonListItem,
|
|
7
|
-
} from './Skeleton'
|
|
1
|
+
export { Skeleton, SkeletonText, SkeletonCircle, SkeletonCard, SkeletonListItem } from './Skeleton'
|
|
8
2
|
export type {
|
|
9
3
|
SkeletonProps,
|
|
10
4
|
SkeletonTextProps,
|
|
@@ -2,6 +2,7 @@ import React from 'react'
|
|
|
2
2
|
import { ActivityIndicator, View, type ViewProps } from 'react-native'
|
|
3
3
|
import { cn } from '../../../utils/cn'
|
|
4
4
|
import { SPINNER_PRIMARY, SPINNER_SECONDARY } from '../../../theme/extracted-colors-ui'
|
|
5
|
+
import { primitiveColors } from '../../../theme/tokens/primitives'
|
|
5
6
|
|
|
6
7
|
export type SpinnerSize = 'sm' | 'md' | 'lg' | 'xl'
|
|
7
8
|
export type SpinnerColor = 'primary' | 'secondary' | 'white' | 'default'
|
|
@@ -27,7 +28,8 @@ const sizeMap: Record<SpinnerSize, 'small' | 'large'> = {
|
|
|
27
28
|
const colorMap: Record<SpinnerColor, string> = {
|
|
28
29
|
primary: SPINNER_PRIMARY,
|
|
29
30
|
secondary: SPINNER_SECONDARY,
|
|
30
|
-
white:
|
|
31
|
+
white: primitiveColors.white,
|
|
32
|
+
// VW-82: Tailwind gray-500; no titan grey matches. Left raw, proposed in the PR.
|
|
31
33
|
default: '#6B7280',
|
|
32
34
|
}
|
|
33
35
|
|
|
@@ -64,10 +66,7 @@ export function Spinner({
|
|
|
64
66
|
className={cn('items-center justify-center', containerSizes[size], className)}
|
|
65
67
|
{...props}
|
|
66
68
|
>
|
|
67
|
-
<ActivityIndicator
|
|
68
|
-
size={sizeMap[size]}
|
|
69
|
-
color={colorMap[color]}
|
|
70
|
-
/>
|
|
69
|
+
<ActivityIndicator size={sizeMap[size]} color={colorMap[color]} />
|
|
71
70
|
</View>
|
|
72
71
|
)
|
|
73
72
|
}
|
|
@@ -5,7 +5,7 @@ import { Stack, HStack, VStack } from './Stack'
|
|
|
5
5
|
const meta: Meta<typeof Stack> = {
|
|
6
6
|
title: 'Components/Atoms/Stack',
|
|
7
7
|
component: Stack,
|
|
8
|
-
tags: ['autodocs'],
|
|
8
|
+
tags: ['autodocs', 'status:stable', '!status:review'],
|
|
9
9
|
argTypes: {
|
|
10
10
|
gap: {
|
|
11
11
|
control: 'select',
|
|
@@ -35,7 +35,7 @@ type Story = StoryObj<typeof Stack>
|
|
|
35
35
|
function Box({ children }: { children: string }) {
|
|
36
36
|
return (
|
|
37
37
|
<View className="rounded bg-brand-primary px-4 py-2">
|
|
38
|
-
<Text className="text-sm text-
|
|
38
|
+
<Text className="text-sm text-on-brand-primary">{children}</Text>
|
|
39
39
|
</View>
|
|
40
40
|
)
|
|
41
41
|
}
|
|
@@ -76,23 +76,23 @@ export const Vertical: Story = {
|
|
|
76
76
|
export const WithAlignment: Story = {
|
|
77
77
|
render: () => (
|
|
78
78
|
<VStack gap={6}>
|
|
79
|
-
<Text className="text-sm font-medium text-
|
|
79
|
+
<Text className="text-sm font-medium text-text-secondary">justify="between"</Text>
|
|
80
80
|
<HStack gap={2} justify="between" className="w-full">
|
|
81
81
|
<Box>A</Box>
|
|
82
82
|
<Box>B</Box>
|
|
83
83
|
<Box>C</Box>
|
|
84
84
|
</HStack>
|
|
85
85
|
|
|
86
|
-
<Text className="text-sm font-medium text-
|
|
86
|
+
<Text className="text-sm font-medium text-text-secondary">align="center"</Text>
|
|
87
87
|
<HStack gap={2} align="center">
|
|
88
88
|
<View className="rounded bg-brand-primary px-4 py-1">
|
|
89
|
-
<Text className="text-sm text-
|
|
89
|
+
<Text className="text-sm text-on-brand-primary">Short</Text>
|
|
90
90
|
</View>
|
|
91
91
|
<View className="rounded bg-brand-primary px-4 py-4">
|
|
92
|
-
<Text className="text-sm text-
|
|
92
|
+
<Text className="text-sm text-on-brand-primary">Tall</Text>
|
|
93
93
|
</View>
|
|
94
94
|
<View className="rounded bg-brand-primary px-4 py-2">
|
|
95
|
-
<Text className="text-sm text-
|
|
95
|
+
<Text className="text-sm text-on-brand-primary">Medium</Text>
|
|
96
96
|
</View>
|
|
97
97
|
</HStack>
|
|
98
98
|
</VStack>
|
|
@@ -114,7 +114,7 @@ export const GapScale: Story = {
|
|
|
114
114
|
<VStack gap={6}>
|
|
115
115
|
{([0, 1, 2, 4, 6, 8, 12] as const).map((g) => (
|
|
116
116
|
<VStack key={g} gap={1}>
|
|
117
|
-
<Text className="text-xs text-
|
|
117
|
+
<Text className="text-xs text-text-secondary">gap={g}</Text>
|
|
118
118
|
<HStack gap={g}>
|
|
119
119
|
<Box>A</Box>
|
|
120
120
|
<Box>B</Box>
|
|
@@ -3,25 +3,36 @@ import { View, Text } from 'react-native'
|
|
|
3
3
|
import { Surface } from './Surface'
|
|
4
4
|
import { useOnSurfaceColor, type SurfaceLevel } from './SurfaceContext'
|
|
5
5
|
import type { ElevationLevel } from '../../../theme/elevation'
|
|
6
|
+
import { semanticColorsLight, semanticColorsDark } from '../../../theme/tokens/semantic'
|
|
7
|
+
import { primitiveRamps } from '../../../theme/tokens/primitives'
|
|
6
8
|
|
|
7
9
|
const meta: Meta<typeof Surface> = {
|
|
8
10
|
title: 'Components/Atoms/Surface',
|
|
9
11
|
component: Surface,
|
|
10
|
-
tags: ['autodocs'],
|
|
12
|
+
tags: ['autodocs', 'status:stable', '!status:review'],
|
|
11
13
|
argTypes: {
|
|
12
14
|
elevation: {
|
|
13
15
|
control: { type: 'range', min: -2, max: 5, step: 1 },
|
|
14
|
-
description:
|
|
16
|
+
description:
|
|
17
|
+
'Depth relative to the enclosing Surface: <0 recess, 0 flat, 1–3 lift a plane each, 4–5 float',
|
|
18
|
+
},
|
|
19
|
+
raise: {
|
|
20
|
+
control: { type: 'range', min: 1, max: 3, step: 1 },
|
|
21
|
+
description: 'Planes to step UP from the enclosing Surface, with the lift treatment',
|
|
15
22
|
},
|
|
16
23
|
level: {
|
|
17
24
|
control: 'select',
|
|
18
25
|
options: ['frame', 'background', 'base', 'elevated', 'raised', 'overlay'],
|
|
19
|
-
description: '
|
|
26
|
+
description: 'Absolute grey plane for a shell root (flat, no lift)',
|
|
20
27
|
},
|
|
21
28
|
pressed: {
|
|
22
29
|
control: 'boolean',
|
|
23
30
|
description: 'Sunken well: one ramp step DOWN from the parent level + inner-shadow recess',
|
|
24
31
|
},
|
|
32
|
+
lift: {
|
|
33
|
+
control: 'boolean',
|
|
34
|
+
description: 'Force the rim + shadow treatment on or off',
|
|
35
|
+
},
|
|
25
36
|
theme: {
|
|
26
37
|
control: 'select',
|
|
27
38
|
options: ['light', 'dark'],
|
|
@@ -47,45 +58,88 @@ export const Default: Story = {
|
|
|
47
58
|
elevation: 2,
|
|
48
59
|
theme: 'dark',
|
|
49
60
|
},
|
|
50
|
-
render: (args)
|
|
51
|
-
|
|
52
|
-
<
|
|
53
|
-
|
|
54
|
-
|
|
61
|
+
render: function Render(args) {
|
|
62
|
+
return (
|
|
63
|
+
<Surface {...args} style={{ padding: 24 }}>
|
|
64
|
+
<Text style={{ color: useOnSurfaceColor('primary') }}>Default Surface</Text>
|
|
65
|
+
</Surface>
|
|
66
|
+
)
|
|
67
|
+
},
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** On-surface elevation label — resolves from whichever Surface encloses it. */
|
|
71
|
+
function ElevationLabel({ level }: { level: ElevationLevel }) {
|
|
72
|
+
return <Text style={{ color: useOnSurfaceColor('primary') }}>Elevation {level}</Text>
|
|
55
73
|
}
|
|
56
74
|
|
|
75
|
+
// Every level is a ramp plane. Negative levels recess, 0 sits flat on the page,
|
|
76
|
+
// 1–3 climb one plane each with the lift treatment, 4–5 float on overlay with a
|
|
77
|
+
// larger shadow. Rendered on a `base` page so the relative model has a host.
|
|
57
78
|
export const ElevationLevels: Story = {
|
|
58
79
|
render: () => (
|
|
59
|
-
<
|
|
80
|
+
<Surface level="base" style={{ gap: 16, padding: 24 }}>
|
|
60
81
|
{([-2, -1, 0, 1, 2, 3, 4, 5] as ElevationLevel[]).map((level) => (
|
|
61
82
|
<Surface key={level} elevation={level} style={{ padding: 16 }}>
|
|
62
|
-
<
|
|
83
|
+
<ElevationLabel level={level} />
|
|
63
84
|
</Surface>
|
|
64
85
|
))}
|
|
65
|
-
</
|
|
86
|
+
</Surface>
|
|
66
87
|
),
|
|
67
88
|
}
|
|
68
89
|
|
|
69
90
|
export const WithGlow: Story = {
|
|
70
|
-
render: ()
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
<
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
91
|
+
render: function Render() {
|
|
92
|
+
const onSurface = useOnSurfaceColor('primary')
|
|
93
|
+
return (
|
|
94
|
+
<View style={{ gap: 16, padding: 24 }}>
|
|
95
|
+
<Surface
|
|
96
|
+
elevation={2}
|
|
97
|
+
glowColor={primitiveRamps.orange[400]}
|
|
98
|
+
glowIntensity="subtle"
|
|
99
|
+
style={{ padding: 16 }}
|
|
100
|
+
>
|
|
101
|
+
<Text style={{ color: onSurface }}>Subtle Orange Glow</Text>
|
|
102
|
+
</Surface>
|
|
103
|
+
<Surface
|
|
104
|
+
elevation={2}
|
|
105
|
+
glowColor={primitiveRamps.orange[400]}
|
|
106
|
+
glowIntensity="medium"
|
|
107
|
+
style={{ padding: 16 }}
|
|
108
|
+
>
|
|
109
|
+
<Text style={{ color: onSurface }}>Medium Orange Glow</Text>
|
|
110
|
+
</Surface>
|
|
111
|
+
<Surface
|
|
112
|
+
elevation={2}
|
|
113
|
+
glowColor={primitiveRamps.orange[400]}
|
|
114
|
+
glowIntensity="strong"
|
|
115
|
+
style={{ padding: 16 }}
|
|
116
|
+
>
|
|
117
|
+
<Text style={{ color: onSurface }}>Strong Orange Glow</Text>
|
|
118
|
+
</Surface>
|
|
119
|
+
<Surface
|
|
120
|
+
elevation={2}
|
|
121
|
+
glowColor={semanticColorsDark['status-success']}
|
|
122
|
+
glowIntensity="medium"
|
|
123
|
+
style={{ padding: 16 }}
|
|
124
|
+
>
|
|
125
|
+
<Text style={{ color: onSurface }}>Green Glow (Success)</Text>
|
|
126
|
+
</Surface>
|
|
127
|
+
<Surface
|
|
128
|
+
elevation={2}
|
|
129
|
+
glowColor={semanticColorsDark['status-error']}
|
|
130
|
+
glowIntensity="medium"
|
|
131
|
+
style={{ padding: 16 }}
|
|
132
|
+
>
|
|
133
|
+
<Text style={{ color: onSurface }}>Red Glow (Error)</Text>
|
|
134
|
+
</Surface>
|
|
135
|
+
</View>
|
|
136
|
+
)
|
|
137
|
+
},
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** On-surface plane label — resolves from whichever Surface encloses it. */
|
|
141
|
+
function NamedPlaneLabel({ level }: { level: SurfaceLevel }) {
|
|
142
|
+
return <Text style={{ color: useOnSurfaceColor('primary') }}>level="{level}"</Text>
|
|
89
143
|
}
|
|
90
144
|
|
|
91
145
|
// The named-plane model: flat, full-bleed grey planes straight from the
|
|
@@ -96,7 +150,7 @@ export const NamedPlanes: Story = {
|
|
|
96
150
|
<View style={{ gap: 12, padding: 24 }}>
|
|
97
151
|
{(['background', 'base', 'elevated', 'raised', 'overlay'] as SurfaceLevel[]).map((level) => (
|
|
98
152
|
<Surface key={level} level={level} style={{ padding: 16 }}>
|
|
99
|
-
<
|
|
153
|
+
<NamedPlaneLabel level={level} />
|
|
100
154
|
</Surface>
|
|
101
155
|
))}
|
|
102
156
|
</View>
|
|
@@ -187,12 +241,17 @@ export const OnSurfaceText: Story = {
|
|
|
187
241
|
),
|
|
188
242
|
}
|
|
189
243
|
|
|
244
|
+
/** On-surface elevation label for the forced-light demo below. */
|
|
245
|
+
function LightElevationLabel({ level }: { level: ElevationLevel }) {
|
|
246
|
+
return <Text style={{ color: useOnSurfaceColor('primary') }}>Light Elevation {level}</Text>
|
|
247
|
+
}
|
|
248
|
+
|
|
190
249
|
export const LightTheme: Story = {
|
|
191
250
|
render: () => (
|
|
192
|
-
<View style={{ gap: 16, padding: 24, backgroundColor: '
|
|
251
|
+
<View style={{ gap: 16, padding: 24, backgroundColor: semanticColorsLight['background-base'] }}>
|
|
193
252
|
{([0, 1, 2, 3, 4, 5] as ElevationLevel[]).map((level) => (
|
|
194
253
|
<Surface key={level} elevation={level} theme="light" style={{ padding: 16 }}>
|
|
195
|
-
<
|
|
254
|
+
<LightElevationLabel level={level} />
|
|
196
255
|
</Surface>
|
|
197
256
|
))}
|
|
198
257
|
</View>
|
|
@@ -12,8 +12,21 @@ import {
|
|
|
12
12
|
useSurfaceMode,
|
|
13
13
|
} from './SurfaceContext'
|
|
14
14
|
import { getSemanticColors } from '../../../theme/tokens/semantic'
|
|
15
|
+
import { greyRamp, primitiveColors } from '../../../theme/tokens/primitives'
|
|
15
16
|
import { getPressedRecessShadow } from '../../../theme/elevation'
|
|
16
17
|
|
|
18
|
+
// Planes by RAMP STEP, never by literal bytes: a re-space of the grey ramp
|
|
19
|
+
// should move these expectations with it, not break them. Which step backs
|
|
20
|
+
// which plane is still asserted — that mapping is the behaviour.
|
|
21
|
+
const FRAME = greyRamp[975]
|
|
22
|
+
const BACKGROUND = greyRamp[950]
|
|
23
|
+
const BASE = greyRamp[925]
|
|
24
|
+
const ELEVATED = greyRamp[900]
|
|
25
|
+
const RAISED = greyRamp[875]
|
|
26
|
+
const OVERLAY = greyRamp[850]
|
|
27
|
+
const LIGHT_BASE = primitiveColors.white
|
|
28
|
+
const LIGHT_TEXT_PRIMARY = getSemanticColors('light')['text-primary']
|
|
29
|
+
|
|
17
30
|
// A descendant probe that renders the on-surface colour + mode it resolves from
|
|
18
31
|
// context, so tests can assert what a nested consumer would actually paint.
|
|
19
32
|
function Probe({ role = 'primary' as const, label = 'probe' }) {
|
|
@@ -72,11 +85,56 @@ describe('Surface (card model)', () => {
|
|
|
72
85
|
expect(screen.getByTestId('my-surface')).toBeInTheDocument()
|
|
73
86
|
})
|
|
74
87
|
|
|
75
|
-
it('
|
|
88
|
+
it('sits flat on the inherited plane by default (dark base, no treatment)', () => {
|
|
76
89
|
render(<Surface testID="s" />)
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
expect(
|
|
90
|
+
const el = screen.getByTestId('s')
|
|
91
|
+
expect(el).toHaveStyle({ backgroundColor: BASE })
|
|
92
|
+
expect(el.style.boxShadow).toBe('')
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
it('lifts onto ramp planes with rim + shadow: elevation 2 from the page is the card plane', () => {
|
|
96
|
+
render(<Surface elevation={2} testID="s" />)
|
|
97
|
+
const el = screen.getByTestId('s')
|
|
98
|
+
expect(el).toHaveStyle({ backgroundColor: RAISED })
|
|
99
|
+
expect(el.style.boxShadow).toContain('inset 0 1px 0')
|
|
100
|
+
expect(el.style.boxShadow).toMatch(/, 0 \d+px \d+px rgba\(0,0,0/)
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
it('raise is relative: one step up from an elevated host lands on raised', () => {
|
|
104
|
+
render(
|
|
105
|
+
<Surface level="elevated">
|
|
106
|
+
<Surface raise={1} testID="s" />
|
|
107
|
+
</Surface>
|
|
108
|
+
)
|
|
109
|
+
expect(screen.getByTestId('s')).toHaveStyle({ backgroundColor: RAISED })
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
it('clamps at overlay so raised-on-raised cannot leave the ramp', () => {
|
|
113
|
+
render(
|
|
114
|
+
<Surface level="overlay">
|
|
115
|
+
<Surface raise={2} testID="s" />
|
|
116
|
+
</Surface>
|
|
117
|
+
)
|
|
118
|
+
expect(screen.getByTestId('s')).toHaveStyle({ backgroundColor: OVERLAY })
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
it('floats on the overlay plane with a larger shadow and no ring', () => {
|
|
122
|
+
render(<Surface elevation={4} testID="s" />)
|
|
123
|
+
const el = screen.getByTestId('s')
|
|
124
|
+
expect(el).toHaveStyle({ backgroundColor: OVERLAY })
|
|
125
|
+
expect(el.style.boxShadow.split(', ').length).toBe(4)
|
|
126
|
+
expect(el.style.borderWidth).toBe('')
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
it('lets a caller switch the lift off on a raised plane, or on for a named one', () => {
|
|
130
|
+
render(
|
|
131
|
+
<>
|
|
132
|
+
<Surface raise={1} lift={false} testID="flat" />
|
|
133
|
+
<Surface level="raised" lift testID="lifted" />
|
|
134
|
+
</>
|
|
135
|
+
)
|
|
136
|
+
expect(screen.getByTestId('flat').style.boxShadow).toBe('')
|
|
137
|
+
expect(screen.getByTestId('lifted').style.boxShadow).toContain('inset 0 1px 0')
|
|
80
138
|
})
|
|
81
139
|
|
|
82
140
|
describe('accessibility', () => {
|
|
@@ -94,10 +152,10 @@ describe('Surface (card model)', () => {
|
|
|
94
152
|
|
|
95
153
|
describe('Surface (named plane)', () => {
|
|
96
154
|
it.each([
|
|
97
|
-
['background',
|
|
98
|
-
['base',
|
|
99
|
-
['elevated',
|
|
100
|
-
['raised',
|
|
155
|
+
['background', BACKGROUND],
|
|
156
|
+
['base', BASE],
|
|
157
|
+
['elevated', ELEVATED],
|
|
158
|
+
['raised', RAISED],
|
|
101
159
|
] as const)('maps level %s to the surface-ramp token %s', (level, hex) => {
|
|
102
160
|
render(<Surface level={level} testID="s" />)
|
|
103
161
|
expect(screen.getByTestId('s')).toHaveStyle({ backgroundColor: hex })
|
|
@@ -105,7 +163,7 @@ describe('Surface (named plane)', () => {
|
|
|
105
163
|
|
|
106
164
|
it('resolves the light-mode background when theme is overridden', () => {
|
|
107
165
|
render(<Surface level="base" theme="light" testID="s" />)
|
|
108
|
-
expect(screen.getByTestId('s')).toHaveStyle({ backgroundColor:
|
|
166
|
+
expect(screen.getByTestId('s')).toHaveStyle({ backgroundColor: LIGHT_BASE })
|
|
109
167
|
})
|
|
110
168
|
|
|
111
169
|
it('lets a caller style override the owned background', () => {
|
|
@@ -134,12 +192,12 @@ function lstar(hex: string): number {
|
|
|
134
192
|
|
|
135
193
|
describe('Surface (pressed well)', () => {
|
|
136
194
|
it.each([
|
|
137
|
-
// TD-surface-tokens S-3 re-space
|
|
138
|
-
//
|
|
139
|
-
['overlay',
|
|
140
|
-
['raised',
|
|
141
|
-
['elevated',
|
|
142
|
-
['base',
|
|
195
|
+
// TD-surface-tokens S-3 re-space widened the top steps; base and
|
|
196
|
+
// background were unchanged. The pairs below are ramp-adjacent by index.
|
|
197
|
+
['overlay', OVERLAY, RAISED], // → raised
|
|
198
|
+
['raised', RAISED, ELEVATED], // → elevated
|
|
199
|
+
['elevated', ELEVATED, BASE], // → base
|
|
200
|
+
['base', BASE, BACKGROUND], // → background
|
|
143
201
|
] as const)(
|
|
144
202
|
'in a %s parent renders one ramp step down (%s → %s), darker than its parent',
|
|
145
203
|
(parent, parentHex, pressedHex) => {
|
|
@@ -155,7 +213,7 @@ describe('Surface (pressed well)', () => {
|
|
|
155
213
|
|
|
156
214
|
it('with no enclosing Surface (default base) presses to the background plane', () => {
|
|
157
215
|
render(<Surface pressed testID="well" />)
|
|
158
|
-
expect(screen.getByTestId('well')).toHaveStyle({ backgroundColor:
|
|
216
|
+
expect(screen.getByTestId('well')).toHaveStyle({ backgroundColor: BACKGROUND })
|
|
159
217
|
})
|
|
160
218
|
|
|
161
219
|
it('clamps at the frame floor: pressed directly in background does not underflow', () => {
|
|
@@ -164,8 +222,8 @@ describe('Surface (pressed well)', () => {
|
|
|
164
222
|
<Surface pressed testID="well" />
|
|
165
223
|
</Surface>
|
|
166
224
|
)
|
|
167
|
-
// background
|
|
168
|
-
expect(screen.getByTestId('well')).toHaveStyle({ backgroundColor:
|
|
225
|
+
// background steps down to the frame floor, the bezel.
|
|
226
|
+
expect(screen.getByTestId('well')).toHaveStyle({ backgroundColor: FRAME })
|
|
169
227
|
})
|
|
170
228
|
|
|
171
229
|
it('does not step below the floor: pressed within a floor-pressed well stays at frame', () => {
|
|
@@ -176,7 +234,7 @@ describe('Surface (pressed well)', () => {
|
|
|
176
234
|
</Surface>
|
|
177
235
|
</Surface>
|
|
178
236
|
)
|
|
179
|
-
expect(screen.getByTestId('deeper')).toHaveStyle({ backgroundColor:
|
|
237
|
+
expect(screen.getByTestId('deeper')).toHaveStyle({ backgroundColor: FRAME })
|
|
180
238
|
})
|
|
181
239
|
|
|
182
240
|
it('publishes the stepped-down level to descendants so a nested press steps again', () => {
|
|
@@ -209,8 +267,8 @@ describe('Surface (pressed well)', () => {
|
|
|
209
267
|
<Surface pressed testID="well" style={{ boxShadow: undefined }} />
|
|
210
268
|
</Surface>
|
|
211
269
|
)
|
|
212
|
-
expect(screen.getByTestId('well')).toHaveStyle({ backgroundColor:
|
|
213
|
-
expect(lstar(
|
|
270
|
+
expect(screen.getByTestId('well')).toHaveStyle({ backgroundColor: BACKGROUND })
|
|
271
|
+
expect(lstar(BACKGROUND)).toBeLessThan(lstar(BASE))
|
|
214
272
|
})
|
|
215
273
|
|
|
216
274
|
it('rounds the well by default and honours an explicit rounded override', () => {
|
|
@@ -240,7 +298,7 @@ describe('pressedLevel helper', () => {
|
|
|
240
298
|
|
|
241
299
|
describe('getPressedRecessShadow', () => {
|
|
242
300
|
it('returns an inset recess tuned to the fill colour on the web path', () => {
|
|
243
|
-
const style = getPressedRecessShadow(
|
|
301
|
+
const style = getPressedRecessShadow(BACKGROUND, 'dark') as { boxShadow?: string }
|
|
244
302
|
expect(style.boxShadow).toContain('inset')
|
|
245
303
|
})
|
|
246
304
|
})
|
|
@@ -262,7 +320,9 @@ describe('Surface on-surface colour context', () => {
|
|
|
262
320
|
|
|
263
321
|
it('resolves dark on-surface colours even with no enclosing Surface', () => {
|
|
264
322
|
render(<Probe role="primary" label="p" />)
|
|
265
|
-
expect(screen.getByTestId('p')).toHaveStyle({
|
|
323
|
+
expect(screen.getByTestId('p')).toHaveStyle({
|
|
324
|
+
color: getSemanticColors('dark')['text-primary'],
|
|
325
|
+
})
|
|
266
326
|
})
|
|
267
327
|
|
|
268
328
|
it('flows an overridden theme to descendant text', () => {
|
|
@@ -271,7 +331,7 @@ describe('Surface on-surface colour context', () => {
|
|
|
271
331
|
<Probe role="primary" label="p" />
|
|
272
332
|
</Surface>
|
|
273
333
|
)
|
|
274
|
-
expect(screen.getByTestId('p')).toHaveStyle({ color:
|
|
334
|
+
expect(screen.getByTestId('p')).toHaveStyle({ color: LIGHT_TEXT_PRIMARY })
|
|
275
335
|
expect(screen.getByTestId('p')).toHaveTextContent('light')
|
|
276
336
|
})
|
|
277
337
|
|
|
@@ -283,15 +343,15 @@ describe('Surface on-surface colour context', () => {
|
|
|
283
343
|
</Surface>
|
|
284
344
|
</Surface>
|
|
285
345
|
)
|
|
286
|
-
expect(screen.getByTestId('p')).toHaveStyle({ color:
|
|
346
|
+
expect(screen.getByTestId('p')).toHaveStyle({ color: LIGHT_TEXT_PRIMARY })
|
|
287
347
|
})
|
|
288
348
|
})
|
|
289
349
|
|
|
290
350
|
describe('surface colour helpers', () => {
|
|
291
351
|
it('surfaceBackground returns literal hex per level + mode', () => {
|
|
292
|
-
expect(surfaceBackground('elevated', 'dark')).toBe(
|
|
293
|
-
expect(surfaceBackground('background', 'dark')).toBe(
|
|
294
|
-
expect(surfaceBackground('base', 'light')).toBe(
|
|
352
|
+
expect(surfaceBackground('elevated', 'dark')).toBe(ELEVATED)
|
|
353
|
+
expect(surfaceBackground('background', 'dark')).toBe(BACKGROUND)
|
|
354
|
+
expect(surfaceBackground('base', 'light')).toBe(LIGHT_BASE)
|
|
295
355
|
})
|
|
296
356
|
|
|
297
357
|
it('resolves the frame floor from its own semantic token', () => {
|