@titan-design/react-ui 0.8.0 → 0.9.1
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 +19 -59
- package/dist/index.d.ts +19 -59
- package/dist/index.js +248 -371
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +249 -368
- package/dist/index.mjs.map +1 -1
- package/dist/{pages-DCFBqp79.d.mts → pages-D7hOD4Vj.d.mts} +1 -1
- package/dist/{pages-_fI3-x7Z.d.ts → pages-DyEx-lBf.d.ts} +1 -1
- package/dist/pages.d.mts +1 -1
- package/dist/pages.d.ts +1 -1
- package/dist/pages.js +199 -161
- package/dist/pages.js.map +1 -1
- package/dist/pages.mjs +199 -161
- package/dist/pages.mjs.map +1 -1
- package/package.json +2 -1
- package/src/components/custom/Workout/ExerciseIndicator.tsx +1 -1
- package/src/components/custom/Workout/README.md +33 -13
- package/src/components/custom/Workout/SetsRepsLoad.test.tsx +6 -0
- package/src/components/custom/Workout/SetsRepsLoad.tsx +15 -6
- package/src/components/custom/Workout/TempoDisplay.stories.tsx +240 -65
- package/src/components/custom/Workout/TempoDisplay.test.tsx +61 -16
- package/src/components/custom/Workout/TempoDisplay.tsx +173 -60
- package/src/components/custom/Workout/VelocityStrip.test.tsx +3 -3
- package/src/components/custom/Workout/VelocityStrip.tsx +45 -11
- package/src/components/custom/Workout/ZoneTrack.tsx +15 -1
- package/src/components/custom/Workout/index.ts +1 -9
- package/src/test/no-device-internals.test.ts +51 -0
- package/src/components/custom/Workout/TempoBar.stories.tsx +0 -164
- package/src/components/custom/Workout/TempoBar.test.tsx +0 -218
- package/src/components/custom/Workout/TempoBar.tsx +0 -300
package/dist/pages.js
CHANGED
|
@@ -78,6 +78,7 @@ var primitiveRamps = {
|
|
|
78
78
|
500: "#22A444",
|
|
79
79
|
600: "#298732"},
|
|
80
80
|
cyan: {
|
|
81
|
+
300: "#22D3EE",
|
|
81
82
|
// pin
|
|
82
83
|
400: "#01B5D1",
|
|
83
84
|
500: "#2697B7",
|
|
@@ -92,6 +93,7 @@ var primitiveRamps = {
|
|
|
92
93
|
// pin
|
|
93
94
|
600: "#1072CB"},
|
|
94
95
|
magenta: {
|
|
96
|
+
400: "#ED69C3",
|
|
95
97
|
600: "#BA2996"}
|
|
96
98
|
};
|
|
97
99
|
var sequentialEffort = [
|
|
@@ -611,13 +613,15 @@ var BARE_STUB_HEIGHT = 3;
|
|
|
611
613
|
var HERO_HEIGHT = 220;
|
|
612
614
|
var HERO_LABEL_HEADROOM = 20;
|
|
613
615
|
var HERO_BAR_GAP = 8;
|
|
614
|
-
var HERO_BAR_MAX_WIDTH =
|
|
616
|
+
var HERO_BAR_MAX_WIDTH = 120;
|
|
617
|
+
var HERO_LABEL_MIN_BAR_WIDTH = 30;
|
|
615
618
|
var HERO_BAR_RADIUS = 5;
|
|
616
619
|
var HERO_MIN_BAR_HEIGHT = 4;
|
|
617
620
|
var HERO_PENDING_COLOR = primitiveColors.charcoal[100];
|
|
618
621
|
var HERO_REFERENCE_COLOR = primitiveColors.charcoal[0];
|
|
622
|
+
var PEAK_HEADROOM = 1.06;
|
|
619
623
|
function scaleDenominator(scale, maxVelocity) {
|
|
620
|
-
return scale === "fixed" ? FIXED_MAX_VELOCITY : maxVelocity *
|
|
624
|
+
return scale === "fixed" ? FIXED_MAX_VELOCITY : maxVelocity * PEAK_HEADROOM;
|
|
621
625
|
}
|
|
622
626
|
function bareSlotHeight(slot, height, denom) {
|
|
623
627
|
if (slot.kind !== "rep" || denom <= 0) return BARE_STUB_HEIGHT;
|
|
@@ -694,10 +698,21 @@ function HeroVelocityChart({
|
|
|
694
698
|
}) {
|
|
695
699
|
const liveVelocity = liveRepIndex != null ? doneVelocities[liveRepIndex] : void 0;
|
|
696
700
|
const liveScale = useLiveRepPop(true, liveRepIndex, liveVelocity, isNewPeak);
|
|
701
|
+
const [plotW, setPlotW] = react.useState(0);
|
|
702
|
+
const onPlotLayout = (e) => setPlotW(e.nativeEvent.layout.width);
|
|
697
703
|
const plotHeight = Math.max(0, height - HERO_LABEL_HEADROOM);
|
|
698
704
|
const barHeight = (velocity) => scaleDenom > 0 ? Math.max(HERO_MIN_BAR_HEIGHT, Math.min(1, velocity / scaleDenom) * plotHeight) : HERO_MIN_BAR_HEIGHT;
|
|
699
705
|
const pendingCount = Math.max(0, (targetReps ?? 0) - doneVelocities.length);
|
|
700
706
|
const referencePx = referenceVelocity > 0 && scaleDenom > 0 ? Math.min(plotHeight, referenceVelocity / scaleDenom * plotHeight) : 0;
|
|
707
|
+
const totalSlots = doneVelocities.length + pendingCount;
|
|
708
|
+
const barWidth = plotW > 0 && totalSlots > 0 ? Math.min(HERO_BAR_MAX_WIDTH, (plotW - HERO_BAR_GAP * (totalSlots - 1)) / totalSlots) : HERO_BAR_MAX_WIDTH;
|
|
709
|
+
const labelsCrowded = plotW > 0 && barWidth < HERO_LABEL_MIN_BAR_WIDTH;
|
|
710
|
+
const heroGap = plotW === 0 ? HERO_BAR_GAP : barWidth < 16 ? 2 : barWidth < 28 ? 4 : HERO_BAR_GAP;
|
|
711
|
+
const peakIndex = doneVelocities.reduce(
|
|
712
|
+
(best, v, i) => v > doneVelocities[best] ? i : best,
|
|
713
|
+
0
|
|
714
|
+
);
|
|
715
|
+
const showBarLabel = (i) => !labelsCrowded || i === peakIndex || i === liveRepIndex;
|
|
701
716
|
const repCount = doneVelocities.length;
|
|
702
717
|
const total = Math.max(repCount, targetReps ?? repCount);
|
|
703
718
|
const label = referenceVelocity > 0 ? `Velocity chart, ${repCount} of ${total} reps, best ${formatVelocity(referenceVelocity)} meters per second` : `Velocity chart, ${repCount} of ${total} reps`;
|
|
@@ -714,11 +729,12 @@ function HeroVelocityChart({
|
|
|
714
729
|
children: /* @__PURE__ */ jsxs(
|
|
715
730
|
reactNative.View,
|
|
716
731
|
{
|
|
732
|
+
onLayout: onPlotLayout,
|
|
717
733
|
style: {
|
|
718
734
|
flex: 1,
|
|
719
735
|
flexDirection: "row",
|
|
720
736
|
alignItems: "flex-end",
|
|
721
|
-
gap:
|
|
737
|
+
gap: heroGap,
|
|
722
738
|
position: "relative",
|
|
723
739
|
borderBottomWidth: 2,
|
|
724
740
|
borderBottomColor: HERO_PENDING_COLOR
|
|
@@ -755,7 +771,7 @@ function HeroVelocityChart({
|
|
|
755
771
|
justifyContent: "flex-end"
|
|
756
772
|
},
|
|
757
773
|
children: [
|
|
758
|
-
/* @__PURE__ */ jsx(
|
|
774
|
+
showBarLabel(i) && /* @__PURE__ */ jsx(
|
|
759
775
|
reactNative.Text,
|
|
760
776
|
{
|
|
761
777
|
className: "text-text-primary",
|
|
@@ -1954,6 +1970,7 @@ function SetsRepsLoad({
|
|
|
1954
1970
|
reps,
|
|
1955
1971
|
load,
|
|
1956
1972
|
unit = "lb",
|
|
1973
|
+
fontSize,
|
|
1957
1974
|
className,
|
|
1958
1975
|
...props
|
|
1959
1976
|
}) {
|
|
@@ -1968,12 +1985,12 @@ function SetsRepsLoad({
|
|
|
1968
1985
|
testID: "sets-reps-load",
|
|
1969
1986
|
...props,
|
|
1970
1987
|
children: [
|
|
1971
|
-
/* @__PURE__ */ jsx(MetricCell, { color: value, children: sets }),
|
|
1972
|
-
/* @__PURE__ */ jsx(MetricCell, { color: sep, children: ` ${TIMES} ` }),
|
|
1973
|
-
/* @__PURE__ */ jsx(MetricCell, { color: value, children: reps }),
|
|
1974
|
-
/* @__PURE__ */ jsx(MetricCell, { color: sep, children: ` ${AT} ` }),
|
|
1975
|
-
/* @__PURE__ */ jsx(MetricCell, { color: value, children: load }),
|
|
1976
|
-
/* @__PURE__ */ jsx(MetricCell, { color: sep, children: ` ${unit}` })
|
|
1988
|
+
/* @__PURE__ */ jsx(MetricCell, { color: value, fontSize, children: sets }),
|
|
1989
|
+
/* @__PURE__ */ jsx(MetricCell, { color: sep, fontSize, children: ` ${TIMES} ` }),
|
|
1990
|
+
/* @__PURE__ */ jsx(MetricCell, { color: value, fontSize, children: reps }),
|
|
1991
|
+
/* @__PURE__ */ jsx(MetricCell, { color: sep, fontSize, children: ` ${AT} ` }),
|
|
1992
|
+
/* @__PURE__ */ jsx(MetricCell, { color: value, fontSize, children: load }),
|
|
1993
|
+
/* @__PURE__ */ jsx(MetricCell, { color: sep, fontSize, children: ` ${unit}` })
|
|
1977
1994
|
]
|
|
1978
1995
|
}
|
|
1979
1996
|
);
|
|
@@ -2287,36 +2304,34 @@ function alpha(color, opacity) {
|
|
|
2287
2304
|
}
|
|
2288
2305
|
return color;
|
|
2289
2306
|
}
|
|
2307
|
+
|
|
2308
|
+
// src/components/custom/Workout/TempoDisplay.tsx
|
|
2290
2309
|
var t2 = getSemanticColors("dark");
|
|
2291
|
-
var
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
const ratio = elapsedMs / targetMs;
|
|
2298
|
-
if (ratio > 1 + TEMPO_PACING.behindThresholdPct) return "behind";
|
|
2299
|
-
return "on-pace";
|
|
2300
|
-
}
|
|
2310
|
+
var INTER = "Inter, sans-serif";
|
|
2311
|
+
var TEXT_TERTIARY = "#6B7280";
|
|
2312
|
+
var STATUS_ERROR = t2["status-error"];
|
|
2313
|
+
var STATUS_SUCCESS = t2["status-success"];
|
|
2314
|
+
var STATUS_WARNING = t2["status-warning"];
|
|
2315
|
+
var ON_TARGET_MS = 100;
|
|
2301
2316
|
function getTempoFillPct(elapsedMs, targetMs) {
|
|
2302
2317
|
if (!targetMs) return 100;
|
|
2303
2318
|
return Math.min(100, elapsedMs / targetMs * 100);
|
|
2304
2319
|
}
|
|
2305
|
-
({
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2320
|
+
function activeNumberTone(elapsedMs, targetMs) {
|
|
2321
|
+
if (targetMs == null) return t2["text-primary"];
|
|
2322
|
+
const remainingMs = targetMs - elapsedMs;
|
|
2323
|
+
if (remainingMs > ON_TARGET_MS) return STATUS_WARNING;
|
|
2324
|
+
if (remainingMs >= -ON_TARGET_MS) return STATUS_SUCCESS;
|
|
2325
|
+
return STATUS_ERROR;
|
|
2326
|
+
}
|
|
2327
|
+
function liveReadoutText(elapsedMs, targetMs, readout) {
|
|
2328
|
+
const seconds = readout === "countup" ? elapsedMs / 1e3 : (targetMs - elapsedMs) / 1e3;
|
|
2329
|
+
return seconds.toFixed(1);
|
|
2330
|
+
}
|
|
2316
2331
|
var phaseColors = {
|
|
2317
|
-
eccentric:
|
|
2332
|
+
eccentric: primitiveRamps.magenta[400],
|
|
2318
2333
|
pauseBottom: TEXT_TERTIARY,
|
|
2319
|
-
concentric:
|
|
2334
|
+
concentric: primitiveRamps.cyan[300],
|
|
2320
2335
|
pauseTop: TEXT_TERTIARY,
|
|
2321
2336
|
dash: TEXT_TERTIARY
|
|
2322
2337
|
};
|
|
@@ -2336,63 +2351,98 @@ var LIVE_PHASES = [
|
|
|
2336
2351
|
{ key: "concentric", color: phaseColors.concentric },
|
|
2337
2352
|
{ key: "pauseTop", color: phaseColors.pauseTop }
|
|
2338
2353
|
];
|
|
2354
|
+
function CellFill({ color, pct }) {
|
|
2355
|
+
return /* @__PURE__ */ jsx(
|
|
2356
|
+
reactNative.View,
|
|
2357
|
+
{
|
|
2358
|
+
style: {
|
|
2359
|
+
position: "absolute",
|
|
2360
|
+
left: 2,
|
|
2361
|
+
right: 2,
|
|
2362
|
+
bottom: 0,
|
|
2363
|
+
height: `${pct}%`,
|
|
2364
|
+
backgroundColor: alpha(color, 0.28),
|
|
2365
|
+
borderRadius: 3
|
|
2366
|
+
}
|
|
2367
|
+
}
|
|
2368
|
+
);
|
|
2369
|
+
}
|
|
2370
|
+
var MONO = "ui-monospace, SFMono-Regular, Menlo, Consolas, monospace";
|
|
2371
|
+
var READOUT_MAX_CHARS = 5;
|
|
2339
2372
|
function LiveTempoCell({
|
|
2340
2373
|
value,
|
|
2341
2374
|
color,
|
|
2342
|
-
|
|
2375
|
+
status,
|
|
2343
2376
|
phaseElapsedMs,
|
|
2344
|
-
|
|
2377
|
+
completedMs,
|
|
2378
|
+
fontSize,
|
|
2379
|
+
readout
|
|
2345
2380
|
}) {
|
|
2346
|
-
if (!isActive) {
|
|
2347
|
-
return /* @__PURE__ */ jsx(TempoValue, { value, color: alpha(color, 0.35), fontSize });
|
|
2348
|
-
}
|
|
2349
2381
|
const targetMs = value > 0 ? value * 1e3 : null;
|
|
2350
|
-
const
|
|
2382
|
+
const cellW = Math.ceil(fontSize * 0.62 * READOUT_MAX_CHARS);
|
|
2383
|
+
const wrap = {
|
|
2384
|
+
position: "relative",
|
|
2385
|
+
width: cellW,
|
|
2386
|
+
minHeight: Math.round(fontSize * 1.25),
|
|
2387
|
+
alignItems: "center",
|
|
2388
|
+
justifyContent: "center"
|
|
2389
|
+
};
|
|
2390
|
+
const num = (c, text) => /* @__PURE__ */ jsx(reactNative.Text, { style: { fontFamily: MONO, fontSize, color: c, fontWeight: "700" }, children: text });
|
|
2391
|
+
if (status === "upcoming") {
|
|
2392
|
+
const targetText = targetMs != null ? (targetMs / 1e3).toFixed(1) : String(value);
|
|
2393
|
+
return /* @__PURE__ */ jsx(reactNative.View, { style: wrap, children: num(color, targetText) });
|
|
2394
|
+
}
|
|
2395
|
+
if (status === "done") {
|
|
2396
|
+
const finalMs = completedMs ?? targetMs ?? 0;
|
|
2397
|
+
const finalText = targetMs != null ? liveReadoutText(finalMs, targetMs, readout) : String(value);
|
|
2398
|
+
const finalTone = targetMs != null ? activeNumberTone(finalMs, targetMs) : color;
|
|
2399
|
+
return /* @__PURE__ */ jsxs(reactNative.View, { style: wrap, testID: "tempo-live-done", children: [
|
|
2400
|
+
/* @__PURE__ */ jsx(CellFill, { color, pct: 100 }),
|
|
2401
|
+
num(finalTone, finalText)
|
|
2402
|
+
] });
|
|
2403
|
+
}
|
|
2404
|
+
const numberTone = activeNumberTone(phaseElapsedMs, targetMs);
|
|
2351
2405
|
const fillPct = getTempoFillPct(phaseElapsedMs, targetMs);
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
style: {
|
|
2357
|
-
position: "absolute",
|
|
2358
|
-
left: 0,
|
|
2359
|
-
top: 0,
|
|
2360
|
-
bottom: 0,
|
|
2361
|
-
width: `${fillPct}%`,
|
|
2362
|
-
backgroundColor: alpha(barColor, 0.3),
|
|
2363
|
-
borderRadius: 2
|
|
2364
|
-
}
|
|
2365
|
-
}
|
|
2366
|
-
),
|
|
2367
|
-
/* @__PURE__ */ jsx(TempoValue, { value, color: barColor, fontSize })
|
|
2406
|
+
const activeText = targetMs != null ? liveReadoutText(phaseElapsedMs, targetMs, readout) : String(value);
|
|
2407
|
+
return /* @__PURE__ */ jsxs(reactNative.View, { style: wrap, testID: "tempo-live-active", children: [
|
|
2408
|
+
/* @__PURE__ */ jsx(CellFill, { color, pct: fillPct }),
|
|
2409
|
+
num(numberTone, activeText)
|
|
2368
2410
|
] });
|
|
2369
2411
|
}
|
|
2370
2412
|
function LiveTempoRow({
|
|
2371
2413
|
values,
|
|
2372
2414
|
live,
|
|
2373
|
-
fontSize
|
|
2415
|
+
fontSize,
|
|
2416
|
+
readout
|
|
2374
2417
|
}) {
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
{
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2418
|
+
const activeIndex = live.activePhase ? LIVE_PHASES.findIndex((p) => p.key === live.activePhase) : -1;
|
|
2419
|
+
return /* @__PURE__ */ jsx(jsxRuntime.Fragment, { children: LIVE_PHASES.map((phase, i) => {
|
|
2420
|
+
const status = activeIndex < 0 || i > activeIndex ? "upcoming" : i < activeIndex ? "done" : "active";
|
|
2421
|
+
return /* @__PURE__ */ jsxs(reactNative.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
2422
|
+
i > 0 && /* @__PURE__ */ jsx(TempoSeparator, { color: phaseColors.dash, fontSize }),
|
|
2423
|
+
/* @__PURE__ */ jsx(
|
|
2424
|
+
LiveTempoCell,
|
|
2425
|
+
{
|
|
2426
|
+
value: values[i],
|
|
2427
|
+
color: phase.color,
|
|
2428
|
+
status,
|
|
2429
|
+
phaseElapsedMs: live.phaseElapsedMs,
|
|
2430
|
+
completedMs: live.completed?.[phase.key],
|
|
2431
|
+
fontSize,
|
|
2432
|
+
readout
|
|
2433
|
+
}
|
|
2434
|
+
)
|
|
2435
|
+
] }, phase.key);
|
|
2436
|
+
}) });
|
|
2388
2437
|
}
|
|
2389
2438
|
function TempoDisplay({
|
|
2390
2439
|
tempo,
|
|
2391
2440
|
size = "md",
|
|
2392
|
-
|
|
2441
|
+
fontSize: fontSizeProp,
|
|
2393
2442
|
showLabel = true,
|
|
2394
2443
|
showInfo = true,
|
|
2395
2444
|
live,
|
|
2445
|
+
liveReadout = "countdown",
|
|
2396
2446
|
onPress,
|
|
2397
2447
|
className,
|
|
2398
2448
|
...props
|
|
@@ -2400,8 +2450,11 @@ function TempoDisplay({
|
|
|
2400
2450
|
const [showTooltip, setShowTooltip] = react.useState(false);
|
|
2401
2451
|
const [eccentric, pauseBottom, concentric, pauseTop] = roundTempo(tempo);
|
|
2402
2452
|
const isSm = size === "sm";
|
|
2403
|
-
const fontSize = isSm ? 9 : 11;
|
|
2404
|
-
const
|
|
2453
|
+
const fontSize = fontSizeProp ?? (isSm ? 9 : 11);
|
|
2454
|
+
const chromePadX = Math.round(fontSize * 0.6);
|
|
2455
|
+
const chromePadY = Math.round(fontSize * 0.3);
|
|
2456
|
+
const chromeRadius = Math.round(fontSize * 0.4);
|
|
2457
|
+
const labelFont = Math.max(9, Math.round(fontSize * 0.5));
|
|
2405
2458
|
const handlePress = react.useCallback(() => {
|
|
2406
2459
|
if (onPress) {
|
|
2407
2460
|
onPress();
|
|
@@ -2418,9 +2471,9 @@ function TempoDisplay({
|
|
|
2418
2471
|
flexDirection: "row",
|
|
2419
2472
|
alignItems: "center",
|
|
2420
2473
|
backgroundColor: "#1C1C1C",
|
|
2421
|
-
paddingHorizontal:
|
|
2422
|
-
paddingVertical:
|
|
2423
|
-
borderRadius:
|
|
2474
|
+
paddingHorizontal: chromePadX,
|
|
2475
|
+
paddingVertical: chromePadY,
|
|
2476
|
+
borderRadius: chromeRadius
|
|
2424
2477
|
},
|
|
2425
2478
|
...props,
|
|
2426
2479
|
children: [
|
|
@@ -2429,12 +2482,13 @@ function TempoDisplay({
|
|
|
2429
2482
|
{
|
|
2430
2483
|
style: {
|
|
2431
2484
|
fontFamily: INTER,
|
|
2432
|
-
fontSize:
|
|
2485
|
+
fontSize: labelFont,
|
|
2433
2486
|
fontWeight: "500",
|
|
2434
|
-
|
|
2487
|
+
// Live-muted green while a rep is running, tertiary at rest.
|
|
2488
|
+
color: live ? t2["status-live-muted"] : TEXT_TERTIARY,
|
|
2435
2489
|
letterSpacing: 0.5,
|
|
2436
2490
|
textTransform: "uppercase",
|
|
2437
|
-
marginRight:
|
|
2491
|
+
marginRight: Math.round(fontSize * 0.5)
|
|
2438
2492
|
},
|
|
2439
2493
|
children: "TEMPO"
|
|
2440
2494
|
}
|
|
@@ -2444,36 +2498,20 @@ function TempoDisplay({
|
|
|
2444
2498
|
{
|
|
2445
2499
|
values: [eccentric, pauseBottom, concentric, pauseTop],
|
|
2446
2500
|
live,
|
|
2447
|
-
fontSize
|
|
2448
|
-
|
|
2449
|
-
) : colored ? /* @__PURE__ */ jsxs(jsxRuntime.Fragment, { children: [
|
|
2450
|
-
/* @__PURE__ */ jsx(TempoValue, { value: eccentric, color: phaseColors.eccentric, fontSize }),
|
|
2451
|
-
/* @__PURE__ */ jsx(TempoSeparator, { color: phaseColors.dash, fontSize }),
|
|
2452
|
-
/* @__PURE__ */ jsx(TempoValue, { value: pauseBottom, color: phaseColors.pauseBottom, fontSize }),
|
|
2453
|
-
/* @__PURE__ */ jsx(TempoSeparator, { color: phaseColors.dash, fontSize }),
|
|
2454
|
-
/* @__PURE__ */ jsx(TempoValue, { value: concentric, color: phaseColors.concentric, fontSize }),
|
|
2455
|
-
/* @__PURE__ */ jsx(TempoSeparator, { color: phaseColors.dash, fontSize }),
|
|
2456
|
-
/* @__PURE__ */ jsx(TempoValue, { value: pauseTop, color: phaseColors.pauseTop, fontSize })
|
|
2457
|
-
] }) : /* @__PURE__ */ jsxs(
|
|
2458
|
-
reactNative.Text,
|
|
2459
|
-
{
|
|
2460
|
-
style: {
|
|
2461
|
-
fontFamily: INTER,
|
|
2462
|
-
fontSize,
|
|
2463
|
-
color: monoColor,
|
|
2464
|
-
fontWeight: "600",
|
|
2465
|
-
letterSpacing: 1
|
|
2466
|
-
},
|
|
2467
|
-
children: [
|
|
2468
|
-
eccentric,
|
|
2469
|
-
"-",
|
|
2470
|
-
pauseBottom,
|
|
2471
|
-
"-",
|
|
2472
|
-
concentric,
|
|
2473
|
-
"-",
|
|
2474
|
-
pauseTop
|
|
2475
|
-
]
|
|
2501
|
+
fontSize,
|
|
2502
|
+
readout: liveReadout
|
|
2476
2503
|
}
|
|
2504
|
+
) : (
|
|
2505
|
+
// Static prescription: the phase-coloured lockup (the same colours the live row rests at).
|
|
2506
|
+
/* @__PURE__ */ jsxs(jsxRuntime.Fragment, { children: [
|
|
2507
|
+
/* @__PURE__ */ jsx(TempoValue, { value: eccentric, color: phaseColors.eccentric, fontSize }),
|
|
2508
|
+
/* @__PURE__ */ jsx(TempoSeparator, { color: phaseColors.dash, fontSize }),
|
|
2509
|
+
/* @__PURE__ */ jsx(TempoValue, { value: pauseBottom, color: phaseColors.pauseBottom, fontSize }),
|
|
2510
|
+
/* @__PURE__ */ jsx(TempoSeparator, { color: phaseColors.dash, fontSize }),
|
|
2511
|
+
/* @__PURE__ */ jsx(TempoValue, { value: concentric, color: phaseColors.concentric, fontSize }),
|
|
2512
|
+
/* @__PURE__ */ jsx(TempoSeparator, { color: phaseColors.dash, fontSize }),
|
|
2513
|
+
/* @__PURE__ */ jsx(TempoValue, { value: pauseTop, color: phaseColors.pauseTop, fontSize })
|
|
2514
|
+
] })
|
|
2477
2515
|
) })
|
|
2478
2516
|
]
|
|
2479
2517
|
}
|
|
@@ -2558,14 +2596,14 @@ function TempoDisplay({
|
|
|
2558
2596
|
}
|
|
2559
2597
|
);
|
|
2560
2598
|
}
|
|
2561
|
-
var
|
|
2599
|
+
var t3 = getSemanticColors("dark");
|
|
2562
2600
|
var INDICATOR_CONFIG = {
|
|
2563
|
-
imbalance: { Icon: ScaleIcon, color:
|
|
2564
|
-
overshoot: { Icon: AlertTriangleIcon, color:
|
|
2565
|
-
"velocity-loss": { Icon: TrendingDownIcon, color:
|
|
2566
|
-
"missed-reps": { Icon: CircleSlashIcon, color:
|
|
2567
|
-
pr: { Icon: AwardIcon, color:
|
|
2568
|
-
info: { Icon: InfoIcon, color:
|
|
2601
|
+
imbalance: { Icon: ScaleIcon, color: t3["status-error"], label: "Left/right imbalance" },
|
|
2602
|
+
overshoot: { Icon: AlertTriangleIcon, color: t3["status-error"], label: "Load overshoot" },
|
|
2603
|
+
"velocity-loss": { Icon: TrendingDownIcon, color: t3["status-warning"], label: "Velocity loss" },
|
|
2604
|
+
"missed-reps": { Icon: CircleSlashIcon, color: t3["status-warning"], label: "Missed reps" },
|
|
2605
|
+
pr: { Icon: AwardIcon, color: t3["status-success"], label: "Personal record" },
|
|
2606
|
+
info: { Icon: InfoIcon, color: t3["status-info"], label: "More info" }
|
|
2569
2607
|
};
|
|
2570
2608
|
function ExerciseIndicator({ kind, onPress, className, ...props }) {
|
|
2571
2609
|
const { Icon, color, label } = INDICATOR_CONFIG[kind];
|
|
@@ -4362,11 +4400,11 @@ function CardContent({ children, className }) {
|
|
|
4362
4400
|
function CardFooter({ children, className }) {
|
|
4363
4401
|
return /* @__PURE__ */ jsx(reactNative.View, { className: cn("px-6 py-4 flex-row items-center gap-2", className), children });
|
|
4364
4402
|
}
|
|
4365
|
-
var
|
|
4403
|
+
var t4 = getSemanticColors("dark");
|
|
4366
4404
|
var solidVariantColors = {
|
|
4367
|
-
success:
|
|
4368
|
-
warning:
|
|
4369
|
-
error:
|
|
4405
|
+
success: t4["status-success"],
|
|
4406
|
+
warning: t4["status-warning"],
|
|
4407
|
+
error: t4["status-error"],
|
|
4370
4408
|
neutral: "#6B7280"
|
|
4371
4409
|
};
|
|
4372
4410
|
var ringVariantStyles = {
|
|
@@ -4406,8 +4444,8 @@ var iconColors = {
|
|
|
4406
4444
|
warning: "#6B4000",
|
|
4407
4445
|
error: "#5C1A1A",
|
|
4408
4446
|
neutral: "#D1D5DB",
|
|
4409
|
-
"on-track":
|
|
4410
|
-
deviation:
|
|
4447
|
+
"on-track": t4["status-success"],
|
|
4448
|
+
deviation: t4["status-warning"],
|
|
4411
4449
|
future: "#6B7280"
|
|
4412
4450
|
};
|
|
4413
4451
|
var sizeDimensions = {
|
|
@@ -4493,13 +4531,13 @@ var MESO_ACCENT_GRADIENT_LIGHT = primitiveRamps.orange[300];
|
|
|
4493
4531
|
var WORKOUT_PILL_DELOAD = primitiveRamps.magenta[600];
|
|
4494
4532
|
|
|
4495
4533
|
// src/components/custom/Workout/MesoStatusCard.tsx
|
|
4496
|
-
var
|
|
4497
|
-
var BRAND_PRIMARY5 =
|
|
4534
|
+
var t5 = getSemanticColors("dark");
|
|
4535
|
+
var BRAND_PRIMARY5 = t5["brand-primary"];
|
|
4498
4536
|
var BRAND_PRIMARY_DARK = MESO_ACCENT_GRADIENT_DARK;
|
|
4499
4537
|
var BRAND_PRIMARY_LIGHT = MESO_ACCENT_GRADIENT_LIGHT;
|
|
4500
|
-
var SUCCESS =
|
|
4501
|
-
var WARNING =
|
|
4502
|
-
var ERROR =
|
|
4538
|
+
var SUCCESS = t5["status-success"];
|
|
4539
|
+
var WARNING = t5["status-warning"];
|
|
4540
|
+
var ERROR = t5["status-error"];
|
|
4503
4541
|
var ACCENT_STOPS = [BRAND_PRIMARY_DARK, BRAND_PRIMARY5, BRAND_PRIMARY_LIGHT];
|
|
4504
4542
|
var CARD_GRADIENT = `linear-gradient(135deg, ${resolveColor("surface-elevated")} 0%, ${resolveColor("surface-raised")} 100%)`;
|
|
4505
4543
|
var GAUGE_GRADIENT = "linear-gradient(90deg, rgba(46,213,115,0.25) 0%, rgba(249,180,21,0.25) 50%, rgba(209,67,67,0.25) 100%)";
|
|
@@ -4859,9 +4897,9 @@ function MesoStatusCard({
|
|
|
4859
4897
|
var sem = getSemanticColors("dark");
|
|
4860
4898
|
var BRAND_PRIMARY6 = sem["brand-primary"];
|
|
4861
4899
|
var PROJECTION_LINE_COLOR = resolveColor("text-tertiary");
|
|
4862
|
-
var
|
|
4900
|
+
var STATUS_SUCCESS2 = sem["status-success"];
|
|
4863
4901
|
var STATUS_ERROR2 = sem["status-error"];
|
|
4864
|
-
var
|
|
4902
|
+
var STATUS_WARNING2 = sem["status-warning"];
|
|
4865
4903
|
var GRID_LINE = "rgba(255,255,255,0.06)";
|
|
4866
4904
|
var SUCCESS_PILL_BG = "rgba(46,213,115,0.10)";
|
|
4867
4905
|
var SUCCESS_PILL_BORDER = "rgba(46,213,115,0.20)";
|
|
@@ -4870,8 +4908,8 @@ var ERROR_PILL_BORDER = "rgba(209,67,67,0.20)";
|
|
|
4870
4908
|
var PLOT_LEFT = 26;
|
|
4871
4909
|
var TOOLTIP_WIDTH = 124;
|
|
4872
4910
|
function timeOf(dateStr) {
|
|
4873
|
-
const
|
|
4874
|
-
return Number.isNaN(
|
|
4911
|
+
const t11 = Date.parse(dateStr);
|
|
4912
|
+
return Number.isNaN(t11) ? 0 : t11;
|
|
4875
4913
|
}
|
|
4876
4914
|
function formatValue(value) {
|
|
4877
4915
|
return `${Math.round(value)}`;
|
|
@@ -5167,7 +5205,7 @@ function StrengthTrendChart({
|
|
|
5167
5205
|
left: c.x - 7,
|
|
5168
5206
|
top: c.y - 20,
|
|
5169
5207
|
fontSize: 12,
|
|
5170
|
-
color:
|
|
5208
|
+
color: STATUS_WARNING2
|
|
5171
5209
|
},
|
|
5172
5210
|
children: "\u2605"
|
|
5173
5211
|
},
|
|
@@ -5260,7 +5298,7 @@ function StrengthTrendChart({
|
|
|
5260
5298
|
marginTop: 1,
|
|
5261
5299
|
fontSize: 10,
|
|
5262
5300
|
fontFamily: "Inter, sans-serif",
|
|
5263
|
-
color: selectedCoord.point.e1rm - geometry.actual[selected - 1].point.e1rm >= 0 ?
|
|
5301
|
+
color: selectedCoord.point.e1rm - geometry.actual[selected - 1].point.e1rm >= 0 ? STATUS_SUCCESS2 : STATUS_ERROR2
|
|
5264
5302
|
},
|
|
5265
5303
|
children: `${selectedCoord.point.e1rm - geometry.actual[selected - 1].point.e1rm >= 0 ? "+" : "-"}${Math.abs(
|
|
5266
5304
|
selectedCoord.point.e1rm - geometry.actual[selected - 1].point.e1rm
|
|
@@ -5316,7 +5354,7 @@ function StrengthTrendChart({
|
|
|
5316
5354
|
fontSize: 11,
|
|
5317
5355
|
fontFamily: "Inter, sans-serif",
|
|
5318
5356
|
fontWeight: "600",
|
|
5319
|
-
color: trend.positive ?
|
|
5357
|
+
color: trend.positive ? STATUS_SUCCESS2 : STATUS_ERROR2
|
|
5320
5358
|
},
|
|
5321
5359
|
children: trendText
|
|
5322
5360
|
}
|
|
@@ -5350,7 +5388,7 @@ function StrengthTrendChart({
|
|
|
5350
5388
|
/* @__PURE__ */ jsx(reactNative.Text, { className: "text-text-secondary", style: { fontSize: 10, fontFamily: "Inter, sans-serif" }, children: "Projected" })
|
|
5351
5389
|
] }),
|
|
5352
5390
|
/* @__PURE__ */ jsxs(reactNative.View, { className: "flex-row items-center", style: { gap: 5 }, children: [
|
|
5353
|
-
/* @__PURE__ */ jsx(reactNative.Text, { style: { fontSize: 12, color:
|
|
5391
|
+
/* @__PURE__ */ jsx(reactNative.Text, { style: { fontSize: 12, color: STATUS_WARNING2 }, children: "\u2605" }),
|
|
5354
5392
|
/* @__PURE__ */ jsx(reactNative.Text, { className: "text-text-secondary", style: { fontSize: 10, fontFamily: "Inter, sans-serif" }, children: "PR" })
|
|
5355
5393
|
] })
|
|
5356
5394
|
]
|
|
@@ -5360,10 +5398,10 @@ function StrengthTrendChart({
|
|
|
5360
5398
|
}
|
|
5361
5399
|
);
|
|
5362
5400
|
}
|
|
5363
|
-
var
|
|
5364
|
-
var
|
|
5365
|
-
var
|
|
5366
|
-
var STATUS_INFO =
|
|
5401
|
+
var t6 = getSemanticColors("dark");
|
|
5402
|
+
var STATUS_SUCCESS3 = t6["status-success"];
|
|
5403
|
+
var STATUS_WARNING3 = t6["status-warning"];
|
|
5404
|
+
var STATUS_INFO = t6["status-info"];
|
|
5367
5405
|
var DOT_BORDER = "#F3F4F6";
|
|
5368
5406
|
var BAND_FILL = "rgba(46,213,115,0.1)";
|
|
5369
5407
|
var BAND_EDGE = "rgba(46,213,115,0.45)";
|
|
@@ -5375,8 +5413,8 @@ var PADDING_BOTTOM = 16;
|
|
|
5375
5413
|
var COLUMN_STEP = 4;
|
|
5376
5414
|
var DOT_SIZE = 8;
|
|
5377
5415
|
var DOT_COLORS = {
|
|
5378
|
-
within:
|
|
5379
|
-
above:
|
|
5416
|
+
within: STATUS_SUCCESS3,
|
|
5417
|
+
above: STATUS_WARNING3,
|
|
5380
5418
|
below: STATUS_INFO
|
|
5381
5419
|
};
|
|
5382
5420
|
var STATUS_PHRASES = {
|
|
@@ -5406,8 +5444,8 @@ function interpEdge(pixels, x, key) {
|
|
|
5406
5444
|
const a = pixels[i];
|
|
5407
5445
|
const b = pixels[i + 1];
|
|
5408
5446
|
if (x >= a.x && x <= b.x) {
|
|
5409
|
-
const
|
|
5410
|
-
return a[key] +
|
|
5447
|
+
const t11 = b.x === a.x ? 0 : (x - a.x) / (b.x - a.x);
|
|
5448
|
+
return a[key] + t11 * (b[key] - a[key]);
|
|
5411
5449
|
}
|
|
5412
5450
|
}
|
|
5413
5451
|
return pixels[pixels.length - 1][key];
|
|
@@ -5601,8 +5639,8 @@ function CapacityBandChart({
|
|
|
5601
5639
|
projection && /* @__PURE__ */ jsxs(reactNative.View, { testID: "capacity-band-chart-projection", children: [
|
|
5602
5640
|
renderColumns(buildColumns2(trainingPixels, COLUMN_STEP), PROJECTION_FILL, "capacity-band-chart-projection-fill"),
|
|
5603
5641
|
renderColumns(buildColumns2(restPixels, COLUMN_STEP), PROJECTION_FILL, "capacity-band-chart-projection-fill"),
|
|
5604
|
-
renderEdges(buildEdges(trainingPixels, "yHigh"),
|
|
5605
|
-
renderEdges(buildEdges(trainingPixels, "yLow"),
|
|
5642
|
+
renderEdges(buildEdges(trainingPixels, "yHigh"), STATUS_SUCCESS3, true, "capacity-band-chart-projection-training"),
|
|
5643
|
+
renderEdges(buildEdges(trainingPixels, "yLow"), STATUS_SUCCESS3, true, "capacity-band-chart-projection-training"),
|
|
5606
5644
|
renderEdges(buildEdges(restPixels, "yHigh"), STATUS_INFO, true, "capacity-band-chart-projection-rest"),
|
|
5607
5645
|
renderEdges(buildEdges(restPixels, "yLow"), STATUS_INFO, true, "capacity-band-chart-projection-rest"),
|
|
5608
5646
|
/* @__PURE__ */ jsx(
|
|
@@ -5614,7 +5652,7 @@ function CapacityBandChart({
|
|
|
5614
5652
|
top: trainingPixels[trainingPixels.length - 1]?.yHigh - 12,
|
|
5615
5653
|
fontSize: 9,
|
|
5616
5654
|
fontFamily: "Inter, sans-serif",
|
|
5617
|
-
color:
|
|
5655
|
+
color: STATUS_SUCCESS3
|
|
5618
5656
|
},
|
|
5619
5657
|
testID: "capacity-band-chart-projection-training-label",
|
|
5620
5658
|
children: "Training"
|
|
@@ -6446,7 +6484,7 @@ function Badge({
|
|
|
6446
6484
|
}
|
|
6447
6485
|
);
|
|
6448
6486
|
}
|
|
6449
|
-
var
|
|
6487
|
+
var t7 = getSemanticColors("dark");
|
|
6450
6488
|
var statusBgColors = {
|
|
6451
6489
|
completed: "rgba(46,213,115,0.15)",
|
|
6452
6490
|
current: "rgba(255,121,0,0.15)",
|
|
@@ -6464,9 +6502,9 @@ var statusBorderStyles = {
|
|
|
6464
6502
|
deload: { borderWidth: 1, borderColor: "rgba(186,41,150,0.3)" }
|
|
6465
6503
|
};
|
|
6466
6504
|
var textColors = {
|
|
6467
|
-
completed:
|
|
6468
|
-
current:
|
|
6469
|
-
next:
|
|
6505
|
+
completed: t7["status-success"],
|
|
6506
|
+
current: t7["brand-primary"],
|
|
6507
|
+
next: t7["brand-primary"],
|
|
6470
6508
|
upcoming: "#6B7280",
|
|
6471
6509
|
missed: "rgba(209,67,67,0.7)",
|
|
6472
6510
|
deload: WORKOUT_PILL_DELOAD
|
|
@@ -6599,19 +6637,19 @@ function WorkoutPill({
|
|
|
6599
6637
|
}
|
|
6600
6638
|
return pill;
|
|
6601
6639
|
}
|
|
6602
|
-
var
|
|
6640
|
+
var t8 = getSemanticColors("dark");
|
|
6603
6641
|
var TRACK_BG = "#333333";
|
|
6604
6642
|
var LABEL_COLOR = "#6B7280";
|
|
6605
6643
|
var TARGET_LINE_COLOR = "rgba(33, 150, 243, 0.5)";
|
|
6606
6644
|
var AT_TARGET_GLOW = "0 0 5px 1px rgba(33, 150, 243, 0.35), 0 0 10px 3px rgba(33, 150, 243, 0.15)";
|
|
6607
6645
|
var ZONE = {
|
|
6608
|
-
building:
|
|
6646
|
+
building: t8["status-success"],
|
|
6609
6647
|
// below target ramp-up
|
|
6610
|
-
approaching:
|
|
6648
|
+
approaching: t8["status-warning"],
|
|
6611
6649
|
// nearing target
|
|
6612
|
-
target:
|
|
6650
|
+
target: t8["brand-primary"],
|
|
6613
6651
|
// exactly at target
|
|
6614
|
-
over1:
|
|
6652
|
+
over1: t8["status-error"],
|
|
6615
6653
|
// mild over-target
|
|
6616
6654
|
over2: WORKOUT_TOKENS.intensity.over2,
|
|
6617
6655
|
// moderate over-target
|
|
@@ -7034,13 +7072,13 @@ function MesoCard({
|
|
|
7034
7072
|
}
|
|
7035
7073
|
) });
|
|
7036
7074
|
}
|
|
7037
|
-
var
|
|
7075
|
+
var t9 = getSemanticColors("dark");
|
|
7038
7076
|
var dotColorMap = {
|
|
7039
7077
|
untrained: "#2C2C2C",
|
|
7040
|
-
behind:
|
|
7041
|
-
ontrack:
|
|
7042
|
-
target:
|
|
7043
|
-
over:
|
|
7078
|
+
behind: t9["brand-secondary"],
|
|
7079
|
+
ontrack: t9["status-success"],
|
|
7080
|
+
target: t9["brand-primary"],
|
|
7081
|
+
over: t9["status-error"]
|
|
7044
7082
|
};
|
|
7045
7083
|
function MuscleGroupChip({
|
|
7046
7084
|
name,
|
|
@@ -7114,10 +7152,10 @@ function MuscleGroupChip({
|
|
|
7114
7152
|
}
|
|
7115
7153
|
|
|
7116
7154
|
// src/components/custom/Workout/WorkoutCard.tsx
|
|
7117
|
-
var
|
|
7155
|
+
var t10 = getSemanticColors("dark");
|
|
7118
7156
|
var COLORS = {
|
|
7119
|
-
statusSuccess:
|
|
7120
|
-
brandPrimary:
|
|
7157
|
+
statusSuccess: t10["status-success"],
|
|
7158
|
+
brandPrimary: t10["brand-primary"],
|
|
7121
7159
|
borderDefault: "#1F1F1F",
|
|
7122
7160
|
brandPrimarySubtle: "rgba(255,121,0,0.06)"
|
|
7123
7161
|
};
|