@12-apps/ui 6.39.10 → 6.39.11

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.
Files changed (50) hide show
  1. package/dist/_internal/components/data-display/DataViews/DataViewsTableBase.js +4 -4
  2. package/dist/_internal/components/data-display/DataViews/SaveViewModal.js +2 -2
  3. package/dist/_internal/components/data-display/DataViews/data-views-table-parts.js +3 -3
  4. package/dist/_internal/components/data-display/HoverCard/HoverCard.hooks.js +1 -1
  5. package/dist/_internal/components/data-display/HoverCard/HoverCard.js +2 -2
  6. package/dist/_internal/components/data-display/index.js +2 -2
  7. package/dist/_internal/components/form/CepField/CepField.js +2 -2
  8. package/dist/_internal/components/form/Input/Input.js +1 -1
  9. package/dist/_internal/components/form/index.js +2 -2
  10. package/dist/_internal/components/form/total-form/Fields/CepField.js +3 -3
  11. package/dist/_internal/components/form/total-form/Fields/TextField.js +2 -2
  12. package/dist/_internal/components/form/total-form/Fields/index.js +5 -5
  13. package/dist/_internal/components/index.js +4 -4
  14. package/dist/{chunk-F6D6HXZU.js → chunk-7X7ZHJHM.js} +2 -2
  15. package/dist/{chunk-DAHYLPK7.js → chunk-CMV6BRQ3.js} +13 -4
  16. package/dist/chunk-CMV6BRQ3.js.map +1 -0
  17. package/dist/{chunk-YS67XMOP.js → chunk-I5ZVCY2N.js} +3 -3
  18. package/dist/{chunk-A5B7B4HT.js → chunk-INMKA5SF.js} +2 -2
  19. package/dist/{chunk-VJG7NMGL.js → chunk-IYF246UA.js} +2 -2
  20. package/dist/{chunk-VURQZBFH.js → chunk-JRJCBDGN.js} +16 -3
  21. package/dist/chunk-JRJCBDGN.js.map +1 -0
  22. package/dist/{chunk-2XX45PC5.js → chunk-TGXCG62P.js} +2 -2
  23. package/dist/{chunk-SXYIXCUB.js → chunk-VNWZWQF3.js} +41 -23
  24. package/dist/chunk-VNWZWQF3.js.map +1 -0
  25. package/dist/{chunk-SSS64KYB.js → chunk-Z43N7ASP.js} +2 -2
  26. package/dist/{chunk-6MFMLQ72.js → chunk-ZNDDILNQ.js} +2 -2
  27. package/dist/data-display/DataViews.js +4 -4
  28. package/dist/data-display/HoverCard.js +2 -2
  29. package/dist/form/CepField.js +2 -2
  30. package/dist/form/Input.js +1 -1
  31. package/dist/form/total-form.js +5 -5
  32. package/dist/types/components/data-display/HoverCard/HoverCard.d.ts.map +1 -1
  33. package/dist/types/components/data-display/HoverCard/HoverCard.hooks.d.ts +1 -0
  34. package/dist/types/components/data-display/HoverCard/HoverCard.hooks.d.ts.map +1 -1
  35. package/dist/types/components/form/Input/Input.d.ts.map +1 -1
  36. package/package.json +1 -1
  37. package/src/components/data-display/HoverCard/HoverCard.hooks.ts +80 -25
  38. package/src/components/data-display/HoverCard/HoverCard.md +1 -0
  39. package/src/components/data-display/HoverCard/HoverCard.tsx +11 -2
  40. package/src/components/form/Input/Input.tsx +40 -1
  41. package/dist/chunk-DAHYLPK7.js.map +0 -1
  42. package/dist/chunk-SXYIXCUB.js.map +0 -1
  43. package/dist/chunk-VURQZBFH.js.map +0 -1
  44. /package/dist/{chunk-F6D6HXZU.js.map → chunk-7X7ZHJHM.js.map} +0 -0
  45. /package/dist/{chunk-YS67XMOP.js.map → chunk-I5ZVCY2N.js.map} +0 -0
  46. /package/dist/{chunk-A5B7B4HT.js.map → chunk-INMKA5SF.js.map} +0 -0
  47. /package/dist/{chunk-VJG7NMGL.js.map → chunk-IYF246UA.js.map} +0 -0
  48. /package/dist/{chunk-2XX45PC5.js.map → chunk-TGXCG62P.js.map} +0 -0
  49. /package/dist/{chunk-SSS64KYB.js.map → chunk-Z43N7ASP.js.map} +0 -0
  50. /package/dist/{chunk-6MFMLQ72.js.map → chunk-ZNDDILNQ.js.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  DataViewsTableBase
4
- } from "../../../../chunk-6MFMLQ72.js";
4
+ } from "../../../../chunk-ZNDDILNQ.js";
5
5
  import "../../../../chunk-3333KCAW.js";
6
6
  import "../../../../chunk-5WT4YWXC.js";
7
7
  import "../../../../chunk-ZOLAYP2D.js";
@@ -40,8 +40,8 @@ import "../../../../chunk-YLGY3D52.js";
40
40
  import "../../../../chunk-S6JHTEV4.js";
41
41
  import "../../../../chunk-XZJM6EPC.js";
42
42
  import "../../../../chunk-M4KVKQRN.js";
43
- import "../../../../chunk-A5B7B4HT.js";
44
- import "../../../../chunk-VJG7NMGL.js";
43
+ import "../../../../chunk-INMKA5SF.js";
44
+ import "../../../../chunk-IYF246UA.js";
45
45
  import "../../../../chunk-ECIHOZPK.js";
46
46
  import "../../../../chunk-5M4TYFR3.js";
47
47
  import "../../../../chunk-HR7YTBR7.js";
@@ -108,7 +108,7 @@ import "../../../../chunk-LXT3X33C.js";
108
108
  import "../../../../chunk-DMNZD3Q7.js";
109
109
  import "../../../../chunk-JC22FNFA.js";
110
110
  import "../../../../chunk-QYKDY4EI.js";
111
- import "../../../../chunk-VURQZBFH.js";
111
+ import "../../../../chunk-JRJCBDGN.js";
112
112
  import "../../../../chunk-SL6454K7.js";
113
113
  import "../../../../chunk-THMT3G3L.js";
114
114
  import "../../../../chunk-RNIU447I.js";
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  SaveViewModal
4
- } from "../../../../chunk-VJG7NMGL.js";
4
+ } from "../../../../chunk-IYF246UA.js";
5
5
  import "../../../../chunk-5M4TYFR3.js";
6
6
  import "../../../../chunk-B7CNP5HW.js";
7
7
  import "../../../../chunk-KHG57NAE.js";
@@ -13,7 +13,7 @@ import "../../../../chunk-RIEV4VXF.js";
13
13
  import "../../../../chunk-TNBJ4DK4.js";
14
14
  import "../../../../chunk-SZS7VZJN.js";
15
15
  import "../../../../chunk-QYKDY4EI.js";
16
- import "../../../../chunk-VURQZBFH.js";
16
+ import "../../../../chunk-JRJCBDGN.js";
17
17
  import "../../../../chunk-SL6454K7.js";
18
18
  import "../../../../chunk-THMT3G3L.js";
19
19
  import "../../../../chunk-RNIU447I.js";
@@ -3,8 +3,8 @@ import {
3
3
  ViewDialogs,
4
4
  ViewMutationErrorAlert,
5
5
  ViewsMenuSlot
6
- } from "../../../../chunk-A5B7B4HT.js";
7
- import "../../../../chunk-VJG7NMGL.js";
6
+ } from "../../../../chunk-INMKA5SF.js";
7
+ import "../../../../chunk-IYF246UA.js";
8
8
  import "../../../../chunk-ECIHOZPK.js";
9
9
  import "../../../../chunk-5M4TYFR3.js";
10
10
  import "../../../../chunk-B7CNP5HW.js";
@@ -26,7 +26,7 @@ import "../../../../chunk-RIEV4VXF.js";
26
26
  import "../../../../chunk-TNBJ4DK4.js";
27
27
  import "../../../../chunk-SZS7VZJN.js";
28
28
  import "../../../../chunk-QYKDY4EI.js";
29
- import "../../../../chunk-VURQZBFH.js";
29
+ import "../../../../chunk-JRJCBDGN.js";
30
30
  import "../../../../chunk-SL6454K7.js";
31
31
  import "../../../../chunk-THMT3G3L.js";
32
32
  import "../../../../chunk-RNIU447I.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  useHoverCard
3
- } from "../../../../chunk-SXYIXCUB.js";
3
+ } from "../../../../chunk-VNWZWQF3.js";
4
4
  import "../../../../chunk-PZ5AY32C.js";
5
5
  export {
6
6
  useHoverCard
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  HoverCard
3
- } from "../../../../chunk-DAHYLPK7.js";
3
+ } from "../../../../chunk-CMV6BRQ3.js";
4
4
  import "../../../../chunk-BSYPPO2I.js";
5
- import "../../../../chunk-SXYIXCUB.js";
5
+ import "../../../../chunk-VNWZWQF3.js";
6
6
  import "../../../../chunk-NRIV2CQ2.js";
7
7
  import "../../../../chunk-ZHV7TCAC.js";
8
8
  import "../../../../chunk-HPK33ACY.js";
@@ -77,9 +77,9 @@ import {
77
77
  import "../../../chunk-6OS4AKWT.js";
78
78
  import {
79
79
  HoverCard
80
- } from "../../../chunk-DAHYLPK7.js";
80
+ } from "../../../chunk-CMV6BRQ3.js";
81
81
  import "../../../chunk-BSYPPO2I.js";
82
- import "../../../chunk-SXYIXCUB.js";
82
+ import "../../../chunk-VNWZWQF3.js";
83
83
  import "../../../chunk-NRIV2CQ2.js";
84
84
  import "../../../chunk-ZHV7TCAC.js";
85
85
  import "../../../chunk-TAF3YYMK.js";
@@ -2,9 +2,9 @@
2
2
  import {
3
3
  CepField,
4
4
  CepField_default
5
- } from "../../../../chunk-F6D6HXZU.js";
5
+ } from "../../../../chunk-7X7ZHJHM.js";
6
6
  import "../../../../chunk-QYKDY4EI.js";
7
- import "../../../../chunk-VURQZBFH.js";
7
+ import "../../../../chunk-JRJCBDGN.js";
8
8
  import "../../../../chunk-SL6454K7.js";
9
9
  import "../../../../chunk-THMT3G3L.js";
10
10
  import "../../../../chunk-RNIU447I.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Input
3
- } from "../../../../chunk-VURQZBFH.js";
3
+ } from "../../../../chunk-JRJCBDGN.js";
4
4
  import "../../../../chunk-SL6454K7.js";
5
5
  import "../../../../chunk-THMT3G3L.js";
6
6
  import "../../../../chunk-RNIU447I.js";
@@ -159,7 +159,7 @@ import "../../../chunk-TERT6TIS.js";
159
159
  import "../../../chunk-6XLMTOJ3.js";
160
160
  import {
161
161
  CepField
162
- } from "../../../chunk-F6D6HXZU.js";
162
+ } from "../../../chunk-7X7ZHJHM.js";
163
163
  import "../../../chunk-PGM5RRQO.js";
164
164
  import {
165
165
  Slider
@@ -185,7 +185,7 @@ import "../../../chunk-GY4NBSCN.js";
185
185
  import "../../../chunk-QYKDY4EI.js";
186
186
  import {
187
187
  Input
188
- } from "../../../chunk-VURQZBFH.js";
188
+ } from "../../../chunk-JRJCBDGN.js";
189
189
  import "../../../chunk-SL6454K7.js";
190
190
  import "../../../chunk-THMT3G3L.js";
191
191
  import "../../../chunk-RNIU447I.js";
@@ -1,12 +1,12 @@
1
1
  "use client";
2
2
  import {
3
3
  CepField
4
- } from "../../../../../chunk-2XX45PC5.js";
4
+ } from "../../../../../chunk-TGXCG62P.js";
5
5
  import "../../../../../chunk-4XK6JQ4D.js";
6
6
  import "../../../../../chunk-6XLMTOJ3.js";
7
- import "../../../../../chunk-F6D6HXZU.js";
7
+ import "../../../../../chunk-7X7ZHJHM.js";
8
8
  import "../../../../../chunk-QYKDY4EI.js";
9
- import "../../../../../chunk-VURQZBFH.js";
9
+ import "../../../../../chunk-JRJCBDGN.js";
10
10
  import "../../../../../chunk-SL6454K7.js";
11
11
  import "../../../../../chunk-THMT3G3L.js";
12
12
  import "../../../../../chunk-RNIU447I.js";
@@ -1,10 +1,10 @@
1
1
  "use client";
2
2
  import {
3
3
  TextField
4
- } from "../../../../../chunk-SSS64KYB.js";
4
+ } from "../../../../../chunk-Z43N7ASP.js";
5
5
  import "../../../../../chunk-4XK6JQ4D.js";
