@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,57 +1,14 @@
|
|
|
1
1
|
import React, { useMemo } from 'react'
|
|
2
|
-
import { View, type ViewProps
|
|
2
|
+
import { View, type ViewProps } from 'react-native'
|
|
3
3
|
import { cn } from '../../../utils/cn'
|
|
4
|
-
import { type
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
getElevationSurface,
|
|
8
|
-
getElevationShadow,
|
|
9
|
-
getPressedRecessShadow,
|
|
10
|
-
getBaseSurfaceColor,
|
|
11
|
-
type GlowIntensity,
|
|
12
|
-
getGlowShadow,
|
|
13
|
-
} from '../../../theme/elevation'
|
|
14
|
-
import {
|
|
15
|
-
SurfaceContext,
|
|
16
|
-
surfaceBackground,
|
|
17
|
-
pressedLevel,
|
|
18
|
-
useSurface,
|
|
19
|
-
type SurfaceContextValue,
|
|
20
|
-
type SurfaceLevel,
|
|
21
|
-
} from './SurfaceContext'
|
|
4
|
+
import { type GlowIntensity, getGlowShadow } from '../../../theme/elevation'
|
|
5
|
+
import { SurfaceContext, type SurfaceContextValue } from './SurfaceContext'
|
|
6
|
+
import { useResolvedSurface, type SurfaceDepthProps } from './resolveSurface'
|
|
22
7
|
|
|
23
|
-
export interface SurfaceProps extends ViewProps {
|
|
24
|
-
/**
|
|
25
|
-
* Numeric depth → a computed lighten + shadow (the raised-card model). The
|
|
26
|
-
* background is derived from the base surface by lightening. Ignored for the
|
|
27
|
-
* background when `level` is set. Default 0 (flat card).
|
|
28
|
-
*/
|
|
29
|
-
elevation?: ElevationLevel
|
|
30
|
-
/**
|
|
31
|
-
* Named grey plane (shell / rail / stage). Sets the background directly
|
|
32
|
-
* from a semantic surface token — reaching the darker nav/page planes the
|
|
33
|
-
* lighten model can't — and drops the default rounding + auto shadow so the
|
|
34
|
-
* plane reads full-bleed. Composable with `elevation`'s glow.
|
|
35
|
-
*/
|
|
36
|
-
level?: SurfaceLevel
|
|
37
|
-
/**
|
|
38
|
-
* Sunken "well": render ONE ramp step DOWN from the parent surface's level —
|
|
39
|
-
* the symmetric twin of a raised surface stepping up — and add an inner-shadow
|
|
40
|
-
* recess so the surface reads pressed (darker fill + inset shadow). Relative to
|
|
41
|
-
* the enclosing Surface's level (not this surface's own `level`), and clamped
|
|
42
|
-
* at the ramp's `inset` floor so it never underflows. One level of depth only.
|
|
43
|
-
*/
|
|
44
|
-
pressed?: boolean
|
|
8
|
+
export interface SurfaceProps extends ViewProps, SurfaceDepthProps {
|
|
45
9
|
glowColor?: string
|
|
46
10
|
glowIntensity?: GlowIntensity
|
|
47
|
-
/**
|
|
48
|
-
* Theme mode. Also seeds the on-surface colour CONTEXT so descendant text /
|
|
49
|
-
* icons resolve their colour from this surface instead of a `text-*` className
|
|
50
|
-
* that silently fails to black on raw RN. Inherits the nearest Surface /
|
|
51
|
-
* ThemeProvider when omitted (default dark — the wall).
|
|
52
|
-
*/
|
|
53
|
-
theme?: ThemeMode
|
|
54
|
-
/** Round the corners. Defaults on for the card model, off for a `level` plane. */
|
|
11
|
+
/** Round the corners. Defaults on for a lifted or pressed surface, off for an absolute plane. */
|
|
55
12
|
rounded?: boolean
|
|
56
13
|
className?: string
|
|
57
14
|
children?: React.ReactNode
|
|
@@ -59,17 +16,23 @@ export interface SurfaceProps extends ViewProps {
|
|
|
59
16
|
|
|
60
17
|
/**
|
|
61
18
|
* A container that OWNS its background and establishes an on-surface colour
|
|
62
|
-
* context.
|
|
63
|
-
* - `
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
19
|
+
* context. Depth is relative to the enclosing Surface:
|
|
20
|
+
* - `raise` / positive `elevation`: step up the ramp and wear the lift
|
|
21
|
+
* treatment (rim-light + ambient shadow). Clamps at `overlay`.
|
|
22
|
+
* - `pressed` / negative `elevation`: step down with an inner-shadow recess.
|
|
23
|
+
* - `level` (absolute): a flat grey plane straight from a token, for shell
|
|
24
|
+
* roots only (shell = background, page = base). No lift.
|
|
25
|
+
* - nothing: sit flat on the inherited plane.
|
|
26
|
+
* Descendants read the surface via {@link useOnSurfaceColor} / {@link useSurfaceMode}
|
|
27
|
+
* rather than hard-coding `getSemanticColors('dark')`.
|
|
68
28
|
*/
|
|
69
29
|
export function Surface({
|
|
70
|
-
elevation
|
|
30
|
+
elevation,
|
|
71
31
|
level,
|
|
32
|
+
raise,
|
|
72
33
|
pressed = false,
|
|
34
|
+
lift,
|
|
35
|
+
liftOptions,
|
|
73
36
|
glowColor,
|
|
74
37
|
glowIntensity,
|
|
75
38
|
theme,
|
|
@@ -79,39 +42,21 @@ export function Surface({
|
|
|
79
42
|
children,
|
|
80
43
|
...props
|
|
81
44
|
}: SurfaceProps) {
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
const baseColor = getBaseSurfaceColor(mode)
|
|
92
|
-
const resolvedLevel = pressed ? pressedLevel(inherited.level) : (level ?? inherited.level)
|
|
93
|
-
|
|
94
|
-
let backgroundColor: string
|
|
95
|
-
let shadowStyle: ViewStyle
|
|
96
|
-
if (pressed) {
|
|
97
|
-
backgroundColor = surfaceBackground(resolvedLevel, mode)
|
|
98
|
-
shadowStyle = getPressedRecessShadow(backgroundColor, mode)
|
|
99
|
-
} else if (isPlane) {
|
|
100
|
-
backgroundColor = surfaceBackground(level, mode)
|
|
101
|
-
// Planes own a flat full-bleed background — no depth shadow.
|
|
102
|
-
shadowStyle = {}
|
|
103
|
-
} else {
|
|
104
|
-
backgroundColor = getElevationSurface(baseColor, elevation, mode)
|
|
105
|
-
shadowStyle = getElevationShadow(baseColor, elevation, mode)
|
|
106
|
-
}
|
|
107
|
-
|
|
45
|
+
const resolved = useResolvedSurface({
|
|
46
|
+
elevation,
|
|
47
|
+
level,
|
|
48
|
+
raise,
|
|
49
|
+
pressed,
|
|
50
|
+
lift,
|
|
51
|
+
liftOptions,
|
|
52
|
+
theme,
|
|
53
|
+
})
|
|
108
54
|
const glowStyle = glowColor ? getGlowShadow(glowColor, glowIntensity) : {}
|
|
109
|
-
|
|
110
|
-
const applyRounded = rounded ?? (pressed || !isPlane)
|
|
55
|
+
const applyRounded = rounded ?? (pressed || level == null)
|
|
111
56
|
|
|
112
57
|
const value = useMemo<SurfaceContextValue>(
|
|
113
|
-
() => ({ mode, level:
|
|
114
|
-
[mode,
|
|
58
|
+
() => ({ mode: resolved.mode, level: resolved.plane }),
|
|
59
|
+
[resolved.mode, resolved.plane]
|
|
115
60
|
)
|
|
116
61
|
|
|
117
62
|
return (
|
|
@@ -119,7 +64,12 @@ export function Surface({
|
|
|
119
64
|
<View
|
|
120
65
|
className={cn(applyRounded && 'rounded-2xl', className)}
|
|
121
66
|
// backgroundColor first so a caller `style` can still override it.
|
|
122
|
-
style={[
|
|
67
|
+
style={[
|
|
68
|
+
{ backgroundColor: resolved.backgroundColor },
|
|
69
|
+
resolved.depthStyle,
|
|
70
|
+
glowStyle,
|
|
71
|
+
style,
|
|
72
|
+
]}
|
|
123
73
|
{...props}
|
|
124
74
|
>
|
|
125
75
|
{children}
|
|
@@ -1,52 +1,31 @@
|
|
|
1
1
|
// On-surface colour context (TD-05.12).
|
|
2
2
|
//
|
|
3
|
-
// A <Surface> owns a background from
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
3
|
+
// A <Surface> owns a background from the surface ramp AND publishes the current
|
|
4
|
+
// theme mode so descendant text/icons resolve their colour from "what surface am
|
|
5
|
+
// I on" instead of a `text-*` className. Those classNames silently fail to black
|
|
6
|
+
// when the tree renders as raw RN in the standalone wall SPA (no global.css, no
|
|
7
|
+
// nativewind), which is the bug class this primitive retires.
|
|
8
8
|
import { createContext, useContext } from 'react'
|
|
9
9
|
import { getSemanticColors, type ThemeMode } from '../../../theme/tokens/semantic'
|
|
10
|
+
import type { SurfaceLevel } from '../../../theme/surface-planes'
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
// The plane vocabulary lives in the theme so `elevation.ts` can resolve levels
|
|
13
|
+
// to planes without importing a component. Re-exported here for callers that
|
|
14
|
+
// reached it through the Surface module.
|
|
15
|
+
export {
|
|
16
|
+
SURFACE_LEVEL_TOKEN,
|
|
17
|
+
PLANE_ORDER,
|
|
18
|
+
surfaceBackground,
|
|
19
|
+
pressedLevel,
|
|
20
|
+
raisedLevel,
|
|
21
|
+
type SurfaceLevel,
|
|
22
|
+
} from '../../../theme/surface-planes'
|
|
12
23
|
|
|
13
|
-
|
|
14
|
-
* A Surface's depth on the dark surface ramp. Each addressable level maps to an
|
|
15
|
-
* EXISTING semantic surface/background token (already grounded in the derived
|
|
16
|
-
* surface ramp — TD-surface-tokens S-1 — and theme-aware) — Surface introduces
|
|
17
|
-
* no new hexes. Darkest → lightest:
|
|
18
|
-
* inset (#13100D) < background (#1C1916) < base (#252321) < elevated (#2A2827) < raised (#2D2C2B) < overlay (#302F2E)
|
|
19
|
-
*
|
|
20
|
-
* `frame` is the bezel the ramp sits inside — the top bar / side nav chrome —
|
|
21
|
-
* and the floor a `<Surface pressed>` clamps at (see {@link pressedLevel}).
|
|
22
|
-
*
|
|
23
|
-
* It replaced a separate `inset` level in TD-07.14. That level was RETIRED, not
|
|
24
|
-
* renamed: at ΔE 1.10 from the frame it was an imperceptible duplicate, which is
|
|
25
|
-
* exactly why pressed (surface − 1) kept collapsing into it.
|
|
26
|
-
*/
|
|
27
|
-
export type SurfaceLevel = 'frame' | 'background' | 'base' | 'elevated' | 'raised' | 'overlay'
|
|
24
|
+
type ColorToken = keyof ReturnType<typeof getSemanticColors>
|
|
28
25
|
|
|
29
26
|
/** On-surface neutral text roles, resolved for the current surface + theme. */
|
|
30
27
|
export type OnSurfaceRole = 'primary' | 'secondary' | 'tertiary'
|
|
31
28
|
|
|
32
|
-
// Which semantic token backs each level. Values live in `semantic.ts` and stay
|
|
33
|
-
// in sync with the grey ramp — this map never carries literal hexes. Every level
|
|
34
|
-
// is present now: swapping `inset` (which had no token) for `frame` (which does)
|
|
35
|
-
// is what made this a total map and removed `surfaceBackground`'s special case.
|
|
36
|
-
export const SURFACE_LEVEL_TOKEN = {
|
|
37
|
-
frame: 'background-frame',
|
|
38
|
-
background: 'background-base',
|
|
39
|
-
base: 'surface-base',
|
|
40
|
-
elevated: 'surface-elevated',
|
|
41
|
-
raised: 'surface-raised',
|
|
42
|
-
overlay: 'surface-overlay',
|
|
43
|
-
} as const satisfies Record<SurfaceLevel, ColorToken>
|
|
44
|
-
|
|
45
|
-
// Darkest → lightest. A `<Surface pressed>` renders one index DOWN from its
|
|
46
|
-
// parent's level and clamps at `frame` (index 0). Kept in lockstep with the grey
|
|
47
|
-
// ramp and the surface.contract.test PLANE_ORDER.
|
|
48
|
-
const PRESSED_RAMP = ['frame', 'background', 'base', 'elevated', 'raised', 'overlay'] as const
|
|
49
|
-
|
|
50
29
|
const ON_SURFACE_TOKEN = {
|
|
51
30
|
primary: 'text-primary',
|
|
52
31
|
secondary: 'text-secondary',
|
|
@@ -56,7 +35,7 @@ const ON_SURFACE_TOKEN = {
|
|
|
56
35
|
export interface SurfaceContextValue {
|
|
57
36
|
/** Active theme mode. Defaults to dark (the wall). */
|
|
58
37
|
mode: ThemeMode
|
|
59
|
-
/**
|
|
38
|
+
/** Plane of the nearest enclosing Surface. */
|
|
60
39
|
level: SurfaceLevel
|
|
61
40
|
}
|
|
62
41
|
|
|
@@ -78,9 +57,9 @@ export function useSurfaceMode(): ThemeMode {
|
|
|
78
57
|
|
|
79
58
|
/**
|
|
80
59
|
* Literal-hex on-surface neutral text colours for a theme mode. Uses
|
|
81
|
-
* `getSemanticColors` (literal hex
|
|
82
|
-
*
|
|
83
|
-
*
|
|
60
|
+
* `getSemanticColors` (literal hex), never `resolveColor` (which returns `var()`
|
|
61
|
+
* under the RNW vitest alias), so values stay real in tested component code and
|
|
62
|
+
* on raw-RN surfaces alike.
|
|
84
63
|
*/
|
|
85
64
|
export function onSurfaceColors(mode: ThemeMode): Record<OnSurfaceRole, string> {
|
|
86
65
|
const c = getSemanticColors(mode)
|
|
@@ -95,22 +74,3 @@ export function onSurfaceColors(mode: ThemeMode): Record<OnSurfaceRole, string>
|
|
|
95
74
|
export function useOnSurfaceColor(role: OnSurfaceRole = 'primary'): string {
|
|
96
75
|
return getSemanticColors(useSurfaceMode())[ON_SURFACE_TOKEN[role]]
|
|
97
76
|
}
|
|
98
|
-
|
|
99
|
-
/** The background hex for a surface level under a theme mode (literal hex). */
|
|
100
|
-
export function surfaceBackground(level: SurfaceLevel, mode: ThemeMode): string {
|
|
101
|
-
return getSemanticColors(mode)[SURFACE_LEVEL_TOKEN[level]]
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* The level a `<Surface pressed>` resolves to: its parent's level stepped one
|
|
106
|
-
* index DOWN the ramp — the symmetric twin of a raised surface stepping up —
|
|
107
|
-
* clamped at the `frame` floor so a pressed surface never underflows the bezel.
|
|
108
|
-
* overlay→raised, raised→elevated, elevated→base, base→background,
|
|
109
|
-
* background→frame, frame→frame (clamped).
|
|
110
|
-
* Pressed exposes ONE level of depth only (no pressed-2).
|
|
111
|
-
*/
|
|
112
|
-
export function pressedLevel(parent: SurfaceLevel): SurfaceLevel {
|
|
113
|
-
const index = PRESSED_RAMP.indexOf(parent)
|
|
114
|
-
const down = Math.max(0, index - 1)
|
|
115
|
-
return PRESSED_RAMP[down]
|
|
116
|
-
}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
export { Surface, type SurfaceProps } from './Surface'
|
|
2
|
+
export {
|
|
3
|
+
resolveSurfaceDepth,
|
|
4
|
+
useResolvedSurface,
|
|
5
|
+
type SurfaceDepthProps,
|
|
6
|
+
type ResolvedSurface,
|
|
7
|
+
} from './resolveSurface'
|
|
2
8
|
export {
|
|
3
9
|
SurfaceContext,
|
|
4
10
|
useSurface,
|
|
@@ -7,7 +13,9 @@ export {
|
|
|
7
13
|
onSurfaceColors,
|
|
8
14
|
surfaceBackground,
|
|
9
15
|
pressedLevel,
|
|
16
|
+
raisedLevel,
|
|
10
17
|
SURFACE_LEVEL_TOKEN,
|
|
18
|
+
PLANE_ORDER,
|
|
11
19
|
type SurfaceLevel,
|
|
12
20
|
type OnSurfaceRole,
|
|
13
21
|
type SurfaceContextValue,
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// How a container decides which plane it sits on and what it wears there.
|
|
2
|
+
//
|
|
3
|
+
// One resolution path shared by <Surface> and <Card>, so the two can never
|
|
4
|
+
// disagree about depth. Everything is RELATIVE to the enclosing Surface unless
|
|
5
|
+
// an absolute `level` names a shell root.
|
|
6
|
+
import { useMemo } from 'react'
|
|
7
|
+
import type { ViewStyle } from 'react-native'
|
|
8
|
+
import {
|
|
9
|
+
FLOATING_ELEVATION_MIN,
|
|
10
|
+
getPressedRecessShadow,
|
|
11
|
+
type ElevationLevel,
|
|
12
|
+
} from '../../../theme/elevation'
|
|
13
|
+
import { liftStyle, type LiftOptions, type LiftStep } from '../../../theme/lift'
|
|
14
|
+
import {
|
|
15
|
+
pressedLevel,
|
|
16
|
+
raisedLevel,
|
|
17
|
+
surfaceBackground,
|
|
18
|
+
type SurfaceLevel,
|
|
19
|
+
} from '../../../theme/surface-planes'
|
|
20
|
+
import type { ThemeMode } from '../../../theme/tokens/semantic'
|
|
21
|
+
import { useSurface, type SurfaceContextValue } from './SurfaceContext'
|
|
22
|
+
|
|
23
|
+
export interface SurfaceDepthProps {
|
|
24
|
+
/** Absolute plane, for shell roots (shell = background, page = base). No lift. */
|
|
25
|
+
level?: SurfaceLevel
|
|
26
|
+
/** Planes to step UP from the enclosing Surface, with the lift treatment. */
|
|
27
|
+
raise?: 1 | 2 | 3
|
|
28
|
+
/**
|
|
29
|
+
* Numeric depth relative to the enclosing Surface: negative recesses, 0 sits
|
|
30
|
+
* flat on the same plane, 1–3 lift, 4–5 float on the overlay plane.
|
|
31
|
+
*/
|
|
32
|
+
elevation?: ElevationLevel
|
|
33
|
+
/** One plane DOWN with an inner-shadow recess. */
|
|
34
|
+
pressed?: boolean
|
|
35
|
+
/** Force the lift treatment on or off regardless of the step taken. */
|
|
36
|
+
lift?: boolean
|
|
37
|
+
/** Tune the lift (rim alpha). Specimens and hero surfaces only. */
|
|
38
|
+
liftOptions?: LiftOptions
|
|
39
|
+
/** Override the inherited theme mode. */
|
|
40
|
+
theme?: ThemeMode
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface ResolvedSurface {
|
|
44
|
+
mode: ThemeMode
|
|
45
|
+
plane: SurfaceLevel
|
|
46
|
+
backgroundColor: string
|
|
47
|
+
/** Recess or lift, to compose after `backgroundColor`. */
|
|
48
|
+
depthStyle: ViewStyle
|
|
49
|
+
/** Planes stepped up (0 when flat, pressed, or an absolute plane). */
|
|
50
|
+
step: number
|
|
51
|
+
lifted: boolean
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function recessDepth(inherited: SurfaceContextValue, planesDown: number, mode: ThemeMode) {
|
|
55
|
+
let plane = inherited.level
|
|
56
|
+
for (let i = 0; i < planesDown; i++) plane = pressedLevel(plane)
|
|
57
|
+
const backgroundColor = surfaceBackground(plane, mode)
|
|
58
|
+
return { plane, backgroundColor, depthStyle: getPressedRecessShadow(backgroundColor, mode) }
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Pure resolution: the plane, its hex, and the treatment. */
|
|
62
|
+
export function resolveSurfaceDepth(
|
|
63
|
+
inherited: SurfaceContextValue,
|
|
64
|
+
props: SurfaceDepthProps
|
|
65
|
+
): ResolvedSurface {
|
|
66
|
+
const mode = props.theme ?? inherited.mode
|
|
67
|
+
const elevation = props.elevation ?? 0
|
|
68
|
+
if (props.pressed || elevation < 0) {
|
|
69
|
+
const down = props.pressed ? 1 : -elevation
|
|
70
|
+
return { mode, step: 0, lifted: false, ...recessDepth(inherited, down, mode) }
|
|
71
|
+
}
|
|
72
|
+
const step = props.level != null ? 0 : (props.raise ?? elevation)
|
|
73
|
+
const floating = step >= FLOATING_ELEVATION_MIN
|
|
74
|
+
const plane = props.level ?? (floating ? 'overlay' : raisedLevel(inherited.level, step))
|
|
75
|
+
const lifted = props.lift ?? step > 0
|
|
76
|
+
const liftStep = Math.max(1, Math.min(5, step)) as LiftStep
|
|
77
|
+
const depthStyle = lifted ? liftStyle(liftStep, mode, props.liftOptions) : {}
|
|
78
|
+
return { mode, plane, backgroundColor: surfaceBackground(plane, mode), depthStyle, step, lifted }
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** The resolved depth of a container at this point in the tree. */
|
|
82
|
+
export function useResolvedSurface(props: SurfaceDepthProps): ResolvedSurface {
|
|
83
|
+
const inherited = useSurface()
|
|
84
|
+
const { level, raise, elevation, pressed, lift, liftOptions, theme } = props
|
|
85
|
+
return useMemo(
|
|
86
|
+
() =>
|
|
87
|
+
resolveSurfaceDepth(inherited, {
|
|
88
|
+
level,
|
|
89
|
+
raise,
|
|
90
|
+
elevation,
|
|
91
|
+
pressed,
|
|
92
|
+
lift,
|
|
93
|
+
liftOptions,
|
|
94
|
+
theme,
|
|
95
|
+
}),
|
|
96
|
+
[inherited, level, raise, elevation, pressed, lift, liftOptions, theme]
|
|
97
|
+
)
|
|
98
|
+
}
|
|
@@ -8,7 +8,8 @@ import { getSemanticColors } from '../../../theme/tokens/semantic'
|
|
|
8
8
|
* palette locks its eligibility mask with a value-level test.
|
|
9
9
|
*
|
|
10
10
|
* Scope: DARK mode only. The north-star diagnosis
|
|
11
|
-
* (sources/design/surface-system-north-star.md
|
|
11
|
+
* (`sources/design/surface-system-north-star.md`, in the `voltras-workspace`
|
|
12
|
+
* active-work initiative rather than this repo) measured and
|
|
12
13
|
* fixed the dark ramp specifically; light mode has its own latent collisions
|
|
13
14
|
* (e.g. `surface-overlay` === `surface-base`, both `#FFFFFF`) that were never
|
|
14
15
|
* part of this investigation — flagged as a follow-up, not silently patched
|
|
@@ -91,6 +92,10 @@ describe('surface ramp contract (dark) — token-value guardrails', () => {
|
|
|
91
92
|
// Locked values from surface-system-north-star.md (re-spaced S-3) — see
|
|
92
93
|
// surfaceRampDark in primitives.ts for the derivation this must match
|
|
93
94
|
// byte-for-byte. background/base are unchanged by the re-space.
|
|
95
|
+
//
|
|
96
|
+
// The literal hexes are the POINT of this one test: it pins the bytes, so a
|
|
97
|
+
// re-space has to come here and say so. Every other test in the suite
|
|
98
|
+
// references the ramp instead.
|
|
94
99
|
expect(dark['background-frame']).toBe('#100D0A')
|
|
95
100
|
expect(dark['background-base']).toBe('#1C1916')
|
|
96
101
|
expect(dark['surface-base']).toBe('#252321')
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import React, { forwardRef } from 'react'
|
|
2
2
|
import { Pressable, View, Text, type PressableProps } from 'react-native'
|
|
3
3
|
import { cn } from '../../../utils/cn'
|
|
4
|
+
import { liftStyle } from '../../../theme/lift'
|
|
5
|
+
import { useSurfaceMode } from '../surface'
|
|
4
6
|
|
|
5
7
|
export type SwitchSize = 'sm' | 'md' | 'lg'
|
|
6
8
|
|
|
@@ -51,6 +53,7 @@ export const Switch = forwardRef<View, SwitchProps>(function Switch(
|
|
|
51
53
|
ref
|
|
52
54
|
) {
|
|
53
55
|
const styles = sizeStyles[size]
|
|
56
|
+
const mode = useSurfaceMode()
|
|
54
57
|
|
|
55
58
|
const handlePress = () => {
|
|
56
59
|
if (!isDisabled) {
|
|
@@ -66,12 +69,14 @@ export const Switch = forwardRef<View, SwitchProps>(function Switch(
|
|
|
66
69
|
isChecked ? 'bg-brand-primary' : 'bg-hairline-strong'
|
|
67
70
|
)}
|
|
68
71
|
>
|
|
72
|
+
{/* The thumb is a raised control resting in its track: one plane of lift. */}
|
|
69
73
|
<View
|
|
70
74
|
className={cn(
|
|
71
|
-
'rounded-full bg-
|
|
75
|
+
'rounded-full bg-on-brand-primary transition-transform',
|
|
72
76
|
styles.thumb,
|
|
73
77
|
isChecked && styles.translate
|
|
74
78
|
)}
|
|
79
|
+
style={liftStyle(1, mode)}
|
|
75
80
|
/>
|
|
76
81
|
</View>
|
|
77
82
|
)
|
|
@@ -84,11 +89,7 @@ export const Switch = forwardRef<View, SwitchProps>(function Switch(
|
|
|
84
89
|
accessibilityRole="switch"
|
|
85
90
|
accessibilityState={{ checked: isChecked, disabled: isDisabled }}
|
|
86
91
|
accessibilityLabel={label}
|
|
87
|
-
className={cn(
|
|
88
|
-
'flex-row items-center gap-2',
|
|
89
|
-
isDisabled && 'opacity-50',
|
|
90
|
-
className
|
|
91
|
-
)}
|
|
92
|
+
className={cn('flex-row items-center gap-2', isDisabled && 'opacity-50', className)}
|
|
92
93
|
{...props}
|
|
93
94
|
>
|
|
94
95
|
{label && labelPosition === 'left' && (
|
|
@@ -5,7 +5,7 @@ import { Tabs, TabList, Tab, TabPanels, TabPanel } from './Tabs'
|
|
|
5
5
|
const meta: Meta<typeof Tabs> = {
|
|
6
6
|
title: 'Components/Molecules/Tabs',
|
|
7
7
|
component: Tabs,
|
|
8
|
-
tags: ['autodocs'],
|
|
8
|
+
tags: ['autodocs', 'status:stable', '!status:review'],
|
|
9
9
|
argTypes: {
|
|
10
10
|
variant: {
|
|
11
11
|
control: 'select',
|
|
@@ -75,10 +75,7 @@ export function Tabs({
|
|
|
75
75
|
return (
|
|
76
76
|
<TabsContext.Provider value={{ activeIndex, setActiveIndex, variant, orientation }}>
|
|
77
77
|
<View
|
|
78
|
-
className={cn(
|
|
79
|
-
orientation === 'vertical' ? 'flex-row' : 'flex-col',
|
|
80
|
-
className
|
|
81
|
-
)}
|
|
78
|
+
className={cn(orientation === 'vertical' ? 'flex-row' : 'flex-col', className)}
|
|
82
79
|
{...props}
|
|
83
80
|
>
|
|
84
81
|
{children}
|
|
@@ -99,9 +96,7 @@ export function TabList({ children, className }: TabListProps) {
|
|
|
99
96
|
const { variant, orientation } = useContext(TabsContext)
|
|
100
97
|
|
|
101
98
|
const variantStyles = {
|
|
102
|
-
line: orientation === 'horizontal'
|
|
103
|
-
? 'border-b border-hairline'
|
|
104
|
-
: 'border-r border-hairline',
|
|
99
|
+
line: orientation === 'horizontal' ? 'border-b border-hairline' : 'border-r border-hairline',
|
|
105
100
|
enclosed: 'bg-surface-raised rounded-lg p-1',
|
|
106
101
|
'soft-rounded': 'bg-surface-raised rounded-full p-1',
|
|
107
102
|
}
|
|
@@ -151,12 +146,7 @@ export interface TabProps {
|
|
|
151
146
|
/**
|
|
152
147
|
* Individual tab button.
|
|
153
148
|
*/
|
|
154
|
-
export function Tab({
|
|
155
|
-
index = 0,
|
|
156
|
-
isDisabled = false,
|
|
157
|
-
className,
|
|
158
|
-
children,
|
|
159
|
-
}: TabProps) {
|
|
149
|
+
export function Tab({ index = 0, isDisabled = false, className, children }: TabProps) {
|
|
160
150
|
const { activeIndex, setActiveIndex, variant, orientation } = useContext(TabsContext)
|
|
161
151
|
const isActive = activeIndex === index
|
|
162
152
|
|
|
@@ -170,16 +160,17 @@ export function Tab({
|
|
|
170
160
|
? 'border-brand-primary text-brand-primary'
|
|
171
161
|
: 'border-transparent text-text-secondary web:hover:text-text-primary'
|
|
172
162
|
),
|
|
163
|
+
// The active enclosed tab is an indicator, not a plane: tone alone marks it.
|
|
173
164
|
enclosed: cn(
|
|
174
165
|
'px-4 py-2 rounded-md',
|
|
175
166
|
isActive
|
|
176
|
-
? 'bg-surface-elevated text-text-primary
|
|
167
|
+
? 'bg-surface-elevated text-text-primary'
|
|
177
168
|
: 'text-text-secondary web:hover:text-text-primary'
|
|
178
169
|
),
|
|
179
170
|
'soft-rounded': cn(
|
|
180
171
|
'px-4 py-2 rounded-full',
|
|
181
172
|
isActive
|
|
182
|
-
? 'bg-brand-primary text-
|
|
173
|
+
? 'bg-brand-primary text-on-brand-primary'
|
|
183
174
|
: 'text-text-secondary web:hover:text-text-primary'
|
|
184
175
|
),
|
|
185
176
|
}
|
|
@@ -202,7 +193,7 @@ export function Tab({
|
|
|
202
193
|
'font-medium',
|
|
203
194
|
isActive
|
|
204
195
|
? variant === 'soft-rounded'
|
|
205
|
-
? 'text-
|
|
196
|
+
? 'text-on-brand-primary'
|
|
206
197
|
: 'text-text-primary'
|
|
207
198
|
: 'text-text-secondary'
|
|
208
199
|
)}
|
|
@@ -245,9 +236,5 @@ export interface TabPanelProps {
|
|
|
245
236
|
* Individual tab panel content.
|
|
246
237
|
*/
|
|
247
238
|
export function TabPanel({ children, className }: TabPanelProps) {
|
|
248
|
-
return (
|
|
249
|
-
<View className={cn('py-4', className)}>
|
|
250
|
-
{children}
|
|
251
|
-
</View>
|
|
252
|
-
)
|
|
239
|
+
return <View className={cn('py-4', className)}>{children}</View>
|
|
253
240
|
}
|
|
@@ -9,7 +9,7 @@ const SUCCESS = getSemanticColors('dark')['status-success']
|
|
|
9
9
|
const meta: Meta<typeof Tile> = {
|
|
10
10
|
title: 'Components/Atoms/Tile',
|
|
11
11
|
component: Tile,
|
|
12
|
-
tags: ['autodocs'],
|
|
12
|
+
tags: ['autodocs', 'status:candidate', '!status:review'],
|
|
13
13
|
parameters: {
|
|
14
14
|
docs: {
|
|
15
15
|
description: {
|
|
@@ -23,6 +23,9 @@ export interface TileProps extends ViewProps {
|
|
|
23
23
|
* @example
|
|
24
24
|
* <Tile label="Volume" value="76%" />
|
|
25
25
|
* <Tile label="Fatigue" value="MOD" valueColor="#F5A623" />
|
|
26
|
+
*
|
|
27
|
+
* @deprecated Use the `Card` stat preset (roadmap decision 1) — removed after
|
|
28
|
+
* AW-127 consumer migration.
|
|
26
29
|
*/
|
|
27
30
|
export function Tile({
|
|
28
31
|
label,
|
|
@@ -6,7 +6,7 @@ import { Button, ButtonText } from '../button'
|
|
|
6
6
|
const meta: Meta<typeof Toast> = {
|
|
7
7
|
title: 'Components/Molecules/Toast',
|
|
8
8
|
component: Toast,
|
|
9
|
-
tags: ['autodocs'],
|
|
9
|
+
tags: ['autodocs', 'status:stable', '!status:review'],
|
|
10
10
|
argTypes: {
|
|
11
11
|
status: {
|
|
12
12
|
control: 'select',
|
|
@@ -90,11 +90,7 @@ describe('ToastProvider', () => {
|
|
|
90
90
|
const { addToast, removeAllToasts } = useToast()
|
|
91
91
|
return (
|
|
92
92
|
<div>
|
|
93
|
-
<button
|
|
94
|
-
onClick={() =>
|
|
95
|
-
addToast({ title: 'New Toast', status: 'success' })
|
|
96
|
-
}
|
|
97
|
-
>
|
|
93
|
+
<button onClick={() => addToast({ title: 'New Toast', status: 'success' })}>
|
|
98
94
|
Add Toast
|
|
99
95
|
</button>
|
|
100
96
|
<button onClick={removeAllToasts}>Clear All</button>
|
|
@@ -179,9 +175,7 @@ describe('ToastProvider', () => {
|
|
|
179
175
|
return null
|
|
180
176
|
}
|
|
181
177
|
|
|
182
|
-
expect(() => render(<BadConsumer />)).toThrow(
|
|
183
|
-
'useToast must be used within a ToastProvider'
|
|
184
|
-
)
|
|
178
|
+
expect(() => render(<BadConsumer />)).toThrow('useToast must be used within a ToastProvider')
|
|
185
179
|
})
|
|
186
180
|
|
|
187
181
|
describe('positions', () => {
|