@shopgate/engage 7.32.0-beta.6 → 7.32.0-beta.7

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 (83) hide show
  1. package/account/components/Profile/ProfileAddressCard.d.ts.map +1 -1
  2. package/account/components/Profile/ProfileAddressCard.js +1 -0
  3. package/admin-preview/components/FrontendSettingsPreviewBridge/types.d.ts +2 -2
  4. package/admin-preview/components/FrontendSettingsPreviewBridge/types.d.ts.map +1 -1
  5. package/cart/components/CartItems/CartItems.js +8 -10
  6. package/cart/components/CartItems/CartItemsSubstitution.js +3 -2
  7. package/components/Card/Card.d.ts +27 -0
  8. package/components/Card/Card.d.ts.map +1 -0
  9. package/components/Card/Card.js +57 -0
  10. package/components/Card/index.d.ts +4 -0
  11. package/components/Card/index.d.ts.map +1 -0
  12. package/components/Card/index.js +2 -0
  13. package/components/Card/spec.d.ts +2 -0
  14. package/components/Card/spec.d.ts.map +1 -0
  15. package/components/Card/spec.js +128 -0
  16. package/components/Card/useCardAppearance.d.ts +11 -0
  17. package/components/Card/useCardAppearance.d.ts.map +1 -0
  18. package/components/Card/useCardAppearance.js +22 -0
  19. package/components/Paper/Paper.d.ts +49 -0
  20. package/components/Paper/Paper.d.ts.map +1 -0
  21. package/components/Paper/Paper.js +64 -0
  22. package/components/Paper/index.d.ts +3 -0
  23. package/components/Paper/index.d.ts.map +1 -0
  24. package/components/Paper/index.js +1 -0
  25. package/components/Paper/spec.d.ts +2 -0
  26. package/components/Paper/spec.d.ts.map +1 -0
  27. package/components/Paper/spec.js +131 -0
  28. package/components/RadioCard/RadioCard.d.ts.map +1 -1
  29. package/components/RadioCard/RadioCard.js +2 -1
  30. package/components/index.d.ts +4 -1
  31. package/components/index.d.ts.map +1 -1
  32. package/components/index.js +3 -2
  33. package/favorites/components/Item/Item.d.ts +1 -1
  34. package/orders/components/OrderHistory/OrderHistoryList.d.ts.map +1 -1
  35. package/orders/components/OrderHistory/OrderHistoryList.js +8 -9
  36. package/orders/components/OrderHistory/OrderHistoryTable.d.ts.map +1 -1
  37. package/orders/components/OrderHistory/OrderHistoryTable.js +4 -0
  38. package/package.json +7 -7
  39. package/product/components/ProductCard/index.js +27 -14
  40. package/product/components/ProductGrid/components/Item/components/ItemDetails/index.js +6 -3
  41. package/product/components/ProductGrid/components/Item/components/ItemName/index.js +5 -1
  42. package/product/components/ProductGrid/components/Item/components/ItemName/spec.js +19 -1
  43. package/product/components/ProductGrid/components/Item/index.js +9 -1
  44. package/product/components/ProductSlider/index.js +4 -2
  45. package/product/components/RelationsSlider/RelationsSliderContent.js +3 -2
  46. package/product/components/RelationsSlider/constants.d.ts +3 -0
  47. package/product/components/RelationsSlider/constants.d.ts.map +1 -0
  48. package/product/components/RelationsSlider/constants.js +2 -1
  49. package/product/components/RelationsSlider/hooks.d.ts +6 -0
  50. package/product/components/RelationsSlider/hooks.d.ts.map +1 -0
  51. package/product/components/RelationsSlider/hooks.js +34 -0
  52. package/settings/action-creators/appSettings.d.ts +3 -3
  53. package/settings/action-creators/appSettings.d.ts.map +1 -1
  54. package/settings/reducers/appSettings.d.ts.map +1 -1
  55. package/settings/reducers/appSettings.js +31 -17
  56. package/settings/reducers/index.d.ts +1 -1
  57. package/settings/selectors/appSettings.d.ts +32 -0
  58. package/settings/selectors/appSettings.d.ts.map +1 -1
  59. package/settings/selectors/appSettings.js +21 -1
  60. package/settings/types/appSettings.d.ts +48 -0
  61. package/settings/types/appSettings.d.ts.map +1 -1
  62. package/styles/index.d.ts +1 -1
  63. package/styles/index.d.ts.map +1 -1
  64. package/styles/theme/createTheme/createComponents.types.d.ts +50 -0
  65. package/styles/theme/createTheme/createComponents.types.d.ts.map +1 -1
  66. package/styles/theme/createTheme/createComponents.types.js +50 -0
  67. package/styles/theme/createTheme/createCssVarsForColorSchemeThemes.d.ts.map +1 -1
  68. package/styles/theme/createTheme/createCssVarsForColorSchemeThemes.js +5 -1
  69. package/styles/theme/createTheme/createPalette.types.d.ts +4 -0
  70. package/styles/theme/createTheme/createPalette.types.d.ts.map +1 -1
  71. package/styles/theme/createTheme/createPalette.types.js +5 -1
  72. package/styles/theme/createTheme/createShape.d.ts +4 -0
  73. package/styles/theme/createTheme/createShape.d.ts.map +1 -1
  74. package/styles/theme/createTheme/createShape.js +2 -1
  75. package/styles/theme/createTheme/createThemeFromColorScheme.d.ts.map +1 -1
  76. package/styles/theme/createTheme/createThemeFromColorScheme.js +2 -1
  77. package/styles/theme/createTheme/shadows.d.ts +11 -1
  78. package/styles/theme/createTheme/shadows.d.ts.map +1 -1
  79. package/styles/theme/createTheme/shadows.js +41 -7
  80. package/styles/theme/createTheme/types.d.ts +5 -1
  81. package/styles/theme/createTheme/types.d.ts.map +1 -1
  82. package/styles/theme/index.d.ts +1 -0
  83. package/styles/theme/index.d.ts.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ProfileAddressCard.d.ts","sourceRoot":"","sources":["../../../../account/components/Profile/ProfileAddressCard.jsx"],"names":[],"mappings":";AAwEA;;GAEG;AACH;;;;;;IAFa,GAAG,CAkGf;;;;;;;;;;;;;;;;sBA1KqB,YAAY"}
