@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,9 +1,17 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { View, Text, Pressable, type ViewProps } from 'react-native'
|
|
3
3
|
import { cn } from '../../../utils/cn'
|
|
4
|
+
import { Pill, type PillTone, type PillVariant } from '../pill'
|
|
4
5
|
|
|
5
6
|
export type ChipVariant = 'solid' | 'subtle' | 'outline'
|
|
6
|
-
export type ChipColor =
|
|
7
|
+
export type ChipColor =
|
|
8
|
+
| 'default'
|
|
9
|
+
| 'primary'
|
|
10
|
+
| 'secondary'
|
|
11
|
+
| 'success'
|
|
12
|
+
| 'error'
|
|
13
|
+
| 'warning'
|
|
14
|
+
| 'info'
|
|
7
15
|
export type ChipSize = 'sm' | 'md' | 'lg'
|
|
8
16
|
|
|
9
17
|
export interface ChipProps extends ViewProps {
|
|
@@ -26,52 +34,53 @@ export interface ChipProps extends ViewProps {
|
|
|
26
34
|
children?: React.ReactNode
|
|
27
35
|
}
|
|
28
36
|
|
|
29
|
-
const
|
|
30
|
-
default:
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
subtle: 'bg-brand-primary-subtle text-brand-primary',
|
|
38
|
-
outline: 'border border-brand-primary text-brand-primary',
|
|
39
|
-
},
|
|
40
|
-
secondary: {
|
|
41
|
-
solid: 'bg-brand-secondary text-white',
|
|
42
|
-
subtle: 'bg-brand-secondary-subtle text-brand-secondary',
|
|
43
|
-
outline: 'border border-brand-secondary text-brand-secondary',
|
|
44
|
-
},
|
|
45
|
-
success: {
|
|
46
|
-
solid: 'bg-status-success text-white',
|
|
47
|
-
subtle: 'bg-status-success-subtle text-status-success',
|
|
48
|
-
outline: 'border border-status-success text-status-success',
|
|
49
|
-
},
|
|
50
|
-
error: {
|
|
51
|
-
solid: 'bg-status-error text-white',
|
|
52
|
-
subtle: 'bg-status-error-subtle text-status-error',
|
|
53
|
-
outline: 'border border-status-error text-status-error',
|
|
54
|
-
},
|
|
55
|
-
warning: {
|
|
56
|
-
solid: 'bg-status-warning text-white',
|
|
57
|
-
subtle: 'bg-status-warning-subtle text-status-warning',
|
|
58
|
-
outline: 'border border-status-warning text-status-warning',
|
|
59
|
-
},
|
|
60
|
-
info: {
|
|
61
|
-
solid: 'bg-status-info text-white',
|
|
62
|
-
subtle: 'bg-status-info-subtle text-status-info',
|
|
63
|
-
outline: 'border border-status-info text-status-info',
|
|
64
|
-
},
|
|
37
|
+
const colorToTone: Record<ChipColor, PillTone> = {
|
|
38
|
+
default: 'neutral',
|
|
39
|
+
primary: 'brand',
|
|
40
|
+
secondary: 'brand-secondary',
|
|
41
|
+
success: 'success',
|
|
42
|
+
error: 'error',
|
|
43
|
+
warning: 'warning',
|
|
44
|
+
info: 'info',
|
|
65
45
|
}
|
|
66
46
|
|
|
47
|
+
/** Chip keeps its own geometry and squared corners; Pill supplies the rest. */
|
|
67
48
|
const sizeStyles: Record<ChipSize, { container: string; text: string; deleteButton: string }> = {
|
|
68
49
|
sm: { container: 'px-2 py-0.5 rounded', text: 'text-xs', deleteButton: 'ml-1 -mr-0.5' },
|
|
69
50
|
md: { container: 'px-3 py-1 rounded-md', text: 'text-sm', deleteButton: 'ml-1.5 -mr-1' },
|
|
70
51
|
lg: { container: 'px-4 py-1.5 rounded-md', text: 'text-base', deleteButton: 'ml-2 -mr-1' },
|
|
71
52
|
}
|
|
72
53
|
|
|
54
|
+
function DeleteButton({
|
|
55
|
+
onDelete,
|
|
56
|
+
isDisabled,
|
|
57
|
+
className,
|
|
58
|
+
}: {
|
|
59
|
+
onDelete: () => void
|
|
60
|
+
isDisabled: boolean
|
|
61
|
+
className: string
|
|
62
|
+
}) {
|
|
63
|
+
return (
|
|
64
|
+
<Pressable
|
|
65
|
+
onPress={(e) => {
|
|
66
|
+
e.stopPropagation?.()
|
|
67
|
+
onDelete()
|
|
68
|
+
}}
|
|
69
|
+
accessibilityRole="button"
|
|
70
|
+
accessibilityLabel="Remove"
|
|
71
|
+
disabled={isDisabled}
|
|
72
|
+
className={cn(
|
|
73
|
+
className,
|
|
74
|
+
'rounded-full p-0.5 web:hover:bg-hairline-subtle active:bg-hairline-strong'
|
|
75
|
+
)}
|
|
76
|
+
>
|
|
77
|
+
<Text className="text-xs leading-none text-inherit">×</Text>
|
|
78
|
+
</Pressable>
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
|
|
73
82
|
/**
|
|
74
|
-
* Chip
|
|
83
|
+
* Chip — a `Pill` preset for tags, labels, and filters.
|
|
75
84
|
*
|
|
76
85
|
* @example
|
|
77
86
|
* <Chip>Default</Chip>
|
|
@@ -92,60 +101,36 @@ export function Chip({
|
|
|
92
101
|
...props
|
|
93
102
|
}: ChipProps) {
|
|
94
103
|
const sizes = sizeStyles[size]
|
|
95
|
-
const isClickable = !!onPress
|
|
96
|
-
|
|
97
|
-
const content = (
|
|
98
|
-
<>
|
|
99
|
-
{leftElement && <View className="mr-1.5">{leftElement}</View>}
|
|
100
|
-
<Text className={cn('font-medium', sizes.text)}>
|
|
101
|
-
{children}
|
|
102
|
-
</Text>
|
|
103
|
-
{onDelete && (
|
|
104
|
-
<Pressable
|
|
105
|
-
onPress={(e) => {
|
|
106
|
-
e.stopPropagation?.()
|
|
107
|
-
onDelete()
|
|
108
|
-
}}
|
|
109
|
-
accessibilityRole="button"
|
|
110
|
-
accessibilityLabel="Remove"
|
|
111
|
-
disabled={isDisabled}
|
|
112
|
-
className={cn(
|
|
113
|
-
sizes.deleteButton,
|
|
114
|
-
'rounded-full p-0.5 web:hover:bg-black/10 active:bg-black/20'
|
|
115
|
-
)}
|
|
116
|
-
>
|
|
117
|
-
<Text className="text-xs leading-none">×</Text>
|
|
118
|
-
</Pressable>
|
|
119
|
-
)}
|
|
120
|
-
</>
|
|
121
|
-
)
|
|
122
|
-
|
|
123
|
-
const baseClassName = cn(
|
|
124
|
-
'flex-row items-center',
|
|
125
|
-
sizes.container,
|
|
126
|
-
colorStyles[color][variant],
|
|
127
|
-
isClickable && 'web:cursor-pointer web:hover:opacity-80 active:opacity-70',
|
|
128
|
-
isDisabled && 'opacity-50 cursor-not-allowed',
|
|
129
|
-
className
|
|
130
|
-
)
|
|
131
|
-
|
|
132
|
-
if (isClickable) {
|
|
133
|
-
return (
|
|
134
|
-
<Pressable
|
|
135
|
-
onPress={onPress}
|
|
136
|
-
disabled={isDisabled}
|
|
137
|
-
accessibilityRole="button"
|
|
138
|
-
className={baseClassName}
|
|
139
|
-
{...props}
|
|
140
|
-
>
|
|
141
|
-
{content}
|
|
142
|
-
</Pressable>
|
|
143
|
-
)
|
|
144
|
-
}
|
|
145
104
|
|
|
146
105
|
return (
|
|
147
|
-
<
|
|
148
|
-
{
|
|
149
|
-
|
|
106
|
+
<Pill
|
|
107
|
+
variant={variant as PillVariant}
|
|
108
|
+
tone={colorToTone[color]}
|
|
109
|
+
rounded={false}
|
|
110
|
+
onPress={onPress}
|
|
111
|
+
isDisabled={isDisabled}
|
|
112
|
+
leading={leftElement && <View className="mr-1.5">{leftElement}</View>}
|
|
113
|
+
trailing={
|
|
114
|
+
onDelete && (
|
|
115
|
+
<DeleteButton
|
|
116
|
+
onDelete={onDelete}
|
|
117
|
+
isDisabled={isDisabled}
|
|
118
|
+
className={sizes.deleteButton}
|
|
119
|
+
/>
|
|
120
|
+
)
|
|
121
|
+
}
|
|
122
|
+
className={cn(
|
|
123
|
+
'self-auto gap-0',
|
|
124
|
+
variant === 'outline' ? 'border' : 'border-0',
|
|
125
|
+
sizes.container,
|
|
126
|
+
onPress && 'web:cursor-pointer web:hover:opacity-80 active:opacity-70',
|
|
127
|
+
isDisabled && 'cursor-not-allowed',
|
|
128
|
+
className
|
|
129
|
+
)}
|
|
130
|
+
textClassName={cn('font-sans font-medium', sizes.text)}
|
|
131
|
+
{...props}
|
|
132
|
+
>
|
|
133
|
+
{children}
|
|
134
|
+
</Pill>
|
|
150
135
|
)
|
|
151
136
|
}
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
const meta: Meta<typeof Accordion> = {
|
|
15
15
|
title: 'Components/Organisms/Accordion',
|
|
16
16
|
component: Accordion,
|
|
17
|
-
tags: ['autodocs'],
|
|
17
|
+
tags: ['autodocs', 'status:stable', '!status:review'],
|
|
18
18
|
argTypes: {
|
|
19
19
|
allowMultiple: {
|
|
20
20
|
control: 'boolean',
|
|
@@ -79,8 +79,8 @@ export const AllowMultiple: Story = {
|
|
|
79
79
|
<AccordionButton>Section Two</AccordionButton>
|
|
80
80
|
<AccordionPanel>
|
|
81
81
|
<Text className="text-text-secondary text-sm">
|
|
82
|
-
This section can be open alongside Section One. In single mode, opening a new
|
|
83
|
-
|
|
82
|
+
This section can be open alongside Section One. In single mode, opening a new section
|
|
83
|
+
would close any previously open one.
|
|
84
84
|
</Text>
|
|
85
85
|
</AccordionPanel>
|
|
86
86
|
</AccordionItem>
|
|
@@ -121,9 +121,7 @@ export const DefaultOpen: Story = {
|
|
|
121
121
|
<AccordionItem>
|
|
122
122
|
<AccordionButton>Also Closed</AccordionButton>
|
|
123
123
|
<AccordionPanel>
|
|
124
|
-
<Text className="text-text-secondary text-sm">
|
|
125
|
-
Another closed section.
|
|
126
|
-
</Text>
|
|
124
|
+
<Text className="text-text-secondary text-sm">Another closed section.</Text>
|
|
127
125
|
</AccordionPanel>
|
|
128
126
|
</AccordionItem>
|
|
129
127
|
</Accordion>
|
|
@@ -146,9 +144,7 @@ export const MultipleDefaultOpen: Story = {
|
|
|
146
144
|
<AccordionItem>
|
|
147
145
|
<AccordionButton>Second (Closed)</AccordionButton>
|
|
148
146
|
<AccordionPanel>
|
|
149
|
-
<Text className="text-text-secondary text-sm">
|
|
150
|
-
This section starts closed.
|
|
151
|
-
</Text>
|
|
147
|
+
<Text className="text-text-secondary text-sm">This section starts closed.</Text>
|
|
152
148
|
</AccordionPanel>
|
|
153
149
|
</AccordionItem>
|
|
154
150
|
<AccordionItem>
|
|
@@ -191,14 +187,18 @@ export const WithRichContent: Story = {
|
|
|
191
187
|
<AccordionButton>Features Included</AccordionButton>
|
|
192
188
|
<AccordionPanel>
|
|
193
189
|
<View style={{ gap: 6 }}>
|
|
194
|
-
{[
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
190
|
+
{[
|
|
191
|
+
'Unlimited projects',
|
|
192
|
+
'Custom domains',
|
|
193
|
+
'Priority support',
|
|
194
|
+
'API access',
|
|
195
|
+
'Team collaboration',
|
|
196
|
+
].map((feature) => (
|
|
197
|
+
<View key={feature} style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
|
|
198
|
+
<Text className="text-status-success text-sm">✓</Text>
|
|
199
|
+
<Text className="text-text-primary text-sm">{feature}</Text>
|
|
200
|
+
</View>
|
|
201
|
+
))}
|
|
202
202
|
</View>
|
|
203
203
|
</AccordionPanel>
|
|
204
204
|
</AccordionItem>
|
|
@@ -213,7 +213,9 @@ export const WithRichContent: Story = {
|
|
|
213
213
|
</Text>
|
|
214
214
|
</View>
|
|
215
215
|
<View style={{ gap: 2 }}>
|
|
216
|
-
<Text className="text-text-primary text-sm font-medium">
|
|
216
|
+
<Text className="text-text-primary text-sm font-medium">
|
|
217
|
+
Is there a free trial?
|
|
218
|
+
</Text>
|
|
217
219
|
<Text className="text-text-secondary text-sm">
|
|
218
220
|
We offer a 14-day free trial for all plans.
|
|
219
221
|
</Text>
|
|
@@ -291,9 +293,7 @@ export const CollapseControlled: Story = {
|
|
|
291
293
|
const [isOpen, setIsOpen] = useState(false)
|
|
292
294
|
return (
|
|
293
295
|
<View style={{ width: 400, gap: 8 }}>
|
|
294
|
-
<Text className="text-sm text-text-secondary">
|
|
295
|
-
State: {isOpen ? 'Open' : 'Closed'}
|
|
296
|
-
</Text>
|
|
296
|
+
<Text className="text-sm text-text-secondary">State: {isOpen ? 'Open' : 'Closed'}</Text>
|
|
297
297
|
<Collapse isOpen={isOpen} onToggle={setIsOpen}>
|
|
298
298
|
<CollapseButton>
|
|
299
299
|
<Text className="text-text-primary font-medium">Controlled Collapse</Text>
|
|
@@ -301,8 +301,8 @@ export const CollapseControlled: Story = {
|
|
|
301
301
|
<CollapseContent>
|
|
302
302
|
<View className="px-4 pb-3">
|
|
303
303
|
<Text className="text-text-secondary text-sm">
|
|
304
|
-
This collapse is controlled externally. The isOpen prop and onToggle callback
|
|
305
|
-
|
|
304
|
+
This collapse is controlled externally. The isOpen prop and onToggle callback manage
|
|
305
|
+
state outside the component.
|
|
306
306
|
</Text>
|
|
307
307
|
</View>
|
|
308
308
|
</CollapseContent>
|
|
@@ -67,19 +67,22 @@ export function Collapse({
|
|
|
67
67
|
|
|
68
68
|
export interface CollapseButtonProps {
|
|
69
69
|
children?: React.ReactNode
|
|
70
|
+
/** Accessible name when the button carries no text of its own (a bare chevron). */
|
|
71
|
+
accessibilityLabel?: string
|
|
70
72
|
className?: string
|
|
71
73
|
}
|
|
72
74
|
|
|
73
75
|
/**
|
|
74
76
|
* Button to toggle collapse state.
|
|
75
77
|
*/
|
|
76
|
-
export function CollapseButton({ children, className }: CollapseButtonProps) {
|
|
78
|
+
export function CollapseButton({ children, accessibilityLabel, className }: CollapseButtonProps) {
|
|
77
79
|
const { isOpen, toggle } = useContext(CollapseContext)
|
|
78
80
|
|
|
79
81
|
return (
|
|
80
82
|
<Pressable
|
|
81
83
|
onPress={toggle}
|
|
82
84
|
accessibilityRole="button"
|
|
85
|
+
accessibilityLabel={accessibilityLabel}
|
|
83
86
|
accessibilityState={{ expanded: isOpen }}
|
|
84
87
|
className={cn(
|
|
85
88
|
'flex-row items-center justify-between py-3 px-4',
|
|
@@ -108,11 +111,7 @@ export function CollapseContent({ children, className }: CollapseContentProps) {
|
|
|
108
111
|
|
|
109
112
|
if (!isOpen) return null
|
|
110
113
|
|
|
111
|
-
return (
|
|
112
|
-
<View className={cn('overflow-hidden', className)}>
|
|
113
|
-
{children}
|
|
114
|
-
</View>
|
|
115
|
-
)
|
|
114
|
+
return <View className={cn('overflow-hidden', className)}>{children}</View>
|
|
116
115
|
}
|
|
117
116
|
|
|
118
117
|
// Accordion component
|
|
@@ -267,9 +266,5 @@ export interface AccordionPanelProps {
|
|
|
267
266
|
export function AccordionPanel({ isOpen = false, children, className }: AccordionPanelProps) {
|
|
268
267
|
if (!isOpen) return null
|
|
269
268
|
|
|
270
|
-
return (
|
|
271
|
-
<View className={cn('pb-4 px-1', className)}>
|
|
272
|
-
{children}
|
|
273
|
-
</View>
|
|
274
|
-
)
|
|
269
|
+
return <View className={cn('pb-4 px-1', className)}>{children}</View>
|
|
275
270
|
}
|
|
@@ -5,7 +5,7 @@ import { DataRow } from './DataRow'
|
|
|
5
5
|
const meta: Meta<typeof DataRow> = {
|
|
6
6
|
title: 'Components/Molecules/DataRow',
|
|
7
7
|
component: DataRow,
|
|
8
|
-
tags: ['autodocs'],
|
|
8
|
+
tags: ['autodocs', 'status:stable', '!status:review'],
|
|
9
9
|
argTypes: {
|
|
10
10
|
label: {
|
|
11
11
|
control: 'text',
|
|
@@ -40,8 +40,19 @@ export const WithCustomValue: Story = {
|
|
|
40
40
|
<DataRow
|
|
41
41
|
label="Status"
|
|
42
42
|
value={
|
|
43
|
-
<View
|
|
44
|
-
|
|
43
|
+
<View
|
|
44
|
+
style={{
|
|
45
|
+
backgroundColor: 'var(--color-status-success)',
|
|
46
|
+
borderRadius: 9999,
|
|
47
|
+
paddingHorizontal: 8,
|
|
48
|
+
paddingVertical: 2,
|
|
49
|
+
}}
|
|
50
|
+
>
|
|
51
|
+
<Text
|
|
52
|
+
style={{ color: 'var(--color-on-status-success)', fontSize: 12, fontWeight: '600' }}
|
|
53
|
+
>
|
|
54
|
+
Active
|
|
55
|
+
</Text>
|
|
45
56
|
</View>
|
|
46
57
|
}
|
|
47
58
|
/>
|
|
@@ -11,9 +11,7 @@ describe('DataRow', () => {
|
|
|
11
11
|
})
|
|
12
12
|
|
|
13
13
|
it('renders label and ReactNode value', () => {
|
|
14
|
-
render(
|
|
15
|
-
<DataRow label="Status" value={<span data-testid="custom-node">Active</span>} />
|
|
16
|
-
)
|
|
14
|
+
render(<DataRow label="Status" value={<span data-testid="custom-node">Active</span>} />)
|
|
17
15
|
expect(screen.getByText('Status')).toBeInTheDocument()
|
|
18
16
|
expect(screen.getByTestId('custom-node')).toBeInTheDocument()
|
|
19
17
|
expect(screen.getByText('Active')).toBeInTheDocument()
|
|
@@ -34,24 +32,18 @@ describe('DataRow', () => {
|
|
|
34
32
|
})
|
|
35
33
|
|
|
36
34
|
it('applies custom className to root container', () => {
|
|
37
|
-
const { container } = render(
|
|
38
|
-
<DataRow label="Test" value="Value" className="bg-red-500" />
|
|
39
|
-
)
|
|
35
|
+
const { container } = render(<DataRow label="Test" value="Value" className="bg-red-500" />)
|
|
40
36
|
const root = container.firstChild as HTMLElement
|
|
41
37
|
expect(root).toBeInTheDocument()
|
|
42
38
|
})
|
|
43
39
|
|
|
44
40
|
it('applies valueClassName to string value', () => {
|
|
45
|
-
render(
|
|
46
|
-
<DataRow label="Test" value="Value" valueClassName="text-lg" />
|
|
47
|
-
)
|
|
41
|
+
render(<DataRow label="Test" value="Value" valueClassName="text-lg" />)
|
|
48
42
|
expect(screen.getByText('Value')).toBeInTheDocument()
|
|
49
43
|
})
|
|
50
44
|
|
|
51
45
|
it('applies valueClassName to ReactNode wrapper', () => {
|
|
52
|
-
render(
|
|
53
|
-
<DataRow label="Test" value={<span>Node</span>} valueClassName="text-lg" />
|
|
54
|
-
)
|
|
46
|
+
render(<DataRow label="Test" value={<span>Node</span>} valueClassName="text-lg" />)
|
|
55
47
|
expect(screen.getByText('Node')).toBeInTheDocument()
|
|
56
48
|
})
|
|
57
49
|
|
|
@@ -68,9 +60,7 @@ describe('DataRow', () => {
|
|
|
68
60
|
})
|
|
69
61
|
|
|
70
62
|
it('has no accessibility violations with ReactNode value', async () => {
|
|
71
|
-
const { container } = render(
|
|
72
|
-
<DataRow label="Status" value={<span>Active</span>} />
|
|
73
|
-
)
|
|
63
|
+
const { container } = render(<DataRow label="Status" value={<span>Active</span>} />)
|
|
74
64
|
const results = await axe(container)
|
|
75
65
|
expect(results).toHaveNoViolations()
|
|
76
66
|
})
|
|
@@ -3,24 +3,35 @@ import { View, Text, type ViewProps } from 'react-native'
|
|
|
3
3
|
import { cn } from '../../../utils/cn'
|
|
4
4
|
|
|
5
5
|
export interface DataRowProps extends ViewProps {
|
|
6
|
-
/** Descriptive label shown on the left */
|
|
7
|
-
label:
|
|
6
|
+
/** Descriptive label shown on the left -- string renders as Text, ReactNode renders inside a View */
|
|
7
|
+
label: React.ReactNode
|
|
8
8
|
/** Value shown on the right -- string renders as Text, ReactNode renders inside a View */
|
|
9
9
|
value: React.ReactNode
|
|
10
|
+
/** Additional className applied to the label element */
|
|
11
|
+
labelClassName?: string
|
|
10
12
|
/** Additional className applied to the value element */
|
|
11
13
|
valueClassName?: string
|
|
12
14
|
/** Additional className applied to the root container */
|
|
13
15
|
className?: string
|
|
14
16
|
}
|
|
15
17
|
|
|
16
|
-
export function DataRow({
|
|
18
|
+
export function DataRow({
|
|
19
|
+
label,
|
|
20
|
+
value,
|
|
21
|
+
labelClassName,
|
|
22
|
+
valueClassName,
|
|
23
|
+
className,
|
|
24
|
+
...props
|
|
25
|
+
}: DataRowProps) {
|
|
17
26
|
return (
|
|
18
27
|
<View className={cn('flex-row items-center justify-between py-2', className)} {...props}>
|
|
19
|
-
|
|
28
|
+
{typeof label === 'string' ? (
|
|
29
|
+
<Text className={cn('text-sm text-text-secondary', labelClassName)}>{label}</Text>
|
|
30
|
+
) : (
|
|
31
|
+
<View className={cn(labelClassName)}>{label}</View>
|
|
32
|
+
)}
|
|
20
33
|
{typeof value === 'string' ? (
|
|
21
|
-
<Text className={cn('text-sm font-medium text-text-primary', valueClassName)}>
|
|
22
|
-
{value}
|
|
23
|
-
</Text>
|
|
34
|
+
<Text className={cn('text-sm font-medium text-text-primary', valueClassName)}>{value}</Text>
|
|
24
35
|
) : (
|
|
25
36
|
<View className={cn(valueClassName)}>{value}</View>
|
|
26
37
|
)}
|
|
@@ -5,7 +5,7 @@ import { Divider } from './Divider'
|
|
|
5
5
|
const meta: Meta<typeof Divider> = {
|
|
6
6
|
title: 'Components/Atoms/Divider',
|
|
7
7
|
component: Divider,
|
|
8
|
-
tags: ['autodocs'],
|
|
8
|
+
tags: ['autodocs', 'status:stable', '!status:review'],
|
|
9
9
|
argTypes: {
|
|
10
10
|
orientation: {
|
|
11
11
|
control: 'select',
|
|
@@ -18,11 +18,7 @@ export interface DividerProps extends ViewProps {
|
|
|
18
18
|
* <Divider />
|
|
19
19
|
* <Divider orientation="vertical" />
|
|
20
20
|
*/
|
|
21
|
-
export function Divider({
|
|
22
|
-
orientation = 'horizontal',
|
|
23
|
-
className,
|
|
24
|
-
...props
|
|
25
|
-
}: DividerProps) {
|
|
21
|
+
export function Divider({ orientation = 'horizontal', className, ...props }: DividerProps) {
|
|
26
22
|
return (
|
|
27
23
|
<View
|
|
28
24
|
accessibilityRole="none"
|
|
@@ -7,7 +7,7 @@ import { Button, ButtonText } from '../button'
|
|
|
7
7
|
const meta: Meta<typeof Drawer> = {
|
|
8
8
|
title: 'Components/Organisms/Drawer',
|
|
9
9
|
component: Drawer,
|
|
10
|
-
tags: ['autodocs'],
|
|
10
|
+
tags: ['autodocs', 'status:stable', '!status:review'],
|
|
11
11
|
argTypes: {
|
|
12
12
|
placement: {
|
|
13
13
|
control: 'select',
|
|
@@ -37,11 +37,7 @@ export const Default: Story = {
|
|
|
37
37
|
<Button onPress={() => setIsOpen(true)}>
|
|
38
38
|
<ButtonText>Open Drawer</ButtonText>
|
|
39
39
|
</Button>
|
|
40
|
-
<Drawer
|
|
41
|
-
isOpen={isOpen}
|
|
42
|
-
onClose={() => setIsOpen(false)}
|
|
43
|
-
title="Drawer Title"
|
|
44
|
-
>
|
|
40
|
+
<Drawer isOpen={isOpen} onClose={() => setIsOpen(false)} title="Drawer Title">
|
|
45
41
|
<DrawerBody>
|
|
46
42
|
<Text className="text-text-primary">
|
|
47
43
|
This is the drawer content. You can put any content here.
|
|
@@ -124,7 +120,7 @@ export const AllSizes: Story = {
|
|
|
124
120
|
render: function Render() {
|
|
125
121
|
const [openSize, setOpenSize] = useState<string | null>(null)
|
|
126
122
|
const sizes = ['sm', 'md', 'lg', 'xl'] as const
|
|
127
|
-
|
|
123
|
+
|
|
128
124
|
return (
|
|
129
125
|
<View className="flex-row gap-2 flex-wrap">
|
|
130
126
|
{sizes.map((size) => (
|
|
@@ -141,9 +137,7 @@ export const AllSizes: Story = {
|
|
|
141
137
|
title={`${size.toUpperCase()} Drawer`}
|
|
142
138
|
>
|
|
143
139
|
<DrawerBody>
|
|
144
|
-
<Text className="text-text-primary">
|
|
145
|
-
This is a {size} size drawer.
|
|
146
|
-
</Text>
|
|
140
|
+
<Text className="text-text-primary">This is a {size} size drawer.</Text>
|
|
147
141
|
</DrawerBody>
|
|
148
142
|
</Drawer>
|
|
149
143
|
))}
|
|
@@ -160,12 +154,7 @@ export const WithFooter: Story = {
|
|
|
160
154
|
<Button onPress={() => setIsOpen(true)}>
|
|
161
155
|
<ButtonText>Open Form Drawer</ButtonText>
|
|
162
156
|
</Button>
|
|
163
|
-
<Drawer
|
|
164
|
-
isOpen={isOpen}
|
|
165
|
-
onClose={() => setIsOpen(false)}
|
|
166
|
-
title="Edit Profile"
|
|
167
|
-
size="lg"
|
|
168
|
-
>
|
|
157
|
+
<Drawer isOpen={isOpen} onClose={() => setIsOpen(false)} title="Edit Profile" size="lg">
|
|
169
158
|
<DrawerBody>
|
|
170
159
|
<View className="gap-4">
|
|
171
160
|
<View>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { View, Text, Pressable, Modal, ScrollView, type ViewProps } from 'react-native'
|
|
3
3
|
import { cn } from '../../../utils/cn'
|
|
4
|
+
import { Surface } from '../surface'
|
|
4
5
|
|
|
5
6
|
export type DrawerPlacement = 'left' | 'right' | 'top' | 'bottom'
|
|
6
7
|
export type DrawerSize = 'sm' | 'md' | 'lg' | 'xl' | 'full'
|
|
@@ -99,23 +100,20 @@ export function Drawer({
|
|
|
99
100
|
}
|
|
100
101
|
|
|
101
102
|
return (
|
|
102
|
-
<Modal
|
|
103
|
-
visible={isOpen}
|
|
104
|
-
transparent
|
|
105
|
-
animationType="fade"
|
|
106
|
-
onRequestClose={onClose}
|
|
107
|
-
>
|
|
103
|
+
<Modal visible={isOpen} transparent animationType="fade" onRequestClose={onClose}>
|
|
108
104
|
<View className="flex-1">
|
|
109
105
|
{/* Backdrop */}
|
|
110
106
|
<Pressable
|
|
111
107
|
onPress={handleOverlayPress}
|
|
112
|
-
className="absolute inset-0 bg-black/50"
|
|
108
|
+
className="absolute inset-0 bg-black/50" /* VW-82: scrim, see Modal.tsx */
|
|
113
109
|
/>
|
|
114
110
|
|
|
115
|
-
{/* Drawer Panel */}
|
|
116
|
-
<
|
|
111
|
+
{/* Drawer Panel — floating: overlay plane + lift, no ring. */}
|
|
112
|
+
<Surface
|
|
113
|
+
elevation={4}
|
|
114
|
+
rounded={false}
|
|
117
115
|
className={cn(
|
|
118
|
-
'absolute
|
|
116
|
+
'absolute',
|
|
119
117
|
placementStyles[placement],
|
|
120
118
|
sizeStyles[placement][size],
|
|
121
119
|
className
|
|
@@ -126,11 +124,7 @@ export function Drawer({
|
|
|
126
124
|
{/* Header */}
|
|
127
125
|
{(title || showCloseButton) && (
|
|
128
126
|
<View className="flex-row items-center justify-between px-4 py-3 border-b border-hairline">
|
|
129
|
-
{title &&
|
|
130
|
-
<Text className="text-lg font-semibold text-text-primary">
|
|
131
|
-
{title}
|
|
132
|
-
</Text>
|
|
133
|
-
)}
|
|
127
|
+
{title && <Text className="text-lg font-semibold text-text-primary">{title}</Text>}
|
|
134
128
|
{showCloseButton && (
|
|
135
129
|
<Pressable
|
|
136
130
|
onPress={onClose}
|
|
@@ -144,10 +138,8 @@ export function Drawer({
|
|
|
144
138
|
)}
|
|
145
139
|
|
|
146
140
|
{/* Content */}
|
|
147
|
-
<View className="flex-1">
|
|
148
|
-
|
|
149
|
-
</View>
|
|
150
|
-
</View>
|
|
141
|
+
<View className="flex-1">{children}</View>
|
|
142
|
+
</Surface>
|
|
151
143
|
</View>
|
|
152
144
|
</Modal>
|
|
153
145
|
)
|
|
@@ -164,10 +156,7 @@ export interface DrawerHeaderProps extends ViewProps {
|
|
|
164
156
|
*/
|
|
165
157
|
export function DrawerHeader({ className, children, ...props }: DrawerHeaderProps) {
|
|
166
158
|
return (
|
|
167
|
-
<View
|
|
168
|
-
className={cn('px-4 py-3 border-b border-hairline', className)}
|
|
169
|
-
{...props}
|
|
170
|
-
>
|
|
159
|
+
<View className={cn('px-4 py-3 border-b border-hairline', className)} {...props}>
|
|
171
160
|
{children}
|
|
172
161
|
</View>
|
|
173
162
|
)
|
|
@@ -187,10 +176,7 @@ export interface DrawerBodyProps extends ViewProps {
|
|
|
187
176
|
export function DrawerBody({ scrollable = true, className, children, ...props }: DrawerBodyProps) {
|
|
188
177
|
if (scrollable) {
|
|
189
178
|
return (
|
|
190
|
-
<ScrollView
|
|
191
|
-
className={cn('flex-1 p-4', className)}
|
|
192
|
-
{...props}
|
|
193
|
-
>
|
|
179
|
+
<ScrollView className={cn('flex-1 p-4', className)} {...props}>
|
|
194
180
|
{children}
|
|
195
181
|
</ScrollView>
|
|
196
182
|
)
|