@titan-design/react-ui 0.9.1 → 0.9.2
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/dist/index.d.mts +13 -3
- package/dist/index.d.ts +13 -3
- package/dist/index.js +20 -21
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +20 -21
- package/dist/index.mjs.map +1 -1
- package/dist/pages.js +2 -1
- package/dist/pages.js.map +1 -1
- package/dist/pages.mjs +2 -1
- package/dist/pages.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/custom/Workout/ExerciseHeading.tsx +5 -3
- package/src/components/custom/Workout/SessionHeader.tsx +6 -5
- package/src/components/custom/Workout/SessionRail.tsx +18 -7
- package/src/components/custom/Workout/SetsRepsLoad.tsx +2 -1
- package/src/components/shell/DashboardShell.tsx +7 -9
- package/src/components/shell/NavItem.tsx +6 -1
package/package.json
CHANGED
|
@@ -10,7 +10,8 @@ export interface ExerciseHeadingProps {
|
|
|
10
10
|
/** Prescription line values (sets × reps @ load). */
|
|
11
11
|
sets: number
|
|
12
12
|
reps: number | string
|
|
13
|
-
load
|
|
13
|
+
/** Load value; a string (e.g. "—") passes through verbatim for an unset/discovery load. */
|
|
14
|
+
load: number | string
|
|
14
15
|
unit?: 'lbs' | 'kg'
|
|
15
16
|
/** Tempo tuple [eccentric, pauseBottom, concentric, pauseTop]; hidden when absent. */
|
|
16
17
|
tempo?: [number, number, number, number]
|
|
@@ -26,10 +27,11 @@ function headingLabel(
|
|
|
26
27
|
name: string,
|
|
27
28
|
sets: number,
|
|
28
29
|
reps: number | string,
|
|
29
|
-
load: number,
|
|
30
|
+
load: number | string,
|
|
30
31
|
unit: string
|
|
31
32
|
) {
|
|
32
|
-
|
|
33
|
+
const loadLabel = typeof load === 'number' ? roundWeight(load) : load
|
|
34
|
+
return `${name}, ${sets}×${reps} @ ${loadLabel} ${unit}`
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
/**
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
// Font mapping: font-heading=Space Grotesk, font-body=Nunito Sans (UI), font-sans=Inter (body)
|
|
2
2
|
import { View, Text, type ViewProps } from 'react-native'
|
|
3
|
-
import { primitiveColors } from '../../../theme/tokens/primitives'
|
|
4
3
|
import { getSemanticColors } from '../../../theme/tokens/semantic'
|
|
5
4
|
import { Typography } from '../Typography'
|
|
6
5
|
import { TimerReadout } from '../TimerReadout'
|
|
@@ -11,9 +10,11 @@ import { paceTone, paceToneColor } from './paceTone'
|
|
|
11
10
|
|
|
12
11
|
const t = getSemanticColors('dark')
|
|
13
12
|
|
|
14
|
-
// The
|
|
15
|
-
// the
|
|
16
|
-
|
|
13
|
+
// The header shares the SideNav's `background-base` (charcoal 900, #101010) so the nav and
|
|
14
|
+
// the rail header read as ONE continuous dark plane on the left — the sunk exercise list
|
|
15
|
+
// (charcoal 800) sits raised off it. Previously charcoal 400 (#1F1F1F), which made the header
|
|
16
|
+
// the lightest rail surface and let it blend with the rows instead of anchoring to the nav.
|
|
17
|
+
const HEADER_BG = t['background-base'] // #101010 — matches SideNav bg-background-base
|
|
17
18
|
|
|
18
19
|
// The chunked pace bar matches the SetStrip language but sits tighter than the default
|
|
19
20
|
// SetStrip gap (5) — the locked design uses a 3px gap and a 9px track.
|
|
@@ -86,7 +87,7 @@ export function SessionHeader({
|
|
|
86
87
|
className={className}
|
|
87
88
|
style={[
|
|
88
89
|
{
|
|
89
|
-
backgroundColor:
|
|
90
|
+
backgroundColor: HEADER_BG,
|
|
90
91
|
paddingTop: 11,
|
|
91
92
|
paddingRight: 12,
|
|
92
93
|
paddingBottom: 12,
|
|
@@ -8,11 +8,14 @@ import type { MetricTileData } from './MetricTiles'
|
|
|
8
8
|
import type { SetStripSet } from './SetStrip'
|
|
9
9
|
import type { ExerciseIndicatorKind } from './ExerciseIndicator'
|
|
10
10
|
|
|
11
|
-
// Charcoal-ramp surfaces (the locked S3 shell shades): the nav + the heading plane
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
// Charcoal-ramp surfaces (the locked S3 shell shades): the nav + the heading plane read as
|
|
12
|
+
// ONE dark plane (charcoal 900, #101010, set in SessionHeader). The exercise list is a
|
|
13
|
+
// LIGHTER inset panel (charcoal 600) — recessed via its inner shadow yet paler than the
|
|
14
|
+
// header, so the transparent exercise headings on it never blend into the header plane.
|
|
15
|
+
// (Band-aid: the list is picked to clear the components; the durable fix is a `<Surface>`
|
|
16
|
+
// primitive whose cards own their own raised background — see the rail's PR notes.)
|
|
17
|
+
const INSET = primitiveColors.charcoal[600] // #191919 — lighter sunk exercise-list panel
|
|
18
|
+
const DIVIDER = primitiveColors.charcoal[300] // #2C2C2C — row divider (raised to read on #191919)
|
|
16
19
|
|
|
17
20
|
const DEFAULT_WIDTH = 246
|
|
18
21
|
|
|
@@ -20,7 +23,15 @@ export interface SessionRailExercise {
|
|
|
20
23
|
/** Stable key + press payload. Falls back to list index when absent. */
|
|
21
24
|
id?: string
|
|
22
25
|
name: string
|
|
23
|
-
|
|
26
|
+
/** `weight` accepts a string (e.g. "—") for an unset/discovery load — never a faked 0. */
|
|
27
|
+
summary: { sets: number; reps: number | string; weight: number | string; unit: 'lbs' | 'kg' }
|
|
28
|
+
/**
|
|
29
|
+
* Prescribed set count for the header total + pace-bar segment width. Distinct from
|
|
30
|
+
* `summary.sets`, which is the row's live DONE count (0 for the active exercise before
|
|
31
|
+
* its first set) — using that for the total under-counts by the active exercise's
|
|
32
|
+
* remaining sets. Falls back to `summary.sets` when absent.
|
|
33
|
+
*/
|
|
34
|
+
plannedSets?: number
|
|
24
35
|
tempo?: [number, number, number, number]
|
|
25
36
|
indicator?: ExerciseIndicatorKind
|
|
26
37
|
/** Per-set performance data driving the heading strip. */
|
|
@@ -84,7 +95,7 @@ export function SessionRail({
|
|
|
84
95
|
>
|
|
85
96
|
<SessionHeader
|
|
86
97
|
title={title}
|
|
87
|
-
plan={exercises.map((ex) => ({ name: ex.name, sets: ex.summary.sets }))}
|
|
98
|
+
plan={exercises.map((ex) => ({ name: ex.name, sets: ex.plannedSets ?? ex.summary.sets }))}
|
|
88
99
|
setsDone={setsDone}
|
|
89
100
|
elapsedMs={elapsedMs}
|
|
90
101
|
budgetMs={budgetMs}
|
|
@@ -11,7 +11,8 @@ const AT = '@'
|
|
|
11
11
|
export interface SetsRepsLoadProps extends ViewProps {
|
|
12
12
|
sets: number
|
|
13
13
|
reps: number | string
|
|
14
|
-
load
|
|
14
|
+
/** Load value; a string (e.g. "—") passes through verbatim for an unset/discovery load. */
|
|
15
|
+
load: number | string
|
|
15
16
|
/** Displayed load unit label (e.g. "lb", "kg"). */
|
|
16
17
|
unit?: string
|
|
17
18
|
/** Cell font size (px). Default 11 — the compact rail/card scale. Raise for a wall read-out. */
|
|
@@ -58,15 +58,13 @@ export function DashboardShell({
|
|
|
58
58
|
className,
|
|
59
59
|
}: DashboardShellProps) {
|
|
60
60
|
return (
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
onSelectDevice={onSelectDevice}
|
|
69
|
-
/>
|
|
61
|
+
// Column: the TopBar spans the FULL width across the top, and the SideNav sits BELOW it
|
|
62
|
+
// in the content row (not a full-height left rail). This keeps the brand/status band
|
|
63
|
+
// unbroken edge-to-edge and lets the nav align under it.
|
|
64
|
+
<View className={cn('flex-1 bg-surface-base', className)}>
|
|
65
|
+
<TopBar state={state} devices={devices} subtitle={subtitle} onSelectDevice={onSelectDevice} />
|
|
66
|
+
<View className="flex-1 flex-row">
|
|
67
|
+
<SideNav activeKey={activeKey} items={navItems} liveKey={liveKey} onNavigate={onNavigate} />
|
|
70
68
|
<View className="flex-1">{children ?? <ContentPlaceholder />}</View>
|
|
71
69
|
</View>
|
|
72
70
|
</View>
|
|
@@ -65,7 +65,12 @@ export function NavItem({
|
|
|
65
65
|
<Typography
|
|
66
66
|
variant="button"
|
|
67
67
|
color="inherit"
|
|
68
|
-
|
|
68
|
+
// fontSize inline, not `text-[8.5px]`: the `button` variant's `text-sm` (14px) and the
|
|
69
|
+
// arbitrary `text-[8.5px]` are a same-property class conflict that the consumer's
|
|
70
|
+
// Tailwind build resolved the wrong way (labels rendered ~14px on the wall). Inline
|
|
71
|
+
// size wins unambiguously; className keeps weight/case/tracking.
|
|
72
|
+
style={{ fontSize: 8.5, lineHeight: 11 }}
|
|
73
|
+
className={cn('font-bold uppercase tracking-[0.4px]', labelColor)}
|
|
69
74
|
>
|
|
70
75
|
{label}
|
|
71
76
|
</Typography>
|