6
6
  import "../../../../../chunk-QYKDY4EI.js";
7
- import "../../../../../chunk-VURQZBFH.js";
7
+ import "../../../../../chunk-JRJCBDGN.js";
8
8
  import "../../../../../chunk-SL6454K7.js";
9
9
  import "../../../../../chunk-THMT3G3L.js";
10
10
  import "../../../../../chunk-RNIU447I.js";
@@ -1,16 +1,16 @@
1
- import "../../../../../chunk-YS67XMOP.js";
1
+ import "../../../../../chunk-I5ZVCY2N.js";
2
2
  import {
3
3
  ToggleField
4
4
  } from "../../../../../chunk-FNG33MKA.js";
5
5
  import {
6
6
  TextField
7
- } from "../../../../../chunk-SSS64KYB.js";
7
+ } from "../../../../../chunk-Z43N7ASP.js";
8
8
  import {
9
9
  SelectField
10
10
  } from "../../../../../chunk-PWZHCBG3.js";
11
11
  import {
12
12
  CepField
13
- } from "../../../../../chunk-2XX45PC5.js";
13
+ } from "../../../../../chunk-TGXCG62P.js";
14
14
  import {
15
15
  CategoryField
16
16
  } from "../../../../../chunk-T6EKPFKZ.js";
@@ -21,7 +21,7 @@ import "../../../../../chunk-WYXNFH5Y.js";
21
21
  import "../../../../../chunk-ONMSTW4B.js";
22
22
  import "../../../../../chunk-W5TI46QN.js";
23
23
  import "../../../../../chunk-6XLMTOJ3.js";
24
- import "../../../../../chunk-F6D6HXZU.js";
24
+ import "../../../../../chunk-7X7ZHJHM.js";
25
25
  import "../../../../../chunk-N5ZWC6CB.js";
26
26
  import "../../../../../chunk-BKASAYQL.js";
27
27
  import "../../../../../chunk-2JNHWKQK.js";
@@ -40,7 +40,7 @@ import "../../../../../chunk-LXT3X33C.js";
40
40
  import "../../../../../chunk-DMNZD3Q7.js";
41
41
  import "../../../../../chunk-JC22FNFA.js";
42
42
  import "../../../../../chunk-QYKDY4EI.js";
43
- import "../../../../../chunk-VURQZBFH.js";
43
+ import "../../../../../chunk-JRJCBDGN.js";
44
44
  import "../../../../../chunk-SL6454K7.js";
45
45
  import "../../../../../chunk-THMT3G3L.js";
46
46
  import "../../../../../chunk-RNIU447I.js";
@@ -365,7 +365,7 @@ import "../../chunk-TERT6TIS.js";
365
365
  import "../../chunk-6XLMTOJ3.js";
366
366
  import {
367
367
  CepField
368
- } from "../../chunk-F6D6HXZU.js";
368
+ } from "../../chunk-7X7ZHJHM.js";
369
369
  import "../../chunk-UCYU56FO.js";
370
370
  import "../../chunk-SJXSWVJG.js";
371
371
  import "../../chunk-A4TYNHBR.js";
@@ -463,9 +463,9 @@ import {
463
463
  import "../../chunk-6OS4AKWT.js";
464
464
  import {
465
465
  HoverCard
466
- } from "../../chunk-DAHYLPK7.js";
466
+ } from "../../chunk-CMV6BRQ3.js";
467
467
  import "../../chunk-BSYPPO2I.js";
468
- import "../../chunk-SXYIXCUB.js";
468
+ import "../../chunk-VNWZWQF3.js";
469
469
  import "../../chunk-NRIV2CQ2.js";
470
470
  import "../../chunk-ZHV7TCAC.js";
471
471
  import "../../chunk-TAF3YYMK.js";
@@ -591,7 +591,7 @@ import "../../chunk-GY4NBSCN.js";
591
591
  import "../../chunk-QYKDY4EI.js";
592
592
  import {
593
593
  Input
594
- } from "../../chunk-VURQZBFH.js";
594
+ } from "../../chunk-JRJCBDGN.js";
595
595
  import "../../chunk-SL6454K7.js";
596
596
  import "../../chunk-THMT3G3L.js";
597
597
  import "../../chunk-RNIU447I.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Input
3
- } from "./chunk-VURQZBFH.js";
3
+ } from "./chunk-JRJCBDGN.js";
4
4
  import {
5
5
  FormControl,
6
6
  FormLabel,
@@ -122,4 +122,4 @@ export {
122
122
  CepField,
123
123
  CepField_default
124
124
  };
125
- //# sourceMappingURL=chunk-F6D6HXZU.js.map
125
+ //# sourceMappingURL=chunk-7X7ZHJHM.js.map
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-BSYPPO2I.js";
8
8
  import {
9
9
  useHoverCard
10
- } from "./chunk-SXYIXCUB.js";
10
+ } from "./chunk-VNWZWQF3.js";
11
11
  import {
12
12
  HoverCardContent
13
13
  } from "./chunk-NRIV2CQ2.js";
