@12-apps/ui 6.53.0 → 6.54.1

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 (91) hide show
  1. package/dist/_internal/components/data-display/AlertDialog/AlertDialog.js +2 -1
  2. package/dist/_internal/components/data-display/AlertDialog/AlertDialog.parts.js +9 -0
  3. package/dist/_internal/components/data-display/AlertDialog/AlertDialog.parts.js.map +1 -0
  4. package/dist/_internal/components/data-display/CardKit/use-remove-confirm.js +7 -6
  5. package/dist/_internal/components/data-display/CardKit/use-row-confirm.js +7 -6
  6. package/dist/_internal/components/data-display/DataViews/DataViewsTableBase.js +9 -8
  7. package/dist/_internal/components/data-display/DataViews/ManageViewsDialog.js +7 -6
  8. package/dist/_internal/components/data-display/DataViews/data-views-table-parts.js +8 -7
  9. package/dist/_internal/components/data-display/InteractiveTooltip/InteractiveTooltip.js +2 -2
  10. package/dist/_internal/components/data-display/InteractiveTooltip/InteractiveTooltip.styles.js +1 -1
  11. package/dist/_internal/components/data-display/Tooltip/Tooltip.js +1 -1
  12. package/dist/_internal/components/data-display/index.js +5 -4
  13. package/dist/_internal/components/feedback/ConfirmAction/ConfirmAction.js +4 -3
  14. package/dist/_internal/components/feedback/ConfirmAction/ConfirmAction.parts.js +3 -2
  15. package/dist/_internal/components/feedback/ConfirmAction/ConfirmButton.js +5 -4
  16. package/dist/_internal/components/feedback/ConfirmAction/with-confirmation.js +4 -3
  17. package/dist/_internal/components/feedback/index.js +6 -5
  18. package/dist/_internal/components/index.js +14 -13
  19. package/dist/_internal/components/layout/SettingCard/SettingCard.js +4 -4
  20. package/dist/_internal/components/layout/SettingCard/SettingCard.summary.js +3 -3
  21. package/dist/_internal/components/layout/SettingCard/SettingGroup.js +5 -5
  22. package/dist/_internal/components/layout/SettingCard/SettingSwitch.js +4 -4
  23. package/dist/_internal/components/layout/SettingCard/SettingToggle.js +5 -5
  24. package/dist/_internal/components/layout/index.js +7 -7
  25. package/dist/{chunk-QOLIBVGS.js → chunk-3CIIB74Y.js} +2 -2
  26. package/dist/{chunk-OG6LYQ7C.js → chunk-4PFKMNLP.js} +8 -68
  27. package/dist/chunk-4PFKMNLP.js.map +1 -0
  28. package/dist/{chunk-TQCQCW2P.js → chunk-524PRSSD.js} +3 -3
  29. package/dist/chunk-524PRSSD.js.map +1 -0
  30. package/dist/{chunk-Y5QDXG5N.js → chunk-6WNMVWAV.js} +2 -2
  31. package/dist/{chunk-OT3KFZRE.js → chunk-7WWPKA7Y.js} +2 -2
  32. package/dist/chunk-AET54GT6.js +99 -0
  33. package/dist/chunk-AET54GT6.js.map +1 -0
  34. package/dist/{chunk-ZXEDKRRT.js → chunk-ECVNRLKD.js} +2 -2
  35. package/dist/{chunk-JUHNEYCH.js → chunk-GCH7CLM4.js} +2 -2
  36. package/dist/{chunk-HCEJT65A.js → chunk-HKD4TDZP.js} +2 -2
  37. package/dist/{chunk-3GVMUASU.js → chunk-HV7HIMMY.js} +2 -2
  38. package/dist/chunk-IQQX3NDO.js +96 -0
  39. package/dist/chunk-IQQX3NDO.js.map +1 -0
  40. package/dist/{chunk-OESAYTNG.js → chunk-JDVHNDY3.js} +2 -2
  41. package/dist/{chunk-TYBZ4XZZ.js → chunk-KRIPQUFB.js} +27 -32
  42. package/dist/chunk-KRIPQUFB.js.map +1 -0
  43. package/dist/{chunk-4WCDMCIS.js → chunk-PI3GPLE2.js} +2 -2
  44. package/dist/{chunk-N4R6T5K7.js → chunk-PKSU3RBT.js} +2 -2
  45. package/dist/{chunk-IRNKHHQM.js → chunk-QKMXMBUK.js} +2 -2
  46. package/dist/{chunk-FWPFCK4D.js → chunk-S6G3CJFP.js} +2 -2
  47. package/dist/{chunk-BJZOBG24.js → chunk-UJHXEOU3.js} +2 -2
  48. package/dist/{chunk-U4QUDFPJ.js → chunk-VKVOP4OK.js} +2 -2
  49. package/dist/data-display/AlertDialog.js +2 -1
  50. package/dist/data-display/CardKit.js +8 -7
  51. package/dist/data-display/DataViews.js +9 -8
  52. package/dist/data-display/InteractiveTooltip.js +2 -2
  53. package/dist/data-display/Tooltip.js +1 -1
  54. package/dist/feedback/ConfirmAction.js +6 -5
  55. package/dist/layout/SettingCard.js +7 -7
  56. package/dist/types/components/data-display/AlertDialog/AlertDialog.d.ts.map +1 -1
  57. package/dist/types/components/data-display/AlertDialog/AlertDialog.parts.d.ts +13 -0
  58. package/dist/types/components/data-display/AlertDialog/AlertDialog.parts.d.ts.map +1 -0
  59. package/dist/types/components/data-display/AlertDialog/AlertDialog.types.d.ts +16 -3
  60. package/dist/types/components/data-display/AlertDialog/AlertDialog.types.d.ts.map +1 -1
  61. package/dist/types/components/data-display/InteractiveTooltip/InteractiveTooltip.d.ts +2 -2
  62. package/dist/types/components/data-display/InteractiveTooltip/InteractiveTooltip.d.ts.map +1 -1
  63. package/dist/types/components/data-display/Tooltip/Tooltip.d.ts +2 -2
  64. package/dist/types/components/data-display/Tooltip/Tooltip.d.ts.map +1 -1
  65. package/package.json +1 -1
  66. package/src/components/data-display/AlertDialog/AlertDialog.md +30 -0
  67. package/src/components/data-display/AlertDialog/AlertDialog.parts.tsx +180 -0
  68. package/src/components/data-display/AlertDialog/AlertDialog.tsx +5 -85
  69. package/src/components/data-display/AlertDialog/AlertDialog.types.ts +17 -3
  70. package/src/components/data-display/InteractiveTooltip/InteractiveTooltip.styles.ts +2 -2
  71. package/src/components/data-display/InteractiveTooltip/InteractiveTooltip.tsx +102 -99
  72. package/src/components/data-display/Tooltip/Tooltip.tsx +64 -56
  73. package/dist/chunk-OG6LYQ7C.js.map +0 -1
  74. package/dist/chunk-TQCQCW2P.js.map +0 -1
  75. package/dist/chunk-TYBZ4XZZ.js.map +0 -1
  76. package/dist/chunk-XM7QCNZQ.js +0 -110
  77. package/dist/chunk-XM7QCNZQ.js.map +0 -1
  78. /package/dist/{chunk-QOLIBVGS.js.map → chunk-3CIIB74Y.js.map} +0 -0
  79. /package/dist/{chunk-Y5QDXG5N.js.map → chunk-6WNMVWAV.js.map} +0 -0
  80. /package/dist/{chunk-OT3KFZRE.js.map → chunk-7WWPKA7Y.js.map} +0 -0
  81. /package/dist/{chunk-ZXEDKRRT.js.map → chunk-ECVNRLKD.js.map} +0 -0
  82. /package/dist/{chunk-JUHNEYCH.js.map → chunk-GCH7CLM4.js.map} +0 -0
  83. /package/dist/{chunk-HCEJT65A.js.map → chunk-HKD4TDZP.js.map} +0 -0
  84. /package/dist/{chunk-3GVMUASU.js.map → chunk-HV7HIMMY.js.map} +0 -0
  85. /package/dist/{chunk-OESAYTNG.js.map → chunk-JDVHNDY3.js.map} +0 -0
  86. /package/dist/{chunk-4WCDMCIS.js.map → chunk-PI3GPLE2.js.map} +0 -0
  87. /package/dist/{chunk-N4R6T5K7.js.map → chunk-PKSU3RBT.js.map} +0 -0
  88. /package/dist/{chunk-IRNKHHQM.js.map → chunk-QKMXMBUK.js.map} +0 -0
  89. /package/dist/{chunk-FWPFCK4D.js.map → chunk-S6G3CJFP.js.map} +0 -0
  90. /package/dist/{chunk-BJZOBG24.js.map → chunk-UJHXEOU3.js.map} +0 -0
  91. /package/dist/{chunk-U4QUDFPJ.js.map → chunk-VKVOP4OK.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/data-display/Tooltip/Tooltip.tsx"],"sourcesContent":["import MuiTooltip from \"@mui/material/Tooltip/index.js\";\nimport { alpha, keyframes } from \"@mui/material/styles/index.js\";\nimport type { CSSObject, Theme } from \"@mui/material/styles/index.js\";\nimport React from \"react\";\n\nimport type { TooltipProps } from \"./Tooltip.types\";\nimport { absoluteInk, neutralTones } from \"../../../tokens/ink\";\nimport { rem, rems, sxRem } from \"../../../tokens/relative\";\n\n// Define pulse animation\nconst pulseAnimation = keyframes`\n 0% {\n transform: scale(1);\n opacity: 1;\n }\n 70% {\n transform: scale(1.05);\n opacity: 0.8;\n }\n 100% {\n transform: scale(1);\n opacity: 1;\n }\n`;\n\nconst SIZE_MAP = {\n sm: { fontSize: sxRem(12), padding: (theme: Theme) => rems(theme, 4, 8) },\n md: { fontSize: sxRem(14), padding: (theme: Theme) => rems(theme, 6, 12) },\n lg: { fontSize: sxRem(16), padding: (theme: Theme) => rems(theme, 8, 16) },\n} as const;\n\nconst getSizeStyles = (\n size?: string,\n): { fontSize: (theme: Theme) => string; padding: (theme: Theme) => string } =>\n SIZE_MAP[size as keyof typeof SIZE_MAP] || SIZE_MAP.md;\n\nconst variantStyles = (theme: Theme, variant?: string): CSSObject => {\n switch (variant) {\n case \"default\":\n return {\n backgroundColor: neutralTones(theme).inverseSurface,\n color: absoluteInk(theme).white,\n };\n case \"dark\":\n return {\n backgroundColor: neutralTones(theme).inverseSurface,\n color: absoluteInk(theme).white,\n };\n case \"light\":\n return {\n backgroundColor: absoluteInk(theme).white,\n color: theme.palette.text.primary,\n border: `1px solid ${alpha(theme.palette.divider, 0.2)}`,\n boxShadow: theme.shadows[4],\n };\n case \"glass\":\n return {\n backgroundColor: alpha(theme.palette.background.paper, 0.1),\n backdropFilter: `blur(${rem(theme, 20)})`,\n border: `1px solid ${alpha(theme.palette.divider, 0.2)}`,\n color: theme.palette.text.primary,\n };\n default:\n return {};\n }\n};\n\n// glow and pulse are independent flags. The three combinations used to be spelled\n// out one by one, but each is just the union of whichever flags are set.\nconst emphasisStyles = (\n theme: Theme,\n glow?: boolean,\n pulse?: boolean,\n): CSSObject => ({\n ...(glow && {\n boxShadow: `${rems(theme, 0, 0, 15, 3)} ${alpha(theme.palette.primary.main, 0.4)} !important`,\n filter: \"brightness(1.05)\",\n }),\n ...(pulse && {\n animation: `${pulseAnimation} 2s infinite`,\n }),\n});\n\nconst arrowColor = (theme: Theme, variant?: string): string => {\n switch (variant) {\n case \"light\":\n return absoluteInk(theme).white;\n case \"glass\":\n return alpha(theme.palette.background.paper, 0.1);\n case \"dark\":\n return neutralTones(theme).inverseSurface;\n default:\n return neutralTones(theme).inverseSurface;\n }\n};\n\n/**\n * The bubble's own look, applied to the BUBBLE (FUT-3093).\n *\n * It used to sit on a `styled(MuiTooltip)` root as `& .MuiTooltip-tooltip`, but\n * MUI renders the bubble in a portal, outside that root — so none of it ever\n * reached the screen, and every tooltip wore MUI's see-through grey instead of\n * the variant it asked for. `slotProps.tooltip.sx` lands on the bubble itself.\n * No `overflow: hidden`: now that it applies, it would clip an `arrow`.\n */\nconst bubbleSx =\n (\n variant: string,\n size: string,\n glow: boolean,\n pulse: boolean,\n maxWidth: number | undefined,\n ) =>\n (theme: Theme): CSSObject => {\n const sizeStyles = getSizeStyles(size);\n return {\n borderRadius: theme.spacing(1),\n fontSize: sizeStyles.fontSize(theme),\n padding: sizeStyles.padding(theme),\n fontWeight: 500,\n transition: \"all 0.3s ease\",\n position: \"relative\",\n maxWidth: tooltipCap(maxWidth)(theme),\n ...variantStyles(theme, variant),\n ...emphasisStyles(theme, glow, pulse),\n };\n };\n\n/**\n * The tooltip's cap: 300 design px unless the caller says otherwise. `sx` has\n * always read a number of 1 or less as a fraction of the parent, and that stays so.\n */\nconst tooltipCap =\n (maxWidth: number | undefined) =>\n (theme: Theme): string => {\n const cap = maxWidth ?? 300;\n return cap <= 1 && cap !== 0 ? `${cap * 100}%` : rem(theme, cap);\n };\n\nexport const Tooltip = React.forwardRef<HTMLDivElement, TooltipProps>(\n (\n {\n variant = \"default\",\n size = \"md\",\n glow = false,\n pulse = false,\n maxWidth,\n dataTestId,\n children,\n ...props\n },\n ref,\n ) => {\n const childWithTestId = dataTestId\n ? React.cloneElement(\n children as React.ReactElement<{ \"data-testid\"?: string }>,\n {\n \"data-testid\": `${dataTestId}-trigger`,\n },\n )\n : children;\n\n return (\n <MuiTooltip\n ref={ref}\n enterDelay={0}\n leaveDelay={0}\n disableHoverListener={false}\n disableFocusListener={false}\n disableTouchListener={false}\n slotProps={{\n tooltip: {\n sx: bubbleSx(variant, size, glow, pulse, maxWidth),\n role: \"tooltip\",\n ...(dataTestId && { \"data-testid\": `${dataTestId}-content` }),\n },\n arrow: {\n sx: (theme: Theme) => ({ color: arrowColor(theme, variant) }),\n },\n }}\n {...props}\n >\n {childWithTestId}\n </MuiTooltip>\n );\n },\n);\n\nTooltip.displayName = \"Tooltip\";\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ConfirmActionDialog
3
- } from "./chunk-BJZOBG24.js";
3
+ } from "./chunk-UJHXEOU3.js";
4
4
  import {
5
5
  useConfirmAction
6
6
  } from "./chunk-EMYESBIT.js";
