@12-apps/ui 6.53.0 → 6.54.0

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 (52) 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/index.js +2 -1
  10. package/dist/_internal/components/feedback/ConfirmAction/ConfirmAction.js +4 -3
  11. package/dist/_internal/components/feedback/ConfirmAction/ConfirmAction.parts.js +3 -2
  12. package/dist/_internal/components/feedback/ConfirmAction/ConfirmButton.js +5 -4
  13. package/dist/_internal/components/feedback/ConfirmAction/with-confirmation.js +4 -3
  14. package/dist/_internal/components/feedback/index.js +6 -5
  15. package/dist/_internal/components/index.js +6 -5
  16. package/dist/{chunk-QOLIBVGS.js → chunk-3CIIB74Y.js} +2 -2
  17. package/dist/{chunk-OG6LYQ7C.js → chunk-4PFKMNLP.js} +8 -68
  18. package/dist/chunk-4PFKMNLP.js.map +1 -0
  19. package/dist/{chunk-OT3KFZRE.js → chunk-7WWPKA7Y.js} +2 -2
  20. package/dist/{chunk-JUHNEYCH.js → chunk-GCH7CLM4.js} +2 -2
  21. package/dist/{chunk-HCEJT65A.js → chunk-HKD4TDZP.js} +2 -2
  22. package/dist/{chunk-3GVMUASU.js → chunk-HV7HIMMY.js} +2 -2
  23. package/dist/chunk-IQQX3NDO.js +96 -0
  24. package/dist/chunk-IQQX3NDO.js.map +1 -0
  25. package/dist/{chunk-4WCDMCIS.js → chunk-PI3GPLE2.js} +2 -2
  26. package/dist/{chunk-FWPFCK4D.js → chunk-S6G3CJFP.js} +2 -2
  27. package/dist/{chunk-BJZOBG24.js → chunk-UJHXEOU3.js} +2 -2
  28. package/dist/{chunk-U4QUDFPJ.js → chunk-VKVOP4OK.js} +2 -2
  29. package/dist/data-display/AlertDialog.js +2 -1
  30. package/dist/data-display/CardKit.js +8 -7
  31. package/dist/data-display/DataViews.js +9 -8
  32. package/dist/feedback/ConfirmAction.js +6 -5
  33. package/dist/types/components/data-display/AlertDialog/AlertDialog.d.ts.map +1 -1
  34. package/dist/types/components/data-display/AlertDialog/AlertDialog.parts.d.ts +13 -0
  35. package/dist/types/components/data-display/AlertDialog/AlertDialog.parts.d.ts.map +1 -0
  36. package/dist/types/components/data-display/AlertDialog/AlertDialog.types.d.ts +16 -3
  37. package/dist/types/components/data-display/AlertDialog/AlertDialog.types.d.ts.map +1 -1
  38. package/package.json +1 -1
  39. package/src/components/data-display/AlertDialog/AlertDialog.md +30 -0
  40. package/src/components/data-display/AlertDialog/AlertDialog.parts.tsx +180 -0
  41. package/src/components/data-display/AlertDialog/AlertDialog.tsx +5 -85
  42. package/src/components/data-display/AlertDialog/AlertDialog.types.ts +17 -3
  43. package/dist/chunk-OG6LYQ7C.js.map +0 -1
  44. /package/dist/{chunk-QOLIBVGS.js.map → chunk-3CIIB74Y.js.map} +0 -0
  45. /package/dist/{chunk-OT3KFZRE.js.map → chunk-7WWPKA7Y.js.map} +0 -0
  46. /package/dist/{chunk-JUHNEYCH.js.map → chunk-GCH7CLM4.js.map} +0 -0
  47. /package/dist/{chunk-HCEJT65A.js.map → chunk-HKD4TDZP.js.map} +0 -0
  48. /package/dist/{chunk-3GVMUASU.js.map → chunk-HV7HIMMY.js.map} +0 -0
  49. /package/dist/{chunk-4WCDMCIS.js.map → chunk-PI3GPLE2.js.map} +0 -0
  50. /package/dist/{chunk-FWPFCK4D.js.map → chunk-S6G3CJFP.js.map} +0 -0
  51. /package/dist/{chunk-BJZOBG24.js.map → chunk-UJHXEOU3.js.map} +0 -0
  52. /package/dist/{chunk-U4QUDFPJ.js.map → chunk-VKVOP4OK.js.map} +0 -0
