@xsolla/xui-b2b-notification-panel 0.197.0 → 0.198.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.
package/README.md CHANGED
@@ -50,7 +50,7 @@ import { NotificationPanel } from '@xsolla/xui-b2b-notification-panel';
50
50
  | `title` | `string` | — | Bold title text. |
51
51
  | `description` | `string` | — | Secondary description text. |
52
52
  | `showIcon` | `boolean` | `true` | Show or hide the icon (the icon frame for `notification`, the inline icon for `announcement`). |
53
- | `icon` | `ReactNode` | — | Custom icon to replace the default type icon. |
53
+ | `icon` | `ReactNode` | — | Custom icon to replace the default type icon. Rendered as authored — the panel does not recolour it. |
54
54
  | `actionButton` | `ActionButtonElement` | — | A `Button`, `IconButton`, or `FlexButton` element. The panel injects styling via `cloneElement` (see below). |
55
55
  | `showCloseButton` | `boolean` | `true` | Show or hide the dismiss (×) button. |
56
56
  | `onClose` | `() => void` | — | Called when the close button is pressed. |
@@ -72,6 +72,23 @@ The element passed to `actionButton`. The panel overrides a small set of props v
72
72
  - **`FlexButton` / `Button`** — `size="xs"`, `variant="primary"`, `background={false}` (text-only XS action per Figma). Prefer [`FlexButton`](./button.md).
73
73
  - **`IconButton`** — `size="xs"` only.
74
74
 
75
+ ## Icon colour
76
+
77
+ The default type icon takes its colour from the surface it sits on, not from the `type` alone.
78
+
79
+ | Surface | Icon background | Glyph token |
80
+ | --- | --- | --- |
81
+ | Desktop `notification` frame — `warning`, `success` | `background.warning.primary` / `background.success.primary` — a solid light fill, the **same value in light and dark** | `content.static.dark` |
82
+ | Desktop `notification` frame — `alert`, `neutral`, `brand` | `overlay.*` over the panel background — follows the theme | `content.primary` |
83
+ | Mobile `notification` icon column | the panel background (no frame) | `content.primary` |
84
+ | `announcement`, both devices | `background.*.secondary` | `content.primary` |
85
+
86
+ `content.static.dark` is theme-independent (`#000000` in every theme). It is required on the two filled frames because `content.primary` resolves to a near-white `#e8eced` in dark mode, which washes the glyph out against the light fill. Do not normalise these back to `content.primary` in a token sweep, and do not apply `content.static.dark` to the other rows — those surfaces are dark in dark mode, so it would be the inverse regression.
87
+
88
+ A custom `icon` is rendered exactly as authored; the panel does not recolour it.
89
+
90
+ See the **Icon frame contrast — both themes** story for a side-by-side check.
91
+
75
92
  ## Examples
76
93
 
77
94
  ### All types
@@ -200,9 +217,23 @@ import { NotificationPanel } from '@xsolla/xui-b2b-notification-panel';
200
217
  />;