@@ -40,4 +40,4 @@ function withConfirmation(Wrapped, defaults) {
40
40
  export {
41
41
  withConfirmation
42
42
  };
43
- //# sourceMappingURL=chunk-4WCDMCIS.js.map
43
+ //# sourceMappingURL=chunk-PI3GPLE2.js.map
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-BFRVMCQM.js";
7
7
  import {
8
8
  InteractiveTooltip
9
- } from "./chunk-XM7QCNZQ.js";
9
+ } from "./chunk-AET54GT6.js";
10
10
  import {
11
11
  Icon
12
12
  } from "./chunk-VEHMODO3.js";
@@ -92,4 +92,4 @@ export {
92
92
  SummaryInfo,
93
93
  useSummaryInfo
94
94
  };
95
- //# sourceMappingURL=chunk-N4R6T5K7.js.map
95
+ //# sourceMappingURL=chunk-PKSU3RBT.js.map
@@ -7,7 +7,7 @@ import {
7
7
  import {
8
8
  SettingSwitchBlock,
9
9
  useSettingSwitchIds
10
- } from "./chunk-Y5QDXG5N.js";
10
+ } from "./chunk-6WNMVWAV.js";
11
11
  import {
12
12
  flatStyles,
13
13
  surfaceStyles,
@@ -44,4 +44,4 @@ SettingToggle.displayName = "SettingToggle";
44
44
  export {
45
45
  SettingToggle
46
46
  };
47
- //# sourceMappingURL=chunk-IRNKHHQM.js.map
47
+ //# sourceMappingURL=chunk-QKMXMBUK.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ConfirmActionDialog
3
- } from "./chunk-BJZOBG24.js";
3
+ } from "./chunk-UJHXEOU3.js";
4
4
  import {
5
5
  useConfirmAction
6
6
  } from "./chunk-EMYESBIT.js";
