@shopgate/pwa-ui-shared 7.32.0-beta.3 → 7.32.0-beta.5

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.
@@ -43,6 +43,11 @@ const useStyles = makeStyles()(theme => ({
43
43
  position: 'absolute',
44
44
  left: 0,
45
45
  top: 0,
46
+ // Purely decorative overlay: let every pointer event fall through to the
47
+ // empty-star buttons underneath, which span all slots and handle selection.
48
+ // Without this, the invisible spacers/half-stars cover the higher-index
49
+ // buttons and swallow clicks in selectable mode.
50
+ pointerEvents: 'none',
46
51
  color: theme.components.ratingStars.filled,
47
52
  display: 'inline-flex',
48
53
  alignItems: 'center',
@@ -107,10 +112,10 @@ const RatingStars = ({
107
112
  const starProps = {
108
113
  className: iconClassName,
109
114
  key: numStars + pos,
115
+ // Decorative duplicate of the underlying empty-star button; hidden from
116
+ // assistive tech and non-interactive (the empty layer handles clicks).
110
117
  ...(isSelectable && {
111
- 'aria-hidden': true,
112
- role: 'button',
113
- onClick: e => handleSelection(e, pos)
118
+ 'aria-hidden': true
114
119
  })
115
120
  };
116
121
  return /*#__PURE__*/_jsx("div", {
@@ -124,7 +129,13 @@ const RatingStars = ({
124
129
  children: /*#__PURE__*/_jsx(StarHalfIcon, {
125
130
  size: size
126
131
  })
127
- }, i + numFullStars))), [iconClassName, numFullStars, numHalfStars, size, handleSelection, isSelectable]);
132
+ }, i + numFullStars)), times(Math.max(numStars - numFullStars - numHalfStars, 0), i => /*#__PURE__*/_jsx("div", {
133
+ className: iconClassName,
134
+ style: {
135
+ width: size
136
+ },
137
+ "aria-hidden": true
138
+ }, `placeholder-${i}`))), [iconClassName, numFullStars, numHalfStars, size, isSelectable]);
128
139
  return /*#__PURE__*/_jsxs("div", {
129
140
  role: isSelectable ? undefined : 'img',
130
141
  className: rootClassName,
@@ -49,34 +49,37 @@ describe('<RatingStars />', () => {
49
49
  expect(wrapper.find(StarHalfIcon).length).toBe(1);
50
50
  expect(wrapper).toMatchSnapshot();
51
51
  });
52
- it('should call onSelection callback when component is selectable', () => {
53
- const spy = jest.fn();
52
+ it('should call onSelection with the clicked rating in selectable mode', () => {
53
+ const selections = [];
54
54
  const wrapper = shallow(/*#__PURE__*/_jsx(RatingStars, {
55
- value: 100,
55
+ value: 20,
56
56
  isSelectable: true,
57
57
  onSelection: e => {
58
+ selections.push(e.target.value);
58
59
  wrapper.setProps({
59
60
  value: e.target.value
60
61
  });
61
- spy();
62
62
  }
63
63
  }), mockRenderOptions);
64
- // Click on 1 filled star.
65
- wrapper.find('[role="button"]').at(5).simulate('click', {
66
- target: {
67
- value: 10
68
- }
64
+
65
+ // Only the empty-star layer is interactive: one button per position, always five.
66
+ // The decorative filled overlay is pointer-transparent and carries no buttons.
67
+ expect(wrapper.find('[role="button"]').length).toBe(numEmptyStars);
68
+
69
+ // Regression: at a low rating the higher positions used to be covered by the
70
+ // filled layer's invisible placeholders, which swallowed the click. Clicking the
71
+ // 5th star must still raise the rating to the full 5 stars.
72
+ wrapper.find('[role="button"]').at(4).simulate('click', {
73
+ target: {}
69
74
  });
70
- expect(spy.mock.calls.length).toBe(1);
71
- expect(wrapper.find('[role="button"]').length).toBe(6);
72
- // Click on 4th empty star
73
- wrapper.find('[role="button"]').at(3).simulate('click', {
74
- target: {
75
- value: 80
76
- }
75
+ expect(selections).toEqual([100]);
76
+
77
+ // The interactive layer is unaffected by the rating; clicking the 1st star lowers it.
78
+ expect(wrapper.find('[role="button"]').length).toBe(numEmptyStars);
79
+ wrapper.find('[role="button"]').at(0).simulate('click', {
80
+ target: {}
77
81
  });
78
- expect(wrapper.find('[role="button"]').length).toBe(9);
79
- expect(spy.mock.calls.length).toBe(2);
82
+ expect(selections).toEqual([100, 20]);
80
83
  });
81
84
  it('should NOT call onSelection callback when component is NOT selectable', () => {
82
85
  const spy = jest.fn();
@@ -8,7 +8,6 @@ import { makeStyles } from '@shopgate/engage/styles';
8
8
  import { jsx as _jsx } from "react/jsx-runtime";
9
9
  const useStyles = makeStyles()(theme => ({
10
10
  text: {
11
- background: theme.palette.background.surface,
12
11
  padding: theme.spacing(2.5, 2)
13
12
  }
14
13
  }));
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "@shopgate/pwa-ui-shared",
3
- "version": "7.32.0-beta.3",
3
+ "version": "7.32.0-beta.5",
4
4
  "description": "Shopgate's shared UI components.",
5
5
  "main": "index.js",
6
6
  "license": "Apache-2.0",
7
7
  "dependencies": {
8
- "@shopgate/pwa-ui-ios": "7.32.0-beta.3",
9
- "@shopgate/pwa-ui-material": "7.32.0-beta.3"
8
+ "@shopgate/pwa-ui-ios": "7.32.0-beta.5",
9
+ "@shopgate/pwa-ui-material": "7.32.0-beta.5"
10
10
  },
11
11
  "devDependencies": {
12
- "@shopgate/pwa-common": "7.32.0-beta.3",
13
- "@shopgate/pwa-common-commerce": "7.32.0-beta.3",
12
+ "@shopgate/pwa-common": "7.32.0-beta.5",
13
+ "@shopgate/pwa-common-commerce": "7.32.0-beta.5",
14
14
  "classnames": "2.5.1",
15
15
  "react": "^17.0.2"
16
16
  },