@12-apps/ui 6.76.1 → 6.77.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 (71) hide show
  1. package/NATIVE.md +1 -1
  2. package/dist/_internal/components/data-display/Alert/Alert.content.js +20 -0
  3. package/dist/_internal/components/data-display/Alert/Alert.content.js.map +1 -0
  4. package/dist/_internal/components/data-display/Alert/Alert.js +5 -3
  5. package/dist/_internal/components/data-display/Alert/Alert.metrics.js +3 -1
  6. package/dist/_internal/components/data-display/Alert/Alert.placement.js +8 -0
  7. package/dist/_internal/components/data-display/Alert/Alert.placement.js.map +1 -0
  8. package/dist/_internal/components/data-display/Alert/Alert.styles.js +2 -2
  9. package/dist/_internal/components/data-display/Banner/Banner.js +3 -3
  10. package/dist/_internal/components/data-display/Banner/Banner.styles.js +2 -2
  11. package/dist/_internal/components/data-display/CardKit/card-actions-context.js +6 -4
  12. package/dist/_internal/components/data-display/CardKit/use-remove-confirm.js +7 -5
  13. package/dist/_internal/components/data-display/DataViews/DataViewsTableBase.js +7 -5
  14. package/dist/_internal/components/data-display/DataViews/data-views-table-parts.js +6 -4
  15. package/dist/_internal/components/data-display/index.js +7 -5
  16. package/dist/_internal/components/feedback/NotificationStatusNotice/NotificationStatusNotice.js +6 -4
  17. package/dist/_internal/components/feedback/index.js +6 -4
  18. package/dist/_internal/components/index.js +8 -6
  19. package/dist/{chunk-3VLVLZ6W.js → chunk-B34WHRKH.js} +2 -2
  20. package/dist/{chunk-JYAXTRNH.js → chunk-CCJJTLF7.js} +2 -2
  21. package/dist/{chunk-52CLMR47.js → chunk-ENXGWNCX.js} +2 -2
  22. package/dist/chunk-IVI574Y5.js +73 -0
  23. package/dist/chunk-IVI574Y5.js.map +1 -0
  24. package/dist/{chunk-3LHZCVGM.js → chunk-JNVUB2D4.js} +3 -1
  25. package/dist/chunk-JNVUB2D4.js.map +1 -0
  26. package/dist/{chunk-REEV7CLC.js → chunk-QDG6V7OC.js} +2 -2
  27. package/dist/chunk-QXUXO22M.js +9 -0
  28. package/dist/chunk-QXUXO22M.js.map +1 -0
  29. package/dist/{chunk-44AXT2SN.js → chunk-QZX43FIC.js} +2 -2
  30. package/dist/{chunk-ZBOGZLX3.js → chunk-T2KONJ45.js} +3 -3
  31. package/dist/{chunk-LY7PBZ3Z.js → chunk-UFNXYOHZ.js} +2 -2
  32. package/dist/{chunk-ERI6JC4M.js → chunk-X2SJJZFH.js} +2 -2
  33. package/dist/{chunk-DQJFCVXW.js → chunk-ZSCKXOKE.js} +32 -47
  34. package/dist/chunk-ZSCKXOKE.js.map +1 -0
  35. package/dist/data-display/Alert.js +5 -3
  36. package/dist/data-display/Banner.js +3 -3
  37. package/dist/data-display/CardKit.js +7 -5
  38. package/dist/data-display/DataViews.js +7 -5
  39. package/dist/feedback/NotificationStatusNotice.js +6 -4
  40. package/dist/native/data-display/Alert.js.map +1 -1
  41. package/dist/types/components/data-display/Alert/Alert.content.d.ts +18 -0
  42. package/dist/types/components/data-display/Alert/Alert.content.d.ts.map +1 -0
  43. package/dist/types/components/data-display/Alert/Alert.d.ts.map +1 -1
  44. package/dist/types/components/data-display/Alert/Alert.metrics.d.ts +4 -0
  45. package/dist/types/components/data-display/Alert/Alert.metrics.d.ts.map +1 -1
  46. package/dist/types/components/data-display/Alert/Alert.placement.d.ts +37 -0
  47. package/dist/types/components/data-display/Alert/Alert.placement.d.ts.map +1 -0
  48. package/dist/types/components/data-display/Alert/Alert.types.d.ts +8 -0
  49. package/dist/types/components/data-display/Alert/Alert.types.d.ts.map +1 -1
  50. package/dist/types/components/data-display/Alert/index.d.ts +1 -1
  51. package/dist/types/components/data-display/Alert/index.d.ts.map +1 -1
  52. package/dist/types-native/components/data-display/Alert/Alert.metrics.d.ts +4 -0
  53. package/dist/types-native/components/data-display/Alert/Alert.metrics.d.ts.map +1 -1
  54. package/package.json +1 -1
  55. package/src/components/data-display/Alert/Alert.content.tsx +79 -0
  56. package/src/components/data-display/Alert/Alert.md +19 -0
  57. package/src/components/data-display/Alert/Alert.metrics.ts +2 -0
  58. package/src/components/data-display/Alert/Alert.placement.ts +45 -0
  59. package/src/components/data-display/Alert/Alert.tsx +41 -61
  60. package/src/components/data-display/Alert/Alert.types.ts +10 -1
  61. package/src/components/data-display/Alert/index.ts +7 -1
  62. package/dist/chunk-3LHZCVGM.js.map +0 -1
  63. package/dist/chunk-DQJFCVXW.js.map +0 -1
  64. /package/dist/{chunk-3VLVLZ6W.js.map → chunk-B34WHRKH.js.map} +0 -0
  65. /package/dist/{chunk-JYAXTRNH.js.map → chunk-CCJJTLF7.js.map} +0 -0
  66. /package/dist/{chunk-52CLMR47.js.map → chunk-ENXGWNCX.js.map} +0 -0
  67. /package/dist/{chunk-REEV7CLC.js.map → chunk-QDG6V7OC.js.map} +0 -0
  68. /package/dist/{chunk-44AXT2SN.js.map → chunk-QZX43FIC.js.map} +0 -0
  69. /package/dist/{chunk-ZBOGZLX3.js.map → chunk-T2KONJ45.js.map} +0 -0
  70. /package/dist/{chunk-LY7PBZ3Z.js.map → chunk-UFNXYOHZ.js.map} +0 -0
  71. /package/dist/{chunk-ERI6JC4M.js.map → chunk-X2SJJZFH.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Alert
3
- } from "./chunk-DQJFCVXW.js";
3
+ } from "./chunk-ZSCKXOKE.js";
4
4
 
5
5
  // src/components/data-display/CardKit/card-actions-context.tsx
6
6
  import { createContext, useCallback, useContext, useState } from "react";
@@ -58,4 +58,4 @@ export {
58
58
  CardActionsProvider,
59
59
  useCardActions
60
60
  };
61
- //# sourceMappingURL=chunk-LY7PBZ3Z.js.map
61
+ //# sourceMappingURL=chunk-UFNXYOHZ.js.map
@@ -12,7 +12,7 @@ import {
12
12
  } from "./chunk-4SQ2WCZA.js";
13
13
  import {
14
14
  Alert
15
- } from "./chunk-DQJFCVXW.js";
15
+ } from "./chunk-ZSCKXOKE.js";
16
16
 
17
17
  // src/components/data-display/DataViews/data-views-table-parts.tsx
18
18
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -121,4 +121,4 @@ export {
121
121
  ViewsMenuSlot,
122
122
  ViewDialogs
123
123
  };
