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