201
218
  ```
202
219
 
220
+ ### Checking both themes at once
221
+
222
+ `themeMode` overrides the theme per instance — no nested provider needed. Useful when reviewing the filled icon frame.
223
+
224
+ ```tsx
225
+ import { NotificationPanel } from '@xsolla/xui-b2b-notification-panel';
226
+
227
+ <>
228
+ <NotificationPanel themeMode="light" type="warning" title="Warning — light" />
229
+ <NotificationPanel themeMode="dark" type="warning" title="Warning — dark" />
230
+ </>;
231
+ ```
232
+
203
233
  ## Accessibility
204
234
 
205
235
  - `role="alert"` for `type="alert"`; `role="status"` for all other types.
206
236
  - `aria-label` on the root is `"<type> <variant> <device>"` (e.g. `"warning notification desktop"`, `"alert announcement mobile"`).
207
237
  - The close control is an icon-only [`IconButton`](./button.md) (`variant="tertiary"`, `tone="mono"`, `size="xs"`, `hoverBackground="none"`) with `aria-label="Close notification"`. Uses Box/`onPress` so it works on React Native as well as web.
208
238
  - The default type icons are decorative — pass `aria-hidden` on any custom `icon` you supply.
239
+ - The filled `warning` / `success` icon frames pair a `content.static.dark` glyph with a light fill (see [Icon colour](#icon-colour)) so the icon keeps its contrast in both themes.
@@ -30,7 +30,7 @@ interface NotificationPanelProps extends ThemeOverrideProps {
30
30
  description?: string;
31
31
  /** Show/hide the icon frame */
32
32
  showIcon?: boolean;
33
- /** Custom icon override (optional) */
33
+ /** Custom icon override (optional). Rendered as authored — the panel does not recolour it. */
34
34
  icon?: React.ReactNode;
35
35
  /**
36
36
  * Action button (optional - pass any Button/IconButton/FlexButton component).
package/native/index.d.ts CHANGED
@@ -30,7 +30,7 @@ interface NotificationPanelProps extends ThemeOverrideProps {
30
30
  description?: string;
31
31
  /** Show/hide the icon frame */
32
32
  showIcon?: boolean;
33
- /** Custom icon override (optional) */
33
+ /** Custom icon override (optional). Rendered as authored — the panel does not recolour it. */
34
34
  icon?: React.ReactNode;
35
35
  /**
36
36
  * Action button (optional - pass any Button/IconButton/FlexButton component).
package/native/index.js CHANGED
@@ -207,6 +207,7 @@ var import_xui_button = require("@xsolla/xui-button");
207
207
  var import_xui_typography = require("@xsolla/xui-typography");
208
208
  var import_xui_icons_base = require("@xsolla/xui-icons-base");
209
209
  var import_jsx_runtime2 = require("react/jsx-runtime");
210
+ var ICON_TEST_ID = "notification-panel-icon";
210
211
  var NotificationPanel = ({
211
212
  variant = "notification",
212
213
  device = "desktop",
@@ -231,6 +232,7 @@ var NotificationPanel = ({
231
232
  announcementBg: theme.colors.background.alert.secondary,
232
233
  iconFrameBg: theme.colors.overlay.alert,
233
234
  iconColor: theme.colors.content.primary,
235
+ frameIconColor: theme.colors.content.primary,
234
236
  buttonTone: "alert",
235
237
  IconComponent: import_xui_icons_base.ExclamationMarkSq
236
238
  },
@@ -239,6 +241,7 @@ var NotificationPanel = ({
239
241
  announcementBg: theme.colors.background.warning.secondary,
240
242
  iconFrameBg: theme.colors.background.warning.primary,
241
243
  iconColor: theme.colors.content.primary,
244
+ frameIconColor: theme.colors.content.static.dark,
242
245
  buttonTone: "mono",
243
246
  IconComponent: import_xui_icons_base.ExclamationMarkSq
244
247
  },
@@ -247,6 +250,7 @@ var NotificationPanel = ({
247
250
  announcementBg: theme.colors.background.success.secondary,
248
251
  iconFrameBg: theme.colors.background.success.primary,
249
252
  iconColor: theme.colors.content.primary,
253
+ frameIconColor: theme.colors.content.static.dark,
250
254
  buttonTone: "brandExtra",
251
255
  IconComponent: import_xui_icons_base.CheckCr
252
256
  },
@@ -255,6 +259,7 @@ var NotificationPanel = ({
255
259
  announcementBg: theme.colors.background.neutral.secondary,
256
260
  iconFrameBg: theme.colors.overlay.mono,
257
261
  iconColor: theme.colors.content.primary,
262
+ frameIconColor: theme.colors.content.primary,
258
263
  buttonTone: "mono",
259
264
  IconComponent: import_xui_icons_base.InfoSq
260
265
  },
@@ -263,6 +268,7 @@ var NotificationPanel = ({
263
268
  announcementBg: theme.colors.background.brand.secondary,
264
269
  iconFrameBg: theme.colors.overlay.brand,
265
270
  iconColor: theme.colors.content.primary,
271
+ frameIconColor: theme.colors.content.primary,
266
272
  buttonTone: "brand",
267
273
  IconComponent: import_xui_icons_base.InfoSq
268
274
  }
@@ -342,7 +348,8 @@ var NotificationPanel = ({
342
348
  {
343
349
  size: config.announcementIconSize,
344
350
  color: currentConfig.iconColor,
345
- variant: "solid"
351
+ variant: "solid",
352
+ "data-testid": ICON_TEST_ID
346
353
  }
347
354
  )),
348
355
  title && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Box, { flex: 1, minWidth: 0, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -418,7 +425,8 @@ var NotificationPanel = ({
418
425
  {
419
426
  size: config.announcementIconSize,
420
427
  color: currentConfig.iconColor,
421
- variant: "solid"
428
+ variant: "solid",
429
+ "data-testid": ICON_TEST_ID
422
430
  }
423
431
  )),
424
432
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
@@ -499,7 +507,8 @@ var NotificationPanel = ({
499
507
  {
500
508
  size: config.mobileIconSize,
501
509
  color: currentConfig.iconColor,
502
- variant: "solid"
510
+ variant: "solid",
511
+ "data-testid": ICON_TEST_ID
503
512
  }
504
513
  )
505
514
  }
@@ -581,8 +590,9 @@ var NotificationPanel = ({
581
590
  IconComponent,
582
591
  {
583
592
  size: config.iconSize,
584
- color: currentConfig.iconColor,
585
- variant: "solid"
593
+ color: currentConfig.frameIconColor,
594
+ variant: "solid",
595
+ "data-testid": ICON_TEST_ID
586
596
  }
587
597
  )
588
598
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.tsx","../../src/NotificationPanel.tsx","../../../../foundation/primitives-native/src/Box.tsx"],"sourcesContent":["export { NotificationPanel } from \"./NotificationPanel\";\nexport type {\n NotificationPanelProps,\n NotificationPanelDevice,\n ActionButtonElement,\n} from \"./NotificationPanel\";\n","import React, { cloneElement, isValidElement } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport {\n IconButton,\n type ButtonProps,\n type IconButtonProps,\n type FlexButtonProps,\n} from \"@xsolla/xui-button\";\nimport { Typography } from \"@xsolla/xui-typography\";\nimport {\n ExclamationMarkSq,\n InfoSq,\n CheckCr,\n Remove,\n type BaseIconComponent,\n} from \"@xsolla/xui-icons-base\";\n\nexport type ActionButtonElement = React.ReactElement<\n ButtonProps | IconButtonProps | FlexButtonProps\n>;\n\nexport type NotificationPanelDevice = \"desktop\" | \"mobile\";\n\nexport interface NotificationPanelProps extends ThemeOverrideProps {\n /**\n * Layout variant.\n * - `notification` (default): full-height banner with an icon frame and a\n * stacked title/description.\n * - `announcement`: slim, single-line bar with an inline icon and the\n * title/description on one row.\n */\n variant?: \"notification\" | \"announcement\";\n /**\n * Device layout mode.\n * - `desktop` (default): horizontal layout with actions on the right.\n * - `mobile`: Figma mobile layout — `notification` uses a three-column row\n * (icon | stacked text + action | close); `announcement` puts icon, title,\n * on one row with description below; action and close are grouped on the\n * right, top-aligned with the title row.\n */\n device?: NotificationPanelDevice;\n /** Visual variant/tone of the notification */\n type?: \"alert\" | \"warning\" | \"success\" | \"neutral\" | \"brand\";\n /** Title text (optional) */\n title?: string;\n /** Description text (optional) */\n description?: string;\n /** Show/hide the icon frame */\n showIcon?: boolean;\n /** Custom icon override (optional) */\n icon?: React.ReactNode;\n /**\n * Action button (optional - pass any Button/IconButton/FlexButton component).\n * `size` — plus `variant` and `background` for non-IconButton actions — falls\n * back to a panel default, but any value you set on the button element itself\n * takes precedence. `tone` is never overridden by the panel.\n */\n actionButton?: React.ReactElement;\n /** Show/hide close button */\n showCloseButton?: boolean;\n /** Close button click handler */\n onClose?: () => void;\n /**\n * Vertical alignment of the action/close button group — \"center\" (default) or\n * \"top\". Applies to the desktop `notification` variant only.\n */\n closeButtonAlign?: \"center\" | \"top\";\n testID?: string;\n}\n\nexport const NotificationPanel: React.FC<NotificationPanelProps> = ({\n variant = \"notification\",\n device = \"desktop\",\n type = \"neutral\",\n title,\n description,\n showIcon = true,\n icon,\n actionButton,\n showCloseButton = true,\n onClose,\n closeButtonAlign = \"center\",\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const config = theme.sizing.notificationPanel(device);\n\n const typeConfig: Record<\n NonNullable<NotificationPanelProps[\"type\"]>,\n {\n panelBg: string;\n /** Background of the slim announcement bar (and inline icon area). */\n announcementBg: string;\n iconFrameBg: string;\n iconColor: string;\n buttonTone: \"brand\" | \"brandExtra\" | \"alert\" | \"mono\";\n IconComponent: BaseIconComponent;\n }\n > = {\n alert: {\n panelBg: theme.colors.overlay.alert,\n announcementBg: theme.colors.background.alert.secondary,\n iconFrameBg: theme.colors.overlay.alert,\n iconColor: theme.colors.content.primary,\n buttonTone: \"alert\",\n IconComponent: ExclamationMarkSq,\n },\n warning: {\n panelBg: theme.colors.overlay.warning,\n announcementBg: theme.colors.background.warning.secondary,\n iconFrameBg: theme.colors.background.warning.primary,\n iconColor: theme.colors.content.primary,\n buttonTone: \"mono\",\n IconComponent: ExclamationMarkSq,\n },\n success: {\n panelBg: theme.colors.overlay.success,\n announcementBg: theme.colors.background.success.secondary,\n iconFrameBg: theme.colors.background.success.primary,\n iconColor: theme.colors.content.primary,\n buttonTone: \"brandExtra\",\n IconComponent: CheckCr,\n },\n neutral: {\n panelBg: theme.colors.overlay.mono,\n announcementBg: theme.colors.background.neutral.secondary,\n iconFrameBg: theme.colors.overlay.mono,\n iconColor: theme.colors.content.primary,\n buttonTone: \"mono\",\n IconComponent: InfoSq,\n },\n brand: {\n panelBg: theme.colors.overlay.brand,\n announcementBg: theme.colors.background.brand.secondary,\n iconFrameBg: theme.colors.overlay.brand,\n iconColor: theme.colors.content.primary,\n buttonTone: \"brand\",\n IconComponent: InfoSq,\n },\n };\n\n const currentConfig = typeConfig[type];\n const IconComponent = currentConfig.IconComponent;\n\n const ariaProps = {\n role: type === \"alert\" ? \"alert\" : \"status\",\n \"aria-label\": `${type} ${variant} ${device}`,\n } as const;\n\n // IconButton (Box-based) stays RN-safe; FlexButton is web-DOM-only.\n const renderCloseButton = (iconSize: number) =>\n showCloseButton ? (\n <IconButton\n variant=\"tertiary\"\n tone=\"mono\"\n size=\"xs\"\n onPress={onClose}\n aria-label=\"Close notification\"\n icon={<Remove size={iconSize} />}\n hoverBackground=\"none\"\n />\n ) : null;\n\n const renderActionButton = () => {\n if (!isValidElement(actionButton)) return null;\n\n const element = actionButton as ActionButtonElement;\n const isIconButton =\n (element.type as { displayName?: string }).displayName === \"IconButton\";\n\n // Caller-supplied props on the element win; the values below are defaults\n // applied only when the caller omits them. (Previously they were hard-coded,\n // and cloneElement's second argument overrides the element's own props, so a\n // passed-in size/variant was silently ignored.)\n const props = element.props as Partial<\n ButtonProps & IconButtonProps & FlexButtonProps\n >;\n\n return cloneElement(\n element,\n isIconButton\n ? { size: props.size ?? \"xs\" }\n : {\n size: props.size ?? \"xs\",\n // Non-IconButton actions default to a text-only FlexButton (Primary\n // palette → content.primary text, no fill), per the Figma \"Flex\n // Button\" node. hoverBackground is left at its default so the subtle\n // mono hover overlay from the design is preserved.\n variant: props.variant ?? \"primary\",\n background: props.background ?? false,\n }\n );\n };\n\n if (variant === \"announcement\") {\n const isMobileAnnouncement = device === \"mobile\";\n\n if (isMobileAnnouncement) {\n const descriptionIndent = showIcon\n ? config.announcementIconSize + config.announcementContentGap\n : 0;\n\n return (\n <Box\n backgroundColor={currentConfig.announcementBg}\n flexDirection=\"row\"\n alignItems=\"stretch\"\n padding={config.announcementPadding}\n gap={config.announcementGap}\n overflow=\"hidden\"\n testID={testID}\n style={{\n backdropFilter: `blur(${config.announcementBlurRadius}px)`,\n }}\n {...ariaProps}\n >\n <Box\n flex={1}\n minWidth={0}\n flexDirection=\"column\"\n gap={config.textGap}\n >\n <Box\n flexDirection=\"row\"\n alignItems=\"flex-start\"\n gap={config.announcementContentGap}\n >\n {showIcon &&\n (icon || (\n <IconComponent\n size={config.announcementIconSize}\n color={currentConfig.iconColor}\n variant=\"solid\"\n />\n ))}\n {title && (\n <Box flex={1} minWidth={0}>\n <Typography\n variant=\"bodyXsAccent\"\n color={theme.colors.content.primary}\n noWrap\n >\n {title}\n </Typography>\n </Box>\n )}\n </Box>\n\n {description && (\n <Box paddingLeft={descriptionIndent}>\n <Typography\n variant=\"bodyXs\"\n color={theme.colors.content.secondary}\n noWrap\n >\n {description}\n </Typography>\n </Box>\n )}\n </Box>\n\n {(actionButton || showCloseButton) && (\n <Box\n flexShrink={0}\n alignSelf=\"flex-start\"\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={config.announcementButtonsGap}\n >\n {renderActionButton()}\n {renderCloseButton(config.announcementCloseIconSize)}\n </Box>\n )}\n </Box>\n );\n }\n\n return (\n <Box\n backgroundColor={currentConfig.announcementBg}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"flex-start\"\n padding={config.announcementPadding}\n gap={config.announcementGap}\n overflow=\"hidden\"\n testID={testID}\n style={{\n backdropFilter: `blur(${config.announcementBlurRadius}px)`,\n }}\n {...ariaProps}\n >\n <Box\n flex={1}\n minWidth={0}\n overflow=\"hidden\"\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={config.announcementContentGap}\n >\n {showIcon &&\n (icon || (\n <IconComponent\n size={config.announcementIconSize}\n color={currentConfig.iconColor}\n variant=\"solid\"\n />\n ))}\n <Box\n flex={1}\n minWidth={0}\n overflow=\"hidden\"\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={config.announcementContentGap}\n >\n {title && (\n <Typography\n variant=\"bodyXsAccent\"\n color={theme.colors.content.primary}\n noWrap\n >\n {title}\n </Typography>\n )}\n {description && (\n <Typography\n variant=\"bodyXs\"\n color={theme.colors.content.secondary}\n noWrap\n >\n {description}\n </Typography>\n )}\n </Box>\n </Box>\n\n {(actionButton || showCloseButton) && (\n <Box\n flexShrink={0}\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={config.announcementButtonsGap}\n >\n {renderActionButton()}\n {renderCloseButton(config.announcementCloseIconSize)}\n </Box>\n )}\n </Box>\n );\n }\n\n if (device === \"mobile\") {\n return (\n <Box\n backgroundColor={currentConfig.panelBg}\n borderRadius={config.borderRadius}\n flexDirection=\"row\"\n alignItems=\"flex-start\"\n justifyContent=\"space-between\"\n overflow=\"hidden\"\n testID={testID}\n {...ariaProps}\n >\n {showIcon && (\n <Box\n alignSelf=\"stretch\"\n paddingTop={config.mobileIconColumnPaddingVertical}\n paddingBottom={config.mobileIconColumnPaddingVertical}\n paddingLeft={config.mobileIconColumnPaddingLeft}\n alignItems=\"flex-start\"\n justifyContent=\"flex-start\"\n >\n {icon || (\n <IconComponent\n size={config.mobileIconSize}\n color={currentConfig.iconColor}\n variant=\"solid\"\n />\n )}\n </Box>\n )}\n\n <Box\n flex={1}\n minWidth={0}\n paddingHorizontal={config.mobileBodyPaddingHorizontal}\n paddingVertical={config.mobileBodyPaddingVertical}\n flexDirection=\"column\"\n alignItems=\"flex-start\"\n justifyContent=\"center\"\n gap={config.mobileBodyContentGap}\n >\n {(title || description) && (\n <Box alignSelf=\"stretch\" gap={config.textGap}>\n {title && (\n <Typography\n variant=\"bodySmAccent\"\n color={theme.colors.content.primary}\n >\n {title}\n </Typography>\n )}\n {description && (\n <Typography\n variant=\"bodyXs\"\n color={theme.colors.content.tertiary}\n >\n {description}\n </Typography>\n )}\n </Box>\n )}\n\n {actionButton && (\n <Box marginLeft={config.mobileNotificationActionButtonOffsetLeft}>\n {renderActionButton()}\n </Box>\n )}\n </Box>\n\n {showCloseButton && (\n <Box\n alignSelf=\"stretch\"\n flexDirection=\"row\"\n paddingTop={config.mobileCloseColumnPaddingVertical}\n paddingBottom={config.mobileCloseColumnPaddingVertical}\n paddingRight={config.mobileCloseColumnPaddingRight}\n alignItems=\"flex-start\"\n justifyContent=\"flex-end\"\n >\n {renderCloseButton(config.notificationCloseIconSize)}\n </Box>\n )}\n </Box>\n );\n }\n\n return (\n <Box\n backgroundColor={currentConfig.panelBg}\n borderRadius={config.borderRadius}\n flexDirection=\"row\"\n alignItems=\"stretch\"\n overflow=\"hidden\"\n testID={testID}\n {...ariaProps}\n >\n {/* Icon Frame */}\n {showIcon && (\n <Box\n backgroundColor={currentConfig.iconFrameBg}\n width={config.iconFrameWidth}\n alignItems=\"center\"\n justifyContent=\"center\"\n style={{\n borderTopLeftRadius: config.borderRadius,\n borderBottomLeftRadius: config.borderRadius,\n }}\n >\n {icon || (\n <IconComponent\n size={config.iconSize}\n color={currentConfig.iconColor}\n variant=\"solid\"\n />\n )}\n </Box>\n )}\n\n {/* Body */}\n <Box\n flex={1}\n flexDirection=\"row\"\n alignItems=\"center\"\n paddingHorizontal={config.bodyPaddingHorizontal}\n paddingVertical={config.bodyPaddingVertical}\n gap={config.contentGap}\n >\n {/* Text Content */}\n <Box flex={1} gap={config.textGap}>\n {title && (\n <Typography\n variant=\"bodyMdAccent\"\n color={theme.colors.content.primary}\n >\n {title}\n </Typography>\n )}\n {description && (\n <Typography variant=\"bodySm\" color={theme.colors.content.tertiary}>\n {description}\n </Typography>\n )}\n </Box>\n\n {/* Buttons */}\n {(actionButton || showCloseButton) && (\n <Box\n flexDirection=\"row\"\n alignSelf={closeButtonAlign === \"top\" ? \"flex-start\" : undefined}\n alignItems=\"center\"\n flexShrink={0}\n gap={config.buttonsGap}\n >\n {renderActionButton()}\n {renderCloseButton(config.notificationCloseIconSize)}\n </Box>\n )}\n </Box>\n </Box>\n );\n};\n\nNotificationPanel.displayName = \"NotificationPanel\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n flexDirection,\n alignItems,\n justifyContent,\n position,\n top,\n bottom,\n left,\n right,\n width,\n minWidth,\n minHeight,\n maxWidth,\n maxHeight,\n flex,\n overflow,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n minWidth: minWidth as DimensionValue,\n minHeight: minHeight as DimensionValue,\n maxWidth: maxWidth as DimensionValue,\n maxHeight: maxHeight as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n flexDirection,\n alignItems,\n justifyContent,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Destructure and drop web-only props from rest before passing to RN components\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": _ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": _ariaDisabled,\n \"aria-live\": _ariaLive,\n className,\n \"data-testid\": _dataTestId,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n if (onPress) {\n return (\n <Pressable\n onPress={onPress}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n"],"mappings":"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","names":["import_jsx_runtime"]}
1
+ {"version":3,"sources":["../../src/index.tsx","../../src/NotificationPanel.tsx","../../../../foundation/primitives-native/src/Box.tsx"],"sourcesContent":["export { NotificationPanel } from \"./NotificationPanel\";\nexport type {\n NotificationPanelProps,\n NotificationPanelDevice,\n ActionButtonElement,\n} from \"./NotificationPanel\";\n","import React, { cloneElement, isValidElement } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport {\n IconButton,\n type ButtonProps,\n type IconButtonProps,\n type FlexButtonProps,\n} from \"@xsolla/xui-button\";\nimport { Typography } from \"@xsolla/xui-typography\";\nimport {\n ExclamationMarkSq,\n InfoSq,\n CheckCr,\n Remove,\n type BaseIconComponent,\n} from \"@xsolla/xui-icons-base\";\n\nexport type ActionButtonElement = React.ReactElement<\n ButtonProps | IconButtonProps | FlexButtonProps\n>;\n\nexport type NotificationPanelDevice = \"desktop\" | \"mobile\";\n\n/** Test id on the default type icon, so its colour is assertable. */\nconst ICON_TEST_ID = \"notification-panel-icon\";\n\nexport interface NotificationPanelProps extends ThemeOverrideProps {\n /**\n * Layout variant.\n * - `notification` (default): full-height banner with an icon frame and a\n * stacked title/description.\n * - `announcement`: slim, single-line bar with an inline icon and the\n * title/description on one row.\n */\n variant?: \"notification\" | \"announcement\";\n /**\n * Device layout mode.\n * - `desktop` (default): horizontal layout with actions on the right.\n * - `mobile`: Figma mobile layout — `notification` uses a three-column row\n * (icon | stacked text + action | close); `announcement` puts icon, title,\n * on one row with description below; action and close are grouped on the\n * right, top-aligned with the title row.\n */\n device?: NotificationPanelDevice;\n /** Visual variant/tone of the notification */\n type?: \"alert\" | \"warning\" | \"success\" | \"neutral\" | \"brand\";\n /** Title text (optional) */\n title?: string;\n /** Description text (optional) */\n description?: string;\n /** Show/hide the icon frame */\n showIcon?: boolean;\n /** Custom icon override (optional). Rendered as authored — the panel does not recolour it. */\n icon?: React.ReactNode;\n /**\n * Action button (optional - pass any Button/IconButton/FlexButton component).\n * `size` — plus `variant` and `background` for non-IconButton actions — falls\n * back to a panel default, but any value you set on the button element itself\n * takes precedence. `tone` is never overridden by the panel.\n */\n actionButton?: React.ReactElement;\n /** Show/hide close button */\n showCloseButton?: boolean;\n /** Close button click handler */\n onClose?: () => void;\n /**\n * Vertical alignment of the action/close button group — \"center\" (default) or\n * \"top\". Applies to the desktop `notification` variant only.\n */\n closeButtonAlign?: \"center\" | \"top\";\n testID?: string;\n}\n\nexport const NotificationPanel: React.FC<NotificationPanelProps> = ({\n variant = \"notification\",\n device = \"desktop\",\n type = \"neutral\",\n title,\n description,\n showIcon = true,\n icon,\n actionButton,\n showCloseButton = true,\n onClose,\n closeButtonAlign = \"center\",\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const config = theme.sizing.notificationPanel(device);\n\n const typeConfig: Record<\n NonNullable<NotificationPanelProps[\"type\"]>,\n {\n panelBg: string;\n /** Background of the slim announcement bar (and inline icon area). */\n announcementBg: string;\n iconFrameBg: string;\n /**\n * Glyph colour when the icon sits directly on the panel or announcement\n * surface — the mobile `notification` icon column and both\n * `announcement` layouts. Those surfaces are `overlay.*` /\n * `background.*.secondary`, which track the theme, so the glyph tracks\n * it too via `content.primary`.\n */\n iconColor: string;\n /**\n * Glyph colour inside the desktop `notification` icon frame.\n *\n * `warning` and `success` fill that frame with a solid light token\n * (`background.warning.primary` #ffc380 / `background.success.primary`\n * #95ff80 — the same value in light and dark), so their glyph uses the\n * theme-independent `content.static.dark`. `content.primary` would be\n * near-white in dark mode and wash the icon out (XUITSD-4). Every other\n * type fills the frame with a translucent overlay over `panelBg`, where\n * `content.primary` is correct.\n */\n frameIconColor: string;\n buttonTone: \"brand\" | \"brandExtra\" | \"alert\" | \"mono\";\n IconComponent: BaseIconComponent;\n }\n > = {\n alert: {\n panelBg: theme.colors.overlay.alert,\n announcementBg: theme.colors.background.alert.secondary,\n iconFrameBg: theme.colors.overlay.alert,\n iconColor: theme.colors.content.primary,\n frameIconColor: theme.colors.content.primary,\n buttonTone: \"alert\",\n IconComponent: ExclamationMarkSq,\n },\n warning: {\n panelBg: theme.colors.overlay.warning,\n announcementBg: theme.colors.background.warning.secondary,\n iconFrameBg: theme.colors.background.warning.primary,\n iconColor: theme.colors.content.primary,\n frameIconColor: theme.colors.content.static.dark,\n buttonTone: \"mono\",\n IconComponent: ExclamationMarkSq,\n },\n success: {\n panelBg: theme.colors.overlay.success,\n announcementBg: theme.colors.background.success.secondary,\n iconFrameBg: theme.colors.background.success.primary,\n iconColor: theme.colors.content.primary,\n frameIconColor: theme.colors.content.static.dark,\n buttonTone: \"brandExtra\",\n IconComponent: CheckCr,\n },\n neutral: {\n panelBg: theme.colors.overlay.mono,\n announcementBg: theme.colors.background.neutral.secondary,\n iconFrameBg: theme.colors.overlay.mono,\n iconColor: theme.colors.content.primary,\n frameIconColor: theme.colors.content.primary,\n buttonTone: \"mono\",\n IconComponent: InfoSq,\n },\n brand: {\n panelBg: theme.colors.overlay.brand,\n announcementBg: theme.colors.background.brand.secondary,\n iconFrameBg: theme.colors.overlay.brand,\n iconColor: theme.colors.content.primary,\n frameIconColor: theme.colors.content.primary,\n buttonTone: \"brand\",\n IconComponent: InfoSq,\n },\n };\n\n const currentConfig = typeConfig[type];\n const IconComponent = currentConfig.IconComponent;\n\n const ariaProps = {\n role: type === \"alert\" ? \"alert\" : \"status\",\n \"aria-label\": `${type} ${variant} ${device}`,\n } as const;\n\n // IconButton (Box-based) stays RN-safe; FlexButton is web-DOM-only.\n const renderCloseButton = (iconSize: number) =>\n showCloseButton ? (\n <IconButton\n variant=\"tertiary\"\n tone=\"mono\"\n size=\"xs\"\n onPress={onClose}\n aria-label=\"Close notification\"\n icon={<Remove size={iconSize} />}\n hoverBackground=\"none\"\n />\n ) : null;\n\n const renderActionButton = () => {\n if (!isValidElement(actionButton)) return null;\n\n const element = actionButton as ActionButtonElement;\n const isIconButton =\n (element.type as { displayName?: string }).displayName === \"IconButton\";\n\n // Caller-supplied props on the element win; the values below are defaults\n // applied only when the caller omits them. (Previously they were hard-coded,\n // and cloneElement's second argument overrides the element's own props, so a\n // passed-in size/variant was silently ignored.)\n const props = element.props as Partial<\n ButtonProps & IconButtonProps & FlexButtonProps\n >;\n\n return cloneElement(\n element,\n isIconButton\n ? { size: props.size ?? \"xs\" }\n : {\n size: props.size ?? \"xs\",\n // Non-IconButton actions default to a text-only FlexButton (Primary\n // palette → content.primary text, no fill), per the Figma \"Flex\n // Button\" node. hoverBackground is left at its default so the subtle\n // mono hover overlay from the design is preserved.\n variant: props.variant ?? \"primary\",\n background: props.background ?? false,\n }\n );\n };\n\n if (variant === \"announcement\") {\n const isMobileAnnouncement = device === \"mobile\";\n\n if (isMobileAnnouncement) {\n const descriptionIndent = showIcon\n ? config.announcementIconSize + config.announcementContentGap\n : 0;\n\n return (\n <Box\n backgroundColor={currentConfig.announcementBg}\n flexDirection=\"row\"\n alignItems=\"stretch\"\n padding={config.announcementPadding}\n gap={config.announcementGap}\n overflow=\"hidden\"\n testID={testID}\n style={{\n backdropFilter: `blur(${config.announcementBlurRadius}px)`,\n }}\n {...ariaProps}\n >\n <Box\n flex={1}\n minWidth={0}\n flexDirection=\"column\"\n gap={config.textGap}\n >\n <Box\n flexDirection=\"row\"\n alignItems=\"flex-start\"\n gap={config.announcementContentGap}\n >\n {showIcon &&\n (icon || (\n <IconComponent\n size={config.announcementIconSize}\n color={currentConfig.iconColor}\n variant=\"solid\"\n data-testid={ICON_TEST_ID}\n />\n ))}\n {title && (\n <Box flex={1} minWidth={0}>\n <Typography\n variant=\"bodyXsAccent\"\n color={theme.colors.content.primary}\n noWrap\n >\n {title}\n </Typography>\n </Box>\n )}\n </Box>\n\n {description && (\n <Box paddingLeft={descriptionIndent}>\n <Typography\n variant=\"bodyXs\"\n color={theme.colors.content.secondary}\n noWrap\n >\n {description}\n </Typography>\n </Box>\n )}\n </Box>\n\n {(actionButton || showCloseButton) && (\n <Box\n flexShrink={0}\n alignSelf=\"flex-start\"\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={config.announcementButtonsGap}\n >\n {renderActionButton()}\n {renderCloseButton(config.announcementCloseIconSize)}\n </Box>\n )}\n </Box>\n );\n }\n\n return (\n <Box\n backgroundColor={currentConfig.announcementBg}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"flex-start\"\n padding={config.announcementPadding}\n gap={config.announcementGap}\n overflow=\"hidden\"\n testID={testID}\n style={{\n backdropFilter: `blur(${config.announcementBlurRadius}px)`,\n }}\n {...ariaProps}\n >\n <Box\n flex={1}\n minWidth={0}\n overflow=\"hidden\"\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={config.announcementContentGap}\n >\n {showIcon &&\n (icon || (\n <IconComponent\n size={config.announcementIconSize}\n color={currentConfig.iconColor}\n variant=\"solid\"\n data-testid={ICON_TEST_ID}\n />\n ))}\n <Box\n flex={1}\n minWidth={0}\n overflow=\"hidden\"\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={config.announcementContentGap}\n >\n {title && (\n <Typography\n variant=\"bodyXsAccent\"\n color={theme.colors.content.primary}\n noWrap\n >\n {title}\n </Typography>\n )}\n {description && (\n <Typography\n variant=\"bodyXs\"\n color={theme.colors.content.secondary}\n noWrap\n >\n {description}\n </Typography>\n )}\n </Box>\n </Box>\n\n {(actionButton || showCloseButton) && (\n <Box\n flexShrink={0}\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={config.announcementButtonsGap}\n >\n {renderActionButton()}\n {renderCloseButton(config.announcementCloseIconSize)}\n </Box>\n )}\n </Box>\n );\n }\n\n if (device === \"mobile\") {\n return (\n <Box\n backgroundColor={currentConfig.panelBg}\n borderRadius={config.borderRadius}\n flexDirection=\"row\"\n alignItems=\"flex-start\"\n justifyContent=\"space-between\"\n overflow=\"hidden\"\n testID={testID}\n {...ariaProps}\n >\n {showIcon && (\n <Box\n alignSelf=\"stretch\"\n paddingTop={config.mobileIconColumnPaddingVertical}\n paddingBottom={config.mobileIconColumnPaddingVertical}\n paddingLeft={config.mobileIconColumnPaddingLeft}\n alignItems=\"flex-start\"\n justifyContent=\"flex-start\"\n >\n {icon || (\n <IconComponent\n size={config.mobileIconSize}\n color={currentConfig.iconColor}\n variant=\"solid\"\n data-testid={ICON_TEST_ID}\n />\n )}\n </Box>\n )}\n\n <Box\n flex={1}\n minWidth={0}\n paddingHorizontal={config.mobileBodyPaddingHorizontal}\n paddingVertical={config.mobileBodyPaddingVertical}\n flexDirection=\"column\"\n alignItems=\"flex-start\"\n justifyContent=\"center\"\n gap={config.mobileBodyContentGap}\n >\n {(title || description) && (\n <Box alignSelf=\"stretch\" gap={config.textGap}>\n {title && (\n <Typography\n variant=\"bodySmAccent\"\n color={theme.colors.content.primary}\n >\n {title}\n </Typography>\n )}\n {description && (\n <Typography\n variant=\"bodyXs\"\n color={theme.colors.content.tertiary}\n >\n {description}\n </Typography>\n )}\n </Box>\n )}\n\n {actionButton && (\n <Box marginLeft={config.mobileNotificationActionButtonOffsetLeft}>\n {renderActionButton()}\n </Box>\n )}\n </Box>\n\n {showCloseButton && (\n <Box\n alignSelf=\"stretch\"\n flexDirection=\"row\"\n paddingTop={config.mobileCloseColumnPaddingVertical}\n paddingBottom={config.mobileCloseColumnPaddingVertical}\n paddingRight={config.mobileCloseColumnPaddingRight}\n alignItems=\"flex-start\"\n justifyContent=\"flex-end\"\n >\n {renderCloseButton(config.notificationCloseIconSize)}\n </Box>\n )}\n </Box>\n );\n }\n\n return (\n <Box\n backgroundColor={currentConfig.panelBg}\n borderRadius={config.borderRadius}\n flexDirection=\"row\"\n alignItems=\"stretch\"\n overflow=\"hidden\"\n testID={testID}\n {...ariaProps}\n >\n {/* Icon Frame */}\n {showIcon && (\n <Box\n backgroundColor={currentConfig.iconFrameBg}\n width={config.iconFrameWidth}\n alignItems=\"center\"\n justifyContent=\"center\"\n style={{\n borderTopLeftRadius: config.borderRadius,\n borderBottomLeftRadius: config.borderRadius,\n }}\n >\n {icon || (\n <IconComponent\n size={config.iconSize}\n color={currentConfig.frameIconColor}\n variant=\"solid\"\n data-testid={ICON_TEST_ID}\n />\n )}\n </Box>\n )}\n\n {/* Body */}\n <Box\n flex={1}\n flexDirection=\"row\"\n alignItems=\"center\"\n paddingHorizontal={config.bodyPaddingHorizontal}\n paddingVertical={config.bodyPaddingVertical}\n gap={config.contentGap}\n >\n {/* Text Content */}\n <Box flex={1} gap={config.textGap}>\n {title && (\n <Typography\n variant=\"bodyMdAccent\"\n color={theme.colors.content.primary}\n >\n {title}\n </Typography>\n )}\n {description && (\n <Typography variant=\"bodySm\" color={theme.colors.content.tertiary}>\n {description}\n </Typography>\n )}\n </Box>\n\n {/* Buttons */}\n {(actionButton || showCloseButton) && (\n <Box\n flexDirection=\"row\"\n alignSelf={closeButtonAlign === \"top\" ? \"flex-start\" : undefined}\n alignItems=\"center\"\n flexShrink={0}\n gap={config.buttonsGap}\n >\n {renderActionButton()}\n {renderCloseButton(config.notificationCloseIconSize)}\n </Box>\n )}\n </Box>\n </Box>\n );\n};\n\nNotificationPanel.displayName = \"NotificationPanel\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n flexDirection,\n alignItems,\n justifyContent,\n position,\n top,\n bottom,\n left,\n right,\n width,\n minWidth,\n minHeight,\n maxWidth,\n maxHeight,\n flex,\n overflow,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n minWidth: minWidth as DimensionValue,\n minHeight: minHeight as DimensionValue,\n maxWidth: maxWidth as DimensionValue,\n maxHeight: maxHeight as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n flexDirection,\n alignItems,\n justifyContent,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Destructure and drop web-only props from rest before passing to RN components\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": _ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": _ariaDisabled,\n \"aria-live\": _ariaLive,\n className,\n \"data-testid\": _dataTestId,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n if (onPress) {\n return (\n <Pressable\n onPress={onPress}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n"],"mappings":"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","names":["import_jsx_runtime"]}
package/native/index.mjs CHANGED
@@ -192,6 +192,7 @@ import {
192
192
  Remove
193
193
  } from "@xsolla/xui-icons-base";
194
194
  import { jsx as jsx2, jsxs } from "react/jsx-runtime";
195
+ var ICON_TEST_ID = "notification-panel-icon";
195
196
  var NotificationPanel = ({
196
197
  variant = "notification",
197
198
  device = "desktop",
@@ -216,6 +217,7 @@ var NotificationPanel = ({
216
217
  announcementBg: theme.colors.background.alert.secondary,
217
218
  iconFrameBg: theme.colors.overlay.alert,
218
219
  iconColor: theme.colors.content.primary,
220
+ frameIconColor: theme.colors.content.primary,
219
221
  buttonTone: "alert",
220
222
  IconComponent: ExclamationMarkSq
221
223
  },
@@ -224,6 +226,7 @@ var NotificationPanel = ({
224
226
  announcementBg: theme.colors.background.warning.secondary,
225
227
  iconFrameBg: theme.colors.background.warning.primary,
226
228
  iconColor: theme.colors.content.primary,
229
+ frameIconColor: theme.colors.content.static.dark,
227
230
  buttonTone: "mono",
228
231
  IconComponent: ExclamationMarkSq
229
232
  },
@@ -232,6 +235,7 @@ var NotificationPanel = ({
232
235
  announcementBg: theme.colors.background.success.secondary,
233
236
  iconFrameBg: theme.colors.background.success.primary,
234
237
  iconColor: theme.colors.content.primary,
238
+ frameIconColor: theme.colors.content.static.dark,
235
239
  buttonTone: "brandExtra",
236
240
  IconComponent: CheckCr
237
241
  },
@@ -240,6 +244,7 @@ var NotificationPanel = ({
240
244
  announcementBg: theme.colors.background.neutral.secondary,
241
245
  iconFrameBg: theme.colors.overlay.mono,
242
246
  iconColor: theme.colors.content.primary,
247
+ frameIconColor: theme.colors.content.primary,
243
248
  buttonTone: "mono",
244
249
  IconComponent: InfoSq
245
250
  },
@@ -248,6 +253,7 @@ var NotificationPanel = ({
248
253
  announcementBg: theme.colors.background.brand.secondary,
249
254
  iconFrameBg: theme.colors.overlay.brand,
250
255
  iconColor: theme.colors.content.primary,
256
+ frameIconColor: theme.colors.content.primary,
251
257
  buttonTone: "brand",
252
258
  IconComponent: InfoSq
253
259
  }
@@ -327,7 +333,8 @@ var NotificationPanel = ({
327
333
  {
328
334
  size: config.announcementIconSize,
329
335
  color: currentConfig.iconColor,
330
- variant: "solid"
336
+ variant: "solid",
337
+ "data-testid": ICON_TEST_ID
331
338
  }
332
339
  )),
333
340
  title && /* @__PURE__ */ jsx2(Box, { flex: 1, minWidth: 0, children: /* @__PURE__ */ jsx2(
@@ -403,7 +410,8 @@ var NotificationPanel = ({
403
410
  {
404
411
  size: config.announcementIconSize,
405
412
  color: currentConfig.iconColor,
406
- variant: "solid"
413
+ variant: "solid",
414
+ "data-testid": ICON_TEST_ID
407
415
  }
408
416
  )),
409
417
  /* @__PURE__ */ jsxs(
@@ -484,7 +492,8 @@ var NotificationPanel = ({
484
492
  {
485
493
  size: config.mobileIconSize,
486
494
  color: currentConfig.iconColor,
487
- variant: "solid"
495
+ variant: "solid",
496
+ "data-testid": ICON_TEST_ID
488
497
  }
489
498
  )
490
499
  }
@@ -566,8 +575,9 @@ var NotificationPanel = ({
566
575
  IconComponent,
567
576
  {
568
577
  size: config.iconSize,
569
- color: currentConfig.iconColor,
570
- variant: "solid"
578
+ color: currentConfig.frameIconColor,
579
+ variant: "solid",
580
+ "data-testid": ICON_TEST_ID
571
581
  }
572
582
  )
573
583
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/NotificationPanel.tsx","../../../../foundation/primitives-native/src/Box.tsx"],"sourcesContent":["import React, { cloneElement, isValidElement } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport {\n IconButton,\n type ButtonProps,\n type IconButtonProps,\n type FlexButtonProps,\n} from \"@xsolla/xui-button\";\nimport { Typography } from \"@xsolla/xui-typography\";\nimport {\n ExclamationMarkSq,\n InfoSq,\n CheckCr,\n Remove,\n type BaseIconComponent,\n} from \"@xsolla/xui-icons-base\";\n\nexport type ActionButtonElement = React.ReactElement<\n ButtonProps | IconButtonProps | FlexButtonProps\n>;\n\nexport type NotificationPanelDevice = \"desktop\" | \"mobile\";\n\nexport interface NotificationPanelProps extends ThemeOverrideProps {\n /**\n * Layout variant.\n * - `notification` (default): full-height banner with an icon frame and a\n * stacked title/description.\n * - `announcement`: slim, single-line bar with an inline icon and the\n * title/description on one row.\n */\n variant?: \"notification\" | \"announcement\";\n /**\n * Device layout mode.\n * - `desktop` (default): horizontal layout with actions on the right.\n * - `mobile`: Figma mobile layout — `notification` uses a three-column row\n * (icon | stacked text + action | close); `announcement` puts icon, title,\n * on one row with description below; action and close are grouped on the\n * right, top-aligned with the title row.\n */\n device?: NotificationPanelDevice;\n /** Visual variant/tone of the notification */\n type?: \"alert\" | \"warning\" | \"success\" | \"neutral\" | \"brand\";\n /** Title text (optional) */\n title?: string;\n /** Description text (optional) */\n description?: string;\n /** Show/hide the icon frame */\n showIcon?: boolean;\n /** Custom icon override (optional) */\n icon?: React.ReactNode;\n /**\n * Action button (optional - pass any Button/IconButton/FlexButton component).\n * `size` — plus `variant` and `background` for non-IconButton actions — falls\n * back to a panel default, but any value you set on the button element itself\n * takes precedence. `tone` is never overridden by the panel.\n */\n actionButton?: React.ReactElement;\n /** Show/hide close button */\n showCloseButton?: boolean;\n /** Close button click handler */\n onClose?: () => void;\n /**\n * Vertical alignment of the action/close button group — \"center\" (default) or\n * \"top\". Applies to the desktop `notification` variant only.\n */\n closeButtonAlign?: \"center\" | \"top\";\n testID?: string;\n}\n\nexport const NotificationPanel: React.FC<NotificationPanelProps> = ({\n variant = \"notification\",\n device = \"desktop\",\n type = \"neutral\",\n title,\n description,\n showIcon = true,\n icon,\n actionButton,\n showCloseButton = true,\n onClose,\n closeButtonAlign = \"center\",\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const config = theme.sizing.notificationPanel(device);\n\n const typeConfig: Record<\n NonNullable<NotificationPanelProps[\"type\"]>,\n {\n panelBg: string;\n /** Background of the slim announcement bar (and inline icon area). */\n announcementBg: string;\n iconFrameBg: string;\n iconColor: string;\n buttonTone: \"brand\" | \"brandExtra\" | \"alert\" | \"mono\";\n IconComponent: BaseIconComponent;\n }\n > = {\n alert: {\n panelBg: theme.colors.overlay.alert,\n announcementBg: theme.colors.background.alert.secondary,\n iconFrameBg: theme.colors.overlay.alert,\n iconColor: theme.colors.content.primary,\n buttonTone: \"alert\",\n IconComponent: ExclamationMarkSq,\n },\n warning: {\n panelBg: theme.colors.overlay.warning,\n announcementBg: theme.colors.background.warning.secondary,\n iconFrameBg: theme.colors.background.warning.primary,\n iconColor: theme.colors.content.primary,\n buttonTone: \"mono\",\n IconComponent: ExclamationMarkSq,\n },\n success: {\n panelBg: theme.colors.overlay.success,\n announcementBg: theme.colors.background.success.secondary,\n iconFrameBg: theme.colors.background.success.primary,\n iconColor: theme.colors.content.primary,\n buttonTone: \"brandExtra\",\n IconComponent: CheckCr,\n },\n neutral: {\n panelBg: theme.colors.overlay.mono,\n announcementBg: theme.colors.background.neutral.secondary,\n iconFrameBg: theme.colors.overlay.mono,\n iconColor: theme.colors.content.primary,\n buttonTone: \"mono\",\n IconComponent: InfoSq,\n },\n brand: {\n panelBg: theme.colors.overlay.brand,\n announcementBg: theme.colors.background.brand.secondary,\n iconFrameBg: theme.colors.overlay.brand,\n iconColor: theme.colors.content.primary,\n buttonTone: \"brand\",\n IconComponent: InfoSq,\n },\n };\n\n const currentConfig = typeConfig[type];\n const IconComponent = currentConfig.IconComponent;\n\n const ariaProps = {\n role: type === \"alert\" ? \"alert\" : \"status\",\n \"aria-label\": `${type} ${variant} ${device}`,\n } as const;\n\n // IconButton (Box-based) stays RN-safe; FlexButton is web-DOM-only.\n const renderCloseButton = (iconSize: number) =>\n showCloseButton ? (\n <IconButton\n variant=\"tertiary\"\n tone=\"mono\"\n size=\"xs\"\n onPress={onClose}\n aria-label=\"Close notification\"\n icon={<Remove size={iconSize} />}\n hoverBackground=\"none\"\n />\n ) : null;\n\n const renderActionButton = () => {\n if (!isValidElement(actionButton)) return null;\n\n const element = actionButton as ActionButtonElement;\n const isIconButton =\n (element.type as { displayName?: string }).displayName === \"IconButton\";\n\n // Caller-supplied props on the element win; the values below are defaults\n // applied only when the caller omits them. (Previously they were hard-coded,\n // and cloneElement's second argument overrides the element's own props, so a\n // passed-in size/variant was silently ignored.)\n const props = element.props as Partial<\n ButtonProps & IconButtonProps & FlexButtonProps\n >;\n\n return cloneElement(\n element,\n isIconButton\n ? { size: props.size ?? \"xs\" }\n : {\n size: props.size ?? \"xs\",\n // Non-IconButton actions default to a text-only FlexButton (Primary\n // palette → content.primary text, no fill), per the Figma \"Flex\n // Button\" node. hoverBackground is left at its default so the subtle\n // mono hover overlay from the design is preserved.\n variant: props.variant ?? \"primary\",\n background: props.background ?? false,\n }\n );\n };\n\n if (variant === \"announcement\") {\n const isMobileAnnouncement = device === \"mobile\";\n\n if (isMobileAnnouncement) {\n const descriptionIndent = showIcon\n ? config.announcementIconSize + config.announcementContentGap\n : 0;\n\n return (\n <Box\n backgroundColor={currentConfig.announcementBg}\n flexDirection=\"row\"\n alignItems=\"stretch\"\n padding={config.announcementPadding}\n gap={config.announcementGap}\n overflow=\"hidden\"\n testID={testID}\n style={{\n backdropFilter: `blur(${config.announcementBlurRadius}px)`,\n }}\n {...ariaProps}\n >\n <Box\n flex={1}\n minWidth={0}\n flexDirection=\"column\"\n gap={config.textGap}\n >\n <Box\n flexDirection=\"row\"\n alignItems=\"flex-start\"\n gap={config.announcementContentGap}\n >\n {showIcon &&\n (icon || (\n <IconComponent\n size={config.announcementIconSize}\n color={currentConfig.iconColor}\n variant=\"solid\"\n />\n ))}\n {title && (\n <Box flex={1} minWidth={0}>\n <Typography\n variant=\"bodyXsAccent\"\n color={theme.colors.content.primary}\n noWrap\n >\n {title}\n </Typography>\n </Box>\n )}\n </Box>\n\n {description && (\n <Box paddingLeft={descriptionIndent}>\n <Typography\n variant=\"bodyXs\"\n color={theme.colors.content.secondary}\n noWrap\n >\n {description}\n </Typography>\n </Box>\n )}\n </Box>\n\n {(actionButton || showCloseButton) && (\n <Box\n flexShrink={0}\n alignSelf=\"flex-start\"\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={config.announcementButtonsGap}\n >\n {renderActionButton()}\n {renderCloseButton(config.announcementCloseIconSize)}\n </Box>\n )}\n </Box>\n );\n }\n\n return (\n <Box\n backgroundColor={currentConfig.announcementBg}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"flex-start\"\n padding={config.announcementPadding}\n gap={config.announcementGap}\n overflow=\"hidden\"\n testID={testID}\n style={{\n backdropFilter: `blur(${config.announcementBlurRadius}px)`,\n }}\n {...ariaProps}\n >\n <Box\n flex={1}\n minWidth={0}\n overflow=\"hidden\"\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={config.announcementContentGap}\n >\n {showIcon &&\n (icon || (\n <IconComponent\n size={config.announcementIconSize}\n color={currentConfig.iconColor}\n variant=\"solid\"\n />\n ))}\n <Box\n flex={1}\n minWidth={0}\n overflow=\"hidden\"\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={config.announcementContentGap}\n >\n {title && (\n <Typography\n variant=\"bodyXsAccent\"\n color={theme.colors.content.primary}\n noWrap\n >\n {title}\n </Typography>\n )}\n {description && (\n <Typography\n variant=\"bodyXs\"\n color={theme.colors.content.secondary}\n noWrap\n >\n {description}\n </Typography>\n )}\n </Box>\n </Box>\n\n {(actionButton || showCloseButton) && (\n <Box\n flexShrink={0}\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={config.announcementButtonsGap}\n >\n {renderActionButton()}\n {renderCloseButton(config.announcementCloseIconSize)}\n </Box>\n )}\n </Box>\n );\n }\n\n if (device === \"mobile\") {\n return (\n <Box\n backgroundColor={currentConfig.panelBg}\n borderRadius={config.borderRadius}\n flexDirection=\"row\"\n alignItems=\"flex-start\"\n justifyContent=\"space-between\"\n overflow=\"hidden\"\n testID={testID}\n {...ariaProps}\n >\n {showIcon && (\n <Box\n alignSelf=\"stretch\"\n paddingTop={config.mobileIconColumnPaddingVertical}\n paddingBottom={config.mobileIconColumnPaddingVertical}\n paddingLeft={config.mobileIconColumnPaddingLeft}\n alignItems=\"flex-start\"\n justifyContent=\"flex-start\"\n >\n {icon || (\n <IconComponent\n size={config.mobileIconSize}\n color={currentConfig.iconColor}\n variant=\"solid\"\n />\n )}\n </Box>\n )}\n\n <Box\n flex={1}\n minWidth={0}\n paddingHorizontal={config.mobileBodyPaddingHorizontal}\n paddingVertical={config.mobileBodyPaddingVertical}\n flexDirection=\"column\"\n alignItems=\"flex-start\"\n justifyContent=\"center\"\n gap={config.mobileBodyContentGap}\n >\n {(title || description) && (\n <Box alignSelf=\"stretch\" gap={config.textGap}>\n {title && (\n <Typography\n variant=\"bodySmAccent\"\n color={theme.colors.content.primary}\n >\n {title}\n </Typography>\n )}\n {description && (\n <Typography\n variant=\"bodyXs\"\n color={theme.colors.content.tertiary}\n >\n {description}\n </Typography>\n )}\n </Box>\n )}\n\n {actionButton && (\n <Box marginLeft={config.mobileNotificationActionButtonOffsetLeft}>\n {renderActionButton()}\n </Box>\n )}\n </Box>\n\n {showCloseButton && (\n <Box\n alignSelf=\"stretch\"\n flexDirection=\"row\"\n paddingTop={config.mobileCloseColumnPaddingVertical}\n paddingBottom={config.mobileCloseColumnPaddingVertical}\n paddingRight={config.mobileCloseColumnPaddingRight}\n alignItems=\"flex-start\"\n justifyContent=\"flex-end\"\n >\n {renderCloseButton(config.notificationCloseIconSize)}\n </Box>\n )}\n </Box>\n );\n }\n\n return (\n <Box\n backgroundColor={currentConfig.panelBg}\n borderRadius={config.borderRadius}\n flexDirection=\"row\"\n alignItems=\"stretch\"\n overflow=\"hidden\"\n testID={testID}\n {...ariaProps}\n >\n {/* Icon Frame */}\n {showIcon && (\n <Box\n backgroundColor={currentConfig.iconFrameBg}\n width={config.iconFrameWidth}\n alignItems=\"center\"\n justifyContent=\"center\"\n style={{\n borderTopLeftRadius: config.borderRadius,\n borderBottomLeftRadius: config.borderRadius,\n }}\n >\n {icon || (\n <IconComponent\n size={config.iconSize}\n color={currentConfig.iconColor}\n variant=\"solid\"\n />\n )}\n </Box>\n )}\n\n {/* Body */}\n <Box\n flex={1}\n flexDirection=\"row\"\n alignItems=\"center\"\n paddingHorizontal={config.bodyPaddingHorizontal}\n paddingVertical={config.bodyPaddingVertical}\n gap={config.contentGap}\n >\n {/* Text Content */}\n <Box flex={1} gap={config.textGap}>\n {title && (\n <Typography\n variant=\"bodyMdAccent\"\n color={theme.colors.content.primary}\n >\n {title}\n </Typography>\n )}\n {description && (\n <Typography variant=\"bodySm\" color={theme.colors.content.tertiary}>\n {description}\n </Typography>\n )}\n </Box>\n\n {/* Buttons */}\n {(actionButton || showCloseButton) && (\n <Box\n flexDirection=\"row\"\n alignSelf={closeButtonAlign === \"top\" ? \"flex-start\" : undefined}\n alignItems=\"center\"\n flexShrink={0}\n gap={config.buttonsGap}\n >\n {renderActionButton()}\n {renderCloseButton(config.notificationCloseIconSize)}\n </Box>\n )}\n </Box>\n </Box>\n );\n};\n\nNotificationPanel.displayName = \"NotificationPanel\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n flexDirection,\n alignItems,\n justifyContent,\n position,\n top,\n bottom,\n left,\n right,\n width,\n minWidth,\n minHeight,\n maxWidth,\n maxHeight,\n flex,\n overflow,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n minWidth: minWidth as DimensionValue,\n minHeight: minHeight as DimensionValue,\n maxWidth: maxWidth as DimensionValue,\n maxHeight: maxHeight as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n flexDirection,\n alignItems,\n justifyContent,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Destructure and drop web-only props from rest before passing to RN components\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": _ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": _ariaDisabled,\n \"aria-live\": _ariaLive,\n className,\n \"data-testid\": _dataTestId,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n if (onPress) {\n return (\n <Pressable\n onPress={onPress}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n"],"mappings":"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","names":["jsx"]}
1
+ {"version":3,"sources":["../../src/NotificationPanel.tsx","../../../../foundation/primitives-native/src/Box.tsx"],"sourcesContent":["import React, { cloneElement, isValidElement } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport {\n IconButton,\n type ButtonProps,\n type IconButtonProps,\n type FlexButtonProps,\n} from \"@xsolla/xui-button\";\nimport { Typography } from \"@xsolla/xui-typography\";\nimport {\n ExclamationMarkSq,\n InfoSq,\n CheckCr,\n Remove,\n type BaseIconComponent,\n} from \"@xsolla/xui-icons-base\";\n\nexport type ActionButtonElement = React.ReactElement<\n ButtonProps | IconButtonProps | FlexButtonProps\n>;\n\nexport type NotificationPanelDevice = \"desktop\" | \"mobile\";\n\n/** Test id on the default type icon, so its colour is assertable. */\nconst ICON_TEST_ID = \"notification-panel-icon\";\n\nexport interface NotificationPanelProps extends ThemeOverrideProps {\n /**\n * Layout variant.\n * - `notification` (default): full-height banner with an icon frame and a\n * stacked title/description.\n * - `announcement`: slim, single-line bar with an inline icon and the\n * title/description on one row.\n */\n variant?: \"notification\" | \"announcement\";\n /**\n * Device layout mode.\n * - `desktop` (default): horizontal layout with actions on the right.\n * - `mobile`: Figma mobile layout — `notification` uses a three-column row\n * (icon | stacked text + action | close); `announcement` puts icon, title,\n * on one row with description below; action and close are grouped on the\n * right, top-aligned with the title row.\n */\n device?: NotificationPanelDevice;\n /** Visual variant/tone of the notification */\n type?: \"alert\" | \"warning\" | \"success\" | \"neutral\" | \"brand\";\n /** Title text (optional) */\n title?: string;\n /** Description text (optional) */\n description?: string;\n /** Show/hide the icon frame */\n showIcon?: boolean;\n /** Custom icon override (optional). Rendered as authored — the panel does not recolour it. */\n icon?: React.ReactNode;\n /**\n * Action button (optional - pass any Button/IconButton/FlexButton component).\n * `size` — plus `variant` and `background` for non-IconButton actions — falls\n * back to a panel default, but any value you set on the button element itself\n * takes precedence. `tone` is never overridden by the panel.\n */\n actionButton?: React.ReactElement;\n /** Show/hide close button */\n showCloseButton?: boolean;\n /** Close button click handler */\n onClose?: () => void;\n /**\n * Vertical alignment of the action/close button group — \"center\" (default) or\n * \"top\". Applies to the desktop `notification` variant only.\n */\n closeButtonAlign?: \"center\" | \"top\";\n testID?: string;\n}\n\nexport const NotificationPanel: React.FC<NotificationPanelProps> = ({\n variant = \"notification\",\n device = \"desktop\",\n type = \"neutral\",\n title,\n description,\n showIcon = true,\n icon,\n actionButton,\n showCloseButton = true,\n onClose,\n closeButtonAlign = \"center\",\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const config = theme.sizing.notificationPanel(device);\n\n const typeConfig: Record<\n NonNullable<NotificationPanelProps[\"type\"]>,\n {\n panelBg: string;\n /** Background of the slim announcement bar (and inline icon area). */\n announcementBg: string;\n iconFrameBg: string;\n /**\n * Glyph colour when the icon sits directly on the panel or announcement\n * surface — the mobile `notification` icon column and both\n * `announcement` layouts. Those surfaces are `overlay.*` /\n * `background.*.secondary`, which track the theme, so the glyph tracks\n * it too via `content.primary`.\n */\n iconColor: string;\n /**\n * Glyph colour inside the desktop `notification` icon frame.\n *\n * `warning` and `success` fill that frame with a solid light token\n * (`background.warning.primary` #ffc380 / `background.success.primary`\n * #95ff80 — the same value in light and dark), so their glyph uses the\n * theme-independent `content.static.dark`. `content.primary` would be\n * near-white in dark mode and wash the icon out (XUITSD-4). Every other\n * type fills the frame with a translucent overlay over `panelBg`, where\n * `content.primary` is correct.\n */\n frameIconColor: string;\n buttonTone: \"brand\" | \"brandExtra\" | \"alert\" | \"mono\";\n IconComponent: BaseIconComponent;\n }\n > = {\n alert: {\n panelBg: theme.colors.overlay.alert,\n announcementBg: theme.colors.background.alert.secondary,\n iconFrameBg: theme.colors.overlay.alert,\n iconColor: theme.colors.content.primary,\n frameIconColor: theme.colors.content.primary,\n buttonTone: \"alert\",\n IconComponent: ExclamationMarkSq,\n },\n warning: {\n panelBg: theme.colors.overlay.warning,\n announcementBg: theme.colors.background.warning.secondary,\n iconFrameBg: theme.colors.background.warning.primary,\n iconColor: theme.colors.content.primary,\n frameIconColor: theme.colors.content.static.dark,\n buttonTone: \"mono\",\n IconComponent: ExclamationMarkSq,\n },\n success: {\n panelBg: theme.colors.overlay.success,\n announcementBg: theme.colors.background.success.secondary,\n iconFrameBg: theme.colors.background.success.primary,\n iconColor: theme.colors.content.primary,\n frameIconColor: theme.colors.content.static.dark,\n buttonTone: \"brandExtra\",\n IconComponent: CheckCr,\n },\n neutral: {\n panelBg: theme.colors.overlay.mono,\n announcementBg: theme.colors.background.neutral.secondary,\n iconFrameBg: theme.colors.overlay.mono,\n iconColor: theme.colors.content.primary,\n frameIconColor: theme.colors.content.primary,\n buttonTone: \"mono\",\n IconComponent: InfoSq,\n },\n brand: {\n panelBg: theme.colors.overlay.brand,\n announcementBg: theme.colors.background.brand.secondary,\n iconFrameBg: theme.colors.overlay.brand,\n iconColor: theme.colors.content.primary,\n frameIconColor: theme.colors.content.primary,\n buttonTone: \"brand\",\n IconComponent: InfoSq,\n },\n };\n\n const currentConfig = typeConfig[type];\n const IconComponent = currentConfig.IconComponent;\n\n const ariaProps = {\n role: type === \"alert\" ? \"alert\" : \"status\",\n \"aria-label\": `${type} ${variant} ${device}`,\n } as const;\n\n // IconButton (Box-based) stays RN-safe; FlexButton is web-DOM-only.\n const renderCloseButton = (iconSize: number) =>\n showCloseButton ? (\n <IconButton\n variant=\"tertiary\"\n tone=\"mono\"\n size=\"xs\"\n onPress={onClose}\n aria-label=\"Close notification\"\n icon={<Remove size={iconSize} />}\n hoverBackground=\"none\"\n />\n ) : null;\n\n const renderActionButton = () => {\n if (!isValidElement(actionButton)) return null;\n\n const element = actionButton as ActionButtonElement;\n const isIconButton =\n (element.type as { displayName?: string }).displayName === \"IconButton\";\n\n // Caller-supplied props on the element win; the values below are defaults\n // applied only when the caller omits them. (Previously they were hard-coded,\n // and cloneElement's second argument overrides the element's own props, so a\n // passed-in size/variant was silently ignored.)\n const props = element.props as Partial<\n ButtonProps & IconButtonProps & FlexButtonProps\n >;\n\n return cloneElement(\n element,\n isIconButton\n ? { size: props.size ?? \"xs\" }\n : {\n size: props.size ?? \"xs\",\n // Non-IconButton actions default to a text-only FlexButton (Primary\n // palette → content.primary text, no fill), per the Figma \"Flex\n // Button\" node. hoverBackground is left at its default so the subtle\n // mono hover overlay from the design is preserved.\n variant: props.variant ?? \"primary\",\n background: props.background ?? false,\n }\n );\n };\n\n if (variant === \"announcement\") {\n const isMobileAnnouncement = device === \"mobile\";\n\n if (isMobileAnnouncement) {\n const descriptionIndent = showIcon\n ? config.announcementIconSize + config.announcementContentGap\n : 0;\n\n return (\n <Box\n backgroundColor={currentConfig.announcementBg}\n flexDirection=\"row\"\n alignItems=\"stretch\"\n padding={config.announcementPadding}\n gap={config.announcementGap}\n overflow=\"hidden\"\n testID={testID}\n style={{\n backdropFilter: `blur(${config.announcementBlurRadius}px)`,\n }}\n {...ariaProps}\n >\n <Box\n flex={1}\n minWidth={0}\n flexDirection=\"column\"\n gap={config.textGap}\n >\n <Box\n flexDirection=\"row\"\n alignItems=\"flex-start\"\n gap={config.announcementContentGap}\n >\n {showIcon &&\n (icon || (\n <IconComponent\n size={config.announcementIconSize}\n color={currentConfig.iconColor}\n variant=\"solid\"\n data-testid={ICON_TEST_ID}\n />\n ))}\n {title && (\n <Box flex={1} minWidth={0}>\n <Typography\n variant=\"bodyXsAccent\"\n color={theme.colors.content.primary}\n noWrap\n >\n {title}\n </Typography>\n </Box>\n )}\n </Box>\n\n {description && (\n <Box paddingLeft={descriptionIndent}>\n <Typography\n variant=\"bodyXs\"\n color={theme.colors.content.secondary}\n noWrap\n >\n {description}\n </Typography>\n </Box>\n )}\n </Box>\n\n {(actionButton || showCloseButton) && (\n <Box\n flexShrink={0}\n alignSelf=\"flex-start\"\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={config.announcementButtonsGap}\n >\n {renderActionButton()}\n {renderCloseButton(config.announcementCloseIconSize)}\n </Box>\n )}\n </Box>\n );\n }\n\n return (\n <Box\n backgroundColor={currentConfig.announcementBg}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"flex-start\"\n padding={config.announcementPadding}\n gap={config.announcementGap}\n overflow=\"hidden\"\n testID={testID}\n style={{\n backdropFilter: `blur(${config.announcementBlurRadius}px)`,\n }}\n {...ariaProps}\n >\n <Box\n flex={1}\n minWidth={0}\n overflow=\"hidden\"\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={config.announcementContentGap}\n >\n {showIcon &&\n (icon || (\n <IconComponent\n size={config.announcementIconSize}\n color={currentConfig.iconColor}\n variant=\"solid\"\n data-testid={ICON_TEST_ID}\n />\n ))}\n <Box\n flex={1}\n minWidth={0}\n overflow=\"hidden\"\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={config.announcementContentGap}\n >\n {title && (\n <Typography\n variant=\"bodyXsAccent\"\n color={theme.colors.content.primary}\n noWrap\n >\n {title}\n </Typography>\n )}\n {description && (\n <Typography\n variant=\"bodyXs\"\n color={theme.colors.content.secondary}\n noWrap\n >\n {description}\n </Typography>\n )}\n </Box>\n </Box>\n\n {(actionButton || showCloseButton) && (\n <Box\n flexShrink={0}\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={config.announcementButtonsGap}\n >\n {renderActionButton()}\n {renderCloseButton(config.announcementCloseIconSize)}\n </Box>\n )}\n </Box>\n );\n }\n\n if (device === \"mobile\") {\n return (\n <Box\n backgroundColor={currentConfig.panelBg}\n borderRadius={config.borderRadius}\n flexDirection=\"row\"\n alignItems=\"flex-start\"\n justifyContent=\"space-between\"\n overflow=\"hidden\"\n testID={testID}\n {...ariaProps}\n >\n {showIcon && (\n <Box\n alignSelf=\"stretch\"\n paddingTop={config.mobileIconColumnPaddingVertical}\n paddingBottom={config.mobileIconColumnPaddingVertical}\n paddingLeft={config.mobileIconColumnPaddingLeft}\n alignItems=\"flex-start\"\n justifyContent=\"flex-start\"\n >\n {icon || (\n <IconComponent\n size={config.mobileIconSize}\n color={currentConfig.iconColor}\n variant=\"solid\"\n data-testid={ICON_TEST_ID}\n />\n )}\n </Box>\n )}\n\n <Box\n flex={1}\n minWidth={0}\n paddingHorizontal={config.mobileBodyPaddingHorizontal}\n paddingVertical={config.mobileBodyPaddingVertical}\n flexDirection=\"column\"\n alignItems=\"flex-start\"\n justifyContent=\"center\"\n gap={config.mobileBodyContentGap}\n >\n {(title || description) && (\n <Box alignSelf=\"stretch\" gap={config.textGap}>\n {title && (\n <Typography\n variant=\"bodySmAccent\"\n color={theme.colors.content.primary}\n >\n {title}\n </Typography>\n )}\n {description && (\n <Typography\n variant=\"bodyXs\"\n color={theme.colors.content.tertiary}\n >\n {description}\n </Typography>\n )}\n </Box>\n )}\n\n {actionButton && (\n <Box marginLeft={config.mobileNotificationActionButtonOffsetLeft}>\n {renderActionButton()}\n </Box>\n )}\n </Box>\n\n {showCloseButton && (\n <Box\n alignSelf=\"stretch\"\n flexDirection=\"row\"\n paddingTop={config.mobileCloseColumnPaddingVertical}\n paddingBottom={config.mobileCloseColumnPaddingVertical}\n paddingRight={config.mobileCloseColumnPaddingRight}\n alignItems=\"flex-start\"\n justifyContent=\"flex-end\"\n >\n {renderCloseButton(config.notificationCloseIconSize)}\n </Box>\n )}\n </Box>\n );\n }\n\n return (\n <Box\n backgroundColor={currentConfig.panelBg}\n borderRadius={config.borderRadius}\n flexDirection=\"row\"\n alignItems=\"stretch\"\n overflow=\"hidden\"\n testID={testID}\n {...ariaProps}\n >\n {/* Icon Frame */}\n {showIcon && (\n <Box\n backgroundColor={currentConfig.iconFrameBg}\n width={config.iconFrameWidth}\n alignItems=\"center\"\n justifyContent=\"center\"\n style={{\n borderTopLeftRadius: config.borderRadius,\n borderBottomLeftRadius: config.borderRadius,\n }}\n >\n {icon || (\n <IconComponent\n size={config.iconSize}\n color={currentConfig.frameIconColor}\n variant=\"solid\"\n data-testid={ICON_TEST_ID}\n />\n )}\n </Box>\n )}\n\n {/* Body */}\n <Box\n flex={1}\n flexDirection=\"row\"\n alignItems=\"center\"\n paddingHorizontal={config.bodyPaddingHorizontal}\n paddingVertical={config.bodyPaddingVertical}\n gap={config.contentGap}\n >\n {/* Text Content */}\n <Box flex={1} gap={config.textGap}>\n {title && (\n <Typography\n variant=\"bodyMdAccent\"\n color={theme.colors.content.primary}\n >\n {title}\n </Typography>\n )}\n {description && (\n <Typography variant=\"bodySm\" color={theme.colors.content.tertiary}>\n {description}\n </Typography>\n )}\n </Box>\n\n {/* Buttons */}\n {(actionButton || showCloseButton) && (\n <Box\n flexDirection=\"row\"\n alignSelf={closeButtonAlign === \"top\" ? \"flex-start\" : undefined}\n alignItems=\"center\"\n flexShrink={0}\n gap={config.buttonsGap}\n >\n {renderActionButton()}\n {renderCloseButton(config.notificationCloseIconSize)}\n </Box>\n )}\n </Box>\n </Box>\n );\n};\n\nNotificationPanel.displayName = \"NotificationPanel\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n flexDirection,\n alignItems,\n justifyContent,\n position,\n top,\n bottom,\n left,\n right,\n width,\n minWidth,\n minHeight,\n maxWidth,\n maxHeight,\n flex,\n overflow,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n minWidth: minWidth as DimensionValue,\n minHeight: minHeight as DimensionValue,\n maxWidth: maxWidth as DimensionValue,\n maxHeight: maxHeight as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n flexDirection,\n alignItems,\n justifyContent,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Destructure and drop web-only props from rest before passing to RN components\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": _ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": _ariaDisabled,\n \"aria-live\": _ariaLive,\n className,\n \"data-testid\": _dataTestId,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n if (onPress) {\n return (\n <Pressable\n onPress={onPress}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n"],"mappings":"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","names":["jsx"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xsolla/xui-b2b-notification-panel",
3
- "version": "0.197.0",
3
+ "version": "0.198.0",
4
4
  "main": "./web/index.js",
5
5
  "module": "./web/index.mjs",
6
6
  "types": "./web/index.d.ts",
@@ -13,11 +13,11 @@
13
13
  "test:coverage": "vitest run --coverage"
14
14
  },
15
15
  "dependencies": {
16
- "@xsolla/xui-button": "0.197.0",
17
- "@xsolla/xui-core": "0.197.0",
18
- "@xsolla/xui-icons-base": "0.197.0",
19
- "@xsolla/xui-primitives-core": "0.197.0",
20
- "@xsolla/xui-typography": "0.197.0"
16
+ "@xsolla/xui-button": "0.198.0",
17
+ "@xsolla/xui-core": "0.198.0",
18
+ "@xsolla/xui-icons-base": "0.198.0",
19
+ "@xsolla/xui-primitives-core": "0.198.0",
20
+ "@xsolla/xui-typography": "0.198.0"
21
21
  },
22
22
  "peerDependencies": {
23
23
  "react": ">=16.8.0",
package/web/index.d.mts CHANGED
@@ -30,7 +30,7 @@ interface NotificationPanelProps extends ThemeOverrideProps {
30
30
  description?: string;
31
31
  /** Show/hide the icon frame */
32
32
  showIcon?: boolean;
33
- /** Custom icon override (optional) */
33
+ /** Custom icon override (optional). Rendered as authored — the panel does not recolour it. */
34
34
  icon?: React.ReactNode;
35
35
  /**
36
36
  * Action button (optional - pass any Button/IconButton/FlexButton component).
package/web/index.d.ts CHANGED
@@ -30,7 +30,7 @@ interface NotificationPanelProps extends ThemeOverrideProps {
30
30
  description?: string;
31
31
  /** Show/hide the icon frame */
32
32
  showIcon?: boolean;
33
- /** Custom icon override (optional) */
33
+ /** Custom icon override (optional). Rendered as authored — the panel does not recolour it. */
34
34
  icon?: React.ReactNode;
35
35
  /**
36
36
  * Action button (optional - pass any Button/IconButton/FlexButton component).