= {
heightInInches: { type: "value", rules: [required] },
royaltiesInCents: { type: "value" },
+ royaltiesInMills: { type: "value" },
};
diff --git a/src/forms/BoundNumberField.tsx b/src/forms/BoundNumberField.tsx
index 267be6e4c..55654de91 100644
--- a/src/forms/BoundNumberField.tsx
+++ b/src/forms/BoundNumberField.tsx
@@ -18,8 +18,8 @@ export function BoundNumberField(props: BoundNumberFieldProps) {
field,
readOnly,
onChange = (value) => field.set(value),
- label = defaultLabel(field.key.replace(/InCents$/, "")),
- type = field.key.endsWith("InCents") ? "cents" : undefined,
+ label = defaultLabel(field.key.replace(/(InCents|InMills)$/, "")),
+ type = field.key.endsWith("InCents") ? "cents" : field.key.endsWith("InMills") ? "mills" : undefined,
onFocus,
onBlur,
onEnter,
diff --git a/src/forms/formStateDomain.ts b/src/forms/formStateDomain.ts
index 00bea4279..e74856bc4 100644
--- a/src/forms/formStateDomain.ts
+++ b/src/forms/formStateDomain.ts
@@ -26,6 +26,7 @@ export interface AuthorInput {
birthday?: Date | null;
heightInInches?: number | null;
royaltiesInCents?: number | null;
+ royaltiesInMills?: number | null;
books?: BookInput[] | null;
address?: AuthorAddress | null;
favoriteSport?: string | null;
diff --git a/src/inputs/NumberField.stories.tsx b/src/inputs/NumberField.stories.tsx
index 07237f211..4a165bdda 100644
--- a/src/inputs/NumberField.stories.tsx
+++ b/src/inputs/NumberField.stories.tsx
@@ -45,6 +45,7 @@ export function NumberFieldStyles() {
Unit Types
+
@@ -80,6 +81,7 @@ export function NumberFieldReadOnly() {
{}} readOnly={true} />
+
diff --git a/src/inputs/NumberField.test.tsx b/src/inputs/NumberField.test.tsx
index 7d66a475a..c0481cbab 100644
--- a/src/inputs/NumberField.test.tsx
+++ b/src/inputs/NumberField.test.tsx
@@ -60,6 +60,14 @@ describe("NumberFieldTest", () => {
expect(onChange).toBeCalledTimes(2); // change and blur
});
+ it("can set mills as dollars", async () => {
+ const r = await render();
+ expect(r.cost).toHaveValue("$1.200");
+ type(r.cost, "14");
+ expect(r.cost).toHaveValue("$14.000");
+ expect(lastSet).toEqual(14000);
+ });
+
it("can set cents as dollars", async () => {
const r = await render();
expect(r.cost).toHaveValue("$12.00");
@@ -92,6 +100,14 @@ describe("NumberFieldTest", () => {
expect(onChange).toBeCalledTimes(2); // change and blur
});
+ it("can set mills as mills", async () => {
+ const r = await render();
+ expect(r.cost).toHaveValue("$12.000");
+ type(r.cost, ".145");
+ expect(r.cost).toHaveValue("$0.145");
+ expect(lastSet).toEqual(145);
+ });
+
it("can set cents as cents", async () => {
const r = await render();
expect(r.cost).toHaveValue("$12.00");
@@ -153,6 +169,7 @@ describe("NumberFieldTest", () => {
const r = await render(
<>
+
@@ -160,6 +177,7 @@ describe("NumberFieldTest", () => {
>,
);
expect(r.days).toHaveValue("+123 days");
+ expect(r.mills).toHaveValue("+$0.456");
expect(r.cents).toHaveValue("+$4.56");
expect(r.basisPoints).toHaveValue("+7.89%");
expect(r.percent).toHaveValue("+123%");
diff --git a/src/inputs/NumberField.tsx b/src/inputs/NumberField.tsx
index efe8fc962..a5d4e8d7e 100644
--- a/src/inputs/NumberField.tsx
+++ b/src/inputs/NumberField.tsx
@@ -8,7 +8,7 @@ import { Css, Xss } from "src/Css";
import { maybeCall } from "src/utils";
import { TextFieldBase } from "./TextFieldBase";
-export type NumberFieldType = "cents" | "dollars" | "percent" | "basisPoints" | "days";
+export type NumberFieldType = "cents" | "dollars" | "percent" | "basisPoints" | "days" | "mills";
// exported for testing purposes
export interface NumberFieldProps extends Pick {
@@ -85,7 +85,9 @@ export function NumberField(props: NumberFieldProps) {
const isDisabled = !!disabled;
const isReadOnly = !!readOnly;
- const factor = type === "percent" || type === "cents" ? 100 : type === "basisPoints" ? 10_000 : 1;
+ const factor =
+ type === "percent" ? 100 : type === "cents" ? 100 : type === "mills" ? 1_000 : type === "basisPoints" ? 10_000 : 1;
+
const signDisplay = displayDirection ? "always" : "auto";
const defaultFormatOptions: Intl.NumberFormatOptions = useMemo(
() => ({
@@ -111,6 +113,8 @@ export function NumberField(props: NumberFieldProps) {
? { style: "percent", minimumFractionDigits: 2 }
: type === "cents"
? { style: "currency", currency: "USD", minimumFractionDigits: 2 }
+ : type === "mills"
+ ? { style: "currency", currency: "USD", minimumFractionDigits: 3 }
: type === "dollars"
? { style: "currency", currency: "USD", minimumFractionDigits: numFractionDigits ?? 2 }
: type === "days"