@@ -0,0 +1,96 @@
1
+ import {
2
+ rem
3
+ } from "./chunk-YKCAJ2TN.js";
4
+
5
+ // src/components/data-display/AlertDialog/AlertDialog.parts.tsx
6
+ import Button from "@mui/material/Button/index.js";
7
+ import CircularProgress from "@mui/material/CircularProgress/index.js";
8
+ import DialogActions from "@mui/material/DialogActions/index.js";
9
+ import { styled, useTheme } from "@mui/material/styles/index.js";
10
+ import { jsx } from "react/jsx-runtime";
11
+ var StyledDialogActions = styled(DialogActions, {
12
+ shouldForwardProp: (prop) => prop !== "fill"
13
+ })(({ theme, fill }) => ({
14
+ padding: theme.spacing(2, 3, 3, 3),
15
+ flexWrap: "wrap-reverse",
16
+ columnGap: theme.spacing(2),
17
+ rowGap: theme.spacing(1),
18
+ ...fill && { "& > .MuiButton-root": { flexGrow: 1 } }
19
+ }));
20
+ var confirmButtonColor = (variant) => variant === "destructive" ? "error" : "primary";
21
+ var buttonLooks = (emphasis, variant) => emphasis === "cancel" ? {
22
+ cancel: { variant: "contained", color: "primary" },
23
+ confirm: { variant: "outlined", color: "inherit" }
24
+ } : {
25
+ cancel: { variant: "outlined", color: "inherit" },
26
+ confirm: { variant: "contained", color: confirmButtonColor(variant) }
27
+ };
28
+ var effectiveEmphasis = (emphasis, showCancel) => emphasis === "cancel" && showCancel ? "cancel" : "confirm";
29
+ var focusesCancel = (initialFocus, emphasis) => (initialFocus ?? emphasis) === "cancel";
30
+ var inSlotOrder = (emphasis, cancel, confirm) => emphasis === "cancel" ? [confirm, cancel] : [cancel, confirm];
31
+ function AlertDialogFooter({
32
+ variant,
33
+ cancelText = "Cancel",
34
+ confirmText = "Confirm",
35
+ showCancel = true,
36
+ loading = false,
37
+ confirmDisabled = false,
38
+ initialFocus,
39
+ emphasis: asked,
40
+ onCancel,
41
+ onConfirm,
42
+ dataTestId
43
+ }) {
44
+ const theme = useTheme();
45
+ const emphasis = effectiveEmphasis(asked, showCancel);
46
+ const look = buttonLooks(emphasis, variant);
47
+ const cancelFocused = focusesCancel(initialFocus, emphasis);
48
+ const cancel = showCancel && /* @__PURE__ */ jsx(
49
+ Button,
50
+ {
51
+ onClick: onCancel,
52
+ variant: look.cancel.variant,
53
+ color: look.cancel.color,
54
+ disabled: loading,
55
+ autoFocus: cancelFocused,
56
+ "data-testid": `${dataTestId}-cancel-button`,
57
+ children: cancelText
58
+ },
59
+ "cancel"
60
+ );
61
+ const confirm = /* @__PURE__ */ jsx(
62
+ Button,
63
+ {
64
+ onClick: onConfirm,
65
+ variant: look.confirm.variant,
66
+ color: look.confirm.color,
67
+ disabled: confirmDisabled || loading,
68
+ startIcon: loading ? /* @__PURE__ */ jsx(
69
+ CircularProgress,
70
+ {
71
+ size: rem(theme, 16),
72
+ color: "inherit",
73
+ "data-testid": `${dataTestId}-loading-spinner`
74
+ }
75
+ ) : void 0,
76
+ autoFocus: !cancelFocused,
77
+ "data-testid": `${dataTestId}-confirm-button`,
78
+ children: confirmText
79
+ },
80
+ "confirm"
81
+ );
82
+ return /* @__PURE__ */ jsx(
83
+ StyledDialogActions,
84
+ {
85
+ disableSpacing: true,
86
+ fill: emphasis === "cancel",
87
+ "data-testid": `${dataTestId}-actions`,
88
+ children: inSlotOrder(emphasis, cancel, confirm)
89
+ }
90
+ );
91
+ }
92
+
93
+ export {
94
+ AlertDialogFooter
95
+ };
96
+ //# sourceMappingURL=chunk-IQQX3NDO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/data-display/AlertDialog/AlertDialog.parts.tsx"],"sourcesContent":["/**\n * The AlertDialog's action row, kept apart from the dialog shell so each stays\n * inside the complexity budget: which button is filled, where each one sits,\n * and how the row wraps.\n */\nimport type { ButtonProps } from '@mui/material/Button/index.js';\nimport Button from '@mui/material/Button/index.js';\nimport CircularProgress from '@mui/material/CircularProgress/index.js';\nimport DialogActions from '@mui/material/DialogActions/index.js';\nimport { styled, useTheme } from '@mui/material/styles/index.js';\nimport React from 'react';\n\nimport { rem } from '../../../tokens/relative';\n\nimport type { AlertDialogProps } from './AlertDialog.types';\n\n/**\n * The action row WRAPS WHOLE BUTTONS; it never breaks a label inside one. A pair\n * that did not fit side by side used to squeeze the longer label onto two\n * lines, so one button stood twice as tall as its neighbour. Now the row breaks\n * instead. `wrap-reverse` puts the LAST button — the primary, whichever\n * `emphasis` picks — on top when it stacks, the same slot it holds on the right\n * when the row fits. A pair that fits is laid out exactly as before: natural\n * widths, pushed to the right.\n *\n * `fill` — set only by `emphasis=\"cancel\"` — lets the buttons grow to share the\n * row, and so to take the full width of their line once it stacks. It is not\n * the default because growing also stretches a pair that fits, which would\n * redraw every existing dialog's footer.\n *\n * Rendered with `disableSpacing`: MUI's own spacing is a left margin on every\n * button after the first, which would indent a button that wrapped onto a line\n * of its own. The gaps below replace it, at the same 16px across.\n */\nconst StyledDialogActions = styled(DialogActions, {\n shouldForwardProp: (prop) => prop !== 'fill',\n})<{ fill: boolean }>(({ theme, fill }) => ({\n padding: theme.spacing(2, 3, 3, 3),\n flexWrap: 'wrap-reverse',\n columnGap: theme.spacing(2),\n rowGap: theme.spacing(1),\n ...(fill && { '& > .MuiButton-root': { flexGrow: 1 } }),\n}));\n\nconst confirmButtonColor = (variant: AlertDialogProps['variant']): 'error' | 'primary' =>\n variant === 'destructive' ? 'error' : 'primary';\n\ninterface ButtonLook {\n variant: ButtonProps['variant'];\n color: ButtonProps['color'];\n}\n\n/**\n * How each button is drawn, by `emphasis`: the emphasised one is filled, the\n * other a NEUTRAL outline. Primary / neutral both ways round — a confirm that\n * steps down drops the variant's colour too, so the one filled button is the\n * only coloured thing in the row and the eye has a single place to land.\n */\nconst buttonLooks = (\n emphasis: AlertDialogProps['emphasis'],\n variant: AlertDialogProps['variant'],\n): { cancel: ButtonLook; confirm: ButtonLook } =>\n emphasis === 'cancel'\n ? {\n cancel: { variant: 'contained', color: 'primary' },\n confirm: { variant: 'outlined', color: 'inherit' },\n }\n : {\n cancel: { variant: 'outlined', color: 'inherit' },\n confirm: { variant: 'contained', color: confirmButtonColor(variant) },\n };\n\n/**\n * The emphasis that applies: `cancel` only while the cancel is shown. A hidden\n * cancel with the confirm stepped down would leave a dialog with no primary.\n */\nconst effectiveEmphasis = (\n emphasis: AlertDialogProps['emphasis'],\n showCancel: boolean,\n): NonNullable<AlertDialogProps['emphasis']> =>\n emphasis === 'cancel' && showCancel ? 'cancel' : 'confirm';\n\n/**\n * Whether the cancel owns focus on open: what `initialFocus` says, and when it\n * says nothing, the emphasised button — so Enter on a steered question keeps\n * the work instead of completing the loss.\n */\nconst focusesCancel = (\n initialFocus: AlertDialogProps['initialFocus'],\n emphasis: NonNullable<AlertDialogProps['emphasis']>,\n): boolean => (initialFocus ?? emphasis) === 'cancel';\n\n/** The two buttons in slot order: the emphasised one LAST, the primary slot. */\nconst inSlotOrder = (\n emphasis: AlertDialogProps['emphasis'],\n cancel: React.ReactNode,\n confirm: React.ReactNode,\n): React.ReactNode[] => (emphasis === 'cancel' ? [confirm, cancel] : [cancel, confirm]);\n\n/**\n * Action row: the optional cancel button and the (variant-coloured) confirm,\n * with the emphasised one LAST — the primary slot, on the right or, once the\n * row stacks, on top. DOM order is the tab order, so it follows the same rule.\n */\nexport function AlertDialogFooter({\n variant,\n cancelText = 'Cancel',\n confirmText = 'Confirm',\n showCancel = true,\n loading = false,\n confirmDisabled = false,\n initialFocus,\n emphasis: asked,\n onCancel,\n onConfirm,\n dataTestId,\n}: Pick<\n AlertDialogProps,\n | 'variant'\n | 'cancelText'\n | 'confirmText'\n | 'showCancel'\n | 'loading'\n | 'confirmDisabled'\n | 'initialFocus'\n | 'emphasis'\n> & {\n onCancel: () => void;\n onConfirm: () => void;\n dataTestId: string;\n}): React.ReactElement {\n const theme = useTheme();\n const emphasis = effectiveEmphasis(asked, showCancel);\n const look = buttonLooks(emphasis, variant);\n const cancelFocused = focusesCancel(initialFocus, emphasis);\n const cancel = showCancel && (\n <Button\n key=\"cancel\"\n onClick={onCancel}\n variant={look.cancel.variant}\n color={look.cancel.color}\n disabled={loading}\n autoFocus={cancelFocused}\n data-testid={`${dataTestId}-cancel-button`}\n >\n {cancelText}\n </Button>\n );\n const confirm = (\n <Button\n key=\"confirm\"\n onClick={onConfirm}\n variant={look.confirm.variant}\n color={look.confirm.color}\n disabled={confirmDisabled || loading}\n startIcon={\n loading ? (\n <CircularProgress\n size={rem(theme, 16)}\n color=\"inherit\"\n data-testid={`${dataTestId}-loading-spinner`}\n />\n ) : undefined\n }\n autoFocus={!cancelFocused}\n data-testid={`${dataTestId}-confirm-button`}\n >\n {confirmText}\n </Button>\n );\n return (\n <StyledDialogActions\n disableSpacing\n fill={emphasis === 'cancel'}\n data-testid={`${dataTestId}-actions`}\n >\n {inSlotOrder(emphasis, cancel, confirm)}\n </StyledDialogActions>\n );\n}\n"],"mappings":";;;;;AAMA,OAAO,YAAY;AACnB,OAAO,sBAAsB;AAC7B,OAAO,mBAAmB;AAC1B,SAAS,QAAQ,gBAAgB;AA+H7B;AAtGJ,IAAM,sBAAsB,OAAO,eAAe;AAAA,EAChD,mBAAmB,CAAC,SAAS,SAAS;AACxC,CAAC,EAAqB,CAAC,EAAE,OAAO,KAAK,OAAO;AAAA,EAC1C,SAAS,MAAM,QAAQ,GAAG,GAAG,GAAG,CAAC;AAAA,EACjC,UAAU;AAAA,EACV,WAAW,MAAM,QAAQ,CAAC;AAAA,EAC1B,QAAQ,MAAM,QAAQ,CAAC;AAAA,EACvB,GAAI,QAAQ,EAAE,uBAAuB,EAAE,UAAU,EAAE,EAAE;AACvD,EAAE;AAEF,IAAM,qBAAqB,CAAC,YAC1B,YAAY,gBAAgB,UAAU;AAaxC,IAAM,cAAc,CAClB,UACA,YAEA,aAAa,WACT;AAAA,EACE,QAAQ,EAAE,SAAS,aAAa,OAAO,UAAU;AAAA,EACjD,SAAS,EAAE,SAAS,YAAY,OAAO,UAAU;AACnD,IACA;AAAA,EACE,QAAQ,EAAE,SAAS,YAAY,OAAO,UAAU;AAAA,EAChD,SAAS,EAAE,SAAS,aAAa,OAAO,mBAAmB,OAAO,EAAE;AACtE;AAMN,IAAM,oBAAoB,CACxB,UACA,eAEA,aAAa,YAAY,aAAa,WAAW;AAOnD,IAAM,gBAAgB,CACpB,cACA,cACa,gBAAgB,cAAc;AAG7C,IAAM,cAAc,CAClB,UACA,QACA,YACuB,aAAa,WAAW,CAAC,SAAS,MAAM,IAAI,CAAC,QAAQ,OAAO;AAO9E,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA,aAAa;AAAA,EACb,cAAc;AAAA,EACd,aAAa;AAAA,EACb,UAAU;AAAA,EACV,kBAAkB;AAAA,EAClB;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AACF,GAcuB;AACrB,QAAM,QAAQ,SAAS;AACvB,QAAM,WAAW,kBAAkB,OAAO,UAAU;AACpD,QAAM,OAAO,YAAY,UAAU,OAAO;AAC1C,QAAM,gBAAgB,cAAc,cAAc,QAAQ;AAC1D,QAAM,SAAS,cACb;AAAA,IAAC;AAAA;AAAA,MAEC,SAAS;AAAA,MACT,SAAS,KAAK,OAAO;AAAA,MACrB,OAAO,KAAK,OAAO;AAAA,MACnB,UAAU;AAAA,MACV,WAAW;AAAA,MACX,eAAa,GAAG,UAAU;AAAA,MAEzB;AAAA;AAAA,IARG;AAAA,EASN;AAEF,QAAM,UACJ;AAAA,IAAC;AAAA;AAAA,MAEC,SAAS;AAAA,MACT,SAAS,KAAK,QAAQ;AAAA,MACtB,OAAO,KAAK,QAAQ;AAAA,MACpB,UAAU,mBAAmB;AAAA,MAC7B,WACE,UACE;AAAA,QAAC;AAAA;AAAA,UACC,MAAM,IAAI,OAAO,EAAE;AAAA,UACnB,OAAM;AAAA,UACN,eAAa,GAAG,UAAU;AAAA;AAAA,MAC5B,IACE;AAAA,MAEN,WAAW,CAAC;AAAA,MACZ,eAAa,GAAG,UAAU;AAAA,MAEzB;AAAA;AAAA,IAjBG;AAAA,EAkBN;AAEF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,gBAAc;AAAA,MACd,MAAM,aAAa;AAAA,MACnB,eAAa,GAAG,UAAU;AAAA,MAEzB,sBAAY,UAAU,QAAQ,OAAO;AAAA;AAAA,EACxC;AAEJ;","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
@@ -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,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";
@@ -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"}
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.0",
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
+ }