@mittwald/flow-react-components 1.5.0-next.40 → 1.5.0-next.41

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.
@@ -11,19 +11,22 @@ import FormField_module_default from "../FormField/FormField.module.mjs";
11
11
  import { useFieldComponent } from "../../lib/hooks/useFieldComponent.mjs";
12
12
  import { useControlledHostValueProps } from "../../lib/remote/useControlledHostValueProps.mjs";
13
13
  import NumberField_module_default from "./NumberField.module.mjs";
14
+ import { NumberFieldUnit } from "./components/NumberFieldUnit.mjs";
14
15
  import clsx from "clsx";
15
- import "react";
16
+ import { useId } from "react";
16
17
  import { jsx, jsxs } from "react/jsx-runtime";
17
18
  import * as Aria from "react-aria-components";
18
19
  //#region src/components/NumberField/NumberField.tsx
19
20
  /** @flr-generate all */
20
21
  var NumberField = flowComponent("NumberField", (props) => {
21
- const { children, className, isWheelDisabled = true, ref, ...rest } = useControlledHostValueProps(props, NaN);
22
+ const { children, className, isWheelDisabled = true, ref, unit, "aria-labelledby": ariaLabelledBy, ...rest } = useControlledHostValueProps(props, NaN);
23
+ const unitId = useId();
22
24
  const { FieldErrorView, FieldErrorCaptureContext, wrapperProps, controlProps, fieldPropsContext } = useFieldComponent(props, "NumberField");
23
25
  const rootClassName = clsx(FormField_module_default.formField, className);
24
26
  return /* @__PURE__ */ jsxs(Aria.NumberField, {
25
27
  ...rest,
26
28
  isWheelDisabled,
29
+ "aria-labelledby": unit ? [ariaLabelledBy, unitId].filter(Boolean).join(" ") : ariaLabelledBy,
27
30
  "aria-describedby": controlProps["aria-describedby"],
28
31
  className: clsx(rootClassName, wrapperProps.className),
29
32
  children: [/* @__PURE__ */ jsxs(PropsContextProvider, {
@@ -40,9 +43,15 @@ var NumberField = flowComponent("NumberField", (props) => {
40
43
  color: "secondary",
41
44
  children: [/* @__PURE__ */ jsx(IconChevronDown, {}), /* @__PURE__ */ jsx(IconMinus, { className: NumberField_module_default.coarsePointerIcon })]
42
45
  }),
43
- /* @__PURE__ */ jsx(Aria.Input, {
44
- className: NumberField_module_default.input,
45
- ref
46
+ /* @__PURE__ */ jsxs("div", {
47
+ className: NumberField_module_default.inputContainer,
48
+ children: [/* @__PURE__ */ jsx(Aria.Input, {
49
+ className: NumberField_module_default.input,
50
+ ref
51
+ }), unit && /* @__PURE__ */ jsx(NumberFieldUnit, {
52
+ id: unitId,
53
+ unit
54
+ })]
46
55
  }),
47
56
  /* @__PURE__ */ jsxs(Button, {
48
57
  ariaSlot: "increment",
@@ -1 +1 @@
1
- {"version":3,"file":"NumberField.mjs","names":["formFieldStyles","styles"],"sources":["../../../../../../../src/components/NumberField/NumberField.tsx"],"sourcesContent":["import { type PropsWithChildren } from \"react\";\nimport * as Aria from \"react-aria-components\";\nimport formFieldStyles from \"@/components/FormField/FormField.module.scss\";\nimport styles from \"./NumberField.module.scss\";\nimport clsx from \"clsx\";\nimport { PropsContextProvider } from \"@/lib/propsContext\";\nimport { Button } from \"@/components/Button\";\nimport {\n IconChevronDown,\n IconChevronUp,\n IconMinus,\n IconPlus,\n} from \"@/components/Icon/components/icons\";\nimport type { FlowComponentProps } from \"@/lib/componentFactory/flowComponent\";\nimport { flowComponent } from \"@/lib/componentFactory/flowComponent\";\nimport { useFieldComponent } from \"@/lib/hooks/useFieldComponent\";\nimport { useControlledHostValueProps } from \"@/lib/remote/useControlledHostValueProps\";\n\nexport interface NumberFieldProps\n extends\n PropsWithChildren<Omit<Aria.NumberFieldProps, \"children\">>,\n FlowComponentProps<HTMLInputElement> {}\n\n/** @flr-generate all */\nexport const NumberField = flowComponent(\"NumberField\", (props) => {\n // `NaN` is what react-aria's number field state uses for \"no number\"\n const {\n children,\n className,\n isWheelDisabled = true,\n ref,\n ...rest\n } = useControlledHostValueProps(props, NaN);\n\n const {\n FieldErrorView,\n FieldErrorCaptureContext,\n wrapperProps,\n controlProps,\n fieldPropsContext,\n } = useFieldComponent(props, \"NumberField\");\n\n const rootClassName = clsx(formFieldStyles.formField, className);\n\n return (\n <Aria.NumberField\n {...rest}\n isWheelDisabled={isWheelDisabled}\n aria-describedby={controlProps[\"aria-describedby\"]}\n className={clsx(rootClassName, wrapperProps.className)}\n >\n <PropsContextProvider props={fieldPropsContext}>\n <FieldErrorCaptureContext>{children}</FieldErrorCaptureContext>\n <FieldErrorView />\n </PropsContextProvider>\n <Aria.Group className={styles.group}>\n <Button\n ariaSlot=\"decrement\"\n className={styles.decrementButton}\n size=\"s\"\n variant=\"plain\"\n color=\"secondary\"\n >\n <IconChevronDown />\n <IconMinus className={styles.coarsePointerIcon} />\n </Button>\n <Aria.Input className={styles.input} ref={ref} />\n <Button\n ariaSlot=\"increment\"\n className={styles.incrementButton}\n size=\"s\"\n variant=\"plain\"\n color=\"secondary\"\n >\n <IconChevronUp />\n <IconPlus className={styles.coarsePointerIcon} />\n </Button>\n </Aria.Group>\n </Aria.NumberField>\n );\n});\n\nexport default NumberField;\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAwBA,IAAa,cAAc,cAAc,gBAAgB,UAAU;CAEjE,MAAM,EACJ,UACA,WACA,kBAAkB,MAClB,KACA,GAAG,SACD,4BAA4B,OAAO,GAAG;CAE1C,MAAM,EACJ,gBACA,0BACA,cACA,cACA,sBACE,kBAAkB,OAAO,aAAa;CAE1C,MAAM,gBAAgB,KAAKA,yBAAgB,WAAW,SAAS;CAE/D,OACE,qBAAC,KAAK,aAAN;EACE,GAAI;EACa;EACjB,oBAAkB,aAAa;EAC/B,WAAW,KAAK,eAAe,aAAa,SAAS;EAJvD,UAAA,CAME,qBAAC,sBAAD;GAAsB,OAAO;GAA7B,UAAA,CACE,oBAAC,0BAAD,EAA2B,SAAmC,CAAA,GAC9D,oBAAC,gBAAD,CAAiB,CAAA,CACG;EACtB,CAAA,GAAA,qBAAC,KAAK,OAAN;GAAY,WAAWC,2BAAO;GAA9B,UAAA;IACE,qBAAC,QAAD;KACE,UAAS;KACT,WAAWA,2BAAO;KAClB,MAAK;KACL,SAAQ;KACR,OAAM;KALR,UAAA,CAOE,oBAAC,iBAAD,CAAkB,CAAA,GAClB,oBAAC,WAAD,EAAW,WAAWA,2BAAO,kBAAoB,CAAA,CAC3C;;IACR,oBAAC,KAAK,OAAN;KAAY,WAAWA,2BAAO;KAAY;IAAM,CAAA;IAChD,qBAAC,QAAD;KACE,UAAS;KACT,WAAWA,2BAAO;KAClB,MAAK;KACL,SAAQ;KACR,OAAM;KALR,UAAA,CAOE,oBAAC,eAAD,CAAgB,CAAA,GAChB,oBAAC,UAAD,EAAU,WAAWA,2BAAO,kBAAoB,CAAA,CAC1C;;GACE;EACI,CAAA,CAAA;;AAEtB,CAAC"}
1
+ {"version":3,"file":"NumberField.mjs","names":["formFieldStyles","styles"],"sources":["../../../../../../../src/components/NumberField/NumberField.tsx"],"sourcesContent":["import { type PropsWithChildren, useId } from \"react\";\nimport * as Aria from \"react-aria-components\";\nimport formFieldStyles from \"@/components/FormField/FormField.module.scss\";\nimport styles from \"./NumberField.module.scss\";\nimport clsx from \"clsx\";\nimport { PropsContextProvider } from \"@/lib/propsContext\";\nimport { Button } from \"@/components/Button\";\nimport {\n IconChevronDown,\n IconChevronUp,\n IconMinus,\n IconPlus,\n} from \"@/components/Icon/components/icons\";\nimport type { FlowComponentProps } from \"@/lib/componentFactory/flowComponent\";\nimport { flowComponent } from \"@/lib/componentFactory/flowComponent\";\nimport { useFieldComponent } from \"@/lib/hooks/useFieldComponent\";\nimport { useControlledHostValueProps } from \"@/lib/remote/useControlledHostValueProps\";\nimport { NumberFieldUnit } from \"./components/NumberFieldUnit\";\n\nexport interface NumberFieldProps\n extends\n PropsWithChildren<Omit<Aria.NumberFieldProps, \"children\">>,\n FlowComponentProps<HTMLInputElement> {\n /**\n * A unit displayed after the number, for units `Intl.NumberFormat` does not\n * support (e.g. \"MiB\"). For supported units, use `formatOptions` instead.\n */\n unit?: string;\n}\n\n/** @flr-generate all */\nexport const NumberField = flowComponent(\"NumberField\", (props) => {\n // `NaN` is what react-aria's number field state uses for \"no number\"\n const {\n children,\n className,\n isWheelDisabled = true,\n ref,\n unit,\n \"aria-labelledby\": ariaLabelledBy,\n ...rest\n } = useControlledHostValueProps(props, NaN);\n\n const unitId = useId();\n\n const {\n FieldErrorView,\n FieldErrorCaptureContext,\n wrapperProps,\n controlProps,\n fieldPropsContext,\n } = useFieldComponent(props, \"NumberField\");\n\n const rootClassName = clsx(formFieldStyles.formField, className);\n\n return (\n <Aria.NumberField\n {...rest}\n isWheelDisabled={isWheelDisabled}\n aria-labelledby={\n unit\n ? [ariaLabelledBy, unitId].filter(Boolean).join(\" \")\n : ariaLabelledBy\n }\n aria-describedby={controlProps[\"aria-describedby\"]}\n className={clsx(rootClassName, wrapperProps.className)}\n >\n <PropsContextProvider props={fieldPropsContext}>\n <FieldErrorCaptureContext>{children}</FieldErrorCaptureContext>\n <FieldErrorView />\n </PropsContextProvider>\n <Aria.Group className={styles.group}>\n <Button\n ariaSlot=\"decrement\"\n className={styles.decrementButton}\n size=\"s\"\n variant=\"plain\"\n color=\"secondary\"\n >\n <IconChevronDown />\n <IconMinus className={styles.coarsePointerIcon} />\n </Button>\n <div className={styles.inputContainer}>\n <Aria.Input className={styles.input} ref={ref} />\n {unit && <NumberFieldUnit id={unitId} unit={unit} />}\n </div>\n <Button\n ariaSlot=\"increment\"\n className={styles.incrementButton}\n size=\"s\"\n variant=\"plain\"\n color=\"secondary\"\n >\n <IconChevronUp />\n <IconPlus className={styles.coarsePointerIcon} />\n </Button>\n </Aria.Group>\n </Aria.NumberField>\n );\n});\n\nexport default NumberField;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AA+BA,IAAa,cAAc,cAAc,gBAAgB,UAAU;CAEjE,MAAM,EACJ,UACA,WACA,kBAAkB,MAClB,KACA,MACA,mBAAmB,gBACnB,GAAG,SACD,4BAA4B,OAAO,GAAG;CAE1C,MAAM,SAAS,MAAM;CAErB,MAAM,EACJ,gBACA,0BACA,cACA,cACA,sBACE,kBAAkB,OAAO,aAAa;CAE1C,MAAM,gBAAgB,KAAKA,yBAAgB,WAAW,SAAS;CAE/D,OACE,qBAAC,KAAK,aAAN;EACE,GAAI;EACa;EACjB,mBACE,OACI,CAAC,gBAAgB,MAAM,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,IACjD;EAEN,oBAAkB,aAAa;EAC/B,WAAW,KAAK,eAAe,aAAa,SAAS;EATvD,UAAA,CAWE,qBAAC,sBAAD;GAAsB,OAAO;GAA7B,UAAA,CACE,oBAAC,0BAAD,EAA2B,SAAmC,CAAA,GAC9D,oBAAC,gBAAD,CAAiB,CAAA,CACG;EACtB,CAAA,GAAA,qBAAC,KAAK,OAAN;GAAY,WAAWC,2BAAO;GAA9B,UAAA;IACE,qBAAC,QAAD;KACE,UAAS;KACT,WAAWA,2BAAO;KAClB,MAAK;KACL,SAAQ;KACR,OAAM;KALR,UAAA,CAOE,oBAAC,iBAAD,CAAkB,CAAA,GAClB,oBAAC,WAAD,EAAW,WAAWA,2BAAO,kBAAoB,CAAA,CAC3C;;IACR,qBAAC,OAAD;KAAK,WAAWA,2BAAO;KAAvB,UAAA,CACE,oBAAC,KAAK,OAAN;MAAY,WAAWA,2BAAO;MAAY;KAAM,CAAA,GAC/C,QAAQ,oBAAC,iBAAD;MAAiB,IAAI;MAAc;KAAO,CAAA,CAChD;;IACL,qBAAC,QAAD;KACE,UAAS;KACT,WAAWA,2BAAO;KAClB,MAAK;KACL,SAAQ;KACR,OAAM;KALR,UAAA,CAOE,oBAAC,eAAD,CAAgB,CAAA,GAChB,oBAAC,UAAD,EAAU,WAAWA,2BAAO,kBAAoB,CAAA,CAC1C;;GACE;EACI,CAAA,CAAA;;AAEtB,CAAC"}
@@ -2,20 +2,28 @@
2
2
  /* */
3
3
  //#region src/components/NumberField/NumberField.module.scss
4
4
  var group = "flow--number-field--group";
5
+ var inputContainer = "flow--number-field--input-container";
5
6
  var input = "flow--number-field--input";
7
+ var unitOverlay = "flow--number-field--unit-overlay";
6
8
  var readonly = "flow--number-field--readonly";
9
+ var unitClip = "flow--number-field--unit-clip";
10
+ var unitSpacer = "flow--number-field--unit-spacer";
7
11
  var decrementButton = "flow--number-field--decrement-button";
8
12
  var incrementButton = "flow--number-field--increment-button";
9
13
  var coarsePointerIcon = "flow--number-field--coarse-pointer-icon";
10
14
  var NumberField_module_default = {
11
15
  group,
16
+ inputContainer,
12
17
  input,
18
+ unitOverlay,
13
19
  readonly,
20
+ unitClip,
21
+ unitSpacer,
14
22
  decrementButton,
15
23
  incrementButton,
16
24
  coarsePointerIcon
17
25
  };
18
26
  //#endregion
19
- export { coarsePointerIcon, decrementButton, NumberField_module_default as default, group, incrementButton, input, readonly };
27
+ export { coarsePointerIcon, decrementButton, NumberField_module_default as default, group, incrementButton, input, inputContainer, readonly, unitClip, unitOverlay, unitSpacer };
20
28
 
21
29
  //# sourceMappingURL=NumberField.module.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"NumberField.module.mjs","names":[],"sources":["../../../../../../../src/components/NumberField/NumberField.module.scss"],"sourcesContent":["@use \"@/styles/mixins/formControl\";\n\n.group {\n order: 2;\n display: grid;\n grid-template-columns: 1fr max-content;\n grid-template-areas:\n \"input increment\"\n \"input decrement\";\n\n .input {\n grid-area: input;\n\n @include formControl.formControl();\n }\n\n .decrementButton {\n grid-area: decrement;\n }\n\n .incrementButton {\n grid-area: increment;\n }\n\n .decrementButton,\n .incrementButton {\n border-width: var(--form-control--border-width);\n border-color: var(--form-control--border-color--default);\n border-style: solid;\n }\n\n &[aria-invalid] {\n .decrementButton,\n .incrementButton {\n border-color: var(--form-control--border-color--invalid);\n }\n }\n\n &[data-focus-within] {\n .decrementButton,\n .incrementButton {\n border-color: var(--form-control--border-color--focused);\n }\n }\n\n &[aria-disabled=\"true\"] {\n .decrementButton,\n .incrementButton {\n border-color: var(--form-control--border-color--disabled);\n }\n }\n\n &:has(.input:read-only):not([aria-disabled=\"true\"]) {\n .decrementButton,\n .incrementButton {\n border-color: var(--form-control--border-color--default);\n }\n }\n}\n\n@media (pointer: fine) {\n .group {\n .input {\n border-start-end-radius: 0;\n border-end-end-radius: 0;\n }\n\n .incrementButton,\n .decrementButton {\n border-inline-start: none;\n border-start-start-radius: 0;\n border-end-start-radius: 0;\n padding-block: 0;\n\n .coarsePointerIcon {\n display: none;\n }\n }\n\n .decrementButton {\n border-start-end-radius: 0;\n }\n\n .incrementButton {\n border-block-end: none;\n border-end-end-radius: 0;\n }\n }\n}\n\n@media (pointer: coarse) {\n .group {\n grid-template-columns: auto 1fr auto;\n grid-template-areas: \"decrement input increment\";\n max-width: 100%;\n\n .input {\n border-radius: 0;\n min-width: 0;\n }\n\n .decrementButton,\n .incrementButton {\n padding-inline: var(--button--padding-icon-only);\n\n .coarsePointerIcon {\n width: var(--icon--size--m);\n height: var(--icon--size--m);\n }\n\n // Hides every icon the stepper buttons render except the coarse-pointer\n // one — Button's own pending/success/failure icons included, and those\n // share no class with the chevrons.\n // stylelint-disable-next-line selector-max-type -- see above\n svg:not(.coarsePointerIcon) {\n display: none;\n }\n }\n\n .decrementButton {\n border-start-end-radius: 0;\n border-end-end-radius: 0;\n border-inline-end: none;\n }\n\n .incrementButton {\n border-start-start-radius: 0;\n border-end-start-radius: 0;\n border-inline-start: none;\n }\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"NumberField.module.mjs","names":[],"sources":["../../../../../../../src/components/NumberField/NumberField.module.scss"],"sourcesContent":["@use \"@/styles/mixins/formControl\";\n\n.group {\n order: 2;\n display: grid;\n grid-template-columns: 1fr max-content;\n grid-template-areas:\n \"input increment\"\n \"input decrement\";\n\n .inputContainer {\n grid-area: input;\n display: grid;\n // Without it the column takes the input's intrinsic width\n grid-template-columns: minmax(0, 1fr);\n min-width: 0;\n }\n\n .input,\n .unitOverlay {\n grid-area: 1 / 1;\n }\n\n .input {\n @include formControl.formControl();\n }\n\n // Mirrors the input's box so the text lines up with the input text\n .unitOverlay {\n @include formControl.formBorder();\n @include formControl.formOutline();\n\n // Grid items paint in `order`; formControl moves the input to 2\n order: 2;\n border-color: transparent;\n color: var(--form-control--content-color--default);\n white-space: pre;\n pointer-events: none;\n contain: inline-size;\n\n &[data-empty] {\n visibility: hidden;\n }\n }\n\n // The input clips its text at the content box, `overflow` clips at the\n // padding box — so the overlay keeps the padding and clips one level deeper\n .unitClip {\n display: block;\n overflow: hidden;\n }\n\n .unitSpacer {\n visibility: hidden;\n }\n\n &[aria-disabled=\"true\"] .unitOverlay {\n color: var(--form-control--content-color--disabled);\n }\n\n .decrementButton {\n grid-area: decrement;\n }\n\n .incrementButton {\n grid-area: increment;\n }\n\n .decrementButton,\n .incrementButton {\n border-width: var(--form-control--border-width);\n border-color: var(--form-control--border-color--default);\n border-style: solid;\n }\n\n &[aria-invalid] {\n .decrementButton,\n .incrementButton {\n border-color: var(--form-control--border-color--invalid);\n }\n }\n\n &[data-focus-within] {\n .decrementButton,\n .incrementButton {\n border-color: var(--form-control--border-color--focused);\n }\n }\n\n &[aria-disabled=\"true\"] {\n .decrementButton,\n .incrementButton {\n border-color: var(--form-control--border-color--disabled);\n }\n }\n\n &:has(.input:read-only):not([aria-disabled=\"true\"]) {\n .decrementButton,\n .incrementButton {\n border-color: var(--form-control--border-color--default);\n }\n }\n}\n\n@media (pointer: fine) {\n .group {\n .input {\n border-start-end-radius: 0;\n border-end-end-radius: 0;\n }\n\n .incrementButton,\n .decrementButton {\n border-inline-start: none;\n border-start-start-radius: 0;\n border-end-start-radius: 0;\n padding-block: 0;\n\n .coarsePointerIcon {\n display: none;\n }\n }\n\n .decrementButton {\n border-start-end-radius: 0;\n }\n\n .incrementButton {\n border-block-end: none;\n border-end-end-radius: 0;\n }\n }\n}\n\n@media (pointer: coarse) {\n .group {\n grid-template-columns: auto 1fr auto;\n grid-template-areas: \"decrement input increment\";\n max-width: 100%;\n\n .input {\n border-radius: 0;\n min-width: 0;\n }\n\n .decrementButton,\n .incrementButton {\n padding-inline: var(--button--padding-icon-only);\n\n .coarsePointerIcon {\n width: var(--icon--size--m);\n height: var(--icon--size--m);\n }\n\n // Hides every icon the stepper buttons render except the coarse-pointer\n // one — Button's own pending/success/failure icons included, and those\n // share no class with the chevrons.\n // stylelint-disable-next-line selector-max-type -- see above\n svg:not(.coarsePointerIcon) {\n display: none;\n }\n }\n\n .decrementButton {\n border-start-end-radius: 0;\n border-end-end-radius: 0;\n border-inline-end: none;\n }\n\n .incrementButton {\n border-start-start-radius: 0;\n border-end-start-radius: 0;\n border-inline-start: none;\n }\n }\n}\n"],"mappings":""}
@@ -0,0 +1,36 @@
1
+ "use client"
2
+ /* */
3
+ import NumberField_module_default from "../NumberField.module.mjs";
4
+ import { useContext } from "react";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ import * as Aria from "react-aria-components";
7
+ //#region src/components/NumberField/components/NumberFieldUnit.tsx
8
+ /**
9
+ * React-aria cannot parse a unit `Intl.NumberFormat` does not know, so the unit
10
+ * is drawn over the input instead of being part of its value. An invisible copy
11
+ * of the input text pushes it right behind the number. The input's name
12
+ * references the unit, like a unit written into the label.
13
+ */
14
+ var NumberFieldUnit = (props) => {
15
+ const { id, unit } = props;
16
+ const inputValue = useContext(Aria.NumberFieldStateContext)?.inputValue;
17
+ return /* @__PURE__ */ jsx("span", {
18
+ className: NumberField_module_default.unitOverlay,
19
+ "data-empty": !inputValue || void 0,
20
+ "aria-hidden": true,
21
+ children: /* @__PURE__ */ jsxs("span", {
22
+ className: NumberField_module_default.unitClip,
23
+ children: [/* @__PURE__ */ jsxs("span", {
24
+ className: NumberField_module_default.unitSpacer,
25
+ children: [inputValue, " "]
26
+ }), /* @__PURE__ */ jsx("span", {
27
+ id,
28
+ children: unit
29
+ })]
30
+ })
31
+ });
32
+ };
33
+ //#endregion
34
+ export { NumberFieldUnit };
35
+
36
+ //# sourceMappingURL=NumberFieldUnit.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NumberFieldUnit.mjs","names":["styles"],"sources":["../../../../../../../../src/components/NumberField/components/NumberFieldUnit.tsx"],"sourcesContent":["import { type FC, useContext } from \"react\";\nimport * as Aria from \"react-aria-components\";\nimport styles from \"../NumberField.module.scss\";\n\ninterface Props {\n id: string;\n unit: string;\n}\n\n/**\n * React-aria cannot parse a unit `Intl.NumberFormat` does not know, so the unit\n * is drawn over the input instead of being part of its value. An invisible copy\n * of the input text pushes it right behind the number. The input's name\n * references the unit, like a unit written into the label.\n */\nexport const NumberFieldUnit: FC<Props> = (props) => {\n const { id, unit } = props;\n const inputValue = useContext(Aria.NumberFieldStateContext)?.inputValue;\n\n return (\n <span\n className={styles.unitOverlay}\n data-empty={!inputValue || undefined}\n aria-hidden\n >\n <span className={styles.unitClip}>\n <span className={styles.unitSpacer}>{inputValue} </span>\n <span id={id}>{unit}</span>\n </span>\n </span>\n );\n};\n"],"mappings":";;;;;;;;;;;;;AAeA,IAAa,mBAA8B,UAAU;CACnD,MAAM,EAAE,IAAI,SAAS;CACrB,MAAM,aAAa,WAAW,KAAK,uBAAuB,CAAC,EAAE;CAE7D,OACE,oBAAC,QAAD;EACE,WAAWA,2BAAO;EAClB,cAAY,CAAC,cAAc,KAAA;EAC3B,eAAA;EAEA,UAAA,qBAAC,QAAD;GAAM,WAAWA,2BAAO;GAAxB,UAAA,CACE,qBAAC,QAAD;IAAM,WAAWA,2BAAO;IAAxB,UAAA,CAAqC,YAAW,GAAO;GACvD,CAAA,GAAA,oBAAC,QAAD;IAAU;IAAK,UAAA;GAAW,CAAA,CACtB;;CACF,CAAA;AAEV"}
@@ -2,6 +2,11 @@ import { PropsWithChildren } from 'react';
2
2
  import { FlowComponentProps } from '../../lib/componentFactory/flowComponent';
3
3
  import * as Aria from "react-aria-components";
4
4
  export interface NumberFieldProps extends PropsWithChildren<Omit<Aria.NumberFieldProps, "children">>, FlowComponentProps<HTMLInputElement> {
5
+ /**
6
+ * A unit displayed after the number, for units `Intl.NumberFormat` does not
7
+ * support (e.g. "MiB"). For supported units, use `formatOptions` instead.
8
+ */
9
+ unit?: string;
5
10
  }
6
11
  /** @flr-generate all */
7
12
  export declare const NumberField: import('react').FunctionComponent<NumberFieldProps & import('react').RefAttributes<HTMLInputElement>>;
@@ -0,0 +1,13 @@
1
+ import { FC } from 'react';
2
+ interface Props {
3
+ id: string;
4
+ unit: string;
5
+ }
6
+ /**
7
+ * React-aria cannot parse a unit `Intl.NumberFormat` does not know, so the unit
8
+ * is drawn over the input instead of being part of its value. An invisible copy
9
+ * of the input text pushes it right behind the number. The input's name
10
+ * references the unit, like a unit written into the label.
11
+ */
12
+ export declare const NumberFieldUnit: FC<Props>;
13
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mittwald/flow-react-components",
3
- "version": "1.5.0-next.40",
3
+ "version": "1.5.0-next.41",
4
4
  "type": "module",
5
5
  "description": "A React implementation of Flow, mittwald’s design system",
6
6
  "homepage": "https://flow.mittwald.de",
@@ -84,9 +84,9 @@
84
84
  "@internationalized/string-compiler": "^3.4.1",
85
85
  "@lezer/common": "^1.5.2",
86
86
  "@lezer/highlight": "^1.2.3",
87
- "@mittwald/flow-icons": "^1.5.0-next.40",
87
+ "@mittwald/flow-icons": "^1.5.0-next.41",
88
88
  "@mittwald/password-tools-js": "^3.0.0",
89
- "@mittwald/react-tunnel": "^1.5.0-next.40",
89
+ "@mittwald/react-tunnel": "^1.5.0-next.41",
90
90
  "@mittwald/react-use-promise": "^4.2.2",
91
91
  "@react-aria/form": "^3.2.1",
92
92
  "@react-aria/i18n": "^3.13.1",
@@ -139,12 +139,12 @@
139
139
  "@internationalized/date": "^3.12.3",
140
140
  "@lezer/generator": "^1.8.0",
141
141
  "@lezer/lr": "^1.4.10",
142
- "@mittwald/flow-core": "1.5.0-next.40",
143
- "@mittwald/flow-design-tokens": "1.5.0-next.40",
144
- "@mittwald/flow-icons-base": "1.5.0-next.40",
142
+ "@mittwald/flow-core": "1.5.0-next.41",
143
+ "@mittwald/flow-design-tokens": "1.5.0-next.41",
144
+ "@mittwald/flow-icons-base": "1.5.0-next.41",
145
145
  "@mittwald/react-use-promise": "^4.2.2",
146
146
  "@mittwald/remote-dom-react": "1.2.2-mittwald.10",
147
- "@mittwald/typescript-config": "1.5.0-next.40",
147
+ "@mittwald/typescript-config": "1.5.0-next.41",
148
148
  "@nx/storybook": "^22.7.6",
149
149
  "@storybook/addon-a11y": "^10.5.10",
150
150
  "@storybook/addon-actions": "^9.0.8",
@@ -198,7 +198,7 @@
198
198
  },
199
199
  "peerDependencies": {
200
200
  "@internationalized/date": "^3.12.2",
201
- "@mittwald/flow-icons-pro": "1.5.0-next.40",
201
+ "@mittwald/flow-icons-pro": "1.5.0-next.41",
202
202
  "@mittwald/react-use-promise": "^4.2.2",
203
203
  "next": "^16.2.3",
204
204
  "react": "^19.2.0",
@@ -222,5 +222,5 @@
222
222
  "browserslist": [
223
223
  "baseline widely available"
224
224
  ],
225
- "gitHead": "04f02e2e9537ecf94f78050ae7cce9030a7748b1"
225
+ "gitHead": "cb0ff41ba072e549af67333c4d7c6df26f9b623a"
226
226
  }