Improve Majic Rod Solver usability with denser table controls, clearer unit-aware guidance, and stronger accessibility affordances for keyboard/screen-reader workflows. Made-with: Cursor
108 lines
3.4 KiB
TypeScript
108 lines
3.4 KiB
TypeScript
import { useMemo } from "react";
|
|
import type { CaseStore } from "../../state/useCaseStore";
|
|
import { Fieldset } from "../common/Fieldset";
|
|
import { Row } from "../common/Row";
|
|
import { NumberField } from "../common/NumberField";
|
|
import { SelectField } from "../common/SelectField";
|
|
import {
|
|
PUMP_PLUNGER_INCH_OPTIONS,
|
|
formatPumpDiameterDual,
|
|
pumpDiameterMmFromInches
|
|
} from "../../state/unitsDisplay";
|
|
|
|
type Props = { store: CaseStore };
|
|
|
|
export function PumpTab({ store }: Props) {
|
|
const { state, update } = store;
|
|
const isMetric = state.unitsSelection === 1;
|
|
|
|
const pumpOptions = useMemo(() => {
|
|
const mmVals = PUMP_PLUNGER_INCH_OPTIONS.map((inchVal) => pumpDiameterMmFromInches(inchVal));
|
|
const opts = PUMP_PLUNGER_INCH_OPTIONS.map((inchVal, i) => ({
|
|
value: mmVals[i],
|
|
label: formatPumpDiameterDual(mmVals[i], state.unitsSelection)
|
|
}));
|
|
const known = opts.some((o) => Math.abs(o.value - state.pumpDiameter) < 0.001);
|
|
if (!known && state.pumpDiameter > 0) {
|
|
opts.unshift({
|
|
value: state.pumpDiameter,
|
|
label: formatPumpDiameterDual(state.pumpDiameter, state.unitsSelection)
|
|
});
|
|
}
|
|
return opts;
|
|
}, [state.pumpDiameter, state.unitsSelection]);
|
|
|
|
return (
|
|
<div className="tab-grid two">
|
|
<Fieldset legend="Pump Geometry">
|
|
<Row
|
|
label="Plunger diameter"
|
|
htmlFor="plungerDiam"
|
|
hint={
|
|
isMetric
|
|
? "Metric-first display with imperial equivalent in each option."
|
|
: "Imperial-first display with metric equivalent in each option."
|
|
}
|
|
>
|
|
<SelectField
|
|
id="plungerDiam"
|
|
value={state.pumpDiameter}
|
|
options={pumpOptions}
|
|
onChange={(v) => update("pumpDiameter", v)}
|
|
ariaLabel="Pump plunger diameter"
|
|
/>
|
|
</Row>
|
|
<Row
|
|
label="Pump Friction"
|
|
htmlFor="pumpFric"
|
|
hint={isMetric ? "N (SI case)" : "lbf (imperial oilfield case)"}
|
|
>
|
|
<NumberField
|
|
id="pumpFric"
|
|
value={state.pumpFriction}
|
|
step={10}
|
|
onChange={(v) => update("pumpFriction", v)}
|
|
/>
|
|
</Row>
|
|
<Row
|
|
label="Pump Intake Pressure"
|
|
htmlFor="pumpIntake"
|
|
hint={isMetric ? "Pa (SI case)" : "psi (imperial oilfield case)"}
|
|
>
|
|
<NumberField
|
|
id="pumpIntake"
|
|
value={state.pumpIntakePressure}
|
|
step={1}
|
|
onChange={(v) => update("pumpIntakePressure", v)}
|
|
/>
|
|
</Row>
|
|
</Fieldset>
|
|
|
|
<Fieldset legend="Fillage">
|
|
<Row label="Pump Fillage Option" htmlFor="fillageOpt">
|
|
<SelectField
|
|
id="fillageOpt"
|
|
value={state.pumpFillageOption}
|
|
onChange={(v) => update("pumpFillageOption", v)}
|
|
options={[
|
|
{ value: 0, label: "0 — auto" },
|
|
{ value: 1, label: "1 — specified" },
|
|
{ value: 2, label: "2 — incomplete fillage" }
|
|
]}
|
|
/>
|
|
</Row>
|
|
<Row label="Percent Pump Fillage (%)" htmlFor="pctFill">
|
|
<NumberField
|
|
id="pctFill"
|
|
value={state.percentPumpFillage}
|
|
step={1}
|
|
min={0}
|
|
max={100}
|
|
onChange={(v) => update("percentPumpFillage", v)}
|
|
/>
|
|
</Row>
|
|
</Fieldset>
|
|
</div>
|
|
);
|
|
}
|