@@ -23,4 +23,4 @@ ConfirmAction.displayName = "ConfirmAction";
23
23
  export {
24
24
  ConfirmAction
25
25
  };
26
- //# sourceMappingURL=chunk-FWPFCK4D.js.map
26
+ //# sourceMappingURL=chunk-S6G3CJFP.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  AlertDialog
3
- } from "./chunk-OG6LYQ7C.js";
3
+ } from "./chunk-4PFKMNLP.js";
4
4
 
5
5
  // src/components/feedback/ConfirmAction/ConfirmAction.parts.tsx
6
6
  import Alert from "@mui/material/Alert/index.js";
@@ -104,4 +104,4 @@ function ConfirmActionDialog({
104
104
  export {
105
105
  ConfirmActionDialog
106
106
  };
107
- //# sourceMappingURL=chunk-BJZOBG24.js.map
107
+ //# sourceMappingURL=chunk-UJHXEOU3.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ConfirmActionDialog
3
- } from "./chunk-BJZOBG24.js";
3
+ } from "./chunk-UJHXEOU3.js";
4
4
  import {
5
5
  useConfirmAction
6
6
  } from "./chunk-EMYESBIT.js";
@@ -43,4 +43,4 @@ function useRowConfirm({
43
43
  export {
44
44
  useRowConfirm
45
45
  };
46
- //# sourceMappingURL=chunk-U4QUDFPJ.js.map
46
+ //# sourceMappingURL=chunk-VKVOP4OK.js.map
@@ -1,7 +1,8 @@
1
1
  import "../chunk-2IBFEHIX.js";
2
2
  import {
3
3
  AlertDialog
4
- } from "../chunk-OG6LYQ7C.js";
4
+ } from "../chunk-4PFKMNLP.js";
5
+ import "../chunk-IQQX3NDO.js";
5
6
  import "../chunk-FQ6UW7IY.js";
6
7
  import "../chunk-6JAIFIPW.js";
7
8
  import "../chunk-N3GAFIXG.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  useRemoveConfirm
3
- } from "../chunk-QOLIBVGS.js";
3
+ } from "../chunk-3CIIB74Y.js";
4
4
  import {
5
5
  rowActionsToMenuItems
6
6
  } from "../chunk-ZBXG6RVJ.js";