@@ -35,6 +35,15 @@ var StyledCard = styled(Card, {
35
35
  var StyledPopover = styled(Popover, {
36
36
  shouldForwardProp: (prop) => prop !== "customAnimation"
37
37
  })(({ customAnimation }) => ({
38
+ // Only the card takes the pointer (its paper sets `pointer-events: auto`).
39
+ // MUI's popover root and its invisible backdrop cover the whole viewport, so
40
+ // while a card was open the pointer was "on the card" wherever it went: the
41
+ // backdrop's mouseover reached the card's onMouseEnter and cancelled the
42
+ // close the trigger's mouseleave had just scheduled. A card left by moving
43
+ // the mouse away stayed open, and the page's next click hit the backdrop
44
+ // instead of its target (FUT-2619). The backdrop was also the only
45
+ // click-away; `useClickAway` in the hooks replaces it.
46
+ pointerEvents: "none",
38
47
  // The popover only positions; StyledCard draws the surface.
39
48
  "& .MuiPopover-paper": {
40
49
  backgroundColor: "transparent",
@@ -93,7 +102,7 @@ var HoverCard = React.forwardRef((props, ref) => {
93
102
  dataTestId,
94
103
  ...rest
95
104
  } = withDefaults(props, DEFAULTS);
96
- const { anchorEl, isOpen, handleClose, triggerHandlers, cardHandlers } = useHoverCard({
105
+ const { anchorEl, isOpen, handleClose, triggerHandlers, cardHandlers, contentRef } = useHoverCard({
97
106
  disabled,
98
107
  touchEnabled,
99
108
  enterDelay,
@@ -126,7 +135,7 @@ var HoverCard = React.forwardRef((props, ref) => {
126
135
  customAnimation: animation,
127
136
  slotProps: { paper: { style: { pointerEvents: "auto" } } },
128
137
  ...rest,
129
- children: /* @__PURE__ */ jsxs(Box, { sx: { position: "relative" }, children: [
138
+ children: /* @__PURE__ */ jsxs(Box, { ref: contentRef, sx: { position: "relative" }, children: [
130
139
  showArrow && /* @__PURE__ */ jsx(ArrowContainer, { placement, offset }),
131
140
  /* @__PURE__ */ jsx(
132
141
  StyledCard,
@@ -163,4 +172,4 @@ HoverCard.displayName = "HoverCard";
163
172
  export {
164
173
  HoverCard
165
174
  };
166
- //# sourceMappingURL=chunk-DAHYLPK7.js.map
175
+ //# sourceMappingURL=chunk-CMV6BRQ3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/data-display/HoverCard/HoverCard.tsx"],"sourcesContent":["import Box from '@mui/material/Box/index.js';\nimport Card from '@mui/material/Card/index.js';\nimport CardContent from '@mui/material/CardContent/index.js';\nimport Popover from '@mui/material/Popover/index.js';\nimport { styled, type Theme } from '@mui/material/styles/index.js';\nimport React from 'react';\n\nimport { rem } from '../../../tokens/relative';\nimport { withDefaults } from '../../../utils/withDefaults';\n\nimport { HoverCardContent } from './HoverCard.content';\nimport { useHoverCard } from './HoverCard.hooks';\nimport { arrowSx, cardSx, getAnchorOrigin, getTransformOrigin, sideOf } from './HoverCard.styles';\nimport type { CardStyleFlags } from './HoverCard.styles';\nimport type { HoverCardAnimation, HoverCardPlacement, HoverCardProps } from './HoverCard.types';\n\nconst ArrowContainer = styled('div')<{ placement: HoverCardPlacement; offset?: number }>(\n ({ theme, placement }) => ({ ...arrowSx(theme, placement) }),\n);\n\nconst StyledCard = styled(Card, {\n shouldForwardProp: (prop) =>\n !['customVariant', 'glow', 'pulse', 'animation'].includes(prop as string),\n})<CardStyleFlags>(({ theme, ...flags }) => ({ ...cardSx(theme, flags) }));\n\nconst StyledPopover = styled(Popover, {\n shouldForwardProp: (prop) => prop !== 'customAnimation',\n})<{ customAnimation?: HoverCardAnimation }>(({ customAnimation }) => ({\n // Only the card takes the pointer (its paper sets `pointer-events: auto`).\n // MUI's popover root and its invisible backdrop cover the whole viewport, so\n // while a card was open the pointer was \"on the card\" wherever it went: the\n // backdrop's mouseover reached the card's onMouseEnter and cancelled the\n // close the trigger's mouseleave had just scheduled. A card left by moving\n // the mouse away stayed open, and the page's next click hit the backdrop\n // instead of its target (FUT-2619). The backdrop was also the only\n // click-away; `useClickAway` in the hooks replaces it.\n pointerEvents: 'none',\n // The popover only positions; StyledCard draws the surface.\n '& .MuiPopover-paper': {\n backgroundColor: 'transparent',\n boxShadow: 'none',\n overflow: 'visible',\n ...(customAnimation === 'scale' && { transformOrigin: 'center' }),\n },\n}));\n\nconst DEFAULTS = {\n variant: 'default',\n glow: false,\n pulse: false,\n placement: 'bottom',\n showArrow: false,\n animation: 'fade',\n enterDelay: 700,\n exitDelay: 0,\n loading: false,\n touchEnabled: true,\n disabled: false,\n} satisfies Partial<HoverCardProps>;\n\ntype ResolvedProps = HoverCardProps & Required<Pick<HoverCardProps, keyof typeof DEFAULTS>>;\n\n/** Padding is the variant's own: detailed roomier, minimal tighter. */\nconst CONTENT_PADDING: Record<string, number> = { detailed: 3, minimal: 1.5 };\n\n/**\n * The card is nudged off the anchor on whichever side it sits — `offset` design\n * px (8 unless the caller says otherwise), through the theme's type scale.\n */\nconst offsetMargin = (theme: Theme, placement: HoverCardPlacement, offset: number | undefined) => {\n const side = sideOf(placement);\n const key = ({ top: 'mt', bottom: 'mb', left: 'ml', right: 'mr' } as const)[side];\n return { [key]: rem(theme, offset ?? 8) };\n};\n\n/**\n * The card's cap: 400 design px unless the caller says otherwise. `sx` has always\n * read a number of 1 or less as a fraction of the parent, and that stays so.\n */\nconst capOf = (theme: Theme, maxWidth: number | undefined): string => {\n const cap = maxWidth ?? 400;\n return cap <= 1 && cap !== 0 ? `${cap * 100}%` : rem(theme, cap);\n};\n\nexport const HoverCard = React.forwardRef<HTMLDivElement, HoverCardProps>((props, ref) => {\n const {\n variant, glow, pulse, title, description, avatar, trigger, placement, showArrow,\n animation, enterDelay, exitDelay, maxWidth, loading, loadingComponent, loadingText, touchEnabled,\n offset, disabled, onOpen, onClose, children, dataTestId,\n ...rest\n } = withDefaults(props, DEFAULTS) as ResolvedProps;\n\n const { anchorEl, isOpen, handleClose, triggerHandlers, cardHandlers, contentRef } = useHoverCard({\n disabled,\n touchEnabled,\n enterDelay,\n exitDelay,\n onOpen,\n onClose,\n });\n\n const triggerProps = {\n ...triggerHandlers,\n style: { cursor: disabled ? 'default' : 'pointer' },\n 'data-testid': dataTestId ? `${dataTestId}-trigger` : 'hover-card-trigger',\n };\n\n const triggerElement = trigger ? (\n React.cloneElement(trigger, triggerProps)\n ) : (\n <span {...triggerProps} style={{ display: 'inline-block', ...triggerProps.style }}>\n {children}\n </span>\n );\n\n const padding = CONTENT_PADDING[variant] ?? 2;\n\n return (\n <>\n {triggerElement}\n <StyledPopover\n ref={ref}\n open={isOpen && !disabled}\n anchorEl={anchorEl}\n onClose={handleClose}\n anchorOrigin={getAnchorOrigin(placement)}\n transformOrigin={getTransformOrigin(placement)}\n {...cardHandlers}\n disableAutoFocus\n disableEnforceFocus\n disableRestoreFocus\n customAnimation={animation}\n slotProps={{ paper: { style: { pointerEvents: 'auto' } } }}\n {...rest}\n >\n <Box ref={contentRef} sx={{ position: 'relative' }}>\n {showArrow && <ArrowContainer placement={placement} offset={offset} />}\n <StyledCard\n customVariant={variant}\n glow={glow}\n pulse={pulse}\n animation={animation}\n data-testid={dataTestId || 'hover-card-content'}\n sx={(theme) => ({ maxWidth: capOf(theme, maxWidth), ...offsetMargin(theme, placement, offset) })}\n >\n <CardContent sx={{ p: padding, '&:last-child': { pb: padding } }}>\n <HoverCardContent\n loadingText={loadingText} variant={variant} title={title}\n description={description}\n avatar={avatar}\n loading={loading}\n loadingComponent={loadingComponent}\n dataTestId={dataTestId}\n >\n {children}\n </HoverCardContent>\n </CardContent>\n </StyledCard>\n </Box>\n </StyledPopover>\n </>\n );\n});\n\nHoverCard.displayName = 'HoverCard';\n"],"mappings":"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","names":[]}
@@ -3,13 +3,13 @@ import {
3
3
  } from "./chunk-FNG33MKA.js";
4
4
  import {
5
5
  TextField
6
- } from "./chunk-SSS64KYB.js";
6
+ } from "./chunk-Z43N7ASP.js";
7
7
  import {
8
8
  SelectField
9
9
  } from "./chunk-PWZHCBG3.js";
10
10
  import {
11
11
  CepField
12
- } from "./chunk-2XX45PC5.js";
12
+ } from "./chunk-TGXCG62P.js";
13
13
  import {
14
14
  CategoryField
15
15
  } from "./chunk-T6EKPFKZ.js";
@@ -30,4 +30,4 @@ __export(Fields_exports, {
30
30
  export {
31
31
  Fields_exports
32
32
  };
33
- //# sourceMappingURL=chunk-YS67XMOP.js.map
33
+ //# sourceMappingURL=chunk-I5ZVCY2N.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  SaveViewModal
3
- } from "./chunk-VJG7NMGL.js";
3
+ } from "./chunk-IYF246UA.js";
4
4
  import {
5
5
  ManageViewsDialog
6
6
  } from "./chunk-ECIHOZPK.js";
@@ -121,4 +121,4 @@ export {
121
121
  ViewsMenuSlot,
122
122
  ViewDialogs
123
123
  };
124
- //# sourceMappingURL=chunk-A5B7B4HT.js.map
124
+ //# sourceMappingURL=chunk-INMKA5SF.js.map
@@ -12,7 +12,7 @@ import {
12
12
  } from "./chunk-ZGCPDA3F.js";
13
13
  import {
14
14
  Input
15
- } from "./chunk-VURQZBFH.js";
15
+ } from "./chunk-JRJCBDGN.js";
16
16
  import {
17
17
  Dialog,
18
18
  DialogContent
@@ -268,4 +268,4 @@ function SaveViewModal({
268
268
  export {
269
269
  SaveViewModal
270
270
  };
271
- //# sourceMappingURL=chunk-VJG7NMGL.js.map
271
+ //# sourceMappingURL=chunk-IYF246UA.js.map
@@ -64,6 +64,14 @@ var interactionProps = (loading, onClick, disabled) => ({
64
64
  disabled: loading || disabled,
65
65
  onClick: loading ? void 0 : onClick
66
66
  });
67
+ function inputAriaOf(a) {
68
+ const describedBy = [a.helperText ? `${a.id}-helper-text` : void 0, a.describedBy].filter(Boolean).join(" ");
69
+ return {
70
+ ...a.label === void 0 ? {} : { "aria-label": a.label },
71
+ ...a.describedBy === void 0 ? {} : { "aria-describedby": describedBy },
72
+ ...a.busy === void 0 ? {} : { "aria-busy": a.busy }
73
+ };
74
+ }
67
75
  var Input = React.forwardRef(
68
76
  ({
69
77
  variant = "outlined",
@@ -82,9 +90,13 @@ var Input = React.forwardRef(
82
90
  onFocus,
83
91
  onBlur,
84
92
  "aria-label": ariaLabel,
93
+ "aria-describedby": ariaDescribedBy,
94
+ "aria-busy": ariaBusy,
85
95
  ...rest
86
96
  }, ref) => {
87
97
  const { testId: dataTestId, rest: props } = splitTestId(rest);
98
+ const generatedId = React.useId();
99
+ const id = props.id ?? generatedId;
88
100
  return /* @__PURE__ */ jsx(
89
101
  StyledTextField,
90
102
  {
@@ -105,14 +117,15 @@ var Input = React.forwardRef(
105
117
  onBlur,
106
118
  inputProps: {
107
119
  "data-testid": dataTestId,
108
- ...ariaLabel === void 0 ? {} : { "aria-label": ariaLabel }
120
+ ...inputAriaOf({ id, helperText, label: ariaLabel, describedBy: ariaDescribedBy, busy: ariaBusy })
109
121
  },
110
122
  InputProps: {
111
123
  startAdornment: startAdornment && /* @__PURE__ */ jsx(InputAdornment, { position: "start", children: startAdornment }),
112
124
  endAdornment: /* @__PURE__ */ jsx(EndAdornment, { loading, endAdornment })
113
125
  },
114
126
  ...SIZE_MAP[size],
115
- ...props
127
+ ...props,
128
+ id
116
129
  }
117
130
  );
118
131
  }
@@ -122,4 +135,4 @@ Input.displayName = "Input";
122
135
  export {
123
136
  Input
124
137
  };
125
- //# sourceMappingURL=chunk-VURQZBFH.js.map
138
+ //# sourceMappingURL=chunk-JRJCBDGN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/form/Input/Input.tsx"],"sourcesContent":["import CircularProgress from '@mui/material/CircularProgress/index.js';\nimport InputAdornment from '@mui/material/InputAdornment/index.js';\nimport { styled, useTheme } from '@mui/material/styles/index.js';\nimport React from 'react';\n\nimport { INPUT_LOADING } from './Input.metrics';\nimport { TextFieldSlim } from './text-field-slim';\n\nimport {\n filledStyles,\n floatingLabelStyles,\n glowStyles,\n inputBaseStyles,\n inputRadiusStyles,\n muiVariantFor,\n outlinedStyles,\n pulseStyles,\n SIZE_MAP,\n} from './Input.styles';\nimport type { InputProps } from './Input.types';\nimport { splitTestId } from '../../../platform/test-id';\nimport { fieldControlStyles } from '../../../tokens/field-height';\nimport { rem } from '../../../tokens/relative';\nimport type { SizeValue } from '../../../tokens/vocabulary';\n\n/**\n * `TextFieldSlim`, not `TextField` — see `text-field-slim.tsx`. MUI's own\n * `TextField` imports `Select` unconditionally, and through it `Menu`,\n * `Popover`, `Modal` and seven more component modules, so every screen with one\n * text box shipped a dropdown it can never render. Same composition, same DOM,\n * same prop routing; the select branch is the only thing missing.\n */\nconst StyledTextField = styled(TextFieldSlim, {\n shouldForwardProp: (prop) =>\n !['customVariant', 'fieldSize', 'floating', 'glow', 'pulse', 'loading'].includes(prop as string),\n})<{\n customVariant?: InputProps['variant'];\n fieldSize: SizeValue;\n floating?: boolean;\n glow?: boolean;\n pulse?: boolean;\n loading?: boolean;\n}>(({ theme, customVariant, fieldSize, floating, glow, pulse, loading }) => ({\n position: 'relative',\n // The theme's field height for this size (outlined family, one line).\n ...fieldControlStyles(theme, fieldSize),\n opacity: loading ? INPUT_LOADING.opacity : 1,\n\n ...(glow ? glowStyles(theme) : {}),\n ...(pulse ? pulseStyles(theme, fieldSize) : {}),\n ...(floating ? floatingLabelStyles(theme) : {}),\n\n '& .MuiInputBase-root': {\n transition: 'all 0.3s ease',\n ...inputRadiusStyles(theme, customVariant),\n ...inputBaseStyles(theme, customVariant),\n },\n\n '& .MuiOutlinedInput-root': outlinedStyles(theme),\n '& .MuiFilledInput-root': filledStyles(theme),\n}));\n\n/** Only one adornment shows at a time: the spinner replaces the caller's while loading. */\nconst EndAdornment: React.FC<{ loading: boolean; endAdornment?: React.ReactNode }> = ({\n loading,\n endAdornment,\n}) => {\n const theme = useTheme();\n if (loading) {\n return (\n <InputAdornment position=\"end\">\n <CircularProgress size={rem(theme, INPUT_LOADING.spinnerSize)} />\n </InputAdornment>\n );\n }\n\n if (!endAdornment) return null;\n\n return <InputAdornment position=\"end\">{endAdornment}</InputAdornment>;\n};\n\n/** While loading the field is inert: no clicks, and disabled to assistive tech. */\nconst interactionProps = (\n loading: boolean,\n onClick: InputProps['onClick'],\n disabled?: boolean,\n) => ({\n disabled: loading || disabled,\n onClick: loading ? undefined : onClick,\n});\n\n/**\n * The ARIA that describes the field has to sit on the `<input>`: the text\n * field puts every attribute it does not recognise on its root `FormControl`,\n * a `<div>` with no role, where a screen reader never reads it.\n *\n * `aria-label` has ridden `inputProps` since FUT-755. `aria-describedby` and\n * `aria-busy` fell through to the div until FUT-2619, so CepField's input\n * pointed at nothing while its lookup status lived in a live region beside it.\n *\n * `inputProps` are spread onto the `<input>` AFTER the `aria-describedby` MUI\n * writes for helper text, so a caller's ids REPLACE the helper text's: MUI's\n * `TextField` on its own keeps only one of the two. This joins both, helper\n * text first. The helper id is MUI's `<id>-helper-text` (the parity test pins\n * that spelling), which is why the field's id is fixed here rather than left\n * to the text field.\n */\nfunction inputAriaOf(a: {\n id: string;\n helperText: React.ReactNode;\n label?: string;\n describedBy?: string;\n busy?: InputProps['aria-busy'];\n}): Record<string, unknown> {\n const describedBy = [a.helperText ? `${a.id}-helper-text` : undefined, a.describedBy]\n .filter(Boolean)\n .join(' ');\n return {\n ...(a.label === undefined ? {} : { 'aria-label': a.label }),\n ...(a.describedBy === undefined ? {} : { 'aria-describedby': describedBy }),\n ...(a.busy === undefined ? {} : { 'aria-busy': a.busy }),\n };\n}\n\nexport const Input = React.forwardRef<HTMLInputElement, InputProps>(\n (\n {\n variant = 'outlined',\n size = 'md',\n label,\n error,\n helperText,\n startAdornment,\n endAdornment,\n fullWidth = true,\n floating = false,\n glow = false,\n pulse = false,\n loading = false,\n onClick,\n onFocus,\n onBlur,\n 'aria-label': ariaLabel,\n 'aria-describedby': ariaDescribedBy,\n 'aria-busy': ariaBusy,\n ...rest\n },\n ref,\n ) => {\n const { testId: dataTestId, rest: props } = splitTestId(rest);\n const generatedId = React.useId();\n const id = props.id ?? generatedId;\n return (\n <StyledTextField\n ref={ref}\n variant={muiVariantFor(variant)}\n customVariant={variant}\n fieldSize={size}\n floating={floating}\n glow={glow}\n pulse={pulse}\n loading={loading}\n label={label}\n error={error}\n helperText={helperText}\n fullWidth={fullWidth}\n {...interactionProps(loading, onClick, props.disabled)}\n onFocus={onFocus}\n onBlur={onBlur}\n /*\n * `aria-label` has to ride `inputProps` to reach the `<input>` (FUT-755).\n * Spread with the rest it lands on the FormControl DIV that the text\n * field renders as its root, which carries no role — so the field kept\n * no accessible name, and a source grep saying \"this input is labelled\"\n * disagreed with the DOM. The reports search box and the block-title\n * inputs were both named in source and anonymous to a screen reader.\n * `aria-describedby` and `aria-busy` are the same case: `inputAriaOf`.\n */\n inputProps={{\n 'data-testid': dataTestId,\n ...inputAriaOf({ id, helperText, label: ariaLabel, describedBy: ariaDescribedBy, busy: ariaBusy }),\n }}\n InputProps={{\n startAdornment: startAdornment && (\n <InputAdornment position=\"start\">{startAdornment}</InputAdornment>\n ),\n endAdornment: <EndAdornment loading={loading} endAdornment={endAdornment} />,\n }}\n {...SIZE_MAP[size]}\n {...props}\n id={id}\n />\n );\n },\n);\n\nInput.displayName = 'Input';\n"],"mappings":"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","names":[]}
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-4XK6JQ4D.js";
4
4
  import {
5
5
  CepField
6
- } from "./chunk-F6D6HXZU.js";
6
+ } from "./chunk-7X7ZHJHM.js";
7
7
 
8
8
  // src/components/form/total-form/Fields/CepField.tsx
9
9
  import { useCallback, useMemo, useRef } from "react";
@@ -80,4 +80,4 @@ function CepField2({
80
80
  export {
81
81
  CepField2 as CepField
82
82
  };
83
- //# sourceMappingURL=chunk-2XX45PC5.js.map
83
+ //# sourceMappingURL=chunk-TGXCG62P.js.map
@@ -1,5 +1,9 @@
1
1
  // src/components/data-display/HoverCard/HoverCard.hooks.ts
2
2
  import React from "react";
3
+ var clearPending = (ref) => {
4
+ if (ref.current !== void 0) window.clearTimeout(ref.current);
5
+ ref.current = void 0;
6
+ };
3
7
  var useHoverHandlers = ({
4
8
  isTouchDevice,
5
9
  touchEnabled,
@@ -25,7 +29,7 @@ var useHoverHandlers = ({
25
29
  const triggerHandlers = {
26
30
  onMouseEnter: (event) => {
27
31
  if (hoverIgnored) return;
28
- openCard(event);
32
+ openCard(event.currentTarget);
29
33
  },
30
34
  onMouseLeave: () => {
31
35
  if (hoverIgnored) return;
@@ -34,16 +38,15 @@ var useHoverHandlers = ({
34
38
  onTouchStart: (event) => {
35
39
  if (!touchEnabled) return;
36
40
  if (touchTimeout) window.clearTimeout(touchTimeout);
37
- setTouchTimeout(window.setTimeout(() => openCard(event), enterDelay));
41
+ const trigger = event.currentTarget;
42
+ setTouchTimeout(window.setTimeout(() => openCard(trigger), enterDelay));
38
43
  },
39
44
  // End and cancel do the same thing: the press did not become a long press.
40
45
  onTouchEnd: cancelTouch,
41
46
  onTouchCancel: cancelTouch
42
47
  };
43
48
  const cardHandlers = {
44
- onMouseEnter: () => {
45
- if (exitTimeoutRef.current) window.clearTimeout(exitTimeoutRef.current);
46
- },
49
+ onMouseEnter: () => clearPending(exitTimeoutRef),
47
50
  onMouseLeave: closeCard
48
51
  };
49
52
  return { triggerHandlers, cardHandlers };
@@ -58,6 +61,25 @@ var useEscapeKey = (active, onEscape) => {
58
61
  return () => document.removeEventListener("keydown", handleEscape);
59
62
  }, [active, onEscape]);
60
63
  };
64
+ var useClickAway = (active, inside, onAway) => {
65
+ React.useEffect(() => {
66
+ if (!active) return;
67
+ const handlePointerDown = (event) => {
68
+ const target = event.target;
69
+ if (target && inside().some((el) => el?.contains(target))) return;
70
+ onAway();
71
+ };
72
+ document.addEventListener("pointerdown", handlePointerDown, true);
73
+ return () => document.removeEventListener("pointerdown", handlePointerDown, true);
74
+ }, [active, inside, onAway]);
75
+ };
76
+ var useClearOnUnmount = (...refs) => {
77
+ React.useEffect(
78
+ () => () => refs.forEach(clearPending),
79
+ // The refs are stable objects: a mount/unmount pair, as before.
80
+ []
81
+ );
82
+ };
61
83
  var useHoverCard = ({
62
84
  disabled,
63
85
  touchEnabled,
@@ -71,18 +93,17 @@ var useHoverCard = ({
71
93
  const [isTouchDevice, setIsTouchDevice] = React.useState(false);
72
94
  const enterTimeoutRef = React.useRef(void 0);
73
95
  const exitTimeoutRef = React.useRef(void 0);
96
+ const contentRef = React.useRef(null);
74
97
  React.useEffect(() => {
75
98
  setIsTouchDevice("ontouchstart" in window);
76
99
  }, []);
77
100
  const openCard = React.useCallback(
78
- (event) => {
101
+ (trigger) => {
79
102
  if (disabled) return;
80
- if (exitTimeoutRef.current) {
81
- window.clearTimeout(exitTimeoutRef.current);
82
- }
83
- const target = event.currentTarget;
103
+ clearPending(exitTimeoutRef);
104
+ clearPending(enterTimeoutRef);
84
105
  enterTimeoutRef.current = window.setTimeout(() => {
85
- setAnchorEl(target);
106
+ setAnchorEl(trigger);
86
107
  setIsOpen(true);
87
108
  onOpen?.();
88
109
  }, enterDelay);
@@ -90,9 +111,8 @@ var useHoverCard = ({
90
111
  [disabled, enterDelay, onOpen]
91
112
  );
92
113
  const closeCard = React.useCallback(() => {
93
- if (enterTimeoutRef.current) {
94
- window.clearTimeout(enterTimeoutRef.current);
95
- }
114
+ clearPending(enterTimeoutRef);
115
+ clearPending(exitTimeoutRef);
96
116
  exitTimeoutRef.current = window.setTimeout(() => {
97
117
  setIsOpen(false);
98
118
  setAnchorEl(null);
@@ -100,6 +120,8 @@ var useHoverCard = ({
100
120
  }, exitDelay);
101
121
  }, [exitDelay, onClose]);
102
122
  const handleClose = React.useCallback(() => {
123
+ clearPending(enterTimeoutRef);
124
+ clearPending(exitTimeoutRef);
103
125
  setIsOpen(false);
104
126
  setAnchorEl(null);
105
127
  onClose?.();
@@ -112,18 +134,14 @@ var useHoverCard = ({
112
134
  closeCard,
113
135
  exitTimeoutRef
114
136
  });
137
+ const insideCard = React.useCallback(() => [anchorEl, contentRef.current], [anchorEl]);
115
138
  useEscapeKey(isOpen, handleClose);
116
- React.useEffect(
117
- () => () => {
118
- if (enterTimeoutRef.current) window.clearTimeout(enterTimeoutRef.current);
119
- if (exitTimeoutRef.current) window.clearTimeout(exitTimeoutRef.current);
120
- },
121
- []
122
- );
123
- return { anchorEl, isOpen, handleClose, triggerHandlers, cardHandlers };
139
+ useClickAway(isOpen, insideCard, handleClose);
140
+ useClearOnUnmount(enterTimeoutRef, exitTimeoutRef);
141
+ return { anchorEl, isOpen, handleClose, triggerHandlers, cardHandlers, contentRef };
124
142
  };
125
143
 
126
144
  export {
127
145
  useHoverCard
128
146
  };
129
- //# sourceMappingURL=chunk-SXYIXCUB.js.map
147
+ //# sourceMappingURL=chunk-VNWZWQF3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/data-display/HoverCard/HoverCard.hooks.ts"],"sourcesContent":["import React from 'react';\n\ntype TimerRef = React.MutableRefObject<number | undefined>;\n\n/**\n * Cancel the timer a ref holds, and forget it. Every place that schedules\n * or dismisses goes through this, so no timer outlives the ref that could\n * cancel it (FUT-2619: an overwritten enter timer reopened a dismissed card).\n */\nconst clearPending = (ref: TimerRef) => {\n if (ref.current !== undefined) window.clearTimeout(ref.current);\n ref.current = undefined;\n};\n\ninterface HandlerInput {\n isTouchDevice: boolean;\n touchEnabled: boolean;\n enterDelay: number;\n openCard: (trigger: HTMLElement) => void;\n closeCard: () => void;\n exitTimeoutRef: TimerRef;\n}\n\n/**\n * The pointer and touch handlers, over the open/close pair. Touch gets a\n * long-press because there is no hover to respond to; the card's own handlers\n * keep it open while the pointer is travelling onto it.\n */\nconst useHoverHandlers = ({\n isTouchDevice,\n touchEnabled,\n enterDelay,\n openCard,\n closeCard,\n exitTimeoutRef,\n}: HandlerInput) => {\n const [touchTimeout, setTouchTimeout] = React.useState<number>();\n\n /** A touch device with touch disabled has no hover to respond to. */\n const hoverIgnored = isTouchDevice && !touchEnabled;\n\n const cancelTouch = React.useCallback(() => {\n if (touchTimeout) {\n window.clearTimeout(touchTimeout);\n setTouchTimeout(undefined);\n }\n }, [touchTimeout]);\n\n React.useEffect(\n () => () => {\n if (touchTimeout) window.clearTimeout(touchTimeout);\n },\n [touchTimeout],\n );\n\n const triggerHandlers = {\n onMouseEnter: (event: React.MouseEvent<HTMLElement>) => {\n if (hoverIgnored) return;\n openCard(event.currentTarget);\n },\n onMouseLeave: () => {\n if (hoverIgnored) return;\n closeCard();\n },\n onTouchStart: (event: React.TouchEvent<HTMLElement>) => {\n if (!touchEnabled) return;\n if (touchTimeout) window.clearTimeout(touchTimeout);\n // Read NOW: React nulls `currentTarget` once the handler returns, so\n // the long-press timer used to open the card with no anchor at all.\n const trigger = event.currentTarget;\n setTouchTimeout(window.setTimeout(() => openCard(trigger), enterDelay));\n },\n // End and cancel do the same thing: the press did not become a long press.\n onTouchEnd: cancelTouch,\n onTouchCancel: cancelTouch,\n };\n\n /** Moving onto the card keeps it open; leaving it starts the exit delay. */\n const cardHandlers = {\n onMouseEnter: () => clearPending(exitTimeoutRef),\n onMouseLeave: closeCard,\n };\n\n return { triggerHandlers, cardHandlers };\n};\n\n/** Escape dismisses the card while it is open. */\nconst useEscapeKey = (active: boolean, onEscape: () => void) => {\n React.useEffect(() => {\n if (!active) return;\n\n const handleEscape = (event: globalThis.KeyboardEvent) => {\n if (event.key === 'Escape') onEscape();\n };\n\n document.addEventListener('keydown', handleEscape);\n return () => document.removeEventListener('keydown', handleEscape);\n }, [active, onEscape]);\n};\n\n/**\n * A press anywhere outside the trigger and the card dismisses it.\n *\n * Touch has no mouse-leave, and MUI's own click-away was the popover's\n * backdrop, which `pointer-events: none` on the popover root (so the page\n * under an open card stays usable) takes out of play. So this listens on the\n * document itself, in the CAPTURE phase, where a `stopPropagation` further in\n * cannot swallow it. It only observes: no `preventDefault`, so the tap or\n * click still reaches whatever it landed on. Attached while open, removed on\n * close and on unmount.\n */\nconst useClickAway = (\n active: boolean,\n inside: () => ReadonlyArray<Element | null>,\n onAway: () => void,\n) => {\n React.useEffect(() => {\n if (!active) return;\n\n const handlePointerDown = (event: globalThis.PointerEvent) => {\n const target = event.target as Node | null;\n if (target && inside().some((el) => el?.contains(target))) return;\n onAway();\n };\n\n document.addEventListener('pointerdown', handlePointerDown, true);\n return () => document.removeEventListener('pointerdown', handlePointerDown, true);\n }, [active, inside, onAway]);\n};\n\n/** Whatever is still pending when the card unmounts is cancelled with it. */\nconst useClearOnUnmount = (...refs: TimerRef[]) => {\n React.useEffect(\n () => () => refs.forEach(clearPending),\n // The refs are stable objects: a mount/unmount pair, as before.\n [],\n );\n};\n\ninterface HoverCardTimingInput {\n disabled: boolean;\n touchEnabled: boolean;\n enterDelay: number;\n exitDelay: number;\n onOpen?: () => void;\n onClose?: () => void;\n}\n\n/**\n * When the card is open, and the delays that decide it.\n *\n * Three timers are in play: the enter delay before opening, the exit delay\n * before closing (so the pointer can travel from the trigger onto the card\n * without dismissing it), and the long-press timer on touch. Each cancels the\n * others' pending work, which is why they live together.\n */\nexport const useHoverCard = ({\n disabled,\n touchEnabled,\n enterDelay,\n exitDelay,\n onOpen,\n onClose,\n}: HoverCardTimingInput) => {\n const [anchorEl, setAnchorEl] = React.useState<HTMLElement | null>(null);\n const [isOpen, setIsOpen] = React.useState(false);\n const [isTouchDevice, setIsTouchDevice] = React.useState(false);\n const enterTimeoutRef = React.useRef<number | undefined>(undefined);\n const exitTimeoutRef = React.useRef<number | undefined>(undefined);\n /** The card's own box, inside the popover paper: a press here is not \"away\". */\n const contentRef = React.useRef<HTMLDivElement | null>(null);\n\n // Probed in an effect, not during render, so SSR and hydration stay intact.\n React.useEffect(() => {\n setIsTouchDevice('ontouchstart' in window);\n }, []);\n\n const openCard = React.useCallback(\n (trigger: HTMLElement) => {\n if (disabled) return;\n\n clearPending(exitTimeoutRef);\n // A second enter before the delay ran out (a click and then a hover, or\n // the pointer jittering across the edge) must REPLACE the pending open,\n // not add one: an overwritten timer can no longer be cancelled, and it\n // reopened the card after Escape had closed it.\n clearPending(enterTimeoutRef);\n\n enterTimeoutRef.current = window.setTimeout(() => {\n setAnchorEl(trigger);\n setIsOpen(true);\n onOpen?.();\n }, enterDelay);\n },\n [disabled, enterDelay, onOpen],\n );\n\n const closeCard = React.useCallback(() => {\n clearPending(enterTimeoutRef);\n clearPending(exitTimeoutRef);\n\n exitTimeoutRef.current = window.setTimeout(() => {\n setIsOpen(false);\n setAnchorEl(null);\n onClose?.();\n }, exitDelay);\n }, [exitDelay, onClose]);\n\n // Escape and the popover's own close are FINAL: nothing still pending may\n // reopen the card behind them. It opens again on the next enter.\n const handleClose = React.useCallback(() => {\n clearPending(enterTimeoutRef);\n clearPending(exitTimeoutRef);\n setIsOpen(false);\n setAnchorEl(null);\n onClose?.();\n }, [onClose]);\n\n const { triggerHandlers, cardHandlers } = useHoverHandlers({\n isTouchDevice,\n touchEnabled,\n enterDelay,\n openCard,\n closeCard,\n exitTimeoutRef,\n });\n\n const insideCard = React.useCallback(() => [anchorEl, contentRef.current], [anchorEl]);\n\n useEscapeKey(isOpen, handleClose);\n useClickAway(isOpen, insideCard, handleClose);\n useClearOnUnmount(enterTimeoutRef, exitTimeoutRef);\n\n return { anchorEl, isOpen, handleClose, triggerHandlers, cardHandlers, contentRef };\n};\n"],"mappings":"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","names":[]}
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-4XK6JQ4D.js";
4
4
  import {
5
5
  Input
6
- } from "./chunk-VURQZBFH.js";
6
+ } from "./chunk-JRJCBDGN.js";
7
7
  import {
8
8
  FormControl,
9
9
  FormLabel,
@@ -38,4 +38,4 @@ function TextField({ name, label, type = "text", placeholder }) {
38
38
  export {
39
39
  TextField
40
40
  };
41
- //# sourceMappingURL=chunk-SSS64KYB.js.map
41
+ //# sourceMappingURL=chunk-Z43N7ASP.js.map
@@ -10,7 +10,7 @@ import {
10
10
  import {
11
11
  ViewDialogs,
12
12
  ViewMutationErrorAlert
13
- } from "./chunk-A5B7B4HT.js";
13
+ } from "./chunk-INMKA5SF.js";
14
14
  import {
15
15
  useSavedViewsController
16
16
  } from "./chunk-HR7YTBR7.js";
@@ -178,4 +178,4 @@ function renderViewDialogs(ctl, fields, columns, views, testIdPrefix, onSaved) {
178
178
  export {
179
179
  DataViewsTableBase
180
180
  };
181
- //# sourceMappingURL=chunk-6MFMLQ72.js.map
181
+ //# sourceMappingURL=chunk-ZNDDILNQ.js.map
@@ -3,7 +3,7 @@ import {
3
3
  } from "../chunk-I5T5PQQW.js";
4
4
  import {
5
5
  DataViewsTableBase
6
- } from "../chunk-6MFMLQ72.js";
6
+ } from "../chunk-ZNDDILNQ.js";
7
7
  import "../chunk-3333KCAW.js";
8
8
  import {
9
9
  DataViewsGrid
@@ -68,8 +68,8 @@ import {
68
68
  cardScaleForZoom
69
69
  } from "../chunk-XZJM6EPC.js";
70
70
  import "../chunk-M4KVKQRN.js";
71
- import "../chunk-A5B7B4HT.js";
72
- import "../chunk-VJG7NMGL.js";
71
+ import "../chunk-INMKA5SF.js";
72
+ import "../chunk-IYF246UA.js";
73
73
  import "../chunk-ECIHOZPK.js";
74
74
  import "../chunk-5M4TYFR3.js";
75
75
  import "../chunk-HR7YTBR7.js";
@@ -151,7 +151,7 @@ import "../chunk-LXT3X33C.js";
151
151
  import "../chunk-DMNZD3Q7.js";
152
152
  import "../chunk-JC22FNFA.js";
153
153
  import "../chunk-QYKDY4EI.js";
154
- import "../chunk-VURQZBFH.js";
154
+ import "../chunk-JRJCBDGN.js";
155
155
  import "../chunk-SL6454K7.js";
156
156
  import "../chunk-THMT3G3L.js";
157
157
  import "../chunk-RNIU447I.js";
@@ -1,9 +1,9 @@
1
1
  import "../chunk-6OS4AKWT.js";
2
2
  import {
3
3
  HoverCard
4
- } from "../chunk-DAHYLPK7.js";
4
+ } from "../chunk-CMV6BRQ3.js";
5
5
  import "../chunk-BSYPPO2I.js";
6
- import "../chunk-SXYIXCUB.js";
6
+ import "../chunk-VNWZWQF3.js";
7
7
  import "../chunk-NRIV2CQ2.js";
8
8
  import "../chunk-ZHV7TCAC.js";
9
9
  import "../chunk-HPK33ACY.js";
@@ -1,9 +1,9 @@
1
1
  import "../chunk-6XLMTOJ3.js";
2
2
  import {
3
3
  CepField
4
- } from "../chunk-F6D6HXZU.js";
4
+ } from "../chunk-7X7ZHJHM.js";
5
5
  import "../chunk-QYKDY4EI.js";
6
- import "../chunk-VURQZBFH.js";
6
+ import "../chunk-JRJCBDGN.js";
7
7
  import "../chunk-SL6454K7.js";
8
8
  import "../chunk-THMT3G3L.js";
9
9
  import "../chunk-RNIU447I.js";
@@ -1,7 +1,7 @@
1
1
  import "../chunk-QYKDY4EI.js";
2
2
  import {
3
3
  Input
4
- } from "../chunk-VURQZBFH.js";
4
+ } from "../chunk-JRJCBDGN.js";
5
5
  import "../chunk-SL6454K7.js";
6
6
  import "../chunk-THMT3G3L.js";
7
7
  import "../chunk-RNIU447I.js";
@@ -9,15 +9,15 @@ import {
9
9
  } from "../chunk-CPAJYJUD.js";
10
10
  import {
11
11
  Fields_exports
12
- } from "../chunk-YS67XMOP.js";
12
+ } from "../chunk-I5ZVCY2N.js";
13
13
  import "../chunk-FNG33MKA.js";
14
14
  import {
15
15
  TextField
16
- } from "../chunk-SSS64KYB.js";
16
+ } from "../chunk-Z43N7ASP.js";
17
17
  import {
18
18
  SelectField
19
19
  } from "../chunk-PWZHCBG3.js";
20
- import "../chunk-2XX45PC5.js";
20
+ import "../chunk-TGXCG62P.js";
21
21
  import {
22
22
  CategoryField
23
23
  } from "../chunk-T6EKPFKZ.js";
@@ -33,7 +33,7 @@ import "../chunk-W5TI46QN.js";
33
33
  import "../chunk-JD5BVIM7.js";
34
34
  import "../chunk-VQYR64QB.js";
35
35
  import "../chunk-6XLMTOJ3.js";
36
- import "../chunk-F6D6HXZU.js";
36
+ import "../chunk-7X7ZHJHM.js";
37
37
  import "../chunk-N5ZWC6CB.js";
38
38
  import "../chunk-BKASAYQL.js";
39
39
  import "../chunk-2JNHWKQK.js";
@@ -52,7 +52,7 @@ import "../chunk-LXT3X33C.js";
52
52
  import "../chunk-DMNZD3Q7.js";
53
53
  import "../chunk-JC22FNFA.js";
54
54
  import "../chunk-QYKDY4EI.js";
55
- import "../chunk-VURQZBFH.js";
55
+ import "../chunk-JRJCBDGN.js";
56
56
  import "../chunk-SL6454K7.js";
57
57
  import "../chunk-THMT3G3L.js";
58
58
  import "../chunk-RNIU447I.js";
@@ -1 +1 @@
1
- {"version":3,"file":"HoverCard.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/HoverCard/HoverCard.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,MAAM,OAAO,CAAC;AAS1B,OAAO,KAAK,EAA0C,cAAc,EAAE,MAAM,mBAAmB,CAAC;AA6DhG,eAAO,MAAM,SAAS,oGA8EpB,CAAC"}
1
+ {"version":3,"file":"HoverCard.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/HoverCard/HoverCard.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,MAAM,OAAO,CAAC;AAS1B,OAAO,KAAK,EAA0C,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAsEhG,eAAO,MAAM,SAAS,oGA8EpB,CAAC"}
@@ -30,6 +30,7 @@ export declare const useHoverCard: ({ disabled, touchEnabled, enterDelay, exitDe
30
30
  onMouseEnter: () => void;
31
31
  onMouseLeave: () => void;
32
32
  };
33
+ contentRef: React.RefObject<HTMLDivElement | null>;
33
34
  };
34
35
  export {};
35
36
  //# sourceMappingURL=HoverCard.hooks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"HoverCard.hooks.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/HoverCard/HoverCard.hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAuF1B,UAAU,oBAAoB;IAC5B,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,GAAI,qEAO1B,oBAAoB;;;;;8BAnEG,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC;;8BAQ7B,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC;;;;;;4BA7CpC,IAAI;;CA4KtB,CAAC"}
1
+ {"version":3,"file":"HoverCard.hooks.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/HoverCard/HoverCard.hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AA2I1B,UAAU,oBAAoB;IAC5B,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,GAAI,qEAO1B,oBAAoB;;;;;8BA3GG,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC;;8BAQ7B,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC;;;;;;4BA7CpC,IAAI;;;CAuNtB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Input.d.ts","sourceRoot":"","sources":["../../../../../src/components/form/Input/Input.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAC;AAgB1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAwEhD,eAAO,MAAM,KAAK,qFAgEjB,CAAC"}
1
+ {"version":3,"file":"Input.d.ts","sourceRoot":"","sources":["../../../../../src/components/form/Input/Input.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAC;AAgB1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAyGhD,eAAO,MAAM,KAAK,qFAsEjB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@12-apps/ui",
3
- "version": "6.39.10",
3
+ "version": "6.39.11",
4
4
  "license": "MIT",
5
5
  "packageManager": "pnpm@10.34.5",
6
6
  "type": "module",
@@ -1,12 +1,24 @@
1
1
  import React from 'react';
2
2
 
3
+ type TimerRef = React.MutableRefObject<number | undefined>;
4
+
5
+ /**
6
+ * Cancel the timer a ref holds, and forget it. Every place that schedules
7
+ * or dismisses goes through this, so no timer outlives the ref that could
8
+ * cancel it (FUT-2619: an overwritten enter timer reopened a dismissed card).
9
+ */
10
+ const clearPending = (ref: TimerRef) => {
11
+ if (ref.current !== undefined) window.clearTimeout(ref.current);
12
+ ref.current = undefined;
13
+ };
14
+
3
15
  interface HandlerInput {
4
16
  isTouchDevice: boolean;
5
17
  touchEnabled: boolean;
6
18
  enterDelay: number;
7
- openCard: (event: React.MouseEvent<HTMLElement> | React.TouchEvent<HTMLElement>) => void;
19
+ openCard: (trigger: HTMLElement) => void;
8
20
  closeCard: () => void;
9
- exitTimeoutRef: React.MutableRefObject<number | undefined>;
21
+ exitTimeoutRef: TimerRef;
10
22
  }
11
23
 
12
24
  /**
@@ -44,7 +56,7 @@ const useHoverHandlers = ({
44
56
  const triggerHandlers = {
45
57
  onMouseEnter: (event: React.MouseEvent<HTMLElement>) => {
46
58
  if (hoverIgnored) return;
47
- openCard(event);
59
+ openCard(event.currentTarget);
48
60
  },
49
61
  onMouseLeave: () => {
50
62
  if (hoverIgnored) return;
@@ -53,7 +65,10 @@ const useHoverHandlers = ({
53
65
  onTouchStart: (event: React.TouchEvent<HTMLElement>) => {
54
66
  if (!touchEnabled) return;
55
67
  if (touchTimeout) window.clearTimeout(touchTimeout);
56
- setTouchTimeout(window.setTimeout(() => openCard(event), enterDelay));
68
+ // Read NOW: React nulls `currentTarget` once the handler returns, so
69
+ // the long-press timer used to open the card with no anchor at all.
70
+ const trigger = event.currentTarget;
71
+ setTouchTimeout(window.setTimeout(() => openCard(trigger), enterDelay));
57
72
  },
58
73
  // End and cancel do the same thing: the press did not become a long press.
59
74
  onTouchEnd: cancelTouch,
@@ -62,9 +77,7 @@ const useHoverHandlers = ({
62
77
 
63
78
  /** Moving onto the card keeps it open; leaving it starts the exit delay. */
64
79
  const cardHandlers = {
65
- onMouseEnter: () => {
66
- if (exitTimeoutRef.current) window.clearTimeout(exitTimeoutRef.current);
67
- },
80
+ onMouseEnter: () => clearPending(exitTimeoutRef),
68
81
  onMouseLeave: closeCard,
69
82
  };
70
83
 
@@ -85,6 +98,45 @@ const useEscapeKey = (active: boolean, onEscape: () => void) => {
85
98
  }, [active, onEscape]);
86
99
  };
87
100
 
101
+ /**
102
+ * A press anywhere outside the trigger and the card dismisses it.
103
+ *
104
+ * Touch has no mouse-leave, and MUI's own click-away was the popover's
105
+ * backdrop, which `pointer-events: none` on the popover root (so the page
106
+ * under an open card stays usable) takes out of play. So this listens on the
107
+ * document itself, in the CAPTURE phase, where a `stopPropagation` further in
108
+ * cannot swallow it. It only observes: no `preventDefault`, so the tap or
109
+ * click still reaches whatever it landed on. Attached while open, removed on
110
+ * close and on unmount.
111
+ */
112
+ const useClickAway = (
113
+ active: boolean,
114
+ inside: () => ReadonlyArray<Element | null>,
115
+ onAway: () => void,
116
+ ) => {
117
+ React.useEffect(() => {
118
+ if (!active) return;
119
+
120
+ const handlePointerDown = (event: globalThis.PointerEvent) => {
121
+ const target = event.target as Node | null;
122
+ if (target && inside().some((el) => el?.contains(target))) return;
123
+ onAway();
124
+ };
125
+
126
+ document.addEventListener('pointerdown', handlePointerDown, true);
127
+ return () => document.removeEventListener('pointerdown', handlePointerDown, true);
128
+ }, [active, inside, onAway]);
129
+ };
130
+
131
+ /** Whatever is still pending when the card unmounts is cancelled with it. */
132
+ const useClearOnUnmount = (...refs: TimerRef[]) => {
133
+ React.useEffect(
134
+ () => () => refs.forEach(clearPending),
135
+ // The refs are stable objects: a mount/unmount pair, as before.
136
+ [],
137
+ );
138
+ };
139
+
88
140
  interface HoverCardTimingInput {
89
141
  disabled: boolean;
90
142
  touchEnabled: boolean;
@@ -115,6 +167,8 @@ export const useHoverCard = ({
115
167
  const [isTouchDevice, setIsTouchDevice] = React.useState(false);
116
168
  const enterTimeoutRef = React.useRef<number | undefined>(undefined);
117
169
  const exitTimeoutRef = React.useRef<number | undefined>(undefined);
170
+ /** The card's own box, inside the popover paper: a press here is not "away". */
171
+ const contentRef = React.useRef<HTMLDivElement | null>(null);
118
172
 
119
173
  // Probed in an effect, not during render, so SSR and hydration stay intact.
120
174
  React.useEffect(() => {
@@ -122,16 +176,18 @@ export const useHoverCard = ({
122
176
  }, []);
123
177
 
124
178
  const openCard = React.useCallback(
125
- (event: React.MouseEvent<HTMLElement> | React.TouchEvent<HTMLElement>) => {
179
+ (trigger: HTMLElement) => {
126
180
  if (disabled) return;
127
181
 
128
- if (exitTimeoutRef.current) {
129
- window.clearTimeout(exitTimeoutRef.current);
130
- }
182
+ clearPending(exitTimeoutRef);
183
+ // A second enter before the delay ran out (a click and then a hover, or
184
+ // the pointer jittering across the edge) must REPLACE the pending open,
185
+ // not add one: an overwritten timer can no longer be cancelled, and it
186
+ // reopened the card after Escape had closed it.
187
+ clearPending(enterTimeoutRef);
131
188
 
132
- const target = event.currentTarget;
133
189
  enterTimeoutRef.current = window.setTimeout(() => {
134
- setAnchorEl(target);
190
+ setAnchorEl(trigger);
135
191
  setIsOpen(true);
136
192
  onOpen?.();
137
193
  }, enterDelay);
@@ -140,9 +196,8 @@ export const useHoverCard = ({
140
196
  );
141
197
 
142
198
  const closeCard = React.useCallback(() => {
143
- if (enterTimeoutRef.current) {
144
- window.clearTimeout(enterTimeoutRef.current);
145
- }
199
+ clearPending(enterTimeoutRef);
200
+ clearPending(exitTimeoutRef);
146
201
 
147
202
  exitTimeoutRef.current = window.setTimeout(() => {
148
203
  setIsOpen(false);
@@ -151,7 +206,11 @@ export const useHoverCard = ({
151
206
  }, exitDelay);
152
207
  }, [exitDelay, onClose]);
153
208
 
209
+ // Escape and the popover's own close are FINAL: nothing still pending may
210
+ // reopen the card behind them. It opens again on the next enter.
154
211
  const handleClose = React.useCallback(() => {
212
+ clearPending(enterTimeoutRef);
213
+ clearPending(exitTimeoutRef);
155
214
  setIsOpen(false);
156
215
  setAnchorEl(null);
157
216
  onClose?.();
@@ -166,15 +225,11 @@ export const useHoverCard = ({
166
225
  exitTimeoutRef,
167
226
  });
168
227
 
169
- useEscapeKey(isOpen, handleClose);
228
+ const insideCard = React.useCallback(() => [anchorEl, contentRef.current], [anchorEl]);
170
229
 
171
- React.useEffect(
172
- () => () => {
173
- if (enterTimeoutRef.current) window.clearTimeout(enterTimeoutRef.current);
174
- if (exitTimeoutRef.current) window.clearTimeout(exitTimeoutRef.current);
175
- },
176
- [],
177
- );
230
+ useEscapeKey(isOpen, handleClose);
231
+ useClickAway(isOpen, insideCard, handleClose);
232
+ useClearOnUnmount(enterTimeoutRef, exitTimeoutRef);
178
233
 
179
- return { anchorEl, isOpen, handleClose, triggerHandlers, cardHandlers };
234
+ return { anchorEl, isOpen, handleClose, triggerHandlers, cardHandlers, contentRef };
180
235
  };
@@ -107,6 +107,7 @@ The HoverCard component displays additional information in a card-style popup wh
107
107
  ## Accessibility Notes
108
108
 
109
109
  - The component supports keyboard navigation (Escape key to close)
110
+ - The card is dismissed by moving the pointer off the trigger and the card (after `exitDelay`), by Escape, or by a tap or click anywhere outside them. The outside press still reaches what it landed on: the page under an open card stays usable
110
111
  - Proper ARIA attributes are applied to the popover
111
112
  - Focus management is handled automatically
112
113
  - Touch support for mobile devices can be enabled/disabled
@@ -26,6 +26,15 @@ const StyledCard = styled(Card, {
26
26
  const StyledPopover = styled(Popover, {
27
27
  shouldForwardProp: (prop) => prop !== 'customAnimation',
28
28
  })<{ customAnimation?: HoverCardAnimation }>(({ customAnimation }) => ({
29
+ // Only the card takes the pointer (its paper sets `pointer-events: auto`).
30
+ // MUI's popover root and its invisible backdrop cover the whole viewport, so
31
+ // while a card was open the pointer was "on the card" wherever it went: the
32
+ // backdrop's mouseover reached the card's onMouseEnter and cancelled the
33
+ // close the trigger's mouseleave had just scheduled. A card left by moving
34
+ // the mouse away stayed open, and the page's next click hit the backdrop
35
+ // instead of its target (FUT-2619). The backdrop was also the only
36
+ // click-away; `useClickAway` in the hooks replaces it.
37
+ pointerEvents: 'none',
29
38
  // The popover only positions; StyledCard draws the surface.
30
39
  '& .MuiPopover-paper': {
31
40
  backgroundColor: 'transparent',
@@ -81,7 +90,7 @@ export const HoverCard = React.forwardRef<HTMLDivElement, HoverCardProps>((props
81
90
  ...rest
82
91
  } = withDefaults(props, DEFAULTS) as ResolvedProps;
83
92
 
84
- const { anchorEl, isOpen, handleClose, triggerHandlers, cardHandlers } = useHoverCard({
93
+ const { anchorEl, isOpen, handleClose, triggerHandlers, cardHandlers, contentRef } = useHoverCard({
85
94
  disabled,
86
95
  touchEnabled,
87
96
  enterDelay,
@@ -124,7 +133,7 @@ export const HoverCard = React.forwardRef<HTMLDivElement, HoverCardProps>((props
124
133
  slotProps={{ paper: { style: { pointerEvents: 'auto' } } }}
125
134
  {...rest}
126
135
  >
127
- <Box sx={{ position: 'relative' }}>
136
+ <Box ref={contentRef} sx={{ position: 'relative' }}>
128
137
  {showArrow && <ArrowContainer placement={placement} offset={offset} />}
129
138
  <StyledCard
130
139
  customVariant={variant}
@@ -89,6 +89,39 @@ const interactionProps = (
89
89
  onClick: loading ? undefined : onClick,
90
90
  });
91
91
 
92
+ /**
93
+ * The ARIA that describes the field has to sit on the `<input>`: the text
94
+ * field puts every attribute it does not recognise on its root `FormControl`,
95
+ * a `<div>` with no role, where a screen reader never reads it.
96
+ *
97
+ * `aria-label` has ridden `inputProps` since FUT-755. `aria-describedby` and
98
+ * `aria-busy` fell through to the div until FUT-2619, so CepField's input
99
+ * pointed at nothing while its lookup status lived in a live region beside it.
100
+ *
101
+ * `inputProps` are spread onto the `<input>` AFTER the `aria-describedby` MUI
102
+ * writes for helper text, so a caller's ids REPLACE the helper text's: MUI's
103
+ * `TextField` on its own keeps only one of the two. This joins both, helper
104
+ * text first. The helper id is MUI's `<id>-helper-text` (the parity test pins
105
+ * that spelling), which is why the field's id is fixed here rather than left
106
+ * to the text field.
107
+ */
108
+ function inputAriaOf(a: {
109
+ id: string;
110
+ helperText: React.ReactNode;
111
+ label?: string;
112
+ describedBy?: string;
113
+ busy?: InputProps['aria-busy'];
114
+ }): Record<string, unknown> {
115
+ const describedBy = [a.helperText ? `${a.id}-helper-text` : undefined, a.describedBy]
116
+ .filter(Boolean)
117
+ .join(' ');
118
+ return {
119
+ ...(a.label === undefined ? {} : { 'aria-label': a.label }),
120
+ ...(a.describedBy === undefined ? {} : { 'aria-describedby': describedBy }),
121
+ ...(a.busy === undefined ? {} : { 'aria-busy': a.busy }),
122
+ };
123
+ }
124
+
92
125
  export const Input = React.forwardRef<HTMLInputElement, InputProps>(
93
126
  (
94
127
  {
@@ -108,11 +141,15 @@ export const Input = React.forwardRef<HTMLInputElement, InputProps>(
108
141
  onFocus,
109
142
  onBlur,
110
143
  'aria-label': ariaLabel,
144
+ 'aria-describedby': ariaDescribedBy,
145
+ 'aria-busy': ariaBusy,
111
146
  ...rest
112
147
  },
113
148
  ref,
114
149
  ) => {
115
150
  const { testId: dataTestId, rest: props } = splitTestId(rest);
151
+ const generatedId = React.useId();
152
+ const id = props.id ?? generatedId;
116
153
  return (
117
154
  <StyledTextField
118
155
  ref={ref}
@@ -137,10 +174,11 @@ export const Input = React.forwardRef<HTMLInputElement, InputProps>(
137
174
  * no accessible name, and a source grep saying "this input is labelled"
138
175
  * disagreed with the DOM. The reports search box and the block-title
139
176
  * inputs were both named in source and anonymous to a screen reader.
177
+ * `aria-describedby` and `aria-busy` are the same case: `inputAriaOf`.
140
178
  */
141
179
  inputProps={{
142
180
  'data-testid': dataTestId,
143
- ...(ariaLabel === undefined ? {} : { 'aria-label': ariaLabel }),
181
+ ...inputAriaOf({ id, helperText, label: ariaLabel, describedBy: ariaDescribedBy, busy: ariaBusy }),
144
182
  }}
145
183
  InputProps={{
146
184
  startAdornment: startAdornment && (
@@ -150,6 +188,7 @@ export const Input = React.forwardRef<HTMLInputElement, InputProps>(
150
188
  }}
151
189
  {...SIZE_MAP[size]}
152
190
  {...props}
191
+ id={id}
153
192
  />
154
193
  );
155
194
  },
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/data-display/HoverCard/HoverCard.tsx"],"sourcesContent":["import Box from '@mui/material/Box/index.js';\nimport Card from '@mui/material/Card/index.js';\nimport CardContent from '@mui/material/CardContent/index.js';\nimport Popover from '@mui/material/Popover/index.js';\nimport { styled, type Theme } from '@mui/material/styles/index.js';\nimport React from 'react';\n\nimport { rem } from '../../../tokens/relative';\nimport { withDefaults } from '../../../utils/withDefaults';\n\nimport { HoverCardContent } from './HoverCard.content';\nimport { useHoverCard } from './HoverCard.hooks';\nimport { arrowSx, cardSx, getAnchorOrigin, getTransformOrigin, sideOf } from './HoverCard.styles';\nimport type { CardStyleFlags } from './HoverCard.styles';\nimport type { HoverCardAnimation, HoverCardPlacement, HoverCardProps } from './HoverCard.types';\n\nconst ArrowContainer = styled('div')<{ placement: HoverCardPlacement; offset?: number }>(\n ({ theme, placement }) => ({ ...arrowSx(theme, placement) }),\n);\n\nconst StyledCard = styled(Card, {\n shouldForwardProp: (prop) =>\n !['customVariant', 'glow', 'pulse', 'animation'].includes(prop as string),\n})<CardStyleFlags>(({ theme, ...flags }) => ({ ...cardSx(theme, flags) }));\n\nconst StyledPopover = styled(Popover, {\n shouldForwardProp: (prop) => prop !== 'customAnimation',\n})<{ customAnimation?: HoverCardAnimation }>(({ customAnimation }) => ({\n // The popover only positions; StyledCard draws the surface.\n '& .MuiPopover-paper': {\n backgroundColor: 'transparent',\n boxShadow: 'none',\n overflow: 'visible',\n ...(customAnimation === 'scale' && { transformOrigin: 'center' }),\n },\n}));\n\nconst DEFAULTS = {\n variant: 'default',\n glow: false,\n pulse: false,\n placement: 'bottom',\n showArrow: false,\n animation: 'fade',\n enterDelay: 700,\n exitDelay: 0,\n loading: false,\n touchEnabled: true,\n disabled: false,\n} satisfies Partial<HoverCardProps>;\n\ntype ResolvedProps = HoverCardProps & Required<Pick<HoverCardProps, keyof typeof DEFAULTS>>;\n\n/** Padding is the variant's own: detailed roomier, minimal tighter. */\nconst CONTENT_PADDING: Record<string, number> = { detailed: 3, minimal: 1.5 };\n\n/**\n * The card is nudged off the anchor on whichever side it sits — `offset` design\n * px (8 unless the caller says otherwise), through the theme's type scale.\n */\nconst offsetMargin = (theme: Theme, placement: HoverCardPlacement, offset: number | undefined) => {\n const side = sideOf(placement);\n const key = ({ top: 'mt', bottom: 'mb', left: 'ml', right: 'mr' } as const)[side];\n return { [key]: rem(theme, offset ?? 8) };\n};\n\n/**\n * The card's cap: 400 design px unless the caller says otherwise. `sx` has always\n * read a number of 1 or less as a fraction of the parent, and that stays so.\n */\nconst capOf = (theme: Theme, maxWidth: number | undefined): string => {\n const cap = maxWidth ?? 400;\n return cap <= 1 && cap !== 0 ? `${cap * 100}%` : rem(theme, cap);\n};\n\nexport const HoverCard = React.forwardRef<HTMLDivElement, HoverCardProps>((props, ref) => {\n const {\n variant, glow, pulse, title, description, avatar, trigger, placement, showArrow,\n animation, enterDelay, exitDelay, maxWidth, loading, loadingComponent, loadingText, touchEnabled,\n offset, disabled, onOpen, onClose, children, dataTestId,\n ...rest\n } = withDefaults(props, DEFAULTS) as ResolvedProps;\n\n const { anchorEl, isOpen, handleClose, triggerHandlers, cardHandlers } = useHoverCard({\n disabled,\n touchEnabled,\n enterDelay,\n exitDelay,\n onOpen,\n onClose,\n });\n\n const triggerProps = {\n ...triggerHandlers,\n style: { cursor: disabled ? 'default' : 'pointer' },\n 'data-testid': dataTestId ? `${dataTestId}-trigger` : 'hover-card-trigger',\n };\n\n const triggerElement = trigger ? (\n React.cloneElement(trigger, triggerProps)\n ) : (\n <span {...triggerProps} style={{ display: 'inline-block', ...triggerProps.style }}>\n {children}\n </span>\n );\n\n const padding = CONTENT_PADDING[variant] ?? 2;\n\n return (\n <>\n {triggerElement}\n <StyledPopover\n ref={ref}\n open={isOpen && !disabled}\n anchorEl={anchorEl}\n onClose={handleClose}\n anchorOrigin={getAnchorOrigin(placement)}\n transformOrigin={getTransformOrigin(placement)}\n {...cardHandlers}\n disableAutoFocus\n disableEnforceFocus\n disableRestoreFocus\n customAnimation={animation}\n slotProps={{ paper: { style: { pointerEvents: 'auto' } } }}\n {...rest}\n >\n <Box sx={{ position: 'relative' }}>\n {showArrow && <ArrowContainer placement={placement} offset={offset} />}\n <StyledCard\n customVariant={variant}\n glow={glow}\n pulse={pulse}\n animation={animation}\n data-testid={dataTestId || 'hover-card-content'}\n sx={(theme) => ({ maxWidth: capOf(theme, maxWidth), ...offsetMargin(theme, placement, offset) })}\n >\n <CardContent sx={{ p: padding, '&:last-child': { pb: padding } }}>\n <HoverCardContent\n loadingText={loadingText} variant={variant} title={title}\n description={description}\n avatar={avatar}\n loading={loading}\n loadingComponent={loadingComponent}\n dataTestId={dataTestId}\n >\n {children}\n </HoverCardContent>\n </CardContent>\n </StyledCard>\n </Box>\n </StyledPopover>\n </>\n );\n});\n\nHoverCard.displayName = 'HoverCard';\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/data-display/HoverCard/HoverCard.hooks.ts"],"sourcesContent":["import React from 'react';\n\ninterface HandlerInput {\n isTouchDevice: boolean;\n touchEnabled: boolean;\n enterDelay: number;\n openCard: (event: React.MouseEvent<HTMLElement> | React.TouchEvent<HTMLElement>) => void;\n closeCard: () => void;\n exitTimeoutRef: React.MutableRefObject<number | undefined>;\n}\n\n/**\n * The pointer and touch handlers, over the open/close pair. Touch gets a\n * long-press because there is no hover to respond to; the card's own handlers\n * keep it open while the pointer is travelling onto it.\n */\nconst useHoverHandlers = ({\n isTouchDevice,\n touchEnabled,\n enterDelay,\n openCard,\n closeCard,\n exitTimeoutRef,\n}: HandlerInput) => {\n const [touchTimeout, setTouchTimeout] = React.useState<number>();\n\n /** A touch device with touch disabled has no hover to respond to. */\n const hoverIgnored = isTouchDevice && !touchEnabled;\n\n const cancelTouch = React.useCallback(() => {\n if (touchTimeout) {\n window.clearTimeout(touchTimeout);\n setTouchTimeout(undefined);\n }\n }, [touchTimeout]);\n\n React.useEffect(\n () => () => {\n if (touchTimeout) window.clearTimeout(touchTimeout);\n },\n [touchTimeout],\n );\n\n const triggerHandlers = {\n onMouseEnter: (event: React.MouseEvent<HTMLElement>) => {\n if (hoverIgnored) return;\n openCard(event);\n },\n onMouseLeave: () => {\n if (hoverIgnored) return;\n closeCard();\n },\n onTouchStart: (event: React.TouchEvent<HTMLElement>) => {\n if (!touchEnabled) return;\n if (touchTimeout) window.clearTimeout(touchTimeout);\n setTouchTimeout(window.setTimeout(() => openCard(event), enterDelay));\n },\n // End and cancel do the same thing: the press did not become a long press.\n onTouchEnd: cancelTouch,\n onTouchCancel: cancelTouch,\n };\n\n /** Moving onto the card keeps it open; leaving it starts the exit delay. */\n const cardHandlers = {\n onMouseEnter: () => {\n if (exitTimeoutRef.current) window.clearTimeout(exitTimeoutRef.current);\n },\n onMouseLeave: closeCard,\n };\n\n return { triggerHandlers, cardHandlers };\n};\n\n/** Escape dismisses the card while it is open. */\nconst useEscapeKey = (active: boolean, onEscape: () => void) => {\n React.useEffect(() => {\n if (!active) return;\n\n const handleEscape = (event: globalThis.KeyboardEvent) => {\n if (event.key === 'Escape') onEscape();\n };\n\n document.addEventListener('keydown', handleEscape);\n return () => document.removeEventListener('keydown', handleEscape);\n }, [active, onEscape]);\n};\n\ninterface HoverCardTimingInput {\n disabled: boolean;\n touchEnabled: boolean;\n enterDelay: number;\n exitDelay: number;\n onOpen?: () => void;\n onClose?: () => void;\n}\n\n/**\n * When the card is open, and the delays that decide it.\n *\n * Three timers are in play: the enter delay before opening, the exit delay\n * before closing (so the pointer can travel from the trigger onto the card\n * without dismissing it), and the long-press timer on touch. Each cancels the\n * others' pending work, which is why they live together.\n */\nexport const useHoverCard = ({\n disabled,\n touchEnabled,\n enterDelay,\n exitDelay,\n onOpen,\n onClose,\n}: HoverCardTimingInput) => {\n const [anchorEl, setAnchorEl] = React.useState<HTMLElement | null>(null);\n const [isOpen, setIsOpen] = React.useState(false);\n const [isTouchDevice, setIsTouchDevice] = React.useState(false);\n const enterTimeoutRef = React.useRef<number | undefined>(undefined);\n const exitTimeoutRef = React.useRef<number | undefined>(undefined);\n\n // Probed in an effect, not during render, so SSR and hydration stay intact.\n React.useEffect(() => {\n setIsTouchDevice('ontouchstart' in window);\n }, []);\n\n const openCard = React.useCallback(\n (event: React.MouseEvent<HTMLElement> | React.TouchEvent<HTMLElement>) => {\n if (disabled) return;\n\n if (exitTimeoutRef.current) {\n window.clearTimeout(exitTimeoutRef.current);\n }\n\n const target = event.currentTarget;\n enterTimeoutRef.current = window.setTimeout(() => {\n setAnchorEl(target);\n setIsOpen(true);\n onOpen?.();\n }, enterDelay);\n },\n [disabled, enterDelay, onOpen],\n );\n\n const closeCard = React.useCallback(() => {\n if (enterTimeoutRef.current) {\n window.clearTimeout(enterTimeoutRef.current);\n }\n\n exitTimeoutRef.current = window.setTimeout(() => {\n setIsOpen(false);\n setAnchorEl(null);\n onClose?.();\n }, exitDelay);\n }, [exitDelay, onClose]);\n\n const handleClose = React.useCallback(() => {\n setIsOpen(false);\n setAnchorEl(null);\n onClose?.();\n }, [onClose]);\n\n const { triggerHandlers, cardHandlers } = useHoverHandlers({\n isTouchDevice,\n touchEnabled,\n enterDelay,\n openCard,\n closeCard,\n exitTimeoutRef,\n });\n\n useEscapeKey(isOpen, handleClose);\n\n React.useEffect(\n () => () => {\n if (enterTimeoutRef.current) window.clearTimeout(enterTimeoutRef.current);\n if (exitTimeoutRef.current) window.clearTimeout(exitTimeoutRef.current);\n },\n [],\n );\n\n return { anchorEl, isOpen, handleClose, triggerHandlers, cardHandlers };\n};\n"],"mappings":";AAAA,OAAO,WAAW;AAgBlB,IAAM,mBAAmB,CAAC;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAoB;AAClB,QAAM,CAAC,cAAc,eAAe,IAAI,MAAM,SAAiB;AAG/D,QAAM,eAAe,iBAAiB,CAAC;AAEvC,QAAM,cAAc,MAAM,YAAY,MAAM;AAC1C,QAAI,cAAc;AAChB,aAAO,aAAa,YAAY;AAChC,sBAAgB,MAAS;AAAA,IAC3B;AAAA,EACF,GAAG,CAAC,YAAY,CAAC;AAEjB,QAAM;AAAA,IACJ,MAAM,MAAM;AACV,UAAI,aAAc,QAAO,aAAa,YAAY;AAAA,IACpD;AAAA,IACA,CAAC,YAAY;AAAA,EACf;AAEA,QAAM,kBAAkB;AAAA,IACtB,cAAc,CAAC,UAAyC;AACtD,UAAI,aAAc;AAClB,eAAS,KAAK;AAAA,IAChB;AAAA,IACA,cAAc,MAAM;AAClB,UAAI,aAAc;AAClB,gBAAU;AAAA,IACZ;AAAA,IACA,cAAc,CAAC,UAAyC;AACtD,UAAI,CAAC,aAAc;AACnB,UAAI,aAAc,QAAO,aAAa,YAAY;AAClD,sBAAgB,OAAO,WAAW,MAAM,SAAS,KAAK,GAAG,UAAU,CAAC;AAAA,IACtE;AAAA;AAAA,IAEA,YAAY;AAAA,IACZ,eAAe;AAAA,EACjB;AAGA,QAAM,eAAe;AAAA,IACnB,cAAc,MAAM;AAClB,UAAI,eAAe,QAAS,QAAO,aAAa,eAAe,OAAO;AAAA,IACxE;AAAA,IACA,cAAc;AAAA,EAChB;AAEA,SAAO,EAAE,iBAAiB,aAAa;AACzC;AAGA,IAAM,eAAe,CAAC,QAAiB,aAAyB;AAC9D,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,OAAQ;AAEb,UAAM,eAAe,CAAC,UAAoC;AACxD,UAAI,MAAM,QAAQ,SAAU,UAAS;AAAA,IACvC;AAEA,aAAS,iBAAiB,WAAW,YAAY;AACjD,WAAO,MAAM,SAAS,oBAAoB,WAAW,YAAY;AAAA,EACnE,GAAG,CAAC,QAAQ,QAAQ,CAAC;AACvB;AAmBO,IAAM,eAAe,CAAC;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAA4B;AAC1B,QAAM,CAAC,UAAU,WAAW,IAAI,MAAM,SAA6B,IAAI;AACvE,QAAM,CAAC,QAAQ,SAAS,IAAI,MAAM,SAAS,KAAK;AAChD,QAAM,CAAC,eAAe,gBAAgB,IAAI,MAAM,SAAS,KAAK;AAC9D,QAAM,kBAAkB,MAAM,OAA2B,MAAS;AAClE,QAAM,iBAAiB,MAAM,OAA2B,MAAS;AAGjE,QAAM,UAAU,MAAM;AACpB,qBAAiB,kBAAkB,MAAM;AAAA,EAC3C,GAAG,CAAC,CAAC;AAEL,QAAM,WAAW,MAAM;AAAA,IACrB,CAAC,UAAyE;AACxE,UAAI,SAAU;AAEd,UAAI,eAAe,SAAS;AAC1B,eAAO,aAAa,eAAe,OAAO;AAAA,MAC5C;AAEA,YAAM,SAAS,MAAM;AACrB,sBAAgB,UAAU,OAAO,WAAW,MAAM;AAChD,oBAAY,MAAM;AAClB,kBAAU,IAAI;AACd,iBAAS;AAAA,MACX,GAAG,UAAU;AAAA,IACf;AAAA,IACA,CAAC,UAAU,YAAY,MAAM;AAAA,EAC/B;AAEA,QAAM,YAAY,MAAM,YAAY,MAAM;AACxC,QAAI,gBAAgB,SAAS;AAC3B,aAAO,aAAa,gBAAgB,OAAO;AAAA,IAC7C;AAEA,mBAAe,UAAU,OAAO,WAAW,MAAM;AAC/C,gBAAU,KAAK;AACf,kBAAY,IAAI;AAChB,gBAAU;AAAA,IACZ,GAAG,SAAS;AAAA,EACd,GAAG,CAAC,WAAW,OAAO,CAAC;AAEvB,QAAM,cAAc,MAAM,YAAY,MAAM;AAC1C,cAAU,KAAK;AACf,gBAAY,IAAI;AAChB,cAAU;AAAA,EACZ,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,EAAE,iBAAiB,aAAa,IAAI,iBAAiB;AAAA,IACzD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,eAAa,QAAQ,WAAW;AAEhC,QAAM;AAAA,IACJ,MAAM,MAAM;AACV,UAAI,gBAAgB,QAAS,QAAO,aAAa,gBAAgB,OAAO;AACxE,UAAI,eAAe,QAAS,QAAO,aAAa,eAAe,OAAO;AAAA,IACxE;AAAA,IACA,CAAC;AAAA,EACH;AAEA,SAAO,EAAE,UAAU,QAAQ,aAAa,iBAAiB,aAAa;AACxE;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/form/Input/Input.tsx"],"sourcesContent":["import CircularProgress from '@mui/material/CircularProgress/index.js';\nimport InputAdornment from '@mui/material/InputAdornment/index.js';\nimport { styled, useTheme } from '@mui/material/styles/index.js';\nimport React from 'react';\n\nimport { INPUT_LOADING } from './Input.metrics';\nimport { TextFieldSlim } from './text-field-slim';\n\nimport {\n filledStyles,\n floatingLabelStyles,\n glowStyles,\n inputBaseStyles,\n inputRadiusStyles,\n muiVariantFor,\n outlinedStyles,\n pulseStyles,\n SIZE_MAP,\n} from './Input.styles';\nimport type { InputProps } from './Input.types';\nimport { splitTestId } from '../../../platform/test-id';\nimport { fieldControlStyles } from '../../../tokens/field-height';\nimport { rem } from '../../../tokens/relative';\nimport type { SizeValue } from '../../../tokens/vocabulary';\n\n/**\n * `TextFieldSlim`, not `TextField` — see `text-field-slim.tsx`. MUI's own\n * `TextField` imports `Select` unconditionally, and through it `Menu`,\n * `Popover`, `Modal` and seven more component modules, so every screen with one\n * text box shipped a dropdown it can never render. Same composition, same DOM,\n * same prop routing; the select branch is the only thing missing.\n */\nconst StyledTextField = styled(TextFieldSlim, {\n shouldForwardProp: (prop) =>\n !['customVariant', 'fieldSize', 'floating', 'glow', 'pulse', 'loading'].includes(prop as string),\n})<{\n customVariant?: InputProps['variant'];\n fieldSize: SizeValue;\n floating?: boolean;\n glow?: boolean;\n pulse?: boolean;\n loading?: boolean;\n}>(({ theme, customVariant, fieldSize, floating, glow, pulse, loading }) => ({\n position: 'relative',\n // The theme's field height for this size (outlined family, one line).\n ...fieldControlStyles(theme, fieldSize),\n opacity: loading ? INPUT_LOADING.opacity : 1,\n\n ...(glow ? glowStyles(theme) : {}),\n ...(pulse ? pulseStyles(theme, fieldSize) : {}),\n ...(floating ? floatingLabelStyles(theme) : {}),\n\n '& .MuiInputBase-root': {\n transition: 'all 0.3s ease',\n ...inputRadiusStyles(theme, customVariant),\n ...inputBaseStyles(theme, customVariant),\n },\n\n '& .MuiOutlinedInput-root': outlinedStyles(theme),\n '& .MuiFilledInput-root': filledStyles(theme),\n}));\n\n/** Only one adornment shows at a time: the spinner replaces the caller's while loading. */\nconst EndAdornment: React.FC<{ loading: boolean; endAdornment?: React.ReactNode }> = ({\n loading,\n endAdornment,\n}) => {\n const theme = useTheme();\n if (loading) {\n return (\n <InputAdornment position=\"end\">\n <CircularProgress size={rem(theme, INPUT_LOADING.spinnerSize)} />\n </InputAdornment>\n );\n }\n\n if (!endAdornment) return null;\n\n return <InputAdornment position=\"end\">{endAdornment}</InputAdornment>;\n};\n\n/** While loading the field is inert: no clicks, and disabled to assistive tech. */\nconst interactionProps = (\n loading: boolean,\n onClick: InputProps['onClick'],\n disabled?: boolean,\n) => ({\n disabled: loading || disabled,\n onClick: loading ? undefined : onClick,\n});\n\nexport const Input = React.forwardRef<HTMLInputElement, InputProps>(\n (\n {\n variant = 'outlined',\n size = 'md',\n label,\n error,\n helperText,\n startAdornment,\n endAdornment,\n fullWidth = true,\n floating = false,\n glow = false,\n pulse = false,\n loading = false,\n onClick,\n onFocus,\n onBlur,\n 'aria-label': ariaLabel,\n ...rest\n },\n ref,\n ) => {\n const { testId: dataTestId, rest: props } = splitTestId(rest);\n return (\n <StyledTextField\n ref={ref}\n variant={muiVariantFor(variant)}\n customVariant={variant}\n fieldSize={size}\n floating={floating}\n glow={glow}\n pulse={pulse}\n loading={loading}\n label={label}\n error={error}\n helperText={helperText}\n fullWidth={fullWidth}\n {...interactionProps(loading, onClick, props.disabled)}\n onFocus={onFocus}\n onBlur={onBlur}\n /*\n * `aria-label` has to ride `inputProps` to reach the `<input>` (FUT-755).\n * Spread with the rest it lands on the FormControl DIV that the text\n * field renders as its root, which carries no role — so the field kept\n * no accessible name, and a source grep saying \"this input is labelled\"\n * disagreed with the DOM. The reports search box and the block-title\n * inputs were both named in source and anonymous to a screen reader.\n */\n inputProps={{\n 'data-testid': dataTestId,\n ...(ariaLabel === undefined ? {} : { 'aria-label': ariaLabel }),\n }}\n InputProps={{\n startAdornment: startAdornment && (\n <InputAdornment position=\"start\">{startAdornment}</InputAdornment>\n ),\n endAdornment: <EndAdornment loading={loading} endAdornment={endAdornment} />,\n }}\n {...SIZE_MAP[size]}\n {...props}\n />\n );\n },\n);\n\nInput.displayName = 'Input';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,sBAAsB;AAC7B,OAAO,oBAAoB;AAC3B,SAAS,QAAQ,gBAAgB;AACjC,OAAO,WAAW;AAoEV;AAvCR,IAAM,kBAAkB,OAAO,eAAe;AAAA,EAC5C,mBAAmB,CAAC,SAClB,CAAC,CAAC,iBAAiB,aAAa,YAAY,QAAQ,SAAS,SAAS,EAAE,SAAS,IAAc;AACnG,CAAC,EAOE,CAAC,EAAE,OAAO,eAAe,WAAW,UAAU,MAAM,OAAO,QAAQ,OAAO;AAAA,EAC3E,UAAU;AAAA;AAAA,EAEV,GAAG,mBAAmB,OAAO,SAAS;AAAA,EACtC,SAAS,UAAU,cAAc,UAAU;AAAA,EAE3C,GAAI,OAAO,WAAW,KAAK,IAAI,CAAC;AAAA,EAChC,GAAI,QAAQ,YAAY,OAAO,SAAS,IAAI,CAAC;AAAA,EAC7C,GAAI,WAAW,oBAAoB,KAAK,IAAI,CAAC;AAAA,EAE7C,wBAAwB;AAAA,IACtB,YAAY;AAAA,IACZ,GAAG,kBAAkB,OAAO,aAAa;AAAA,IACzC,GAAG,gBAAgB,OAAO,aAAa;AAAA,EACzC;AAAA,EAEA,4BAA4B,eAAe,KAAK;AAAA,EAChD,0BAA0B,aAAa,KAAK;AAC9C,EAAE;AAGF,IAAM,eAA+E,CAAC;AAAA,EACpF;AAAA,EACA;AACF,MAAM;AACJ,QAAM,QAAQ,SAAS;AACvB,MAAI,SAAS;AACX,WACE,oBAAC,kBAAe,UAAS,OACvB,8BAAC,oBAAiB,MAAM,IAAI,OAAO,cAAc,WAAW,GAAG,GACjE;AAAA,EAEJ;AAEA,MAAI,CAAC,aAAc,QAAO;AAE1B,SAAO,oBAAC,kBAAe,UAAS,OAAO,wBAAa;AACtD;AAGA,IAAM,mBAAmB,CACvB,SACA,SACA,cACI;AAAA,EACJ,UAAU,WAAW;AAAA,EACrB,SAAS,UAAU,SAAY;AACjC;AAEO,IAAM,QAAQ,MAAM;AAAA,EACzB,CACE;AAAA,IACE,UAAU;AAAA,IACV,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,EAAE,QAAQ,YAAY,MAAM,MAAM,IAAI,YAAY,IAAI;AAC5D,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,SAAS,cAAc,OAAO;AAAA,QAC9B,eAAe;AAAA,QACf,WAAW;AAAA,QACX;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACC,GAAG,iBAAiB,SAAS,SAAS,MAAM,QAAQ;AAAA,QACrD;AAAA,QACA;AAAA,QASA,YAAY;AAAA,UACV,eAAe;AAAA,UACf,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,cAAc,UAAU;AAAA,QAC/D;AAAA,QACA,YAAY;AAAA,UACV,gBAAgB,kBACd,oBAAC,kBAAe,UAAS,SAAS,0BAAe;AAAA,UAEnD,cAAc,oBAAC,gBAAa,SAAkB,cAA4B;AAAA,QAC5E;AAAA,QACC,GAAG,SAAS,IAAI;AAAA,QAChB,GAAG;AAAA;AAAA,IACN;AAAA,EAEJ;AACF;AAEA,MAAM,cAAc;","names":[]}