1
+ {"version":3,"file":"ProfileAddressCard.d.ts","sourceRoot":"","sources":["../../../../account/components/Profile/ProfileAddressCard.jsx"],"names":[],"mappings":";AAyEA;;GAEG;AACH;;;;;;IAFa,GAAG,CAkGf;;;;;;;;;;;;;;;;sBA3KqB,YAAY"}
@@ -8,6 +8,7 @@ import iso3166 from "../../../components/Form/Builder/helpers/iso-3166-2";
8
8
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
9
9
  const useStyles = makeStyles()(theme => ({
10
10
  root: {
11
+ margin: '5px 5px 10px',
11
12
  padding: 16,
12
13
  display: 'flex',
13
14
  flexDirection: 'column',
@@ -1,4 +1,4 @@
1
- import type { AppSettings } from '@shopgate/engage/settings/types/appSettings';
1
+ import type { AppSettingsPayload } from '@shopgate/engage/settings/types/appSettings';
2
2
  import type { ColorSchemeName } from '@shopgate/engage/styles/theme/createTheme';
3
3
  export type CSSDeclarationValue = string | number;
4
4
  export type FrontendSettingsStyling = Record<string, Record<string, CSSDeclarationValue>>;
@@ -6,7 +6,7 @@ export type FrontendSettingsPreviewBridgeMessage = {
6
6
  type: 'receiveFrontendSettings';
7
7
  payload?: {
8
8
  styling?: FrontendSettingsStyling;
9
- appSettings?: AppSettings;
9
+ appSettings?: AppSettingsPayload;
10
10
  };
11
11
  } | {
12
12
  type: 'setColorScheme';
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../admin-preview/components/FrontendSettingsPreviewBridge/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6CAA6C,CAAC;AAC/E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAEjF,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,MAAM,CAAC;AAClD,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC;AAE1F,MAAM,MAAM,oCAAoC,GAC5C;IACA,IAAI,EAAE,yBAAyB,CAAC;IAChC,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,EAAE,uBAAuB,CAAC;QAClC,WAAW,CAAC,EAAE,WAAW,CAAC;KAC3B,CAAC;CACH,GACC;IACA,IAAI,EAAE,gBAAgB,CAAC;IACvB,OAAO,EAAE;QACP,WAAW,EAAE,eAAe,CAAC;KAC9B,CAAC;CACH,GACC;IACA,IAAI,EAAE,8BAA8B,CAAC;IACrC,OAAO,CAAC,EAAE,KAAK,CAAC;CACjB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../admin-preview/components/FrontendSettingsPreviewBridge/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AACtF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAEjF,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,MAAM,CAAC;AAClD,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC;AAE1F,MAAM,MAAM,oCAAoC,GAC5C;IACA,IAAI,EAAE,yBAAyB,CAAC;IAChC,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,EAAE,uBAAuB,CAAC;QAClC,WAAW,CAAC,EAAE,kBAAkB,CAAC;KAClC,CAAC;CACH,GACC;IACA,IAAI,EAAE,gBAAgB,CAAC;IACvB,OAAO,EAAE;QACP,WAAW,EAAE,eAAe,CAAC;KAC9B,CAAC;CACH,GACC;IACA,IAAI,EAAE,8BAA8B,CAAC;IACrC,OAAO,CAAC,EAAE,KAAK,CAAC;CACjB,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { CardList, ResponsiveContainer } from '@shopgate/engage/components';
2
+ import { ResponsiveContainer, Card } from '@shopgate/engage/components';
3
3
  import { FulfillmentSlotSwitcher } from '@shopgate/engage/locations';
4
4
  import { makeStyles } from '@shopgate/engage/styles';
5
5
  import PropTypes from 'prop-types';
@@ -14,15 +14,11 @@ const useStyles = makeStyles()(theme => ({
14
14
  marginBottom: theme.spacing(-1.5)
15
15
  },
16
16
  card: {
17
- background: theme.palette.background.surface,
18
17
  marginBottom: theme.spacing(1.5),
19
18
  ':last-of-type': {
20
19
  marginBottom: 0
21
20
  },
22
- border: `1px solid ${theme.components.border.light}`,
23
- boxSizing: 'border-box',
24
- boxShadow: '0px 4px 2px rgba(0, 0, 0, 0.05)',
25
- borderRadius: 5
21
+ boxSizing: 'border-box'
26
22
  }
27
23
  }));
28
24
 
@@ -54,7 +50,8 @@ const CartItems = ({
54
50
  isDirectShipOnly
55
51
  }) => {
56
52
  const {
57
- classes
53
+ classes,
54
+ cx
58
55
  } = useStyles();
59
56
  if (!cartItems || cartItems.length === 0) {
60
57
  return null;
@@ -69,8 +66,8 @@ const CartItems = ({
69
66
  isDirectShipOnly: isDirectShipOnly,
70
67
  isCheckoutConfirmation: isCheckoutConfirmation
71
68
  })
72
- }), /*#__PURE__*/_jsxs(CardList, {
73
- className: classes.items,
69
+ }), /*#__PURE__*/_jsxs("ul", {
70
+ className: cx('ui-shared__card-list', classes.items),
74
71
  children: [!isOrderDetails ? /*#__PURE__*/_jsx(ResponsiveContainer, {
75
72
  appAlways: true,
76
73
  breakpoint: "<=xs",
@@ -87,8 +84,9 @@ const CartItems = ({
87
84
  wrapCard: true,
88
85
  className: classes.card
89
86
  })
90
- }), cartItems.map(item => /*#__PURE__*/_jsx(CardList.Item, {
87
+ }), cartItems.map(item => /*#__PURE__*/_jsx(Card, {
91
88
  className: classes.card,
89
+ component: "li",
92
90
  children: /*#__PURE__*/_jsx(CartItemProvider, {
93
91
  cartItem: item,
94
92
  isEditable: editable,
@@ -1,7 +1,7 @@
1
1
  import React, { useMemo, useCallback } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { i18n } from '@shopgate/engage/core/helpers';
4
- import { CardList } from '@shopgate/engage/components';
4
+ import { Card } from '@shopgate/engage/components';
5
5
  import Substitution, { SubstitutionWrapper } from "../Substitution";
6
6
  import connect from "./CartItemsSubscription.connector";
7
7
 
@@ -24,8 +24,9 @@ const CartItemsSubstitution = ({
24
24
  }))), [allAllowed, cartItems, updateProductsInCart]);
25
25
  if (wrapCard) {
26
26
  return /*#__PURE__*/_jsx(SubstitutionWrapper, {
27
- children: /*#__PURE__*/_jsx(CardList.Item, {
27
+ children: /*#__PURE__*/_jsx(Card, {
28
28
  className: className,
29
+ component: "li",
29
30
  children: /*#__PURE__*/_jsx(Substitution, {
30
31
  id: "substitution-all",
31
32
  label: i18n.text('cart.allow_substitution_all'),
@@ -0,0 +1,27 @@
1
+ import React from 'react';
2
+ import type { ShadowSize } from '@shopgate/engage/styles';
3
+ export type CardVariant = 'elevation' | 'outlined' | 'plain';
4
+ export interface CardOwnProps {
5
+ children?: React.ReactNode;
6
+ className?: string;
7
+ id?: string;
8
+ /** Element or component to render as. @default 'div' */
9
+ component?: React.ElementType;
10
+ /** Overrides the merchant-configured style. `plain` renders no chrome at all. */
11
+ variant?: CardVariant;
12
+ /** Overrides the configured elevation. Ignored unless the resolved variant is `elevation`. */
13
+ elevation?: number | ShadowSize;
14
+ /** Removes the rounded corners. */
15
+ square?: boolean;
16
+ }
17
+ export type CardProps = CardOwnProps & Omit<React.HTMLAttributes<HTMLElement>, keyof CardOwnProps> & {
18
+ [key: `data-${string}`]: string;
19
+ };
20
+ /**
21
+ * A themed content surface built on `Paper`, reading the merchant's card settings.
22
+ */
23
+ declare const Card: React.ForwardRefExoticComponent<CardOwnProps & Omit<React.HTMLAttributes<HTMLElement>, keyof CardOwnProps> & {
24
+ [key: `data-${string}`]: string;
25
+ } & React.RefAttributes<HTMLElement>>;
26
+ export default Card;
27
+ //# sourceMappingURL=Card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Card.d.ts","sourceRoot":"","sources":["../../../components/Card/Card.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAE1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAK1D,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,UAAU,GAAG,OAAO,CAAC;AAE7D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,wDAAwD;IACxD,SAAS,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC;IAC9B,iFAAiF;IACjF,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,8FAA8F;IAC9F,SAAS,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;IAChC,mCAAmC;IACnC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,MAAM,SAAS,GACnB,YAAY,GACV,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,MAAM,YAAY,CAAC,GAC3D;IAAE,CAAC,GAAG,EAAE,QAAQ,MAAM,EAAE,GAAG,MAAM,CAAA;CAAE,CAAC;AAUxC;;GAEG;AACH,QAAA,MAAM,IAAI;;qCA2BR,CAAC;AAIH,eAAe,IAAI,CAAC"}
@@ -0,0 +1,57 @@
1
+ import React, { forwardRef } from 'react';
2
+ import { useTheme, makeStyles } from '@shopgate/engage/styles';
3
+ import Paper from "../Paper";
4
+ import { useCardAppearance } from "./useCardAppearance";
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ const useStyles = makeStyles({
7
+ name: 'Card'
8
+ })((theme, {
9
+ variant
10
+ }) => ({
11
+ root: {
12
+ ...(variant !== 'plain' && {
13
+ overflow: 'hidden'
14
+ })
15
+ }
16
+ }));
17
+
18
+ /**
19
+ * A themed content surface built on `Paper`, reading the merchant's card settings.
20
+ */
21
+ const Card = /*#__PURE__*/forwardRef(({
22
+ className,
23
+ children,
24
+ id,
25
+ variant,
26
+ elevation,
27
+ square,
28
+ ...rest
29
+ }, ref) => {
30
+ const theme = useTheme();
31
+ const appearance = useCardAppearance();
32
+ const resolvedVariant = variant ?? appearance.variant;
33
+ const isPlain = resolvedVariant === 'plain';
34
+ const paperVariant = resolvedVariant === 'outlined' ? 'outlined' : 'elevation';
35
+ const {
36
+ classes,
37
+ cx
38
+ } = useStyles({
39
+ variant: resolvedVariant
40
+ });
41
+ return /*#__PURE__*/_jsx(Paper, {
42
+ ref: ref,
43
+ id: id,
44
+ variant: paperVariant,
45
+ elevation: isPlain ? 0 : elevation ?? appearance.elevation,
46
+ square: square || isPlain,
47
+ borderRadius: theme.shape.cardsBorderRadius,
48
+ background: isPlain ? 'transparent' : theme.components.cards.backgroundColor,
49
+ border: theme.components.cards.border,
50
+ shadowColor: theme.components.cards.shadowColor,
51
+ className: cx(classes.root, 'engage__card', 'ui-shared__card', className),
52
+ ...rest,
53
+ children: children
54
+ });
55
+ });
56
+ Card.displayName = 'Card';
57
+ export default Card;
@@ -0,0 +1,4 @@
1
+ export { default } from './Card';
2
+ export type { CardProps, CardVariant } from './Card';
3
+ export { useCardAppearance } from './useCardAppearance';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../components/Card/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACjC,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { default } from "./Card";
2
+ export { useCardAppearance } from "./useCardAppearance";
@@ -0,0 +1,2 @@
1
+ import '@testing-library/jest-dom';
2
+ //# sourceMappingURL=spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec.d.ts","sourceRoot":"","sources":["../../../components/Card/spec.tsx"],"names":[],"mappings":"AAEA,OAAO,2BAA2B,CAAC"}
@@ -0,0 +1,128 @@
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import '@testing-library/jest-dom';
4
+ import { Provider } from 'react-redux';
5
+ import { createStore } from 'redux';
6
+ import { ThemeProvider, createTheme } from '@shopgate/engage/styles';
7
+ import Card from "./Card";
8
+
9
+ // ThemeProvider resolves the active breakpoint via matchMedia, which jsdom doesn't implement.
10
+ import { jsx as _jsx } from "react/jsx-runtime";
11
+ Object.defineProperty(window, 'matchMedia', {
12
+ writable: true,
13
+ value: query => ({
14
+ matches: false,
15
+ media: query,
16
+ addEventListener: jest.fn(),
17
+ removeEventListener: jest.fn()
18
+ })
19
+ });
20
+ const theme = createTheme();
21
+ const styleText = () => Array.from(document.styleSheets).flatMap(sheet => {
22
+ try {
23
+ return Array.from(sheet.cssRules);
24
+ } catch {
25
+ return [];
26
+ }
27
+ }).map(rule => rule.cssText).join('');
28
+ const renderCard = (ui, cards = {
29
+ style: 'shadow',
30
+ shadow: {
31
+ size: 'medium'
32
+ }
33
+ }) => {
34
+ const store = createStore(() => ({
35
+ settings: {
36
+ appSettings: {
37
+ cards
38
+ }
39
+ }
40
+ }));
41
+ return render(/*#__PURE__*/_jsx(Provider, {
42
+ store: store,
43
+ children: /*#__PURE__*/_jsx(ThemeProvider, {
44
+ theme: theme,
45
+ children: ui
46
+ })
47
+ }));
48
+ };
49
+ describe('<Card />', () => {
50
+ it('passes id, className and children through', () => {
51
+ renderCard(/*#__PURE__*/_jsx(Card, {
52
+ id: "c1",
53
+ className: "custom",
54
+ "data-testid": "card",
55
+ children: "body"
56
+ }));
57
+ const el = screen.getByTestId('card');
58
+ expect(el).toHaveAttribute('id', 'c1');
59
+ expect(el).toHaveTextContent('body');
60
+ expect(el).toHaveClass('custom');
61
+ });
62
+ it('emits the engage__card, ui-shared__card and engage__paper classes', () => {
63
+ renderCard(/*#__PURE__*/_jsx(Card, {
64
+ "data-testid": "card",
65
+ children: "x"
66
+ }));
67
+ const el = screen.getByTestId('card');
68
+ expect(el).toHaveClass('engage__card');
69
+ expect(el).toHaveClass('ui-shared__card');
70
+ expect(el).toHaveClass('engage__paper');
71
+ });
72
+ it('draws a shadow for the configured shadow style', () => {
73
+ renderCard(/*#__PURE__*/_jsx(Card, {
74
+ "data-testid": "card",
75
+ children: "x"
76
+ }), {
77
+ style: 'shadow',
78
+ shadow: {
79
+ size: 'medium'
80
+ }
81
+ });
82
+ expect(styleText()).toContain('var(--sg-palette-shadow)');
83
+ });
84
+ it('draws the card border for the configured border style', () => {
85
+ renderCard(/*#__PURE__*/_jsx(Card, {
86
+ "data-testid": "card",
87
+ children: "x"
88
+ }), {
89
+ style: 'border',
90
+ shadow: {
91
+ size: 'none'
92
+ }
93
+ });
94
+ expect(styleText()).toContain('var(--sg-components-cards-border)');
95
+ });
96
+ it('lets an explicit variant override the configured appearance', () => {
97
+ renderCard(/*#__PURE__*/_jsx(Card, {
98
+ variant: "outlined",
99
+ "data-testid": "card",
100
+ children: "x"
101
+ }), {
102
+ style: 'shadow',
103
+ shadow: {
104
+ size: 'medium'
105
+ }
106
+ });
107
+ expect(styleText()).toContain('var(--sg-components-cards-border)');
108
+ });
109
+ it('forwards a ref to the rendered element', () => {
110
+ const ref = /*#__PURE__*/React.createRef();
111
+ renderCard(/*#__PURE__*/_jsx(Card, {
112
+ ref: ref,
113
+ "data-testid": "card",
114
+ children: "x"
115
+ }));
116
+ expect(ref.current).toBe(screen.getByTestId('card'));
117
+ });
118
+ it('renders the plain variant', () => {
119
+ renderCard(/*#__PURE__*/_jsx(Card, {
120
+ variant: "plain",
121
+ "data-testid": "card",
122
+ children: "x"
123
+ }));
124
+ const el = screen.getByTestId('card');
125
+ expect(el).toHaveClass('engage__card');
126
+ expect(el).toHaveClass('engage__paper');
127
+ });
128
+ });
@@ -0,0 +1,11 @@
1
+ import type { ShadowSize } from '@shopgate/engage/styles';
2
+ import type { CardVariant } from './Card';
3
+ /**
4
+ * Resolves the merchant-configured card appearance from app settings.
5
+ * @returns The card variant and, for the shadow style, its elevation size.
6
+ */
7
+ export declare const useCardAppearance: () => {
8
+ variant: CardVariant;
9
+ elevation: ShadowSize;
10
+ };
11
+ //# sourceMappingURL=useCardAppearance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCardAppearance.d.ts","sourceRoot":"","sources":["../../../components/Card/useCardAppearance.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAG1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAQ1C;;;GAGG;AACH,eAAO,MAAM,iBAAiB,QAAO;IAAE,OAAO,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE,UAAU,CAAA;CAQjF,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { useSelector } from 'react-redux';
2
+ import { getCardSettings, getCardShadowSize } from '@shopgate/engage/settings/selectors/appSettings';
3
+ const VARIANT_BY_STYLE = {
4
+ shadow: 'elevation',
5
+ border: 'outlined',
6
+ flat: 'elevation'
7
+ };
8
+
9
+ /**
10
+ * Resolves the merchant-configured card appearance from app settings.
11
+ * @returns The card variant and, for the shadow style, its elevation size.
12
+ */
13
+ export const useCardAppearance = () => {
14
+ const {
15
+ style
16
+ } = useSelector(getCardSettings);
17
+ const elevation = useSelector(getCardShadowSize);
18
+ return {
19
+ variant: VARIANT_BY_STYLE[style] ?? 'elevation',
20
+ elevation
21
+ };
22
+ };
@@ -0,0 +1,49 @@
1
+ import React from 'react';
2
+ import type { ShadowSize } from '@shopgate/engage/styles';
3
+ export type PaperVariant = 'elevation' | 'outlined';
4
+ export interface PaperOwnProps {
5
+ /** Element or component to render as. @default 'div' */
6
+ component?: React.ElementType;
7
+ /**
8
+ * Depth of the drop shadow. A number indexes `theme.shadows` (0–24), a `ShadowSize` resolves
9
+ * through `theme.shadowSizes`. Ignored unless `variant` is `elevation`. @default 1
10
+ */
11
+ elevation?: number | ShadowSize;
12
+ /** `elevation` draws a shadow, `outlined` a border instead. @default 'elevation' */
13
+ variant?: PaperVariant;
14
+ /** Removes the rounded corners. @default false */
15
+ square?: boolean;
16
+ /**
17
+ * Corner radius. The theme carries a dedicated value per surface — `shape.cardsBorderRadius` for
18
+ * cards. Ignored when `square`.
19
+ * @default theme.shape.borderRadius
20
+ */
21
+ borderRadius?: number | string;
22
+ /**
23
+ * CSS `border` shorthand, drawn only when `variant` is `outlined`.
24
+ * @default `1px solid ${theme.components.border.light}`
25
+ */
26
+ border?: string;
27
+ /**
28
+ * A key of `theme.palette.background` (`default` | `surface` | `emphasized`), or any CSS color.
29
+ * @default 'surface'
30
+ */
31
+ background?: 'default' | 'surface' | 'emphasized' | (string & NonNullable<unknown>);
32
+ /**
33
+ * CSS color the shadow is drawn in. Sets `--sg-palette-shadow` on this element. Ignored unless
34
+ * `variant` is `elevation`.
35
+ */
36
+ shadowColor?: string;
37
+ }
38
+ export type PaperProps = PaperOwnProps & Omit<React.HTMLAttributes<HTMLElement>, keyof PaperOwnProps> & {
39
+ [key: `data-${string}`]: string;
40
+ };
41
+ /**
42
+ * A surface primitive that owns elevation, variant, corner radius and background — the base the
43
+ * themed `Card` composes. Settings-free; theme only.
44
+ */
45
+ declare const Paper: React.ForwardRefExoticComponent<PaperOwnProps & Omit<React.HTMLAttributes<HTMLElement>, keyof PaperOwnProps> & {
46
+ [key: `data-${string}`]: string;
47
+ } & React.RefAttributes<HTMLElement>>;
48
+ export default Paper;
49
+ //# sourceMappingURL=Paper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Paper.d.ts","sourceRoot":"","sources":["../../../components/Paper/Paper.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAE1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE1D,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,UAAU,CAAC;AAEpD,MAAM,WAAW,aAAa;IAC5B,wDAAwD;IACxD,SAAS,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC;IAC9B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;IAChC,oFAAoF;IACpF,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,kDAAkD;IAClD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,UAAU,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,YAAY,GAAG,CAAC,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;IACpF;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,UAAU,GACpB,aAAa,GACX,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,MAAM,aAAa,CAAC,GAC5D;IAAE,CAAC,GAAG,EAAE,QAAQ,MAAM,EAAE,GAAG,MAAM,CAAA;CAAE,CAAC;AA2BxC;;;GAGG;AACH,QAAA,MAAM,KAAK;;qCAkCT,CAAC;AAIH,eAAe,KAAK,CAAC"}
@@ -0,0 +1,64 @@
1
+ import React, { forwardRef } from 'react';
2
+ import { makeStyles } from '@shopgate/engage/styles';
3
+ import { jsx as _jsx } from "react/jsx-runtime";
4
+ const useStyles = makeStyles({
5
+ name: 'Paper'
6
+ })((theme, p) => {
7
+ const palette = theme.palette.background[p.background];
8
+ return {
9
+ root: {
10
+ position: 'relative',
11
+ backgroundColor: typeof palette === 'string' ? palette : p.background,
12
+ borderRadius: p.square ? 0 : p.borderRadius ?? theme.shape.borderRadius,
13
+ ...(p.variant === 'elevation' && {
14
+ boxShadow: typeof p.elevation === 'number' ? theme.shadows[p.elevation] : theme.shadowSizes[p.elevation],
15
+ ...(p.shadowColor && {
16
+ [theme.vars.palette.shadow]: p.shadowColor
17
+ })
18
+ }),
19
+ ...(p.variant === 'outlined' && {
20
+ border: p.border ?? `1px solid ${theme.components.border.light}`
21
+ })
22
+ }
23
+ };
24
+ });
25
+
26
+ /**
27
+ * A surface primitive that owns elevation, variant, corner radius and background — the base the
28
+ * themed `Card` composes. Settings-free; theme only.
29
+ */
30
+ const Paper = /*#__PURE__*/forwardRef((props, ref) => {
31
+ const {
32
+ children,
33
+ className,
34
+ component: Component = 'div',
35
+ elevation = 1,
36
+ variant = 'elevation',
37
+ square = false,
38
+ borderRadius,
39
+ border,
40
+ background = 'surface',
41
+ shadowColor,
42
+ ...restProps
43
+ } = props;
44
+ const {
45
+ classes,
46
+ cx
47
+ } = useStyles({
48
+ variant,
49
+ elevation,
50
+ square,
51
+ borderRadius,
52
+ border,
53
+ background,
54
+ shadowColor
55
+ });
56
+ return /*#__PURE__*/_jsx(Component, {
57
+ ref: ref,
58
+ className: cx(classes.root, 'engage__paper', className),
59
+ ...restProps,
60
+ children: children
61
+ });
62
+ });
63
+ Paper.displayName = 'Paper';
64
+ export default Paper;
@@ -0,0 +1,3 @@
1
+ export { default } from './Paper';
2
+ export type { PaperProps, PaperOwnProps, PaperVariant } from './Paper';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../components/Paper/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1 @@
1
+ export { default } from "./Paper";
@@ -0,0 +1,2 @@
1
+ import '@testing-library/jest-dom';
2
+ //# sourceMappingURL=spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec.d.ts","sourceRoot":"","sources":["../../../components/Paper/spec.tsx"],"names":[],"mappings":"AAEA,OAAO,2BAA2B,CAAC"}
@@ -0,0 +1,131 @@
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import '@testing-library/jest-dom';
4
+ import { ThemeProvider, createTheme } from '@shopgate/engage/styles';
5
+ import Paper from "./Paper";
6
+
7
+ // ThemeProvider resolves the active breakpoint via matchMedia, which jsdom doesn't implement.
8
+ import { jsx as _jsx } from "react/jsx-runtime";
9
+ Object.defineProperty(window, 'matchMedia', {
10
+ writable: true,
11
+ value: query => ({
12
+ matches: false,
13
+ media: query,
14
+ addEventListener: jest.fn(),
15
+ removeEventListener: jest.fn()
16
+ })
17
+ });
18
+ const theme = createTheme();
19
+ const renderWithTheme = ui => render(/*#__PURE__*/_jsx(ThemeProvider, {
20
+ theme: theme,
21
+ children: ui
22
+ }));
23
+
24
+ // tss keeps injected rules in the document across tests, so assertions have to be scoped to the
25
+ // element under test — a global sweep would also match rules another test left behind.
26
+ const styleTextFor = element => Array.from(document.styleSheets).flatMap(sheet => {
27
+ try {
28
+ return Array.from(sheet.cssRules);
29
+ } catch {
30
+ return [];
31
+ }
32
+ }).filter(rule => rule instanceof CSSStyleRule && element.matches(rule.selectorText)).map(rule => rule.cssText).join('');
33
+ const renderPaper = ui => {
34
+ renderWithTheme(ui);
35
+ return styleTextFor(screen.getByTestId('paper'));
36
+ };
37
+ describe('<Paper />', () => {
38
+ it('renders children and the engage__paper class next to a caller className', () => {
39
+ renderWithTheme(/*#__PURE__*/_jsx(Paper, {
40
+ className: "custom",
41
+ "data-testid": "paper",
42
+ children: "content"
43
+ }));
44
+ const el = screen.getByTestId('paper');
45
+ expect(el).toHaveTextContent('content');
46
+ expect(el).toHaveClass('engage__paper');
47
+ expect(el).toHaveClass('custom');
48
+ });
49
+ it('renders as the given component', () => {
50
+ renderWithTheme(/*#__PURE__*/_jsx(Paper, {
51
+ component: "section",
52
+ "data-testid": "paper",
53
+ children: "x"
54
+ }));
55
+ expect(screen.getByTestId('paper').tagName).toBe('SECTION');
56
+ });
57
+ it('passes data attributes through to the element', () => {
58
+ renderWithTheme(/*#__PURE__*/_jsx(Paper, {
59
+ "data-testid": "paper",
60
+ "data-foo": "bar",
61
+ children: "x"
62
+ }));
63
+ expect(screen.getByTestId('paper')).toHaveAttribute('data-foo', 'bar');
64
+ });
65
+ it('draws a shadow reading the shadow color variable for the elevation variant', () => {
66
+ const css = renderPaper(/*#__PURE__*/_jsx(Paper, {
67
+ elevation: 4,
68
+ "data-testid": "paper",
69
+ children: "x"
70
+ }));
71
+ expect(css).toContain('var(--sg-palette-shadow)');
72
+ });
73
+ it('sets the shadow color custom property when shadowColor is given', () => {
74
+ const css = renderPaper(/*#__PURE__*/_jsx(Paper, {
75
+ shadowColor: "#7a3cff",
76
+ "data-testid": "paper",
77
+ children: "x"
78
+ }));
79
+ expect(css).toContain('--sg-palette-shadow: #7a3cff');
80
+ });
81
+ it('draws the default border for the outlined variant', () => {
82
+ const css = renderPaper(/*#__PURE__*/_jsx(Paper, {
83
+ variant: "outlined",
84
+ "data-testid": "paper",
85
+ children: "x"
86
+ }));
87
+ expect(css).toContain('var(--sg-components-border-light)');
88
+ });
89
+ it('lets the border prop override the default outlined border', () => {
90
+ const css = renderPaper(/*#__PURE__*/_jsx(Paper, {
91
+ variant: "outlined",
92
+ border: "2px dashed #abc",
93
+ "data-testid": "paper",
94
+ children: "x"
95
+ }));
96
+ expect(css).toContain('2px dashed #abc');
97
+ });
98
+ it('resolves a palette key to its background color', () => {
99
+ const css = renderPaper(/*#__PURE__*/_jsx(Paper, {
100
+ background: "emphasized",
101
+ "data-testid": "paper",
102
+ children: "x"
103
+ }));
104
+ expect(css).toContain('var(--sg-palette-background-emphasized)');
105
+ });
106
+ it('passes an arbitrary background color through', () => {
107
+ const css = renderPaper(/*#__PURE__*/_jsx(Paper, {
108
+ background: "#123456",
109
+ "data-testid": "paper",
110
+ children: "x"
111
+ }));
112
+ expect(css).toContain('#123456');
113
+ });
114
+ it('applies the given border radius', () => {
115
+ const css = renderPaper(/*#__PURE__*/_jsx(Paper, {
116
+ borderRadius: 12,
117
+ "data-testid": "paper",
118
+ children: "x"
119
+ }));
120
+ expect(css).toContain('border-radius: 12px');
121
+ });
122
+ it('drops the border radius when square', () => {
123
+ const css = renderPaper(/*#__PURE__*/_jsx(Paper, {
124
+ square: true,
125
+ borderRadius: 12,
126
+ "data-testid": "paper",
127
+ children: "x"
128
+ }));
129
+ expect(css).toContain('border-radius: 0');
130
+ });
131
+ });