@@ -20,21 +20,22 @@ import {
20
20
  } from "../chunk-2NIQSL7M.js";
21
21
  import {
22
22
  useRowConfirm
23
- } from "../chunk-U4QUDFPJ.js";
23
+ } from "../chunk-VKVOP4OK.js";
24
24
  import "../chunk-WVML3ENZ.js";
25
25
  import "../chunk-U3DBQXPI.js";
26
26
  import "../chunk-XCBQXSTR.js";
27
- import "../chunk-3GVMUASU.js";
28
- import "../chunk-FWPFCK4D.js";
29
- import "../chunk-4WCDMCIS.js";
30
- import "../chunk-BJZOBG24.js";
27
+ import "../chunk-HV7HIMMY.js";
28
+ import "../chunk-S6G3CJFP.js";
29
+ import "../chunk-PI3GPLE2.js";
30
+ import "../chunk-UJHXEOU3.js";
31
31
  import "../chunk-EMYESBIT.js";
32
32
  import "../chunk-NUGT7LMR.js";
33
33
  import "../chunk-AUHYR7ID.js";
34
34
  import "../chunk-MO47Y26B.js";
35
35
  import "../chunk-L7VH6IMR.js";
36
36
  import "../chunk-2IBFEHIX.js";
37
- import "../chunk-OG6LYQ7C.js";
37
+ import "../chunk-4PFKMNLP.js";
38
+ import "../chunk-IQQX3NDO.js";
38
39
  import "../chunk-P2UIXDEG.js";
39
40
  import "../chunk-6DPAWXZ3.js";
40
41
  import "../chunk-BA4RHQ3B.js";
@@ -3,7 +3,7 @@ import {
3
3
  } from "../chunk-UNEJ4MUR.js";
4
4
  import {
5
5
  DataViewsTableBase
6
- } from "../chunk-OT3KFZRE.js";
6
+ } from "../chunk-7WWPKA7Y.js";
7
7
  import "../chunk-67LNVBFO.js";
