feat(01-input-ux-01): add WeightInput, RepsInput wrappers + stepper CSS
- WeightInput: wraps StepperInput with step=2.5, suffix=kg - RepsInput: wraps StepperInput with step=1, no suffix - App.css: appended stepper styles (.stepper-wrapper, .stepper-btn, etc.) - Buttons min 44x44px touch targets, font-size 16px on input - No existing CSS removed; block appended at end
This commit is contained in:
+154
-4
@@ -50,8 +50,8 @@
|
|||||||
.week-selector button {
|
.week-selector button {
|
||||||
background: var(--bg-card);
|
background: var(--bg-card);
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
width: 36px;
|
width: 44px;
|
||||||
height: 36px;
|
height: 44px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
@@ -506,8 +506,8 @@
|
|||||||
.calendar-nav {
|
.calendar-nav {
|
||||||
background: var(--bg);
|
background: var(--bg);
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
width: 32px;
|
width: 44px;
|
||||||
height: 32px;
|
height: 44px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -659,6 +659,7 @@
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
|
min-height: 44px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.start-workout-btn:hover {
|
.start-workout-btn:hover {
|
||||||
@@ -834,6 +835,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0.25rem;
|
gap: 0.25rem;
|
||||||
|
min-height: 44px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Page Main */
|
/* Page Main */
|
||||||
@@ -874,6 +876,7 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
|
min-height: 44px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Info Grid */
|
/* Info Grid */
|
||||||
@@ -954,6 +957,7 @@
|
|||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
|
min-height: 44px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.save-btn {
|
.save-btn {
|
||||||
@@ -965,6 +969,7 @@
|
|||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
min-height: 44px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.save-btn:disabled {
|
.save-btn:disabled {
|
||||||
@@ -1056,6 +1061,7 @@
|
|||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
color: var(--text-muted);
|
color: var(--text-muted);
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
|
min-height: 44px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-btn.active {
|
.tab-btn.active {
|
||||||
@@ -1322,6 +1328,7 @@
|
|||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
|
min-height: 44px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.warmup-item:hover {
|
.warmup-item:hover {
|
||||||
@@ -1385,6 +1392,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
|
min-height: 44px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.warmup-done-btn:hover {
|
.warmup-done-btn:hover {
|
||||||
@@ -1433,6 +1441,7 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
|
min-height: 44px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.finish-workout-btn:hover {
|
.finish-workout-btn:hover {
|
||||||
@@ -1777,9 +1786,150 @@
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
|
min-height: 44px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.start-btn:hover {
|
.start-btn:hover {
|
||||||
background: var(--accent-hover);
|
background: var(--accent-hover);
|
||||||
transform: scale(1.02);
|
transform: scale(1.02);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
GLOBAL INPUT ACCESSIBILITY
|
||||||
|
Ensure all inputs have font-size >= 16px to prevent iOS auto-zoom
|
||||||
|
============================================ */
|
||||||
|
|
||||||
|
input[type="text"],
|
||||||
|
input[type="email"],
|
||||||
|
input[type="password"],
|
||||||
|
input[type="number"],
|
||||||
|
input[type="tel"],
|
||||||
|
select,
|
||||||
|
textarea {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
STEPPER INPUT COMPONENT
|
||||||
|
============================================ */
|
||||||
|
|
||||||
|
.stepper-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.4rem;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stepper-label {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: var(--text-muted);
|
||||||
|
font-weight: 500;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stepper-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.25rem;
|
||||||
|
background: var(--bg-card);
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
padding: 0.2rem;
|
||||||
|
height: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stepper-btn {
|
||||||
|
width: 44px;
|
||||||
|
height: 44px;
|
||||||
|
min-width: 44px;
|
||||||
|
min-height: 44px;
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-size: 1.4rem;
|
||||||
|
font-weight: 300;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
transition: background 0.15s, color 0.15s;
|
||||||
|
flex-shrink: 0;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stepper-btn:hover:not(:disabled) {
|
||||||
|
background: var(--accent);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stepper-btn:active:not(:disabled) {
|
||||||
|
transform: scale(0.94);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stepper-btn:disabled {
|
||||||
|
opacity: 0.35;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stepper-input-wrapper {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.25rem;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stepper-input {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-size: 16px; /* >= 16px prevents iOS auto-zoom */
|
||||||
|
font-weight: 600;
|
||||||
|
text-align: center;
|
||||||
|
padding: 0.4rem 0.25rem;
|
||||||
|
outline: none;
|
||||||
|
font-family: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stepper-input:disabled {
|
||||||
|
opacity: 0.6;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove browser native number spinners */
|
||||||
|
.stepper-input::-webkit-outer-spin-button,
|
||||||
|
.stepper-input::-webkit-inner-spin-button {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stepper-input[type='number'] {
|
||||||
|
-moz-appearance: textfield;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-suffix {
|
||||||
|
color: var(--text-muted);
|
||||||
|
font-size: 0.8rem;
|
||||||
|
font-weight: 500;
|
||||||
|
white-space: nowrap;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mobile: slightly larger touch targets */
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.stepper-container {
|
||||||
|
height: 52px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stepper-btn {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
min-width: 48px;
|
||||||
|
min-height: 48px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import StepperInput from './StepperInput';
|
||||||
|
|
||||||
|
function RepsInput({ value, onChange, disabled = false }) {
|
||||||
|
return (
|
||||||
|
<StepperInput
|
||||||
|
value={value}
|
||||||
|
onChange={onChange}
|
||||||
|
step={1}
|
||||||
|
min={0}
|
||||||
|
max={null}
|
||||||
|
label="Reps"
|
||||||
|
suffix=""
|
||||||
|
disabled={disabled}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RepsInput;
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import StepperInput from './StepperInput';
|
||||||
|
|
||||||
|
function WeightInput({ value, onChange, disabled = false }) {
|
||||||
|
return (
|
||||||
|
<StepperInput
|
||||||
|
value={value}
|
||||||
|
onChange={onChange}
|
||||||
|
step={2.5}
|
||||||
|
min={0}
|
||||||
|
max={null}
|
||||||
|
label="Weight"
|
||||||
|
suffix="kg"
|
||||||
|
disabled={disabled}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default WeightInput;
|
||||||
Reference in New Issue
Block a user