124
- //# sourceMappingURL=chunk-ERI6JC4M.js.map
124
+ //# sourceMappingURL=chunk-X2SJJZFH.js.map
@@ -5,7 +5,13 @@ import {
5
5
  fadeInScale,
6
6
  getColorFromTheme,
7
7
  getVariantIcon
8
- } from "./chunk-JYAXTRNH.js";
8
+ } from "./chunk-CCJJTLF7.js";
9
+ import {
10
+ resolveIconPlacement
11
+ } from "./chunk-QXUXO22M.js";
12
+ import {
13
+ AlertContent
14
+ } from "./chunk-IVI574Y5.js";
9
15
  import {
10
16
  resolveAlertProps,
11
17
  resolveAnnouncement,
@@ -19,14 +25,12 @@ import {
19
25
  CLOSE_BUTTON,
20
26
  CLOSE_DELAY_MS,
21
27
  COLLAPSE_MS,
22
- DESCRIPTION,
23
28
  FADE_IN,
24
29
  FOCUS,
25
30
  GLOW,
26
31
  HOVER,
27
- TITLE,
28
32
  seconds
29
- } from "./chunk-3LHZCVGM.js";
33
+ } from "./chunk-JNVUB2D4.js";
30
34
  import {
31
35
  resolveTestId,
32
36
  withoutTestIdProps
@@ -37,20 +41,18 @@ import {
37
41
  } from "./chunk-XJAD6E3V.js";
38
42
  import {
39
43
  rem,
40
- rems,
41
- sxRem
44
+ rems
42
45
  } from "./chunk-YKCAJ2TN.js";
43
46
 
44
47
  // src/components/data-display/Alert/Alert.tsx
45
48
  import Close from "@mui/icons-material/Close";
46
49
  import MuiAlert from "@mui/material/Alert/index.js";
47
- import AlertTitle from "@mui/material/AlertTitle/index.js";
48
50
  import Box from "@mui/material/Box/index.js";
49
51
  import Collapse from "@mui/material/Collapse/index.js";
50
52
  import IconButton from "@mui/material/IconButton/index.js";
51
- import { alpha, styled } from "@mui/material/styles/index.js";
53
+ import { alpha, styled, useTheme } from "@mui/material/styles/index.js";
52
54
  import React from "react";
53
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
55
+ import { jsx } from "react/jsx-runtime";
54
56
  var transition = `all ${seconds(ALERT_TRANSITION_MS)} ${ALERT_EASING}`;
55
57
  function pointerShadow(theme, colorPalette, glow, variant) {
56
58
  const ink = variant === "gradient" ? absoluteInk(theme).black : modeInk(theme);
@@ -133,39 +135,6 @@ var MUI_SEVERITY = {
133
135
  gradient: "info"
134
136
  };
135
137
  var toMuiSeverity = (variant) => MUI_SEVERITY[variant] ?? variant;
136
- var AlertContent = ({ title, description, dataTestId, children }) => /* @__PURE__ */ jsxs(Fragment, { children: [
137
- title && /* @__PURE__ */ jsx(
138
- AlertTitle,
139
- {
140
- "data-testid": testIdFor(dataTestId, "title"),
141
- sx: {
142
- fontWeight: TITLE.fontWeight,
143
- fontSize: sxRem(TITLE.fontSize),
144
- marginBottom: description ? TITLE.marginBottomUnits : 0,
145
- wordWrap: "break-word",
146
- overflowWrap: "break-word",
147
- wordBreak: "break-word"
148
- },
149
- children: title
150
- }
151
- ),
152
- description && /* @__PURE__ */ jsx(
153
- Box,
154
- {
155
- component: "div",
156
- "data-testid": testIdFor(dataTestId, "message"),
157
- sx: {
158
- opacity: DESCRIPTION.opacity,
159
- fontSize: sxRem(DESCRIPTION.fontSize),
160
- wordWrap: "break-word",
161
- overflowWrap: "break-word",
162
- wordBreak: "break-word"
163
- },
164
- children: description
165
- }
166
- ),
167
- children
168
- ] });
169
138
  var AlertCloseButton = ({
170
139
  dataTestId,
171
140
  label,
@@ -224,6 +193,16 @@ function dismissButton(props, dataTestId, onClose) {
224
193
  if (!props.closable) return null;
225
194
  return /* @__PURE__ */ jsx(AlertCloseButton, { dataTestId, label: props.closeLabel, onClose });
226
195
  }
196
+ function placeIcon({
197
+ icon,
198
+ dataTestId,
199
+ hasTitle,
200
+ placement
201
+ }) {
202
+ if (icon === null) return { slot: false };
203
+ const glyph = /* @__PURE__ */ jsx(Box, { component: "span", "data-testid": testIdFor(dataTestId, "icon"), children: icon });
204
+ return placement === "title" && hasTitle ? { slot: false, titleIcon: glyph } : { slot: glyph };
205
+ }
227
206
  var Alert = React.forwardRef((alertProps, ref) => {
228
207
  const {
229
208
  variant,
@@ -237,6 +216,7 @@ var Alert = React.forwardRef((alertProps, ref) => {
237
216
  description,
238
217
  children,
239
218
  animate,
219
+ iconPlacement,
240
220
  role: _role,
241
221
  announce: _announce,
242
222
  // resolved from `alertProps` — see `resolveAnnouncement`
@@ -246,6 +226,7 @@ var Alert = React.forwardRef((alertProps, ref) => {
246
226
  const dataTestId = resolveTestId(others, "alert");
247
227
  const props = withoutAlertOnlyProps(withoutTestIdProps(others));
248
228
  const announcement = resolveAnnouncement(alertProps, variant);
229
+ const theme = useTheme();
249
230
  const [open, setOpen] = React.useState(true);
250
231
  const [isClosing, setIsClosing] = React.useState(false);
251
232
  const handleClose = () => {
@@ -256,8 +237,12 @@ var Alert = React.forwardRef((alertProps, ref) => {
256
237
  }, CLOSE_DELAY_MS);
257
238
  };
258
239
  const severity = toMuiSeverity(variant);
259
- const displayIcon = showIcon ? /* @__PURE__ */ jsx(Box, { component: "span", "data-testid": testIdFor(dataTestId, "icon"), children: icon || getVariantIcon(variant) }) : false;
260
- const content = /* @__PURE__ */ jsx(AlertContent, { title, description, dataTestId, children });
240
+ const { slot, titleIcon } = placeIcon({
241
+ icon: showIcon ? icon ?? getVariantIcon(variant) : null,
242
+ dataTestId,
243
+ hasTitle: Boolean(title),
244
+ placement: resolveIconPlacement(theme, iconPlacement)
245
+ });
261
246
  return /* @__PURE__ */ jsx(Collapse, { in: open && !isClosing, timeout: COLLAPSE_MS, children: /* @__PURE__ */ jsx(
262
247
  StyledAlert,
263
248
  {
@@ -269,14 +254,14 @@ var Alert = React.forwardRef((alertProps, ref) => {
269
254
  glow,
270
255
  pulse,
271
256
  animate,
272
- icon: displayIcon,
257
+ icon: slot,
273
258
  role: announcement.role,
274
259
  "aria-live": announcement["aria-live"],
275
260
  "aria-atomic": ariaAtomic,
276
261
  tabIndex: 0,
277
262
  action: dismissButton(alertProps, dataTestId, handleClose),
278
263
  ...props,
279
- children: content
264
+ children: /* @__PURE__ */ jsx(AlertContent, { title, description, titleIcon, dataTestId, children })
280
265
  }
281
266
  ) });
282
267
  });
@@ -292,4 +277,4 @@ export {
292
277
  Alert,
293
278
  ALERT_ONLY_PROPS
294
279
  };
295
- //# sourceMappingURL=chunk-DQJFCVXW.js.map
280
+ //# sourceMappingURL=chunk-ZSCKXOKE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/data-display/Alert/Alert.tsx"],"sourcesContent":["import Close from '@mui/icons-material/Close';\nimport MuiAlert from '@mui/material/Alert/index.js';\nimport Box from '@mui/material/Box/index.js';\nimport Collapse from '@mui/material/Collapse/index.js';\nimport IconButton from '@mui/material/IconButton/index.js';\nimport { alpha, styled, useTheme } from '@mui/material/styles/index.js';\nimport type { Theme } from '@mui/material/styles/index.js';\nimport React from 'react';\n\nimport { absoluteInk, modeInk } from '../../../tokens/ink';\n\nimport { AlertContent } from './Alert.content';\nimport { resolveAlertProps, resolveAnnouncement, testIdFor } from './Alert.helpers';\nimport { resolveIconPlacement, type AlertIconPlacement } from './Alert.placement';\nimport type { AlertPalette } from './Alert.metrics';\nimport {\n ACTIVE,\n GLOW,\n ALERT_EASING,\n ALERT_RADIUS_UNITS,\n ALERT_TRANSITION_MS,\n CLOSE_BUTTON,\n CLOSE_DELAY_MS,\n COLLAPSE_MS,\n FADE_IN,\n FOCUS,\n HOVER,\n seconds,\n} from './Alert.metrics';\nimport {\n alertEmphasisStyles,\n alertLayoutStyles,\n alertVariantStyles,\n fadeInScale,\n getColorFromTheme,\n getVariantIcon,\n} from './Alert.styles';\nimport type { AlertColor } from '@mui/material/Alert/index.js';\nimport type { AlertProps } from './Alert.types';\nimport { resolveTestId, withoutTestIdProps } from '../../../platform/test-id';\nimport { rem, rems } from '../../../tokens/relative';\n\nconst transition = `all ${seconds(ALERT_TRANSITION_MS)} ${ALERT_EASING}`;\n\n// Define animations\n/**\n * The pointer states' shadow: a flat tint, plus the glow when the alert has one.\n *\n * The tint is an inset spread at 100vmax, which always exceeds the element, so\n * it covers the surface edge to edge. It paints ABOVE the background and BELOW\n * the content, which is what keeps the ink's own contrast out of these states\n * entirely — see `ACTIVE` in `Alert.metrics.ts` for why a layer replaced the\n * opacity dip and the brightness multiplier that each preceded it.\n *\n * The glow is COMPOSED rather than replaced, so hovering a glowing alert keeps\n * its glow; `glowStyles` gave up its `!important` for this.\n */\nfunction pointerShadow(\n theme: Theme,\n colorPalette: AlertPalette,\n glow: boolean,\n variant: string | undefined,\n): (alpha_: number) => string {\n // The tint moves the surface AWAY from its own ink, which is why this reads\n // the variant and not only the mode.\n //\n // `gradient` is the one variant where the two disagree: it paints a\n // mid-lightness sweep (L* 42–61) under WHITE ink in BOTH modes, so the\n // mode-keyed answer tinted it white in dark mode — toward the text. Measured:\n // white-on-gradient fell to 2.90:1 on hover and 2.41:1 pressed, under the 3:1\n // floor and below its own idle. Every other variant's surface tracks the mode,\n // so for them the two rules agree.\n const ink = variant === 'gradient' ? absoluteInk(theme).black : modeInk(theme);\n const glowShadow = glow\n ? `0 0 ${rems(theme, GLOW.blur, GLOW.spread)} ${alpha(colorPalette.main, GLOW.alpha)}`\n : null;\n return (alpha_) =>\n [`inset 0 0 0 100vmax ${alpha(ink, alpha_)}`, glowShadow].filter(Boolean).join(', ');\n}\n\nconst StyledAlert = styled(MuiAlert, {\n shouldForwardProp: (prop) =>\n !['customVariant', 'customColor', 'glow', 'pulse', 'animate'].includes(prop as string),\n})<{\n customVariant?: string;\n customColor?: string;\n glow?: boolean;\n pulse?: boolean;\n animate?: boolean;\n}>(({ theme, customVariant, customColor, glow, pulse, animate }) => {\n const colorPalette = getColorFromTheme(theme, customColor || customVariant || 'info');\n\n const withTint = pointerShadow(theme, colorPalette, Boolean(glow), customVariant);\n\n return {\n borderRadius: theme.spacing(ALERT_RADIUS_UNITS),\n transition: `${transition}, box-shadow ${seconds(ACTIVE.ms)} ${ALERT_EASING}`,\n position: 'relative',\n overflow: 'hidden',\n animation: animate ? `${fadeInScale(theme)} ${seconds(FADE_IN.ms)} ease-out` : 'none',\n willChange: 'transform, opacity',\n\n ...alertLayoutStyles(theme, colorPalette, animate),\n\n // Hover: one tint step, and nothing that moves. An alert is a surface\n // rather than a control, so the pointer only needs telling it is here. The\n // icon keeps its own place for the same reason — it is the variant's\n // meaning, not an affordance to animate.\n '&:hover': {\n boxShadow: withTint(HOVER.tintAlpha),\n\n '&::before': {\n opacity: 1,\n },\n },\n\n // Press: a 20% tint, landing at once and easing back. Still no geometry.\n //\n // `transition: none` here is what makes the dip INSTANT: a click's\n // `:active` lasts about as long as the finger is down, so easing into it\n // would be cut off in its first tenth and read as a flicker. The ease is on\n // the way back, governed by the root.\n //\n // Neither `:hover` nor `:focus-visible` may declare `transition`, and that\n // is not a style preference. `:active` under a mouse ALWAYS implies\n // `:hover`, so a bare shorthand in the hover block outranks the root's\n // (0,2,0 beats 0,1,0) and silently resets the timing this state rests on.\n //\n // The `:not(:has(…))` names CONTROLS, not any descendant. `:active`\n // matches an ancestor of whatever is pressed, so dismissing an alert\n // dimmed the alert being dismissed and pressing a call to action dimmed\n // the message explaining it. Excluding `:has(:active)` wholesale does not\n // work and was the first attempt: pressing the TEXT makes that text\n // `:active` too, so the guard matched on every press and the state never\n // fired at all.\n '&:active:not(:has(button:active, a:active, [role=\"button\"]:active))': {\n boxShadow: withTint(ACTIVE.tintAlpha),\n transition: 'none',\n },\n\n // Focus: `:focus-visible`, not `:focus-within`.\n //\n // The alert carries `tabIndex={0}`, so a MOUSE CLICK focused it and painted\n // the ring — a keyboard affordance answering a pointer, which is what made\n // clicking one look like an error state. `:focus-visible` is the browser's\n // own answer to \"did this focus come from the keyboard\": the ring stays for\n // whoever tabs here and never fires on a click.\n //\n // One ring, not three. It was a 3px outline at 3px offset UNDER a 6px halo,\n // and stacking two rings on one edge is what read as unfinished rather than\n // as emphasis.\n // It declares no `transition`: `outline-style` is discrete, so the ring\n // arrives at full width with only its COLOUR easing — from `currentcolor`,\n // the near-black alert ink, to the blue. That is a visible dark flash on\n // every keyboard focus, and it would also outrank the root's opacity\n // transition the way the hover block did.\n '&:focus-visible': {\n outline: `${rem(theme, FOCUS.ringWidth)} solid ${alpha(colorPalette.main, FOCUS.ringAlpha)}`,\n outlineOffset: rem(theme, FOCUS.offset),\n },\n\n ...alertVariantStyles(theme, customVariant, colorPalette),\n ...alertEmphasisStyles(theme, colorPalette, Boolean(glow), Boolean(pulse)),\n };\n});\n\n// glass and gradient are our own looks with no MUI severity of their own; both\n// borrow info's. danger is MUI's error.\nconst MUI_SEVERITY: Record<string, AlertColor> = {\n danger: 'error',\n glass: 'info',\n gradient: 'info',\n};\n\nconst toMuiSeverity = (variant: string): AlertColor =>\n MUI_SEVERITY[variant] ?? (variant as AlertColor);\n\nconst AlertCloseButton: React.FC<{ dataTestId?: string; label: string; onClose: () => void }> = ({\n dataTestId,\n label,\n onClose,\n}) => (\n <IconButton\n data-testid={testIdFor(dataTestId, 'close')}\n aria-label={label}\n color=\"inherit\"\n size=\"small\"\n onClick={onClose}\n sx={(theme) => ({\n transition,\n opacity: CLOSE_BUTTON.opacity,\n // Opacity and a wash only: the button used to spin 90deg and grow 1.1,\n // which drew the eye to the dismiss rather than to the message.\n '&:hover': {\n opacity: 1,\n backgroundColor: alpha(theme.palette.action.hover, CLOSE_BUTTON.washAlpha),\n },\n // A REAL ring, on the keyboard-only selector.\n //\n // This used to be `&:focus` setting `outline: 'none'` over a\n // `rgba(0,0,0,0.1)` wash — 1.25:1 against the info surface, and MUI's\n // ButtonBase already sets `outline: 0`, so there was no UA fallback\n // either. It went unnoticed while the ROOT still matched `:focus-within`\n // and drew a ring around the whole alert; moving the root to\n // `:focus-visible` took that away and left this button with no visible\n // focus at all. `Banner`'s dismiss already draws its own outline, so\n // this is also what keeps the two surfaces telling a keyboard user the\n // same thing.\n '&:focus-visible': {\n opacity: 1,\n // `currentColor` is the alert's own ink, inherited through\n // `color=\"inherit\"`, so the ring is drawn in whatever colour was\n // already chosen to be READ on this surface. Measured 11.2:1 on the\n // semantic variants and 5.7:1 on `gradient`.\n //\n // That is a reasoned choice, not a test-backed one, and the difference\n // matters: `alert-contrast.test.tsx` covers the ink of the four\n // semantic variants only — its `glass` case asserts the pane's alpha\n // rather than its ink, and `gradient` it does not render at all. A\n // translucent surface's contrast depends on what sits behind it, which\n // is why that test stops where it does and why this comment does not\n // borrow a guarantee it never made.\n outline: `${rem(theme, FOCUS.ringWidth)} solid currentColor`,\n outlineOffset: rem(theme, FOCUS.offset),\n backgroundColor: alpha(theme.palette.action.focus, CLOSE_BUTTON.washAlpha),\n },\n })}\n >\n <Close fontSize=\"inherit\" />\n </IconButton>\n);\n\n/**\n * The dismiss button, or nothing.\n *\n * Reads `closeLabel` straight off the props rather than through the\n * `definedProps` merge, which would widen it to `string | undefined` and hand\n * the button an empty name. The UNION in `AlertProps` guarantees the label\n * wherever `closable` is true — that narrowing is gone inside the component,\n * which is why the fallback below exists and why it is unreachable.\n */\nfunction dismissButton(\n props: AlertProps,\n dataTestId: string | undefined,\n onClose: () => void,\n): React.JSX.Element | null {\n if (!props.closable) return null;\n return <AlertCloseButton dataTestId={dataTestId} label={props.closeLabel} onClose={onClose} />;\n}\n\n/**\n * Where the icon goes: MUI's own slot (`slot`), or the title's row\n * (`titleIcon`) — never both. On the title's row only when there IS a title\n * and an icon to put on it (`Alert.placement.ts`).\n */\nfunction placeIcon({\n icon,\n dataTestId,\n hasTitle,\n placement,\n}: {\n icon: React.ReactNode;\n dataTestId: string | undefined;\n hasTitle: boolean;\n placement: AlertIconPlacement;\n}): { slot: React.ReactNode; titleIcon?: React.ReactNode } {\n if (icon === null) return { slot: false };\n const glyph = (\n <Box component=\"span\" data-testid={testIdFor(dataTestId, 'icon')}>\n {icon}\n </Box>\n );\n return placement === 'title' && hasTitle ? { slot: false, titleIcon: glyph } : { slot: glyph };\n}\n\nexport const Alert = React.forwardRef<HTMLDivElement, AlertProps>((alertProps, ref) => {\n const {\n variant,\n color,\n glow,\n pulse,\n icon,\n showIcon,\n onClose,\n title,\n description,\n children,\n animate,\n iconPlacement,\n role: _role, announce: _announce, // resolved from `alertProps` — see `resolveAnnouncement`\n 'aria-atomic': ariaAtomic,\n ...others\n } = resolveAlertProps(alertProps);\n\n // Every spelling of the test id the shared contract allows, mapped to the\n // one the DOM reads and defaulted to `alert`; the native Alert does the same.\n const dataTestId = resolveTestId(others, 'alert');\n // Then the dismiss union, which `dismissButton` reads off `alertProps` rather\n // than through this destructure — so without this strip it rides `...props`\n // onto the DOM. `ALERT_DEFAULTS` supplies `closable: false`, so that happened\n // on EVERY alert, not only the closable ones.\n const props = withoutAlertOnlyProps(withoutTestIdProps(others));\n\n // Depends on `variant`, so it cannot live in the static defaults above.\n const announcement = resolveAnnouncement(alertProps, variant);\n const theme = useTheme();\n const [open, setOpen] = React.useState(true);\n const [isClosing, setIsClosing] = React.useState(false);\n\n const handleClose = () => {\n setIsClosing(true);\n window.setTimeout(() => {\n setOpen(false);\n onClose?.();\n }, CLOSE_DELAY_MS);\n };\n\n const severity = toMuiSeverity(variant);\n\n const { slot, titleIcon } = placeIcon({\n icon: showIcon ? (icon ?? getVariantIcon(variant)) : null,\n dataTestId,\n hasTitle: Boolean(title),\n placement: resolveIconPlacement(theme, iconPlacement),\n });\n\n return (\n <Collapse in={open && !isClosing} timeout={COLLAPSE_MS}>\n <StyledAlert\n ref={ref}\n data-testid={dataTestId}\n severity={severity}\n customVariant={variant}\n customColor={color}\n glow={glow}\n pulse={pulse}\n animate={animate}\n icon={slot}\n role={announcement.role}\n aria-live={announcement['aria-live']}\n aria-atomic={ariaAtomic}\n tabIndex={0}\n action={dismissButton(alertProps, dataTestId, handleClose)}\n {...props}\n >\n <AlertContent title={title} description={description} titleIcon={titleIcon} dataTestId={dataTestId}>\n {children}\n </AlertContent>\n </StyledAlert>\n </Collapse>\n );\n});\n\n/**\n * The props `Alert` OWNS, which must never reach the DOM.\n *\n * `AlertProps` extends MUI's, whose rest-spread is how a host's real HTML\n * attributes get onto the root — so the same spread carries the alert's own\n * configuration unless it is named here. Everything else the component consumes\n * leaves through the destructure above; these two do not, because\n * `dismissButton` reads them off the original props to keep the dismiss union's\n * narrowing intact.\n *\n * Exported so a test can render an alert carrying every name on it and assert\n * none reaches the DOM — the check that would have caught `closable`.\n */\nexport const ALERT_ONLY_PROPS = ['closable', 'closeLabel'] as const;\n\nfunction withoutAlertOnlyProps<P extends object>(rest: P): P {\n const html = { ...rest } as Record<string, unknown>;\n for (const key of ALERT_ONLY_PROPS) delete html[key];\n return html as P;\n}\n\nAlert.displayName = 'Alert';\n"],"mappings":"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","names":[]}
@@ -1,10 +1,12 @@
1
1
  import "../chunk-NUGT7LMR.js";
2
2
  import {
3
3
  Alert
4
- } from "../chunk-DQJFCVXW.js";
5
- import "../chunk-JYAXTRNH.js";
4
+ } from "../chunk-ZSCKXOKE.js";
5
+ import "../chunk-CCJJTLF7.js";
6
+ import "../chunk-QXUXO22M.js";
7
+ import "../chunk-IVI574Y5.js";
6
8
  import "../chunk-L7VH6IMR.js";
7
- import "../chunk-3LHZCVGM.js";
9
+ import "../chunk-JNVUB2D4.js";
8
10
  import "../chunk-TYJR4GOF.js";
9
11
  import "../chunk-2FBGDSGC.js";
10
12
  import "../chunk-VBP46YP4.js";
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  Banner
3
- } from "../chunk-ZBOGZLX3.js";
4
- import "../chunk-44AXT2SN.js";
5
- import "../chunk-3LHZCVGM.js";
3
+ } from "../chunk-T2KONJ45.js";
4
+ import "../chunk-QZX43FIC.js";
5
+ import "../chunk-JNVUB2D4.js";
6
6
  import "../chunk-2FBGDSGC.js";
7
7
  import "../chunk-VBP46YP4.js";
8
8
  import "../chunk-44BD7SFH.js";
@@ -3,7 +3,7 @@ import {
3
3
  } from "../chunk-KYTADPS2.js";
4
4
  import {
5
5
  useRemoveConfirm
6
- } from "../chunk-3VLVLZ6W.js";
6
+ } from "../chunk-B34WHRKH.js";
7
7
  import {
8
8
  rowActionsToMenuItems
9
9
  } from "../chunk-ZBXG6RVJ.js";
@@ -17,7 +17,7 @@ import {
17
17
  import {
18
18
  CardActionsProvider,
19
19
  useCardActions
20
- } from "../chunk-LY7PBZ3Z.js";
20
+ } from "../chunk-UFNXYOHZ.js";
21
21
  import {
22
22
  CardKebab
23
23
  } from "../chunk-P4LR2GLN.js";
@@ -32,13 +32,15 @@ import "../chunk-EMYESBIT.js";
32
32
  import "../chunk-LZRVUOMU.js";
33
33
  import "../chunk-EEB66IVH.js";
34
34
  import "../chunk-NUGT7LMR.js";
35
- import "../chunk-DQJFCVXW.js";
36
- import "../chunk-JYAXTRNH.js";
35
+ import "../chunk-ZSCKXOKE.js";
36
+ import "../chunk-CCJJTLF7.js";
37
+ import "../chunk-QXUXO22M.js";
38
+ import "../chunk-IVI574Y5.js";
37
39
  import "../chunk-L7VH6IMR.js";
38
40
  import "../chunk-2IBFEHIX.js";
39
41
  import "../chunk-RZCXYKY4.js";
40
42
  import "../chunk-BGTG7G54.js";
41
- import "../chunk-3LHZCVGM.js";
43
+ import "../chunk-JNVUB2D4.js";
42
44
  import "../chunk-6DPAWXZ3.js";
43
45
  import "../chunk-BA4RHQ3B.js";
44
46
  import "../chunk-364NH2NY.js";
@@ -3,7 +3,7 @@ import {
3
3
  } from "../chunk-MBMZNSBP.js";
4
4
  import {
5
5
  DataViewsTableBase
6
- } from "../chunk-52CLMR47.js";
6
+ } from "../chunk-ENXGWNCX.js";
7
7
  import "../chunk-VWVA74JY.js";
8
8
  import {
9
9
  DataViewsGrid
@@ -50,7 +50,7 @@ import "../chunk-FJ3UZ4RC.js";
50
50
  import "../chunk-7D7CJRL7.js";
51
51
  import "../chunk-GCZJH4XL.js";
52
52
  import "../chunk-CBOB5AV6.js";
53
- import "../chunk-ERI6JC4M.js";
53
+ import "../chunk-X2SJJZFH.js";
54
54
  import "../chunk-BF3SGOWT.js";
55
55
  import "../chunk-LBEZ7A3F.js";
56
56
  import "../chunk-5M4TYFR3.js";
@@ -197,15 +197,17 @@ import "../chunk-G3E66C6J.js";
197
197
  import "../chunk-SNCSGLJ6.js";
198
198
  import "../chunk-UMICTXMP.js";
199
199
  import "../chunk-NUGT7LMR.js";
200
- import "../chunk-DQJFCVXW.js";
201
- import "../chunk-JYAXTRNH.js";
200
+ import "../chunk-ZSCKXOKE.js";
201
+ import "../chunk-CCJJTLF7.js";
202
+ import "../chunk-QXUXO22M.js";
203
+ import "../chunk-IVI574Y5.js";
202
204
  import "../chunk-L7VH6IMR.js";
203
205
  import "../chunk-2IBFEHIX.js";
204
206
  import "../chunk-RZCXYKY4.js";
205
207
  import "../chunk-BGTG7G54.js";
206
208
  import "../chunk-3UIDKLML.js";
207
209
  import "../chunk-PYC4CWCQ.js";
208
- import "../chunk-3LHZCVGM.js";
210
+ import "../chunk-JNVUB2D4.js";
209
211
  import "../chunk-6DPAWXZ3.js";
210
212
  import "../chunk-WEBEOBN5.js";
211
213
  import "../chunk-VUHLNYAE.js";
@@ -1,16 +1,18 @@
1
1
  import "../chunk-JQRKXMSH.js";
2
2
  import {
3
3
  NotificationStatusNotice
4
- } from "../chunk-REEV7CLC.js";
4
+ } from "../chunk-QDG6V7OC.js";
5
5
  import "../chunk-55FFONIV.js";
6
6
  import {
7
7
  detectNotificationBrowser,
8
8
  notificationUnblockSteps
9
9
  } from "../chunk-L7BRU4UF.js";
10
- import "../chunk-DQJFCVXW.js";
11
- import "../chunk-JYAXTRNH.js";
10
+ import "../chunk-ZSCKXOKE.js";
11
+ import "../chunk-CCJJTLF7.js";
12
+ import "../chunk-QXUXO22M.js";
13
+ import "../chunk-IVI574Y5.js";
12
14
  import "../chunk-L7VH6IMR.js";
13
- import "../chunk-3LHZCVGM.js";
15
+ import "../chunk-JNVUB2D4.js";
14
16
  import "../chunk-364NH2NY.js";
15
17
  import "../chunk-PPEHBI5O.js";
16
18
  import "../chunk-G2FUZALJ.js";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/data-display/Alert/Alert.native.tsx","../../../src/components/data-display/Alert/Alert.helpers.ts","../../../src/components/data-display/Alert/Alert.metrics.ts","../../../src/components/data-display/Alert/Alert.look.native.ts"],"sourcesContent":["import * as React from 'react';\nimport {\n Animated,\n Easing,\n type LayoutChangeEvent,\n Platform,\n Pressable,\n type Role,\n StyleSheet,\n Text as RNText,\n View,\n type ViewStyle,\n} from 'react-native';\n\nimport { resolveAlertProps, resolveAnnouncement, testIdFor, VARIANT_ICON } from './Alert.helpers';\nimport {\n actionSlotStyle,\n alertLook,\n closeButtonStyle,\n descriptionStyle,\n iconSlotStyle,\n messageSlotStyle,\n messageTextStyle,\n titleStyle,\n} from './Alert.look.native';\nimport { CLOSE_BUTTON, CLOSE_DELAY_MS, COLLAPSE_MS, FADE_IN, ICON_SLOT, ICON_SPIN, PULSE } from './Alert.metrics';\nimport type { AlertProps, AlertVariant } from './Alert.types.native';\nimport { Icon } from '../../../icons/Icon.native';\nimport { webAria } from '../../../platform/aria';\nimport { renderTextChildren } from '../../../platform/text-children';\nimport { resolveTestId, withoutTestIdProps } from '../../../platform/test-id';\nimport { useUiTheme } from '../../../provider/use-ui-theme.native';\n\ntype AnimatedStyle = Animated.WithAnimatedValue<ViewStyle>;\nconst nativeDriver = Platform.OS !== 'web';\n\n/** A 0→1 progress that starts on mount when `animate` is set, else sits at 1. */\nfunction useProgress(animate: boolean, duration: number): Animated.Value {\n const progress = React.useRef(new Animated.Value(animate ? 0 : 1)).current;\n React.useEffect(() => {\n if (!animate) return undefined;\n const timing = Animated.timing(progress, { toValue: 1, duration, easing: Easing.out(Easing.ease), useNativeDriver: nativeDriver });\n timing.start();\n return () => timing.stop();\n }, [animate, duration, progress]);\n return progress;\n}\n\n/** The web's `fadeInScale` keyframes: in from 0 opacity, 0.95 scale and 10px above, over 300ms. */\nfunction useFadeIn(animate: boolean): AnimatedStyle | undefined {\n const progress = useProgress(animate, FADE_IN.ms);\n if (!animate) return undefined;\n return {\n opacity: progress,\n transform: [\n { scale: progress.interpolate({ inputRange: [0, 1], outputRange: [FADE_IN.scale, 1] }) },\n { translateY: progress.interpolate({ inputRange: [0, 1], outputRange: [-FADE_IN.lift, 0] }) },\n ],\n };\n}\n\n/** The web's `iconRotate` keyframes: one full turn, 0.8 → 1.1 → 1, over 600ms. */\nfunction useIconSpin(animate: boolean): AnimatedStyle | undefined {\n const progress = useProgress(animate, ICON_SPIN.ms);\n if (!animate) return undefined;\n return {\n transform: [\n { rotate: progress.interpolate({ inputRange: [0, 1], outputRange: ['0deg', '360deg'] }) },\n { scale: progress.interpolate({ inputRange: [0, 0.5, 1], outputRange: [ICON_SPIN.from, ICON_SPIN.mid, 1] }) },\n ],\n };\n}\n\n/** The web's `::after` pulse: a wash of the hue over the card, fading out every two seconds, behind the words. */\nfunction Pulse({ color, radius, testID }: { color: string; radius: number; testID: string }): React.JSX.Element {\n const progress = React.useRef(new Animated.Value(0)).current;\n React.useEffect(() => {\n const loop = Animated.loop(\n Animated.timing(progress, { toValue: 1, duration: PULSE.ms, easing: Easing.linear, useNativeDriver: nativeDriver }),\n );\n loop.start();\n return () => loop.stop();\n }, [progress]);\n return (\n <Animated.View\n testID={testID}\n aria-hidden\n style={[\n StyleSheet.absoluteFill,\n {\n pointerEvents: 'none',\n borderRadius: radius,\n backgroundColor: color,\n opacity: progress.interpolate({ inputRange: [0, 0.7, 1], outputRange: [PULSE.alpha, 0, 0] }),\n },\n ]}\n />\n );\n}\n\n/**\n * MUI's `Collapse`: open, it is a plain wrapper with its overflow visible (so\n * a glow can escape); closing, it clips and shrinks over 300ms, then says so.\n */\nfunction Collapse({ open, onCollapsed, children }: { open: boolean; onCollapsed: () => void; children: React.ReactNode }): React.JSX.Element {\n const [height, setHeight] = React.useState<number | null>(null);\n const progress = React.useRef(new Animated.Value(1)).current;\n React.useEffect(() => {\n if (open) return undefined;\n const timing = Animated.timing(progress, { toValue: 0, duration: COLLAPSE_MS, easing: Easing.inOut(Easing.ease), useNativeDriver: false });\n timing.start(({ finished }) => {\n if (finished) onCollapsed();\n });\n return () => timing.stop();\n }, [open, onCollapsed, progress]);\n const onLayout = (event: LayoutChangeEvent): void => {\n if (open) setHeight(event.nativeEvent.layout.height);\n };\n const shrink: AnimatedStyle = height == null ? {} : { maxHeight: progress.interpolate({ inputRange: [0, 1], outputRange: [0, height] }) };\n return (\n <Animated.View style={[{ overflow: open ? 'visible' : 'hidden', opacity: progress }, shrink]}>\n <View onLayout={onLayout}>{children}</View>\n </Animated.View>\n );\n}\n\ninterface IconSlotProps {\n variant: AlertVariant;\n icon: React.ReactNode;\n color: string;\n animate: boolean;\n testID: string;\n}\n\n/** The icon slot; `glass` and `gradient` have no glyph of their own, so theirs is empty unless an `icon` is given — as on the web. */\nfunction IconSlot({ variant, icon, color, animate, testID }: IconSlotProps): React.JSX.Element {\n const theme = useUiTheme();\n const spin = useIconSpin(animate);\n const glyph = VARIANT_ICON[variant];\n return (\n <Animated.View testID={testID} style={[iconSlotStyle(theme), spin]}>\n {icon || (glyph ? <Icon name={glyph} size={ICON_SLOT.size} color={color} /> : null)}\n </Animated.View>\n );\n}\n\nfunction CloseButton({ label, ink, onPress, testID }: { label: string | undefined; ink: string; onPress: () => void; testID: string }): React.JSX.Element {\n const theme = useUiTheme();\n return (\n <Pressable role=\"button\" aria-label={label} testID={testID} onPress={onPress} style={({ pressed }) => closeButtonStyle(theme, pressed)}>\n <Icon name=\"Close\" size={CLOSE_BUTTON.iconSize} color={ink} />\n </Pressable>\n );\n}\n\ninterface ContentProps {\n title?: string;\n description?: string;\n children?: React.ReactNode;\n ink: string;\n testId: string;\n}\n\nfunction AlertContent({ title, description, children, ink, testId }: ContentProps): React.JSX.Element {\n const theme = useUiTheme();\n return (\n <View style={messageSlotStyle(theme)}>\n {title ? (\n <RNText testID={testIdFor(testId, 'title')} style={titleStyle(theme, ink, Boolean(description))}>\n {title}\n </RNText>\n ) : null}\n {description ? (\n <RNText testID={testIdFor(testId, 'message')} style={descriptionStyle(theme, ink)}>\n {description}\n </RNText>\n ) : null}\n {renderTextChildren(children, messageTextStyle(theme, ink))}\n </View>\n );\n}\n\n/** The dismiss sequence the web runs: mark closing, fire `onClose` 200ms in, stay until the collapse has run. */\nfunction useDismiss(onClose: (() => void) | undefined): { open: boolean; gone: boolean; close: () => void; onCollapsed: () => void } {\n const [closing, setClosing] = React.useState(false);\n const [gone, setGone] = React.useState(false);\n const timer = React.useRef<ReturnType<typeof setTimeout> | null>(null);\n React.useEffect(() => () => {\n if (timer.current) clearTimeout(timer.current);\n }, []);\n const close = (): void => {\n setClosing(true);\n timer.current = setTimeout(() => onClose?.(), CLOSE_DELAY_MS);\n };\n const onCollapsed = React.useCallback(() => setGone(true), []);\n return { open: !closing, gone, close, onCollapsed };\n}\n\nexport const Alert = React.forwardRef<View, AlertProps>((alertProps, ref) => {\n const {\n variant, color, glow, pulse, icon, showIcon, onClose, title, description, children, animate,\n // `role`, `announce` and `aria-live` all leave here and are resolved\n // TOGETHER below, off `alertProps` — see `resolveAnnouncement`.\n role: _role, announce: _announce,\n 'aria-atomic': ariaAtomic, 'aria-live': _ariaLive, closable, closeLabel, style, ...others\n } = resolveAlertProps(alertProps);\n const theme = useUiTheme();\n const testId = resolveTestId(others, 'alert') as string;\n const rest = withoutTestIdProps(others);\n const look = alertLook(theme, { variant, color, glow, pulse });\n const fadeIn = useFadeIn(animate);\n const dismiss = useDismiss(onClose);\n const announcement = resolveAnnouncement(alertProps, variant);\n\n if (dismiss.gone) return null;\n return (\n <Collapse open={dismiss.open} onCollapsed={dismiss.onCollapsed}>\n <Animated.View\n ref={ref}\n role={announcement.role as Role}\n aria-live={announcement['aria-live']}\n {...webAria({ 'aria-atomic': ariaAtomic })}\n tabIndex={0}\n testID={testId}\n style={[look.root, fadeIn, style]}\n {...rest}\n >\n {pulse ? <Pulse color={look.palette.main} radius={look.root.borderRadius as number} testID={testIdFor(testId, 'pulse')} /> : null}\n {showIcon ? <IconSlot variant={variant} icon={icon} color={look.iconColor} animate={animate} testID={testIdFor(testId, 'icon')} /> : null}\n <AlertContent title={title} description={description} ink={look.ink} testId={testId}>\n {children}\n </AlertContent>\n {closable ? (\n <View style={actionSlotStyle(theme)}>\n <CloseButton label={closeLabel} ink={look.ink} onPress={dismiss.close} testID={testIdFor(testId, 'close')} />\n </View>\n ) : null}\n </Animated.View>\n </Collapse>\n );\n});\n\nAlert.displayName = 'Alert';\n","import type { AlertBaseFields, AlertVariant } from './Alert.base';\nimport type { IconName } from '../../../icons/Icon.types';\n\ntype AlertDefaultedKeys = 'variant' | 'glow' | 'pulse' | 'showIcon' | 'animate' | 'role' | 'aria-atomic';\n\nexport const ALERT_DEFAULTS: Required<Pick<AlertBaseFields, AlertDefaultedKeys>> & { closable: false } = {\n variant: 'info',\n glow: false,\n pulse: false,\n showIcon: true,\n closable: false,\n animate: true,\n role: 'alert',\n 'aria-atomic': 'true',\n};\n\n/**\n * Generic over the renderer's own props: the web and the native `Alert` pass\n * different extras through, and both come back out untouched.\n */\nexport type ResolvedAlertProps<P extends AlertBaseFields> = P &\n Required<Pick<AlertBaseFields, AlertDefaultedKeys>>;\n\n// Strips explicitly-undefined props before the merge so `prop={undefined}` still\n// falls back to the default, the way a destructuring default would.\nconst definedProps = <P extends AlertBaseFields>(props: P): Partial<P> =>\n Object.fromEntries(\n Object.entries(props).filter(([, value]) => value !== undefined),\n ) as Partial<P>;\n\n// Through `unknown`: `closable: false` in the defaults belongs to the dismiss\n// union rather than to `AlertBaseFields`, so TypeScript cannot see the merge as\n// comparable to `P` although every field of `P` survives it untouched.\nexport const resolveAlertProps = <P extends AlertBaseFields>(props: P): ResolvedAlertProps<P> =>\n ({ ...ALERT_DEFAULTS, ...definedProps(props) }) as unknown as ResolvedAlertProps<P>;\n\n/** `danger` announces itself; everything else waits its turn. */\nexport const defaultAriaLive = (variant: AlertVariant): 'polite' | 'assertive' =>\n variant === 'danger' ? 'assertive' : 'polite';\n\n/**\n * The ARIA role each `announce` level is spelled with.\n *\n * Both roles carry an IMPLICIT live setting, and that implicit one is what\n * assistive tech acts on — `alert` is assertive, `status` is polite. Pairing\n * them here is what stops `role` and `aria-live` from contradicting each\n * other, which they do by default: every alert is `role=\"alert\"` regardless of\n * variant, so an `info` alert asks to be polite in one attribute and to\n * interrupt in the other.\n */\nexport const ANNOUNCE_ROLE: Record<NonNullable<AlertBaseFields['announce']>, string> = {\n assertive: 'alert',\n polite: 'status',\n};\n\n/**\n * The two attributes that decide whether an alert interrupts, resolved TOGETHER.\n *\n * Both renderers therefore let `role` and `announce` leave their destructure\n * unused (`_role`, `_announce`) and call this instead — the first because the\n * defaults have already answered it, the second because it must never reach\n * the DOM.\n *\n * Reads the caller's own props rather than the defaulted ones, because the\n * whole question is which of them the caller actually spelled:\n * {@link ALERT_DEFAULTS} supplies `role: 'alert'` for everything, so after the\n * merge there is no longer any difference between an alert that asked to\n * interrupt and one that never mentioned it.\n *\n * Precedence, most specific first — an explicit `role` or `aria-live` beats\n * `announce`, so a call site that already spells either by hand is untouched:\n *\n * 1. `role` / `aria-live` as given;\n * 2. {@link AlertBaseFields.announce}, which supplies both;\n * 3. today's behaviour — `ALERT_DEFAULTS.role` and {@link defaultAriaLive}.\n *\n * With none of the three named, the result is byte-for-byte what it was before\n * `announce` existed.\n */\nexport const resolveAnnouncement = (\n props: Pick<AlertBaseFields, 'announce' | 'role' | 'aria-live'>,\n variant: AlertVariant,\n): { role: string; 'aria-live': 'polite' | 'assertive' | 'off' } => {\n const announce = props.announce;\n return {\n role: props.role ?? (announce === undefined ? ALERT_DEFAULTS.role : ANNOUNCE_ROLE[announce]),\n 'aria-live': props['aria-live'] ?? announce ?? defaultAriaLive(variant),\n };\n};\n\nexport const testIdFor = (base: string | undefined, suffix: string): string =>\n base ? `${base}-${suffix}` : `alert-${suffix}`;\n\n/**\n * The glyph each semantic variant carries, by the shared icon set's name.\n * `glass` and `gradient` carry none of their own: the web renders an empty\n * icon slot for them unless the caller passes an `icon`, and so does native.\n */\nexport const VARIANT_ICON: Partial<Record<AlertVariant, IconName>> = {\n info: 'Info',\n success: 'CheckCircle',\n warning: 'Warning',\n danger: 'Error',\n};\n","import type { AlertVariant } from './Alert.base';\nimport { alpha, darken, lighten } from '../../../tokens/color';\nimport { NEUTRAL_RAMP } from '../../../tokens/ink.core';\nimport { contrastText, type UiGreyStep, type UiTheme } from '../../../tokens/theme';\n\n/**\n * THE NUMBERS BOTH `Alert` RENDERERS DRAW WITH.\n *\n * `Alert.styles.tsx` / `Alert.tsx` (MUI) and `Alert.native.tsx` (React\n * Native) read this one table. Spacing is in SPACING UNITS where the web\n * writes `theme.spacing(n)`; durations are ms (the web turns them into `s`\n * through {@link seconds} so its emitted CSS is byte-for-byte what it was);\n * everything else is px, a ratio or an alpha. The hover, active and focus\n * numbers are here too although only the DOM can honour them — a number the\n * web draws with belongs in the table whether or not native can reach it.\n */\n\n/** The root: 12px corners, 14px 16px of padding, one 300ms curve for everything. */\nexport const ALERT_RADIUS_UNITS = 1.5;\nexport const ALERT_PADDING_UNITS = { vertical: 1.75, horizontal: 2 } as const;\nexport const ALERT_TRANSITION_MS = 300;\nexport const ALERT_EASING = 'cubic-bezier(0.4, 0, 0.2, 1)';\n\n/** Mount: the web's `fadeInScale` keyframes and the icon's `iconRotate`. */\nexport const FADE_IN = { ms: 300, scale: 0.95, lift: 10 } as const;\nexport const ICON_SPIN = { ms: 600, from: 0.8, mid: 1.1 } as const;\n/** Dismiss: MUI `Collapse` runs 300ms; `onClose` fires 200ms in. */\nexport const COLLAPSE_MS = 300;\nexport const CLOSE_DELAY_MS = 200;\n\n/** The message column: 8px between title, description and children; 0.95rem body on 1.5. */\nexport const MESSAGE_GAP_UNITS = 1;\nexport const MESSAGE_FONT_SIZE = 15.2;\nexport const MESSAGE_LINE_HEIGHT = 1.5;\n/** A control inside the message gets an edge: 4px above, a hairline at 0.45 of the hue. */\nexport const MESSAGE_BUTTON = { marginTopUnits: 0.5, borderAlpha: 0.45 } as const;\n\n/** The title: 1.05rem at 600; MUI's `AlertTitle` lifts it 2px; 4px below it when a description follows. */\nexport const TITLE = { fontSize: 16.8, fontWeight: 600, marginTop: -2, marginBottomUnits: 0.5 } as const;\n/** The description: 0.925rem, slightly faded. */\nexport const DESCRIPTION = { fontSize: 14.8, opacity: 0.9 } as const;\n\n/** The icon slot: MUI's 22px glyph at 0.9, 14px from the words, 2px down (MUI's 7px stays below). */\nexport const ICON_SLOT = { size: 22, opacity: 0.9, marginRightUnits: 1.75, paddingTopUnits: 0.25, paddingBottom: 7 } as const;\n/** The action slot: MUI's `4px 0 0 16px` with the 16px ours, pushed right, 8px into the padding. */\nexport const ACTION_SLOT = { paddingLeftUnits: 2, paddingTop: 4, marginRight: -8 } as const;\n/** The close button: MUI's small `IconButton` (5px padding, 18px glyph) at 0.7. */\nexport const CLOSE_BUTTON = { padding: 5, iconSize: 18, opacity: 0.7, washAlpha: 0.1 } as const;\n\n/**\n * A semantic Alert's surface and ink: an OPAQUE tint of the hue with a dark\n * ink of the same hue — MUI's own `standard` recipe, at its ratios. See\n * `semanticSurface` in `Alert.styles.tsx` for why not `alpha(main, 0.1)`.\n */\nexport const SEMANTIC_SURFACE = { tint: { light: 0.9, dark: 0.8 }, ink: 0.6, borderAlpha: 0.35 } as const;\n/** `glass`: 85% paper under a 20px blur, a 0.4 divider hairline. */\nexport const GLASS = { backgroundAlpha: 0.85, borderAlpha: 0.4, blur: 20, saturatePercent: 180 } as const;\n/**\n * `gradient`: light→dark at 0.9 along 135°, a 0.2 white shimmer sweeping 1000px every 3s.\n *\n * It carries no hover of its own, and that is load-bearing rather than an\n * omission. `alertVariantStyles` is spread AFTER the root's `'&:hover'` in the\n * same object literal, so a second `'&:hover'` key does not merge with it — it\n * REPLACES it. While this variant had one, `gradient` was the only alert that\n * brightened on hover while every other variant darkened, and the only one to\n * lose the shimmer reveal the root's hover performs.\n */\nexport const GRADIENT = {\n angleDeg: 135,\n stopAlpha: 0.9,\n shimmerAlpha: 0.2,\n shimmerMs: 3000,\n shimmerTravel: 1000,\n} as const;\n\n/** Emphasis: the glow's shadow and brightness, the pulse's wash. */\nexport const GLOW = { blur: 20, spread: 5, alpha: 0.3, brightness: 1.05 } as const;\nexport const PULSE = { alpha: 0.2, ms: 2000, spread: 10 } as const;\n\n/**\n * Pointer states — DOM only, kept so the web derives them.\n *\n * HOVER and ACTIVE carry NO geometry, and that is the point rather than an\n * omission. They used to lift the card 3px, scale it 1.01, grow a 20px shadow\n * and spin the icon 10deg at 1.15 — four things moving at once on a surface\n * that is not a control, which made a page of alerts twitch under the pointer.\n *\n * Both are a TINT now: a flat inset layer over the surface. Two mechanisms\n * came before it and each failed on a case the next had to fix. Dropping the\n * element's `opacity` composites toward the PAGE, so it inverted the hover on\n * a light tint (L* 95.0 idle, 89.1 hovered, 91.1 pressed) and vanished on a\n * dark one. A `filter: brightness()` fixed the direction but is MULTIPLICATIVE,\n * so it moved a near-black `glass` by four counts (ΔE76 1.71, under the JND)\n * and Banner's 10%-alpha wash by ΔE76 0.44. A layer is additive: it reads the\n * same on an opaque tint, a translucent wash and a gradient, and because it\n * paints above the background and below the content the ink keeps its own\n * contrast.\n */\nexport const HOVER = { tintAlpha: 0.06 } as const;\n\n/**\n * The press: a 20% tint LAYER, eased back fast.\n *\n * The layer is the point. The first attempt dropped the whole element's\n * opacity, which composites toward the PAGE and so behaves differently on\n * every surface it is asked about. Measured: over a light page it made a light\n * tint LIGHTER (L* 95.0 idle, 89.1 hovered, 91.1 pressed), so pushing the\n * surface looked like the pointer leaving; over a dark page it landed back on\n * the idle surface (ΔE76 0.82 on `glass`); on `gradient` it washed white body\n * copy to 2.31:1, under AA; and it diluted the ink during a text-selection\n * drag. A `brightness()` step instead of it fixed the direction but not the\n * reach — a multiplier does nothing to a near-black `glass` in dark mode\n * (ΔE76 1.71) and nothing to Banner's 10%-alpha wash (ΔE76 0.44), because it\n * scales only what the element already paints.\n *\n * An inset shadow at 100vmax is a flat tint over the whole surface: ADDITIVE,\n * so it reads the same on an opaque tint, a translucent wash and a gradient;\n * painted above the background and below the content, so the ink keeps its\n * own contrast; and animatable, which `background-image` is not.\n *\n * `ms` is 250 and not the 1000 first asked for, and the reason is that ONE\n * property carries both states. CSS runs a transition from the DESTINATION\n * state's declaration, and entering hover and releasing a press share that\n * destination — so they cannot have different durations without a second\n * animatable property, and both free pseudo-elements are already spent on the\n * `gradient` shimmer and the `pulse` wash. At 1000ms the hover inherited the\n * second: crossing an alert in 300ms peaked at a ≈ 0.024, under the JND, and\n * for ~360ms the alert you had just LEFT was darker than the one under the\n * pointer. A fast press-return is the smaller loss, and it is the call the\n * product owner made when shown both.\n */\nexport const ACTIVE = { tintAlpha: 0.2, ms: 250 } as const;\n\nexport const FOCUS = { ringWidth: 2, ringAlpha: 1, offset: 2 } as const;\n\n/** `neutral` has no palette slot; the web has always drawn it from three greys. */\nexport const NEUTRAL_GREY: Record<'main' | 'light' | 'dark', UiGreyStep> = { main: 500, light: 300, dark: 700 };\n\n/** A duration as the CSS the web has always emitted: `2000` → `2s`, `300` → `0.3s`. */\nexport const seconds = (ms: number): string => `${ms / 1000}s`;\n\n/** The palette shape the web's `getColorFromTheme` returns — a main plus optional shades. */\nexport interface AlertPalette {\n main: string;\n light?: string;\n dark?: string;\n}\n\n/**\n * The renderer-free twin of the web's `getColorFromTheme`: a variant or\n * colour name to its palette, `neutral` from the greys, anything unknown\n * (`glass`, `gradient`) to `info`.\n */\nexport function alertPalette(theme: UiTheme, key: string | undefined): AlertPalette {\n switch (key) {\n case 'info':\n case 'success':\n case 'warning':\n case 'danger':\n case 'primary':\n case 'secondary':\n return theme.palette[key];\n case 'neutral':\n return {\n main: NEUTRAL_RAMP[NEUTRAL_GREY.main],\n light: NEUTRAL_RAMP[NEUTRAL_GREY.light],\n dark: NEUTRAL_RAMP[NEUTRAL_GREY.dark],\n };\n default:\n return theme.palette.info;\n }\n}\n\n/** What a variant paints: its fill, its ink, its hairline if any, and the colour of its glyph. */\nexport interface AlertSurface {\n backgroundColor: string;\n color: string;\n borderColor?: string;\n iconColor: string;\n}\n\nexport const SEMANTIC_VARIANTS: ReadonlySet<AlertVariant> = new Set(['info', 'success', 'warning', 'danger']);\n\n/** The opaque tint and same-hue ink, inverted for dark mode; the hairline keeps its alpha. */\nexport function semanticSurface(theme: UiTheme, palette: AlertPalette): AlertSurface {\n const dark = theme.mode === 'dark';\n return {\n backgroundColor: dark\n ? darken(palette.main, SEMANTIC_SURFACE.tint.dark)\n : lighten(palette.main, SEMANTIC_SURFACE.tint.light),\n color: dark ? lighten(palette.main, SEMANTIC_SURFACE.ink) : darken(palette.main, SEMANTIC_SURFACE.ink),\n borderColor: alpha(palette.main, SEMANTIC_SURFACE.borderAlpha),\n iconColor: palette.main,\n };\n}\n\nexport function glassSurface(theme: UiTheme): AlertSurface {\n return {\n backgroundColor: alpha(theme.palette.background.paper, GLASS.backgroundAlpha),\n color: theme.palette.text.primary,\n borderColor: alpha(theme.palette.divider, GLASS.borderAlpha),\n iconColor: theme.palette.primary.main,\n };\n}\n\n/** The gradient's two stops; a renderer with no gradient fill paints `from`. */\nexport function gradientStops(palette: AlertPalette): { from: string; to: string } {\n return {\n from: alpha(palette.light || palette.main, GRADIENT.stopAlpha),\n to: alpha(palette.dark || palette.main, GRADIENT.stopAlpha),\n };\n}\n\nexport function gradientSurface(palette: AlertPalette): AlertSurface {\n const ink = contrastText(palette.main);\n return { backgroundColor: gradientStops(palette).from, color: ink, iconColor: ink };\n}\n\n/** The surface for a variant, `glass` and `gradient` included. */\nexport function alertSurface(theme: UiTheme, variant: AlertVariant, palette: AlertPalette): AlertSurface {\n if (variant === 'glass') return glassSurface(theme);\n if (variant === 'gradient') return gradientSurface(palette);\n return semanticSurface(theme, palette);\n}\n","import type { TextStyle, ViewStyle } from 'react-native';\n\nimport type { AlertVariant } from './Alert.base';\nimport {\n ACTION_SLOT,\n ALERT_PADDING_UNITS,\n ALERT_RADIUS_UNITS,\n type AlertPalette,\n alertPalette,\n alertSurface,\n CLOSE_BUTTON,\n DESCRIPTION,\n GLOW,\n ICON_SLOT,\n MESSAGE_FONT_SIZE,\n MESSAGE_GAP_UNITS,\n MESSAGE_LINE_HEIGHT,\n TITLE,\n} from './Alert.metrics';\nimport { alpha } from '../../../tokens/color';\nimport { muiTypeStyle } from '../../../tokens/mui-type';\nimport type { UiTheme } from '../../../tokens/theme';\nimport type { ColorValue } from '../../../tokens/vocabulary';\n\n/**\n * THE PAINT, KEPT APART FROM THE STRUCTURE.\n *\n * `Alert.native.tsx` reads as what renders where; this file reads as\n * arithmetic — the same palette slots, alphas and px the web's\n * `Alert.styles.tsx` derives from `Alert.metrics.ts`.\n */\n\nexport interface AlertLookArgs {\n variant: AlertVariant;\n color: ColorValue | undefined;\n glow: boolean;\n pulse: boolean;\n}\n\nexport interface AlertLook {\n palette: AlertPalette;\n /** What the words are set in. */\n ink: string;\n iconColor: string;\n root: ViewStyle;\n}\n\n/**\n * The root's paint. The web keeps `overflow: hidden` (its pulse wash is\n * clipped to the card, as it is here); only the glow opens it, because a\n * view's own shadow is clipped by its own overflow on a device.\n */\nexport function alertLook(theme: UiTheme, a: AlertLookArgs): AlertLook {\n const palette = alertPalette(theme, a.color ?? a.variant);\n const surface = alertSurface(theme, a.variant, palette);\n const root: ViewStyle = {\n flexDirection: 'row',\n paddingVertical: theme.spacing(ALERT_PADDING_UNITS.vertical),\n paddingHorizontal: theme.spacing(ALERT_PADDING_UNITS.horizontal),\n borderRadius: theme.spacing(ALERT_RADIUS_UNITS),\n overflow: a.glow ? 'visible' : 'hidden',\n backgroundColor: surface.backgroundColor,\n ...(surface.borderColor ? { borderWidth: 1, borderColor: surface.borderColor } : {}),\n ...(a.glow\n ? {\n boxShadow: `0 0 ${GLOW.blur}px ${GLOW.spread}px ${alpha(palette.main, GLOW.alpha)}`,\n filter: `brightness(${GLOW.brightness})`,\n }\n : {}),\n };\n return { palette, ink: surface.color, iconColor: surface.iconColor, root };\n}\n\n/** The message column: 8px between its lines, allowed to shrink so long text wraps beside the icon. */\nexport const messageSlotStyle = (theme: UiTheme): ViewStyle => ({\n flexDirection: 'column',\n gap: theme.spacing(MESSAGE_GAP_UNITS),\n flexShrink: 1,\n minWidth: 0,\n});\n\n/** A string child: MUI's `body2` letter-spacing at 0.95rem on the message's 1.5. */\nexport const messageTextStyle = (theme: UiTheme, ink: string): TextStyle => ({\n ...muiTypeStyle(theme, 'body2', MESSAGE_FONT_SIZE),\n lineHeight: MESSAGE_FONT_SIZE * MESSAGE_LINE_HEIGHT,\n color: ink,\n});\n\n/** MUI's `AlertTitle` (a `body1` Typography) at 1.05rem and 600, lifted 2px, 4px above a description. */\nexport const titleStyle = (theme: UiTheme, ink: string, hasDescription: boolean): TextStyle => ({\n ...muiTypeStyle(theme, 'body1', TITLE.fontSize),\n fontWeight: `${TITLE.fontWeight}`,\n color: ink,\n marginTop: TITLE.marginTop,\n marginBottom: hasDescription ? theme.spacing(TITLE.marginBottomUnits) : 0,\n});\n\n/** The description: 0.925rem on the message's 1.5, faded to 0.9. */\nexport const descriptionStyle = (theme: UiTheme, ink: string): TextStyle => ({\n ...muiTypeStyle(theme, 'body2', DESCRIPTION.fontSize),\n lineHeight: DESCRIPTION.fontSize * MESSAGE_LINE_HEIGHT,\n color: ink,\n opacity: DESCRIPTION.opacity,\n});\n\n/** MUI's `.MuiAlert-icon` with the web's overrides: first-line aligned, 14px from the words, 2px down. */\nexport const iconSlotStyle = (theme: UiTheme): ViewStyle => ({\n alignSelf: 'flex-start',\n alignItems: 'center',\n marginRight: theme.spacing(ICON_SLOT.marginRightUnits),\n paddingTop: theme.spacing(ICON_SLOT.paddingTopUnits),\n paddingBottom: ICON_SLOT.paddingBottom,\n opacity: ICON_SLOT.opacity,\n});\n\n/** MUI's `.MuiAlert-action`: top-aligned, pushed to the right edge, 16px off the text. */\nexport const actionSlotStyle = (theme: UiTheme): ViewStyle => ({\n alignItems: 'flex-start',\n paddingTop: ACTION_SLOT.paddingTop,\n paddingLeft: theme.spacing(ACTION_SLOT.paddingLeftUnits),\n marginLeft: 'auto',\n marginRight: ACTION_SLOT.marginRight,\n});\n\n/** MUI's small `IconButton` at 0.7; pressed stands in for the web's hover (full opacity, a faint wash). */\nexport const closeButtonStyle = (theme: UiTheme, pressed: boolean): ViewStyle => ({\n padding: CLOSE_BUTTON.padding,\n borderRadius: theme.radius.full,\n opacity: pressed ? 1 : CLOSE_BUTTON.opacity,\n backgroundColor: pressed ? alpha(theme.palette.action.hover, CLOSE_BUTTON.washAlpha) : 'transparent',\n});\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/components/data-display/Alert/Alert.native.tsx","../../../src/components/data-display/Alert/Alert.helpers.ts","../../../src/components/data-display/Alert/Alert.metrics.ts","../../../src/components/data-display/Alert/Alert.look.native.ts"],"sourcesContent":["import * as React from 'react';\nimport {\n Animated,\n Easing,\n type LayoutChangeEvent,\n Platform,\n Pressable,\n type Role,\n StyleSheet,\n Text as RNText,\n View,\n type ViewStyle,\n} from 'react-native';\n\nimport { resolveAlertProps, resolveAnnouncement, testIdFor, VARIANT_ICON } from './Alert.helpers';\nimport {\n actionSlotStyle,\n alertLook,\n closeButtonStyle,\n descriptionStyle,\n iconSlotStyle,\n messageSlotStyle,\n messageTextStyle,\n titleStyle,\n} from './Alert.look.native';\nimport { CLOSE_BUTTON, CLOSE_DELAY_MS, COLLAPSE_MS, FADE_IN, ICON_SLOT, ICON_SPIN, PULSE } from './Alert.metrics';\nimport type { AlertProps, AlertVariant } from './Alert.types.native';\nimport { Icon } from '../../../icons/Icon.native';\nimport { webAria } from '../../../platform/aria';\nimport { renderTextChildren } from '../../../platform/text-children';\nimport { resolveTestId, withoutTestIdProps } from '../../../platform/test-id';\nimport { useUiTheme } from '../../../provider/use-ui-theme.native';\n\ntype AnimatedStyle = Animated.WithAnimatedValue<ViewStyle>;\nconst nativeDriver = Platform.OS !== 'web';\n\n/** A 0→1 progress that starts on mount when `animate` is set, else sits at 1. */\nfunction useProgress(animate: boolean, duration: number): Animated.Value {\n const progress = React.useRef(new Animated.Value(animate ? 0 : 1)).current;\n React.useEffect(() => {\n if (!animate) return undefined;\n const timing = Animated.timing(progress, { toValue: 1, duration, easing: Easing.out(Easing.ease), useNativeDriver: nativeDriver });\n timing.start();\n return () => timing.stop();\n }, [animate, duration, progress]);\n return progress;\n}\n\n/** The web's `fadeInScale` keyframes: in from 0 opacity, 0.95 scale and 10px above, over 300ms. */\nfunction useFadeIn(animate: boolean): AnimatedStyle | undefined {\n const progress = useProgress(animate, FADE_IN.ms);\n if (!animate) return undefined;\n return {\n opacity: progress,\n transform: [\n { scale: progress.interpolate({ inputRange: [0, 1], outputRange: [FADE_IN.scale, 1] }) },\n { translateY: progress.interpolate({ inputRange: [0, 1], outputRange: [-FADE_IN.lift, 0] }) },\n ],\n };\n}\n\n/** The web's `iconRotate` keyframes: one full turn, 0.8 → 1.1 → 1, over 600ms. */\nfunction useIconSpin(animate: boolean): AnimatedStyle | undefined {\n const progress = useProgress(animate, ICON_SPIN.ms);\n if (!animate) return undefined;\n return {\n transform: [\n { rotate: progress.interpolate({ inputRange: [0, 1], outputRange: ['0deg', '360deg'] }) },\n { scale: progress.interpolate({ inputRange: [0, 0.5, 1], outputRange: [ICON_SPIN.from, ICON_SPIN.mid, 1] }) },\n ],\n };\n}\n\n/** The web's `::after` pulse: a wash of the hue over the card, fading out every two seconds, behind the words. */\nfunction Pulse({ color, radius, testID }: { color: string; radius: number; testID: string }): React.JSX.Element {\n const progress = React.useRef(new Animated.Value(0)).current;\n React.useEffect(() => {\n const loop = Animated.loop(\n Animated.timing(progress, { toValue: 1, duration: PULSE.ms, easing: Easing.linear, useNativeDriver: nativeDriver }),\n );\n loop.start();\n return () => loop.stop();\n }, [progress]);\n return (\n <Animated.View\n testID={testID}\n aria-hidden\n style={[\n StyleSheet.absoluteFill,\n {\n pointerEvents: 'none',\n borderRadius: radius,\n backgroundColor: color,\n opacity: progress.interpolate({ inputRange: [0, 0.7, 1], outputRange: [PULSE.alpha, 0, 0] }),\n },\n ]}\n />\n );\n}\n\n/**\n * MUI's `Collapse`: open, it is a plain wrapper with its overflow visible (so\n * a glow can escape); closing, it clips and shrinks over 300ms, then says so.\n */\nfunction Collapse({ open, onCollapsed, children }: { open: boolean; onCollapsed: () => void; children: React.ReactNode }): React.JSX.Element {\n const [height, setHeight] = React.useState<number | null>(null);\n const progress = React.useRef(new Animated.Value(1)).current;\n React.useEffect(() => {\n if (open) return undefined;\n const timing = Animated.timing(progress, { toValue: 0, duration: COLLAPSE_MS, easing: Easing.inOut(Easing.ease), useNativeDriver: false });\n timing.start(({ finished }) => {\n if (finished) onCollapsed();\n });\n return () => timing.stop();\n }, [open, onCollapsed, progress]);\n const onLayout = (event: LayoutChangeEvent): void => {\n if (open) setHeight(event.nativeEvent.layout.height);\n };\n const shrink: AnimatedStyle = height == null ? {} : { maxHeight: progress.interpolate({ inputRange: [0, 1], outputRange: [0, height] }) };\n return (\n <Animated.View style={[{ overflow: open ? 'visible' : 'hidden', opacity: progress }, shrink]}>\n <View onLayout={onLayout}>{children}</View>\n </Animated.View>\n );\n}\n\ninterface IconSlotProps {\n variant: AlertVariant;\n icon: React.ReactNode;\n color: string;\n animate: boolean;\n testID: string;\n}\n\n/** The icon slot; `glass` and `gradient` have no glyph of their own, so theirs is empty unless an `icon` is given — as on the web. */\nfunction IconSlot({ variant, icon, color, animate, testID }: IconSlotProps): React.JSX.Element {\n const theme = useUiTheme();\n const spin = useIconSpin(animate);\n const glyph = VARIANT_ICON[variant];\n return (\n <Animated.View testID={testID} style={[iconSlotStyle(theme), spin]}>\n {icon || (glyph ? <Icon name={glyph} size={ICON_SLOT.size} color={color} /> : null)}\n </Animated.View>\n );\n}\n\nfunction CloseButton({ label, ink, onPress, testID }: { label: string | undefined; ink: string; onPress: () => void; testID: string }): React.JSX.Element {\n const theme = useUiTheme();\n return (\n <Pressable role=\"button\" aria-label={label} testID={testID} onPress={onPress} style={({ pressed }) => closeButtonStyle(theme, pressed)}>\n <Icon name=\"Close\" size={CLOSE_BUTTON.iconSize} color={ink} />\n </Pressable>\n );\n}\n\ninterface ContentProps {\n title?: string;\n description?: string;\n children?: React.ReactNode;\n ink: string;\n testId: string;\n}\n\nfunction AlertContent({ title, description, children, ink, testId }: ContentProps): React.JSX.Element {\n const theme = useUiTheme();\n return (\n <View style={messageSlotStyle(theme)}>\n {title ? (\n <RNText testID={testIdFor(testId, 'title')} style={titleStyle(theme, ink, Boolean(description))}>\n {title}\n </RNText>\n ) : null}\n {description ? (\n <RNText testID={testIdFor(testId, 'message')} style={descriptionStyle(theme, ink)}>\n {description}\n </RNText>\n ) : null}\n {renderTextChildren(children, messageTextStyle(theme, ink))}\n </View>\n );\n}\n\n/** The dismiss sequence the web runs: mark closing, fire `onClose` 200ms in, stay until the collapse has run. */\nfunction useDismiss(onClose: (() => void) | undefined): { open: boolean; gone: boolean; close: () => void; onCollapsed: () => void } {\n const [closing, setClosing] = React.useState(false);\n const [gone, setGone] = React.useState(false);\n const timer = React.useRef<ReturnType<typeof setTimeout> | null>(null);\n React.useEffect(() => () => {\n if (timer.current) clearTimeout(timer.current);\n }, []);\n const close = (): void => {\n setClosing(true);\n timer.current = setTimeout(() => onClose?.(), CLOSE_DELAY_MS);\n };\n const onCollapsed = React.useCallback(() => setGone(true), []);\n return { open: !closing, gone, close, onCollapsed };\n}\n\nexport const Alert = React.forwardRef<View, AlertProps>((alertProps, ref) => {\n const {\n variant, color, glow, pulse, icon, showIcon, onClose, title, description, children, animate,\n // `role`, `announce` and `aria-live` all leave here and are resolved\n // TOGETHER below, off `alertProps` — see `resolveAnnouncement`.\n role: _role, announce: _announce,\n 'aria-atomic': ariaAtomic, 'aria-live': _ariaLive, closable, closeLabel, style, ...others\n } = resolveAlertProps(alertProps);\n const theme = useUiTheme();\n const testId = resolveTestId(others, 'alert') as string;\n const rest = withoutTestIdProps(others);\n const look = alertLook(theme, { variant, color, glow, pulse });\n const fadeIn = useFadeIn(animate);\n const dismiss = useDismiss(onClose);\n const announcement = resolveAnnouncement(alertProps, variant);\n\n if (dismiss.gone) return null;\n return (\n <Collapse open={dismiss.open} onCollapsed={dismiss.onCollapsed}>\n <Animated.View\n ref={ref}\n role={announcement.role as Role}\n aria-live={announcement['aria-live']}\n {...webAria({ 'aria-atomic': ariaAtomic })}\n tabIndex={0}\n testID={testId}\n style={[look.root, fadeIn, style]}\n {...rest}\n >\n {pulse ? <Pulse color={look.palette.main} radius={look.root.borderRadius as number} testID={testIdFor(testId, 'pulse')} /> : null}\n {showIcon ? <IconSlot variant={variant} icon={icon} color={look.iconColor} animate={animate} testID={testIdFor(testId, 'icon')} /> : null}\n <AlertContent title={title} description={description} ink={look.ink} testId={testId}>\n {children}\n </AlertContent>\n {closable ? (\n <View style={actionSlotStyle(theme)}>\n <CloseButton label={closeLabel} ink={look.ink} onPress={dismiss.close} testID={testIdFor(testId, 'close')} />\n </View>\n ) : null}\n </Animated.View>\n </Collapse>\n );\n});\n\nAlert.displayName = 'Alert';\n","import type { AlertBaseFields, AlertVariant } from './Alert.base';\nimport type { IconName } from '../../../icons/Icon.types';\n\ntype AlertDefaultedKeys = 'variant' | 'glow' | 'pulse' | 'showIcon' | 'animate' | 'role' | 'aria-atomic';\n\nexport const ALERT_DEFAULTS: Required<Pick<AlertBaseFields, AlertDefaultedKeys>> & { closable: false } = {\n variant: 'info',\n glow: false,\n pulse: false,\n showIcon: true,\n closable: false,\n animate: true,\n role: 'alert',\n 'aria-atomic': 'true',\n};\n\n/**\n * Generic over the renderer's own props: the web and the native `Alert` pass\n * different extras through, and both come back out untouched.\n */\nexport type ResolvedAlertProps<P extends AlertBaseFields> = P &\n Required<Pick<AlertBaseFields, AlertDefaultedKeys>>;\n\n// Strips explicitly-undefined props before the merge so `prop={undefined}` still\n// falls back to the default, the way a destructuring default would.\nconst definedProps = <P extends AlertBaseFields>(props: P): Partial<P> =>\n Object.fromEntries(\n Object.entries(props).filter(([, value]) => value !== undefined),\n ) as Partial<P>;\n\n// Through `unknown`: `closable: false` in the defaults belongs to the dismiss\n// union rather than to `AlertBaseFields`, so TypeScript cannot see the merge as\n// comparable to `P` although every field of `P` survives it untouched.\nexport const resolveAlertProps = <P extends AlertBaseFields>(props: P): ResolvedAlertProps<P> =>\n ({ ...ALERT_DEFAULTS, ...definedProps(props) }) as unknown as ResolvedAlertProps<P>;\n\n/** `danger` announces itself; everything else waits its turn. */\nexport const defaultAriaLive = (variant: AlertVariant): 'polite' | 'assertive' =>\n variant === 'danger' ? 'assertive' : 'polite';\n\n/**\n * The ARIA role each `announce` level is spelled with.\n *\n * Both roles carry an IMPLICIT live setting, and that implicit one is what\n * assistive tech acts on — `alert` is assertive, `status` is polite. Pairing\n * them here is what stops `role` and `aria-live` from contradicting each\n * other, which they do by default: every alert is `role=\"alert\"` regardless of\n * variant, so an `info` alert asks to be polite in one attribute and to\n * interrupt in the other.\n */\nexport const ANNOUNCE_ROLE: Record<NonNullable<AlertBaseFields['announce']>, string> = {\n assertive: 'alert',\n polite: 'status',\n};\n\n/**\n * The two attributes that decide whether an alert interrupts, resolved TOGETHER.\n *\n * Both renderers therefore let `role` and `announce` leave their destructure\n * unused (`_role`, `_announce`) and call this instead — the first because the\n * defaults have already answered it, the second because it must never reach\n * the DOM.\n *\n * Reads the caller's own props rather than the defaulted ones, because the\n * whole question is which of them the caller actually spelled:\n * {@link ALERT_DEFAULTS} supplies `role: 'alert'` for everything, so after the\n * merge there is no longer any difference between an alert that asked to\n * interrupt and one that never mentioned it.\n *\n * Precedence, most specific first — an explicit `role` or `aria-live` beats\n * `announce`, so a call site that already spells either by hand is untouched:\n *\n * 1. `role` / `aria-live` as given;\n * 2. {@link AlertBaseFields.announce}, which supplies both;\n * 3. today's behaviour — `ALERT_DEFAULTS.role` and {@link defaultAriaLive}.\n *\n * With none of the three named, the result is byte-for-byte what it was before\n * `announce` existed.\n */\nexport const resolveAnnouncement = (\n props: Pick<AlertBaseFields, 'announce' | 'role' | 'aria-live'>,\n variant: AlertVariant,\n): { role: string; 'aria-live': 'polite' | 'assertive' | 'off' } => {\n const announce = props.announce;\n return {\n role: props.role ?? (announce === undefined ? ALERT_DEFAULTS.role : ANNOUNCE_ROLE[announce]),\n 'aria-live': props['aria-live'] ?? announce ?? defaultAriaLive(variant),\n };\n};\n\nexport const testIdFor = (base: string | undefined, suffix: string): string =>\n base ? `${base}-${suffix}` : `alert-${suffix}`;\n\n/**\n * The glyph each semantic variant carries, by the shared icon set's name.\n * `glass` and `gradient` carry none of their own: the web renders an empty\n * icon slot for them unless the caller passes an `icon`, and so does native.\n */\nexport const VARIANT_ICON: Partial<Record<AlertVariant, IconName>> = {\n info: 'Info',\n success: 'CheckCircle',\n warning: 'Warning',\n danger: 'Error',\n};\n","import type { AlertVariant } from './Alert.base';\nimport { alpha, darken, lighten } from '../../../tokens/color';\nimport { NEUTRAL_RAMP } from '../../../tokens/ink.core';\nimport { contrastText, type UiGreyStep, type UiTheme } from '../../../tokens/theme';\n\n/**\n * THE NUMBERS BOTH `Alert` RENDERERS DRAW WITH.\n *\n * `Alert.styles.tsx` / `Alert.tsx` (MUI) and `Alert.native.tsx` (React\n * Native) read this one table. Spacing is in SPACING UNITS where the web\n * writes `theme.spacing(n)`; durations are ms (the web turns them into `s`\n * through {@link seconds} so its emitted CSS is byte-for-byte what it was);\n * everything else is px, a ratio or an alpha. The hover, active and focus\n * numbers are here too although only the DOM can honour them — a number the\n * web draws with belongs in the table whether or not native can reach it.\n */\n\n/** The root: 12px corners, 14px 16px of padding, one 300ms curve for everything. */\nexport const ALERT_RADIUS_UNITS = 1.5;\nexport const ALERT_PADDING_UNITS = { vertical: 1.75, horizontal: 2 } as const;\nexport const ALERT_TRANSITION_MS = 300;\nexport const ALERT_EASING = 'cubic-bezier(0.4, 0, 0.2, 1)';\n\n/** Mount: the web's `fadeInScale` keyframes and the icon's `iconRotate`. */\nexport const FADE_IN = { ms: 300, scale: 0.95, lift: 10 } as const;\nexport const ICON_SPIN = { ms: 600, from: 0.8, mid: 1.1 } as const;\n/** Dismiss: MUI `Collapse` runs 300ms; `onClose` fires 200ms in. */\nexport const COLLAPSE_MS = 300;\nexport const CLOSE_DELAY_MS = 200;\n\n/** The message column: 8px between title, description and children; 0.95rem body on 1.5. */\nexport const MESSAGE_GAP_UNITS = 1;\nexport const MESSAGE_FONT_SIZE = 15.2;\nexport const MESSAGE_LINE_HEIGHT = 1.5;\n/** A control inside the message gets an edge: 4px above, a hairline at 0.45 of the hue. */\nexport const MESSAGE_BUTTON = { marginTopUnits: 0.5, borderAlpha: 0.45 } as const;\n\n/** The title: 1.05rem at 600; MUI's `AlertTitle` lifts it 2px; 4px below it when a description follows. */\nexport const TITLE = { fontSize: 16.8, fontWeight: 600, marginTop: -2, marginBottomUnits: 0.5 } as const;\n/** The description: 0.925rem, slightly faded. */\nexport const DESCRIPTION = { fontSize: 14.8, opacity: 0.9 } as const;\n\n/** The icon on the title's line (`iconPlacement: 'title'`): 10px from the title. */\nexport const TITLE_ICON = { gapUnits: 1.25 } as const;\n/** The icon slot: MUI's 22px glyph at 0.9, 14px from the words, 2px down (MUI's 7px stays below). */\nexport const ICON_SLOT = { size: 22, opacity: 0.9, marginRightUnits: 1.75, paddingTopUnits: 0.25, paddingBottom: 7 } as const;\n/** The action slot: MUI's `4px 0 0 16px` with the 16px ours, pushed right, 8px into the padding. */\nexport const ACTION_SLOT = { paddingLeftUnits: 2, paddingTop: 4, marginRight: -8 } as const;\n/** The close button: MUI's small `IconButton` (5px padding, 18px glyph) at 0.7. */\nexport const CLOSE_BUTTON = { padding: 5, iconSize: 18, opacity: 0.7, washAlpha: 0.1 } as const;\n\n/**\n * A semantic Alert's surface and ink: an OPAQUE tint of the hue with a dark\n * ink of the same hue — MUI's own `standard` recipe, at its ratios. See\n * `semanticSurface` in `Alert.styles.tsx` for why not `alpha(main, 0.1)`.\n */\nexport const SEMANTIC_SURFACE = { tint: { light: 0.9, dark: 0.8 }, ink: 0.6, borderAlpha: 0.35 } as const;\n/** `glass`: 85% paper under a 20px blur, a 0.4 divider hairline. */\nexport const GLASS = { backgroundAlpha: 0.85, borderAlpha: 0.4, blur: 20, saturatePercent: 180 } as const;\n/**\n * `gradient`: light→dark at 0.9 along 135°, a 0.2 white shimmer sweeping 1000px every 3s.\n *\n * It carries no hover of its own, and that is load-bearing rather than an\n * omission. `alertVariantStyles` is spread AFTER the root's `'&:hover'` in the\n * same object literal, so a second `'&:hover'` key does not merge with it — it\n * REPLACES it. While this variant had one, `gradient` was the only alert that\n * brightened on hover while every other variant darkened, and the only one to\n * lose the shimmer reveal the root's hover performs.\n */\nexport const GRADIENT = {\n angleDeg: 135,\n stopAlpha: 0.9,\n shimmerAlpha: 0.2,\n shimmerMs: 3000,\n shimmerTravel: 1000,\n} as const;\n\n/** Emphasis: the glow's shadow and brightness, the pulse's wash. */\nexport const GLOW = { blur: 20, spread: 5, alpha: 0.3, brightness: 1.05 } as const;\nexport const PULSE = { alpha: 0.2, ms: 2000, spread: 10 } as const;\n\n/**\n * Pointer states — DOM only, kept so the web derives them.\n *\n * HOVER and ACTIVE carry NO geometry, and that is the point rather than an\n * omission. They used to lift the card 3px, scale it 1.01, grow a 20px shadow\n * and spin the icon 10deg at 1.15 — four things moving at once on a surface\n * that is not a control, which made a page of alerts twitch under the pointer.\n *\n * Both are a TINT now: a flat inset layer over the surface. Two mechanisms\n * came before it and each failed on a case the next had to fix. Dropping the\n * element's `opacity` composites toward the PAGE, so it inverted the hover on\n * a light tint (L* 95.0 idle, 89.1 hovered, 91.1 pressed) and vanished on a\n * dark one. A `filter: brightness()` fixed the direction but is MULTIPLICATIVE,\n * so it moved a near-black `glass` by four counts (ΔE76 1.71, under the JND)\n * and Banner's 10%-alpha wash by ΔE76 0.44. A layer is additive: it reads the\n * same on an opaque tint, a translucent wash and a gradient, and because it\n * paints above the background and below the content the ink keeps its own\n * contrast.\n */\nexport const HOVER = { tintAlpha: 0.06 } as const;\n\n/**\n * The press: a 20% tint LAYER, eased back fast.\n *\n * The layer is the point. The first attempt dropped the whole element's\n * opacity, which composites toward the PAGE and so behaves differently on\n * every surface it is asked about. Measured: over a light page it made a light\n * tint LIGHTER (L* 95.0 idle, 89.1 hovered, 91.1 pressed), so pushing the\n * surface looked like the pointer leaving; over a dark page it landed back on\n * the idle surface (ΔE76 0.82 on `glass`); on `gradient` it washed white body\n * copy to 2.31:1, under AA; and it diluted the ink during a text-selection\n * drag. A `brightness()` step instead of it fixed the direction but not the\n * reach — a multiplier does nothing to a near-black `glass` in dark mode\n * (ΔE76 1.71) and nothing to Banner's 10%-alpha wash (ΔE76 0.44), because it\n * scales only what the element already paints.\n *\n * An inset shadow at 100vmax is a flat tint over the whole surface: ADDITIVE,\n * so it reads the same on an opaque tint, a translucent wash and a gradient;\n * painted above the background and below the content, so the ink keeps its\n * own contrast; and animatable, which `background-image` is not.\n *\n * `ms` is 250 and not the 1000 first asked for, and the reason is that ONE\n * property carries both states. CSS runs a transition from the DESTINATION\n * state's declaration, and entering hover and releasing a press share that\n * destination — so they cannot have different durations without a second\n * animatable property, and both free pseudo-elements are already spent on the\n * `gradient` shimmer and the `pulse` wash. At 1000ms the hover inherited the\n * second: crossing an alert in 300ms peaked at a ≈ 0.024, under the JND, and\n * for ~360ms the alert you had just LEFT was darker than the one under the\n * pointer. A fast press-return is the smaller loss, and it is the call the\n * product owner made when shown both.\n */\nexport const ACTIVE = { tintAlpha: 0.2, ms: 250 } as const;\n\nexport const FOCUS = { ringWidth: 2, ringAlpha: 1, offset: 2 } as const;\n\n/** `neutral` has no palette slot; the web has always drawn it from three greys. */\nexport const NEUTRAL_GREY: Record<'main' | 'light' | 'dark', UiGreyStep> = { main: 500, light: 300, dark: 700 };\n\n/** A duration as the CSS the web has always emitted: `2000` → `2s`, `300` → `0.3s`. */\nexport const seconds = (ms: number): string => `${ms / 1000}s`;\n\n/** The palette shape the web's `getColorFromTheme` returns — a main plus optional shades. */\nexport interface AlertPalette {\n main: string;\n light?: string;\n dark?: string;\n}\n\n/**\n * The renderer-free twin of the web's `getColorFromTheme`: a variant or\n * colour name to its palette, `neutral` from the greys, anything unknown\n * (`glass`, `gradient`) to `info`.\n */\nexport function alertPalette(theme: UiTheme, key: string | undefined): AlertPalette {\n switch (key) {\n case 'info':\n case 'success':\n case 'warning':\n case 'danger':\n case 'primary':\n case 'secondary':\n return theme.palette[key];\n case 'neutral':\n return {\n main: NEUTRAL_RAMP[NEUTRAL_GREY.main],\n light: NEUTRAL_RAMP[NEUTRAL_GREY.light],\n dark: NEUTRAL_RAMP[NEUTRAL_GREY.dark],\n };\n default:\n return theme.palette.info;\n }\n}\n\n/** What a variant paints: its fill, its ink, its hairline if any, and the colour of its glyph. */\nexport interface AlertSurface {\n backgroundColor: string;\n color: string;\n borderColor?: string;\n iconColor: string;\n}\n\nexport const SEMANTIC_VARIANTS: ReadonlySet<AlertVariant> = new Set(['info', 'success', 'warning', 'danger']);\n\n/** The opaque tint and same-hue ink, inverted for dark mode; the hairline keeps its alpha. */\nexport function semanticSurface(theme: UiTheme, palette: AlertPalette): AlertSurface {\n const dark = theme.mode === 'dark';\n return {\n backgroundColor: dark\n ? darken(palette.main, SEMANTIC_SURFACE.tint.dark)\n : lighten(palette.main, SEMANTIC_SURFACE.tint.light),\n color: dark ? lighten(palette.main, SEMANTIC_SURFACE.ink) : darken(palette.main, SEMANTIC_SURFACE.ink),\n borderColor: alpha(palette.main, SEMANTIC_SURFACE.borderAlpha),\n iconColor: palette.main,\n };\n}\n\nexport function glassSurface(theme: UiTheme): AlertSurface {\n return {\n backgroundColor: alpha(theme.palette.background.paper, GLASS.backgroundAlpha),\n color: theme.palette.text.primary,\n borderColor: alpha(theme.palette.divider, GLASS.borderAlpha),\n iconColor: theme.palette.primary.main,\n };\n}\n\n/** The gradient's two stops; a renderer with no gradient fill paints `from`. */\nexport function gradientStops(palette: AlertPalette): { from: string; to: string } {\n return {\n from: alpha(palette.light || palette.main, GRADIENT.stopAlpha),\n to: alpha(palette.dark || palette.main, GRADIENT.stopAlpha),\n };\n}\n\nexport function gradientSurface(palette: AlertPalette): AlertSurface {\n const ink = contrastText(palette.main);\n return { backgroundColor: gradientStops(palette).from, color: ink, iconColor: ink };\n}\n\n/** The surface for a variant, `glass` and `gradient` included. */\nexport function alertSurface(theme: UiTheme, variant: AlertVariant, palette: AlertPalette): AlertSurface {\n if (variant === 'glass') return glassSurface(theme);\n if (variant === 'gradient') return gradientSurface(palette);\n return semanticSurface(theme, palette);\n}\n","import type { TextStyle, ViewStyle } from 'react-native';\n\nimport type { AlertVariant } from './Alert.base';\nimport {\n ACTION_SLOT,\n ALERT_PADDING_UNITS,\n ALERT_RADIUS_UNITS,\n type AlertPalette,\n alertPalette,\n alertSurface,\n CLOSE_BUTTON,\n DESCRIPTION,\n GLOW,\n ICON_SLOT,\n MESSAGE_FONT_SIZE,\n MESSAGE_GAP_UNITS,\n MESSAGE_LINE_HEIGHT,\n TITLE,\n} from './Alert.metrics';\nimport { alpha } from '../../../tokens/color';\nimport { muiTypeStyle } from '../../../tokens/mui-type';\nimport type { UiTheme } from '../../../tokens/theme';\nimport type { ColorValue } from '../../../tokens/vocabulary';\n\n/**\n * THE PAINT, KEPT APART FROM THE STRUCTURE.\n *\n * `Alert.native.tsx` reads as what renders where; this file reads as\n * arithmetic — the same palette slots, alphas and px the web's\n * `Alert.styles.tsx` derives from `Alert.metrics.ts`.\n */\n\nexport interface AlertLookArgs {\n variant: AlertVariant;\n color: ColorValue | undefined;\n glow: boolean;\n pulse: boolean;\n}\n\nexport interface AlertLook {\n palette: AlertPalette;\n /** What the words are set in. */\n ink: string;\n iconColor: string;\n root: ViewStyle;\n}\n\n/**\n * The root's paint. The web keeps `overflow: hidden` (its pulse wash is\n * clipped to the card, as it is here); only the glow opens it, because a\n * view's own shadow is clipped by its own overflow on a device.\n */\nexport function alertLook(theme: UiTheme, a: AlertLookArgs): AlertLook {\n const palette = alertPalette(theme, a.color ?? a.variant);\n const surface = alertSurface(theme, a.variant, palette);\n const root: ViewStyle = {\n flexDirection: 'row',\n paddingVertical: theme.spacing(ALERT_PADDING_UNITS.vertical),\n paddingHorizontal: theme.spacing(ALERT_PADDING_UNITS.horizontal),\n borderRadius: theme.spacing(ALERT_RADIUS_UNITS),\n overflow: a.glow ? 'visible' : 'hidden',\n backgroundColor: surface.backgroundColor,\n ...(surface.borderColor ? { borderWidth: 1, borderColor: surface.borderColor } : {}),\n ...(a.glow\n ? {\n boxShadow: `0 0 ${GLOW.blur}px ${GLOW.spread}px ${alpha(palette.main, GLOW.alpha)}`,\n filter: `brightness(${GLOW.brightness})`,\n }\n : {}),\n };\n return { palette, ink: surface.color, iconColor: surface.iconColor, root };\n}\n\n/** The message column: 8px between its lines, allowed to shrink so long text wraps beside the icon. */\nexport const messageSlotStyle = (theme: UiTheme): ViewStyle => ({\n flexDirection: 'column',\n gap: theme.spacing(MESSAGE_GAP_UNITS),\n flexShrink: 1,\n minWidth: 0,\n});\n\n/** A string child: MUI's `body2` letter-spacing at 0.95rem on the message's 1.5. */\nexport const messageTextStyle = (theme: UiTheme, ink: string): TextStyle => ({\n ...muiTypeStyle(theme, 'body2', MESSAGE_FONT_SIZE),\n lineHeight: MESSAGE_FONT_SIZE * MESSAGE_LINE_HEIGHT,\n color: ink,\n});\n\n/** MUI's `AlertTitle` (a `body1` Typography) at 1.05rem and 600, lifted 2px, 4px above a description. */\nexport const titleStyle = (theme: UiTheme, ink: string, hasDescription: boolean): TextStyle => ({\n ...muiTypeStyle(theme, 'body1', TITLE.fontSize),\n fontWeight: `${TITLE.fontWeight}`,\n color: ink,\n marginTop: TITLE.marginTop,\n marginBottom: hasDescription ? theme.spacing(TITLE.marginBottomUnits) : 0,\n});\n\n/** The description: 0.925rem on the message's 1.5, faded to 0.9. */\nexport const descriptionStyle = (theme: UiTheme, ink: string): TextStyle => ({\n ...muiTypeStyle(theme, 'body2', DESCRIPTION.fontSize),\n lineHeight: DESCRIPTION.fontSize * MESSAGE_LINE_HEIGHT,\n color: ink,\n opacity: DESCRIPTION.opacity,\n});\n\n/** MUI's `.MuiAlert-icon` with the web's overrides: first-line aligned, 14px from the words, 2px down. */\nexport const iconSlotStyle = (theme: UiTheme): ViewStyle => ({\n alignSelf: 'flex-start',\n alignItems: 'center',\n marginRight: theme.spacing(ICON_SLOT.marginRightUnits),\n paddingTop: theme.spacing(ICON_SLOT.paddingTopUnits),\n paddingBottom: ICON_SLOT.paddingBottom,\n opacity: ICON_SLOT.opacity,\n});\n\n/** MUI's `.MuiAlert-action`: top-aligned, pushed to the right edge, 16px off the text. */\nexport const actionSlotStyle = (theme: UiTheme): ViewStyle => ({\n alignItems: 'flex-start',\n paddingTop: ACTION_SLOT.paddingTop,\n paddingLeft: theme.spacing(ACTION_SLOT.paddingLeftUnits),\n marginLeft: 'auto',\n marginRight: ACTION_SLOT.marginRight,\n});\n\n/** MUI's small `IconButton` at 0.7; pressed stands in for the web's hover (full opacity, a faint wash). */\nexport const closeButtonStyle = (theme: UiTheme, pressed: boolean): ViewStyle => ({\n padding: CLOSE_BUTTON.padding,\n borderRadius: theme.radius.full,\n opacity: pressed ? 1 : CLOSE_BUTTON.opacity,\n backgroundColor: pressed ? alpha(theme.palette.action.hover, CLOSE_BUTTON.washAlpha) : 'transparent',\n});\n"],"mappings":"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","names":[]}
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ import type { AlertProps } from './Alert.types';
3
+ /**
4
+ * The message column: title, description, then whatever the caller put inside.
5
+ *
6
+ * `titleIcon` is the icon when it sits on the title's line
7
+ * (`iconPlacement: 'title'`, see `Alert.placement.ts`). The title then shares
8
+ * a row with it, and the description below is a sibling of that row — so it
9
+ * starts at the column's own edge rather than under the title's first letter.
10
+ */
11
+ export declare const AlertContent: React.FC<{
12
+ title?: AlertProps['title'];
13
+ description?: AlertProps['description'];
14
+ titleIcon?: React.ReactNode;
15
+ dataTestId?: string;
16
+ children?: React.ReactNode;
17
+ }>;
18
+ //# sourceMappingURL=Alert.content.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Alert.content.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/Alert/Alert.content.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAQhD;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC;IAClC,KAAK,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;IAC5B,WAAW,CAAC,EAAE,UAAU,CAAC,aAAa,CAAC,CAAC;IACxC,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B,CAgDA,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Alert.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/Alert/Alert.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,MAAM,OAAO,CAAC;AA4R1B,eAAO,MAAM,KAAK;;;;;;;;iDA+EhB,CAAC;AAEH;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gBAAgB,qCAAsC,CAAC"}
1
+ {"version":3,"file":"Alert.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/Alert/Alert.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,MAAM,OAAO,CAAC;AA4Q1B,eAAO,MAAM,KAAK;;;;;;;;iDA4EhB,CAAC;AAEH;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gBAAgB,qCAAsC,CAAC"}
@@ -54,6 +54,10 @@ export declare const DESCRIPTION: {
54
54
  readonly fontSize: 14.8;
55
55
  readonly opacity: 0.9;
56
56
  };
57
+ /** The icon on the title's line (`iconPlacement: 'title'`): 10px from the title. */
58
+ export declare const TITLE_ICON: {
59
+ readonly gapUnits: 1.25;
60
+ };
57
61
  /** The icon slot: MUI's 22px glyph at 0.9, 14px from the words, 2px down (MUI's 7px stays below). */
58
62
  export declare const ICON_SLOT: {
59
63
  readonly size: 22;
@@ -1 +1 @@
1
- {"version":3,"file":"Alert.metrics.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/Alert/Alert.metrics.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Alert.metrics.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/Alert/Alert.metrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAGjD,OAAO,EAAgB,KAAK,UAAU,EAAE,KAAK,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEpF;;;;;;;;;;GAUG;AAEH,oFAAoF;AACpF,eAAO,MAAM,kBAAkB,MAAM,CAAC;AACtC,eAAO,MAAM,mBAAmB;;;CAA6C,CAAC;AAC9E,eAAO,MAAM,mBAAmB,MAAM,CAAC;AACvC,eAAO,MAAM,YAAY,iCAAiC,CAAC;AAE3D,4EAA4E;AAC5E,eAAO,MAAM,OAAO;;;;CAA8C,CAAC;AACnE,eAAO,MAAM,SAAS;;;;CAA4C,CAAC;AACnE,oEAAoE;AACpE,eAAO,MAAM,WAAW,MAAM,CAAC;AAC/B,eAAO,MAAM,cAAc,MAAM,CAAC;AAElC,4FAA4F;AAC5F,eAAO,MAAM,iBAAiB,IAAI,CAAC;AACnC,eAAO,MAAM,iBAAiB,OAAO,CAAC;AACtC,eAAO,MAAM,mBAAmB,MAAM,CAAC;AACvC,2FAA2F;AAC3F,eAAO,MAAM,cAAc;;;CAAsD,CAAC;AAElF,2GAA2G;AAC3G,eAAO,MAAM,KAAK;;;;;CAAsF,CAAC;AACzG,iDAAiD;AACjD,eAAO,MAAM,WAAW;;;CAA4C,CAAC;AAErE,oFAAoF;AACpF,eAAO,MAAM,UAAU;;CAA8B,CAAC;AACtD,qGAAqG;AACrG,eAAO,MAAM,SAAS;;;;;;CAAuG,CAAC;AAC9H,oGAAoG;AACpG,eAAO,MAAM,WAAW;;;;CAAmE,CAAC;AAC5F,mFAAmF;AACnF,eAAO,MAAM,YAAY;;;;;CAAsE,CAAC;AAEhG;;;;GAIG;AACH,eAAO,MAAM,gBAAgB;;;;;;;CAA4E,CAAC;AAC1G,oEAAoE;AACpE,eAAO,MAAM,KAAK;;;;;CAAuF,CAAC;AAC1G;;;;;;;;;GASG;AACH,eAAO,MAAM,QAAQ;;;;;;CAMX,CAAC;AAEX,oEAAoE;AACpE,eAAO,MAAM,IAAI;;;;;CAAiE,CAAC;AACnF,eAAO,MAAM,KAAK;;;;CAAgD,CAAC;AAEnE;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,KAAK;;CAA+B,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,eAAO,MAAM,MAAM;;;CAAuC,CAAC;AAE3D,eAAO,MAAM,KAAK;;;;CAAqD,CAAC;AAExE,mFAAmF;AACnF,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,UAAU,CAAwC,CAAC;AAEhH,uFAAuF;AACvF,eAAO,MAAM,OAAO,GAAI,IAAI,MAAM,KAAG,MAAyB,CAAC;AAE/D,6FAA6F;AAC7F,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,YAAY,CAkBlF;AAED,kGAAkG;AAClG,MAAM,WAAW,YAAY;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,YAAY,CAAqD,CAAC;AAE9G,8FAA8F;AAC9F,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,GAAG,YAAY,CAUnF;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,CAOzD;AAED,gFAAgF;AAChF,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAKjF;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,YAAY,CAGnE;AAED,kEAAkE;AAClE,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,GAAG,YAAY,CAIvG"}