8
8
  import {
9
9
  DataViewsGrid
@@ -48,9 +48,9 @@ import "../chunk-EIY5EYO3.js";
48
48
  import "../chunk-I32M7WNL.js";
49
49
  import "../chunk-QZY5NG5N.js";
50
50
  import "../chunk-O5UGAL2V.js";
51
- import "../chunk-HCEJT65A.js";
51
+ import "../chunk-HKD4TDZP.js";
52
52
  import "../chunk-4E4MSUY5.js";
53
- import "../chunk-JUHNEYCH.js";
53
+ import "../chunk-GCH7CLM4.js";
54
54
  import "../chunk-5M4TYFR3.js";
55
55
  import "../chunk-IM5SR7G2.js";
56
56
  import "../chunk-X3DVZNZH.js";
@@ -158,10 +158,10 @@ import "../chunk-JU3FRRO2.js";
158
158
  import "../chunk-C3UKR3NT.js";
159
159
  import "../chunk-D6KL74KI.js";
160
160
  import "../chunk-XCBQXSTR.js";
161
- import "../chunk-3GVMUASU.js";
162
- import "../chunk-FWPFCK4D.js";
163
- import "../chunk-4WCDMCIS.js";
164
- import "../chunk-BJZOBG24.js";
161
+ import "../chunk-HV7HIMMY.js";
162
+ import "../chunk-S6G3CJFP.js";
163
+ import "../chunk-PI3GPLE2.js";
164
+ import "../chunk-UJHXEOU3.js";
165
165
  import "../chunk-EMYESBIT.js";
166
166
  import "../chunk-KFJKOVDD.js";
167
167
  import "../chunk-MQ277OLB.js";
@@ -190,7 +190,8 @@ import "../chunk-AUHYR7ID.js";
190
190
  import "../chunk-MO47Y26B.js";
191
191
  import "../chunk-L7VH6IMR.js";
192
192
  import "../chunk-2IBFEHIX.js";
193
- import "../chunk-OG6LYQ7C.js";
193
+ import "../chunk-4PFKMNLP.js";
194
+ import "../chunk-IQQX3NDO.js";
194
195
  import "../chunk-3UIDKLML.js";
195
196
  import "../chunk-PYC4CWCQ.js";
196
197
  import "../chunk-P2UIXDEG.js";
@@ -1,8 +1,8 @@
1
1
  import "../chunk-TAF3YYMK.js";
2
2
  import {
3
3
  InteractiveTooltip
4
- } from "../chunk-XM7QCNZQ.js";
5
- import "../chunk-TQCQCW2P.js";
4
+ } from "../chunk-AET54GT6.js";
5
+ import "../chunk-524PRSSD.js";
6
6
  import "../chunk-QYJ25FWM.js";
7
7
  import "../chunk-FQ6UW7IY.js";
8
8
  import "../chunk-6JAIFIPW.js";
@@ -1,7 +1,7 @@
1
1
  import "../chunk-4N244WVL.js";
2
2
  import {
3
3
  Tooltip
4
- } from "../chunk-TYBZ4XZZ.js";
4
+ } from "../chunk-KRIPQUFB.js";
5
5
  import "../chunk-FQ6UW7IY.js";
6
6
  import "../chunk-6JAIFIPW.js";
7
7
  import "../chunk-N3GAFIXG.js";
@@ -1,21 +1,22 @@
1
1
  import "../chunk-XCBQXSTR.js";
2
2
  import {
3
3
  createConfirmButton
4
- } from "../chunk-3GVMUASU.js";
4
+ } from "../chunk-HV7HIMMY.js";
5
5
  import {
6
6
  ConfirmAction
7
- } from "../chunk-FWPFCK4D.js";
7
+ } from "../chunk-S6G3CJFP.js";
8
8
  import {
9
9
  withConfirmation
10
- } from "../chunk-4WCDMCIS.js";
10
+ } from "../chunk-PI3GPLE2.js";
11
11
  import {
12
12
  ConfirmActionDialog
13
- } from "../chunk-BJZOBG24.js";
13
+ } from "../chunk-UJHXEOU3.js";
14
14
  import {
15
15
  useConfirmAction
16
16
  } from "../chunk-EMYESBIT.js";
17
17
  import "../chunk-2IBFEHIX.js";
18
- import "../chunk-OG6LYQ7C.js";
18
+ import "../chunk-4PFKMNLP.js";
19
+ import "../chunk-IQQX3NDO.js";
19
20
  import "../chunk-BA4RHQ3B.js";
20
21
  import "../chunk-RIZRF5XR.js";
21
22
  import "../chunk-LTE2QHBH.js";
@@ -5,17 +5,17 @@ import {
5
5
  } from "../chunk-WAKGVAOB.js";
6
6
  import {
7
7
  SettingCard
8
- } from "../chunk-OESAYTNG.js";
8
+ } from "../chunk-JDVHNDY3.js";
9
9
  import {
10
10
  SettingToggle
11
- } from "../chunk-IRNKHHQM.js";
11
+ } from "../chunk-QKMXMBUK.js";
12
12
  import {
13
13
  SettingGroup
14
- } from "../chunk-ZXEDKRRT.js";
14
+ } from "../chunk-ECVNRLKD.js";
15
15
  import "../chunk-XJQNSMGA.js";
16
16
  import "../chunk-SALQ65SM.js";
17
- import "../chunk-Y5QDXG5N.js";
18
- import "../chunk-N4R6T5K7.js";
17
+ import "../chunk-6WNMVWAV.js";
18
+ import "../chunk-PKSU3RBT.js";
19
19
  import "../chunk-2JTZWQ25.js";
20
20
  import "../chunk-WE2LNTR6.js";
21
21
  import "../chunk-BFRVMCQM.js";
@@ -23,8 +23,8 @@ import "../chunk-RN7UJI7S.js";
23
23
  import "../chunk-JYWF76Z5.js";
24
24
  import "../chunk-GGMB6LJH.js";
25
25
  import "../chunk-TAF3YYMK.js";
26
- import "../chunk-XM7QCNZQ.js";
27
- import "../chunk-TQCQCW2P.js";
26
+ import "../chunk-AET54GT6.js";
27
+ import "../chunk-524PRSSD.js";
28
28
  import "../chunk-QYJ25FWM.js";
29
29
  import "../chunk-2GTORM5E.js";
30
30
  import "../chunk-OZPLAOI4.js";
@@ -1 +1 @@
1
- {"version":3,"file":"AlertDialog.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/AlertDialog/AlertDialog.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AA6R5D,eAAO,MAAM,WAAW,sGAgFvB,CAAC"}
1
+ {"version":3,"file":"AlertDialog.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/AlertDialog/AlertDialog.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAmN5D,eAAO,MAAM,WAAW,sGA6EvB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ import type { AlertDialogProps } from './AlertDialog.types';
3
+ /**
4
+ * Action row: the optional cancel button and the (variant-coloured) confirm,
5
+ * with the emphasised one LAST — the primary slot, on the right or, once the
6
+ * row stacks, on top. DOM order is the tab order, so it follows the same rule.
7
+ */
8
+ export declare function AlertDialogFooter({ variant, cancelText, confirmText, showCancel, loading, confirmDisabled, initialFocus, emphasis: asked, onCancel, onConfirm, dataTestId, }: Pick<AlertDialogProps, 'variant' | 'cancelText' | 'confirmText' | 'showCancel' | 'loading' | 'confirmDisabled' | 'initialFocus' | 'emphasis'> & {
9
+ onCancel: () => void;
10
+ onConfirm: () => void;
11
+ dataTestId: string;
12
+ }): React.ReactElement;
13
+ //# sourceMappingURL=AlertDialog.parts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AlertDialog.parts.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/AlertDialog/AlertDialog.parts.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAqF5D;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,OAAO,EACP,UAAqB,EACrB,WAAuB,EACvB,UAAiB,EACjB,OAAe,EACf,eAAuB,EACvB,YAAY,EACZ,QAAQ,EAAE,KAAK,EACf,QAAQ,EACR,SAAS,EACT,UAAU,GACX,EAAE,IAAI,CACL,gBAAgB,EACd,SAAS,GACT,YAAY,GACZ,aAAa,GACb,YAAY,GACZ,SAAS,GACT,iBAAiB,GACjB,cAAc,GACd,UAAU,CACb,GAAG;IACF,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,KAAK,CAAC,YAAY,CAiDrB"}
@@ -54,11 +54,24 @@ export interface AlertDialogProps extends Omit<MuiDialogProps, 'variant'> {
54
54
  */
55
55
  confirmDisabled?: boolean;
56
56
  /**
57
- * Which button owns focus when the dialog opens. Defaults to `confirm`, which
58
- * is right for an acknowledgement; a destructive dialog should pass `cancel`
59
- * so a stray Enter on the trigger cannot complete the action.
57
+ * Which button owns focus when the dialog opens. Defaults to the emphasised
58
+ * one — `confirm`, unless `emphasis="cancel"` — which is right for an
59
+ * acknowledgement; a destructive dialog should pass `cancel` so a stray Enter
60
+ * on the trigger cannot complete the action.
60
61
  */
61
62
  initialFocus?: 'confirm' | 'cancel';
63
+ /**
64
+ * Which button is the filled, primary one. Defaults to `confirm`. Pass
65
+ * `cancel` when backing out is the action to steer toward — a "discard what
66
+ * you wrote?" question, where the confirm is the loss: cancel is then filled
67
+ * and takes the primary slot (right, or on top once the row stacks), and the
68
+ * confirm steps down to the neutral outline cancel normally wears — primary
69
+ * and neutral, whatever the variant. The two buttons then grow to share the
70
+ * row, so once it stacks each takes its full width; focus opens on the cancel
71
+ * unless `initialFocus` says otherwise. With `showCancel={false}` it has no
72
+ * effect: the confirm keeps its default, filled look.
73
+ */
74
+ emphasis?: 'confirm' | 'cancel';
62
75
  /**
63
76
  * Optional data-testid attribute for testing
64
77
  */
@@ -1 +1 @@
1
- {"version":3,"file":"AlertDialog.types.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/AlertDialog/AlertDialog.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,IAAI,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACnF,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC;IACvE;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,GAAG,aAAa,GAAG,OAAO,CAAC;IAE9C;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAE9B;;OAEG;IACH,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAEvB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IAEtB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IAEvB;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;;;OAIG;IACH,YAAY,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAEpC;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB"}
1
+ {"version":3,"file":"AlertDialog.types.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/AlertDialog/AlertDialog.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,IAAI,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACnF,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC;IACvE;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,GAAG,aAAa,GAAG,OAAO,CAAC;IAE9C;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAE9B;;OAEG;IACH,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAEvB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IAEtB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IAEvB;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;;;;OAKG;IACH,YAAY,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAEpC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAEhC;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB"}
@@ -1,4 +1,4 @@
1
- import React from 'react';
2
- import type { InteractiveTooltipProps } from './InteractiveTooltip.types';
1
+ import React from "react";
2
+ import type { InteractiveTooltipProps } from "./InteractiveTooltip.types";
3
3
  export declare const InteractiveTooltip: React.ForwardRefExoticComponent<Omit<InteractiveTooltipProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
4
4
  //# sourceMappingURL=InteractiveTooltip.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"InteractiveTooltip.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/InteractiveTooltip/InteractiveTooltip.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAU1B,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAgC1E,eAAO,MAAM,kBAAkB,6GA6E9B,CAAC"}
1
+ {"version":3,"file":"InteractiveTooltip.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/InteractiveTooltip/InteractiveTooltip.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAc1B,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AA8B1E,eAAO,MAAM,kBAAkB,6GA8E7B,CAAC"}
@@ -1,4 +1,4 @@
1
- import React from 'react';
2
- import type { TooltipProps } from './Tooltip.types';
1
+ import React from "react";
2
+ import type { TooltipProps } from "./Tooltip.types";
3
3
  export declare const Tooltip: React.ForwardRefExoticComponent<Omit<TooltipProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
4
4
  //# sourceMappingURL=Tooltip.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Tooltip.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/Tooltip/Tooltip.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAgIpD,eAAO,MAAM,OAAO,kGA6CnB,CAAC"}
1
+ {"version":3,"file":"Tooltip.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/Tooltip/Tooltip.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAsIpD,eAAO,MAAM,OAAO,kGA+CnB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@12-apps/ui",
3
- "version": "6.53.0",
3
+ "version": "6.54.1",
4
4
  "license": "MIT",
5
5
  "packageManager": "pnpm@10.34.5",
6
6
  "type": "module",
@@ -34,6 +34,7 @@ The AlertDialog component provides a modal dialog for alerts, confirmations, and
34
34
  | `showCancel` | `boolean` | true | Whether to show the cancel button |
35
35
  | `confirmDisabled` | `boolean` | false | Whether the confirm button is disabled |
36
36
  | `loading` | `boolean` | false | Shows loading state on confirm button |
37
+ | `emphasis` | `'confirm' \| 'cancel'` | 'confirm' | Which button is filled and takes the primary slot (right, or top when the row stacks). Use `cancel` when the confirm is the loss, e.g. "discard what you wrote?": the confirm becomes the neutral outline, both buttons grow to share the row, and focus opens on the cancel. Ignored when `showCancel` is false |
37
38
 
38
39
  ### Visual Props
39
40
 
@@ -124,6 +125,35 @@ function DeleteConfirmation() {
124
125
  />
125
126
  ```
126
127
 
128
+ ### Steering Toward Cancel
129
+
130
+ When confirming throws work away, make keeping it the primary action: the
131
+ filled cancel takes the primary slot and the confirm becomes the neutral
132
+ outline — primary and neutral, even on the destructive variant.
133
+
134
+ ```tsx
135
+ <AlertDialog
136
+ open={open}
137
+ variant="destructive"
138
+ emphasis="cancel"
139
+ initialFocus="cancel"
140
+ title="Discard this order?"
141
+ description="You have already written 3 items."
142
+ confirmText="Discard"
143
+ cancelText="Keep writing"
144
+ onConfirm={handleDiscard}
145
+ onCancel={() => setOpen(false)}
146
+ onClose={() => setOpen(false)}
147
+ />
148
+ ```
149
+
150
+ ### Button Layout
151
+
152
+ The action row wraps whole buttons and never breaks a label inside one. A pair
153
+ that fits keeps its natural widths, pushed to the right; a pair that does not
154
+ stacks, with the primary on top. With `emphasis="cancel"` the two buttons also
155
+ grow to share the row, so stacked they take its full width.
156
+
127
157
  ### Without Cancel Button
128
158
 
129
159
  ```tsx
@@ -0,0 +1,180 @@
1
+ /**
2
+ * The AlertDialog's action row, kept apart from the dialog shell so each stays
3
+ * inside the complexity budget: which button is filled, where each one sits,
4
+ * and how the row wraps.
5
+ */
6
+ import type { ButtonProps } from '@mui/material/Button/index.js';
7
+ import Button from '@mui/material/Button/index.js';
8
+ import CircularProgress from '@mui/material/CircularProgress/index.js';
9
+ import DialogActions from '@mui/material/DialogActions/index.js';
10
+ import { styled, useTheme } from '@mui/material/styles/index.js';
11
+ import React from 'react';
12
+
13
+ import { rem } from '../../../tokens/relative';
14
+
15
+ import type { AlertDialogProps } from './AlertDialog.types';
16
+
17
+ /**
18
+ * The action row WRAPS WHOLE BUTTONS; it never breaks a label inside one. A pair
19
+ * that did not fit side by side used to squeeze the longer label onto two
20
+ * lines, so one button stood twice as tall as its neighbour. Now the row breaks
21
+ * instead. `wrap-reverse` puts the LAST button — the primary, whichever
22
+ * `emphasis` picks — on top when it stacks, the same slot it holds on the right
23
+ * when the row fits. A pair that fits is laid out exactly as before: natural
24
+ * widths, pushed to the right.
25
+ *
26
+ * `fill` — set only by `emphasis="cancel"` — lets the buttons grow to share the
27
+ * row, and so to take the full width of their line once it stacks. It is not
28
+ * the default because growing also stretches a pair that fits, which would
29
+ * redraw every existing dialog's footer.
30
+ *
31
+ * Rendered with `disableSpacing`: MUI's own spacing is a left margin on every
32
+ * button after the first, which would indent a button that wrapped onto a line
33
+ * of its own. The gaps below replace it, at the same 16px across.
34
+ */
35
+ const StyledDialogActions = styled(DialogActions, {
36
+ shouldForwardProp: (prop) => prop !== 'fill',
37
+ })<{ fill: boolean }>(({ theme, fill }) => ({
38
+ padding: theme.spacing(2, 3, 3, 3),
39
+ flexWrap: 'wrap-reverse',
40
+ columnGap: theme.spacing(2),
41
+ rowGap: theme.spacing(1),
42
+ ...(fill && { '& > .MuiButton-root': { flexGrow: 1 } }),
43
+ }));
44
+
45
+ const confirmButtonColor = (variant: AlertDialogProps['variant']): 'error' | 'primary' =>
46
+ variant === 'destructive' ? 'error' : 'primary';
47
+
48
+ interface ButtonLook {
49
+ variant: ButtonProps['variant'];
50
+ color: ButtonProps['color'];
51
+ }
52
+
53
+ /**
54
+ * How each button is drawn, by `emphasis`: the emphasised one is filled, the
55
+ * other a NEUTRAL outline. Primary / neutral both ways round — a confirm that
56
+ * steps down drops the variant's colour too, so the one filled button is the
57
+ * only coloured thing in the row and the eye has a single place to land.
58
+ */
59
+ const buttonLooks = (
60
+ emphasis: AlertDialogProps['emphasis'],
61
+ variant: AlertDialogProps['variant'],
62
+ ): { cancel: ButtonLook; confirm: ButtonLook } =>
63
+ emphasis === 'cancel'
64
+ ? {
65
+ cancel: { variant: 'contained', color: 'primary' },
66
+ confirm: { variant: 'outlined', color: 'inherit' },
67
+ }
68
+ : {
69
+ cancel: { variant: 'outlined', color: 'inherit' },
70
+ confirm: { variant: 'contained', color: confirmButtonColor(variant) },
71
+ };
72
+
73
+ /**
74
+ * The emphasis that applies: `cancel` only while the cancel is shown. A hidden
75
+ * cancel with the confirm stepped down would leave a dialog with no primary.
76
+ */
77
+ const effectiveEmphasis = (
78
+ emphasis: AlertDialogProps['emphasis'],
79
+ showCancel: boolean,
80
+ ): NonNullable<AlertDialogProps['emphasis']> =>
81
+ emphasis === 'cancel' && showCancel ? 'cancel' : 'confirm';
82
+
83
+ /**
84
+ * Whether the cancel owns focus on open: what `initialFocus` says, and when it
85
+ * says nothing, the emphasised button — so Enter on a steered question keeps
86
+ * the work instead of completing the loss.
87
+ */
88
+ const focusesCancel = (
89
+ initialFocus: AlertDialogProps['initialFocus'],
90
+ emphasis: NonNullable<AlertDialogProps['emphasis']>,
91
+ ): boolean => (initialFocus ?? emphasis) === 'cancel';
92
+
93
+ /** The two buttons in slot order: the emphasised one LAST, the primary slot. */
94
+ const inSlotOrder = (
95
+ emphasis: AlertDialogProps['emphasis'],
96
+ cancel: React.ReactNode,
97
+ confirm: React.ReactNode,
98
+ ): React.ReactNode[] => (emphasis === 'cancel' ? [confirm, cancel] : [cancel, confirm]);
99
+
100
+ /**
101
+ * Action row: the optional cancel button and the (variant-coloured) confirm,
102
+ * with the emphasised one LAST — the primary slot, on the right or, once the
103
+ * row stacks, on top. DOM order is the tab order, so it follows the same rule.
104
+ */
105
+ export function AlertDialogFooter({
106
+ variant,
107
+ cancelText = 'Cancel',
108
+ confirmText = 'Confirm',
109
+ showCancel = true,
110
+ loading = false,
111
+ confirmDisabled = false,
112
+ initialFocus,
113
+ emphasis: asked,
114
+ onCancel,
115
+ onConfirm,
116
+ dataTestId,
117
+ }: Pick<
118
+ AlertDialogProps,
119
+ | 'variant'
120
+ | 'cancelText'
121
+ | 'confirmText'
122
+ | 'showCancel'
123
+ | 'loading'
124
+ | 'confirmDisabled'
125
+ | 'initialFocus'
126
+ | 'emphasis'
127
+ > & {
128
+ onCancel: () => void;
129
+ onConfirm: () => void;
130
+ dataTestId: string;
131
+ }): React.ReactElement {
132
+ const theme = useTheme();
133
+ const emphasis = effectiveEmphasis(asked, showCancel);
134
+ const look = buttonLooks(emphasis, variant);
135
+ const cancelFocused = focusesCancel(initialFocus, emphasis);
136
+ const cancel = showCancel && (
137
+ <Button
138
+ key="cancel"
139
+ onClick={onCancel}
140
+ variant={look.cancel.variant}
141
+ color={look.cancel.color}
142
+ disabled={loading}
143
+ autoFocus={cancelFocused}
144
+ data-testid={`${dataTestId}-cancel-button`}
145
+ >
146
+ {cancelText}
147
+ </Button>
148
+ );
149
+ const confirm = (
150
+ <Button
151
+ key="confirm"
152
+ onClick={onConfirm}
153
+ variant={look.confirm.variant}
154
+ color={look.confirm.color}
155
+ disabled={confirmDisabled || loading}
156
+ startIcon={
157
+ loading ? (
158
+ <CircularProgress
159
+ size={rem(theme, 16)}
160
+ color="inherit"
161
+ data-testid={`${dataTestId}-loading-spinner`}
162
+ />
163
+ ) : undefined
164
+ }
165
+ autoFocus={!cancelFocused}
166
+ data-testid={`${dataTestId}-confirm-button`}
167
+ >
168
+ {confirmText}
169
+ </Button>
170
+ );
171
+ return (
172
+ <StyledDialogActions
173
+ disableSpacing
174
+ fill={emphasis === 'cancel'}
175
+ data-testid={`${dataTestId}-actions`}
176
+ >
177
+ {inSlotOrder(emphasis, cancel, confirm)}
178
+ </StyledDialogActions>
179
+ );
180
+ }