@sproutsocial/racine 11.0.0-mixin-beta.0 → 11.0.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # Change Log
2
2
 
3
+ ## 11.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 82a6a89: Adjusted styling of selected state to be less confusing for users based on org wide feedback
8
+
9
+ ## 11.0.0
10
+
11
+ ### Major Changes
12
+
13
+ - 3f25fab: Remove themed mixin in favor of functions only
14
+
15
+ - Changes in 10.0.0 made the mixin unnecessary
16
+ - The functions that were created for use with the mixin can now be used standalone for the same purpose.
17
+ - Migration requires removal of all `@include themed` mixin calls. The code inside can stay the same. For example:
18
+
19
+ ```scss
20
+ @include themed {
21
+ color: colors("text.body");
22
+ }
23
+ ```
24
+
25
+ becomes
26
+
27
+ ```scss
28
+ color: colors("text.body");
29
+ ```
30
+
31
+ ### Patch Changes
32
+
33
+ - f28456b: Add overlay theme object
34
+ - a3ed9eb: Patches Menu Group margin issue
35
+
3
36
  ## 10.0.0
4
37
 
5
38
  ### Major Changes
@@ -165,10 +165,6 @@ describe("Listbox", () => {
165
165
  });
166
166
 
167
167
  describe("AsListbox", () => {
168
- it("should match snapshot", () => {
169
- expect(render(<AsListbox />).baseElement).toMatchSnapshot();
170
- });
171
-
172
168
  it("should render items with option role", async () => {
173
169
  const { findByText, queryByLabelText, queryByRole } = render(
174
170
  <AsListbox />
@@ -211,10 +207,6 @@ describe("Listbox", () => {
211
207
  });
212
208
 
213
209
  describe("AsListbox multiselect", () => {
214
- it("should match snapshot", () => {
215
- expect(render(<AsListboxMultiselect />).baseElement).toMatchSnapshot();
216
- });
217
-
218
210
  it("should render items with option role", async () => {
219
211
  const { queryByLabelText, queryByText, queryByRole } = render(
220
212
  <AsListboxMultiselect />
@@ -244,10 +236,6 @@ describe("Listbox", () => {
244
236
  });
245
237
 
246
238
  describe("AsListbox with checkboxes", () => {
247
- it("should match snapshot", () => {
248
- expect(render(<AsListboxWithCheckboxes />).baseElement).toMatchSnapshot();
249
- });
250
-
251
239
  it("should render items with checkbox role", async () => {
252
240
  const { queryByRole } = render(<AsListboxWithCheckboxes />);
253
241
  const firstItem = queryByRole(MENU_ITEM_ROLES.CHECKBOX, {
@@ -267,12 +255,6 @@ describe("Listbox", () => {
267
255
  });
268
256
 
269
257
  describe("AsListbox with filter input", () => {
270
- it("should match snapshot", () => {
271
- expect(
272
- render(<AsListboxWithFilterInput />).baseElement
273
- ).toMatchSnapshot();
274
- });
275
-
276
258
  it("should allow filtering", async () => {
277
259
  const { queryByLabelText, queryAllByRole } = render(
278
260
  <AsListboxWithFilterInput />
@@ -1,277 +1,7 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
- exports[`Menu AsMenu should match snapshot 1`] = `
4
- .c0 {
5
- box-sizing: border-box;
6
- font-family: system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;
7
- margin: 0px;
8
- padding: 0px;
9
- width: 200px;
10
- overflow: hidden;
11
- }
12
-
13
- .c2 {
14
- box-sizing: border-box;
15
- font-family: system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;
16
- padding-left: 16px;
17
- margin-top: -1px;
18
- border-top: 1px solid;
19
- border-color: #dee1e1;
20
- }
21
-
22
- .c4 {
23
- box-sizing: border-box;
24
- font-family: system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;
25
- margin: 8px;
26
- padding: 8px;
27
- }
28
-
29
- .c5 {
30
- box-sizing: border-box;
31
- font-family: system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;
32
- }
33
-
34
- .c7 {
35
- display: block;
36
- width: 100%;
37
- border-radius: 6px;
38
- background-color: transparent;
39
- border: none;
40
- text-align: left;
41
- color: #364141;
42
- font-family: system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;
43
- font-weight: 400;
44
- padding: 6px 8px;
45
- list-style-type: none;
46
- outline: 0;
47
- font-size: 13px;
48
- line-height: 21.333333333333332px;
49
- }
50
-
51
- .c7:focus,
52
- .c7:hover {
53
- color: #364141;
54
- background-color: #f3f4f4;
55
- }
56
-
57
- .c7:focus .Icon-svg,
58
- .c7:hover .Icon-svg {
59
- color: unset;
60
- }
61
-
62
- .c7:hover {
63
- cursor: pointer;
64
- }
65
-
66
- .c6 {
67
- display: block;
68
- width: 100%;
69
- border-radius: 6px;
70
- background-color: transparent;
71
- border: none;
72
- text-align: left;
73
- color: #364141;
74
- font-family: system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;
75
- font-weight: 400;
76
- padding: 6px 8px;
77
- list-style-type: none;
78
- outline: 0;
79
- font-size: 13px;
80
- line-height: 21.333333333333332px;
81
- color: #FFFFFF;
82
- background-color: #364141;
83
- }
84
-
85
- .c6 .Icon-svg {
86
- color: #FFFFFF;
87
- }
88
-
89
- .c6:focus,
90
- .c6:hover {
91
- color: #364141;
92
- background-color: #f3f4f4;
93
- }
94
-
95
- .c6:focus .Icon-svg,
96
- .c6:hover .Icon-svg {
97
- color: unset;
98
- }
99
-
100
- .c6:hover {
101
- cursor: pointer;
102
- }
103
-
104
- .c1 {
105
- list-style-type: none;
106
- outline: 0;
107
- }
108
-
109
- .c3 {
110
- margin: 0;
111
- padding-left: 0;
112
- padding-right: 0;
113
- font-family: system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;
114
- margin-top: 12px;
115
- color: #273333;
116
- font-size: 13px;
117
- line-height: 21.333333333333332px;
118
- font-weight: 600;
119
- }
120
-
121
- <body>
122
- <div>
123
- <ul
124
- aria-activedescendant="MenuItem-1"
125
- class="c0 c1"
126
- overflow="hidden"
127
- role="menu"
128
- tabindex="0"
129
- width="200px"
130
- >
131
- <div
132
- class="c2"
133
- >
134
- <div
135
- class="c3 "
136
- color="text.headline"
137
- data-qa-text="Fruit"
138
- font-weight="600"
139
- >
140
- Fruit
141
- </div>
142
- </div>
143
- <div
144
- class="c4"
145
- role="group"
146
- >
147
- <li
148
- class="c5 c6"
149
- data-qa-menu-item="Apple"
150
- id="MenuItem-1"
151
- role="menuitem"
152
- tabindex="-1"
153
- >
154
- <div
155
- style="display: flex; align-items: center; justify-content: space-between;"
156
- >
157
- <div
158
- style="flex-grow: 1; word-break: break-word; min-width: 0;"
159
- >
160
- Apple
161
- </div>
162
- </div>
163
- </li>
164
- <li
165
- class="c5 c7"
166
- data-qa-menu-item="Banana"
167
- id="MenuItem-2"
168
- role="menuitem"
169
- tabindex="-1"
170
- >
171
- <div
172
- style="display: flex; align-items: center; justify-content: space-between;"
173
- >
174
- <div
175
- style="flex-grow: 1; word-break: break-word; min-width: 0;"
176
- >
177
- Banana
178
- </div>
179
- </div>
180
- </li>
181
- <li
182
- class="c5 c7"
183
- data-qa-menu-item="Orange"
184
- id="MenuItem-3"
185
- role="menuitem"
186
- tabindex="-1"
187
- >
188
- <div
189
- style="display: flex; align-items: center; justify-content: space-between;"
190
- >
191
- <div
192
- style="flex-grow: 1; word-break: break-word; min-width: 0;"
193
- >
194
- Orange
195
- </div>
196
- </div>
197
- </li>
198
- </div>
199
- <div
200
- class="c2"
201
- >
202
- <div
203
- class="c3 "
204
- color="text.headline"
205
- data-qa-text="Maybe Fruit"
206
- font-weight="600"
207
- >
208
- Maybe Fruit
209
- </div>
210
- </div>
211
- <div
212
- class="c4"
213
- role="group"
214
- >
215
- <li
216
- class="c5 c7"
217
- data-qa-menu-item="Tomato"
218
- id="MenuItem-4"
219
- role="menuitem"
220
- tabindex="-1"
221
- >
222
- <div
223
- style="display: flex; align-items: center; justify-content: space-between;"
224
- >
225
- <div
226
- style="flex-grow: 1; word-break: break-word; min-width: 0;"
227
- >
228
- Tomato
229
- </div>
230
- </div>
231
- </li>
232
- <li
233
- class="c5 c7"
234
- data-qa-menu-item="Cucumber"
235
- id="MenuItem-5"
236
- role="menuitem"
237
- tabindex="-1"
238
- >
239
- <div
240
- style="display: flex; align-items: center; justify-content: space-between;"
241
- >
242
- <div
243
- style="flex-grow: 1; word-break: break-word; min-width: 0;"
244
- >
245
- Cucumber
246
- </div>
247
- </div>
248
- </li>
249
- <li
250
- class="c5 c7"
251
- data-qa-menu-item="Squash"
252
- id="MenuItem-6"
253
- role="menuitem"
254
- tabindex="-1"
255
- >
256
- <div
257
- style="display: flex; align-items: center; justify-content: space-between;"
258
- >
259
- <div
260
- style="flex-grow: 1; word-break: break-word; min-width: 0;"
261
- >
262
- Squash
263
- </div>
264
- </div>
265
- </li>
266
- </div>
267
- </ul>
268
- </div>
269
- </body>
270
- `;
271
-
272
3
  exports[`Menu AsMenuButton should match snapshot 1`] = `
273
- <body>
274
- .c3 {
4
+ .c3 {
275
5
  display: inline-block;
276
6
  color: inherit;
277
7
  vertical-align: middle;
@@ -357,7 +87,8 @@ html .c3 {
357
87
  display: inline-block;
358
88
  }
359
89
 
360
- <div>
90
+ <body>
91
+ <div>
361
92
  <div
362
93
  class="c0"
363
94
  >
@@ -368,7 +99,7 @@ html .c3 {
368
99
  class="c1"
369
100
  data-qa-button=""
370
101
  data-qa-button-isdisabled="false"
371
- id="MenuButton-13"
102
+ id="MenuButton-7"
372
103
  type="button"
373
104
  >
374
105
  <span
@@ -85,7 +85,6 @@ export const MenuItem = ({
85
85
  selected,
86
86
  disabled,
87
87
  indeterminate,
88
- active,
89
88
  label: labelProp,
90
89
  ...props
91
90
  }: TypeMenuItemProps) => {
@@ -121,6 +120,7 @@ export const MenuItem = ({
121
120
  const isHidden = filteredItems && !filteredItems.includes(index);
122
121
  const isFocused = index === selectionIndex;
123
122
  selectCallbacks.current[index] = onClick;
123
+ const [keyPressed, setKeyPressed] = useState(false);
124
124
 
125
125
  const isCheckboxOrRadio = [
126
126
  MENU_ITEM_ROLES.CHECKBOX,
@@ -150,6 +150,14 @@ export const MenuItem = ({
150
150
  }
151
151
  }, [ref, isCheckboxOrRadio]);
152
152
 
153
+ useEffect(() => {
154
+ if (filteredItems) {
155
+ setKeyPressed(true);
156
+ } else if (selectionIndex !== 0) {
157
+ setKeyPressed(true);
158
+ }
159
+ }, [selectionIndex, filteredItems]);
160
+
153
161
  const handleClick = useCallback(
154
162
  (e: SyntheticEvent<HTMLButtonElement>) => {
155
163
  menuRef.current?.focus();
@@ -210,7 +218,7 @@ export const MenuItem = ({
210
218
  <MenuItemContainer
211
219
  data-qa-menu-item={label}
212
220
  {...props}
213
- active={active || isFocused}
221
+ active={isFocused && keyPressed}
214
222
  id={id}
215
223
  aria-label={labelProp}
216
224
  value={valueProp}
@@ -287,7 +295,7 @@ export const MenuGroup = ({
287
295
  </Text>
288
296
  </Box>
289
297
  )}
290
- <Box {...props} m={300} p={300} role="group">
298
+ <Box {...props} p={300} role="group">
291
299
  {children}
292
300
  </Box>
293
301
  </>
@@ -7,7 +7,7 @@ import { names } from "./names";
7
7
  import Text from "../Text";
8
8
  import Box from "../Box";
9
9
 
10
- const fruit = ["Apple", "Banana", "Orange"];
10
+ const fruit = ["Apple", "Banana", "Blueberry", "Orange"];
11
11
  const maybeFruit = ["Tomato", "Cucumber", "Squash"];
12
12
 
13
13
  export default {
@@ -233,3 +233,21 @@ export const MenuWithIcons = (props) => {
233
233
  </Box>
234
234
  );
235
235
  };
236
+
237
+ export const MenuWithFilter = (props) => {
238
+ return (
239
+ <Box
240
+ width="200px"
241
+ border={500}
242
+ borderRadius="outer"
243
+ borderColor="container.border.base"
244
+ boxShadow="medium"
245
+ backgroundColor="container.background.base"
246
+ >
247
+ <Menu {...props}>
248
+ <Menu.FilterInput placeholder="filter contents..." m={300} />
249
+ <BaseContents />
250
+ </Menu>
251
+ </Box>
252
+ );
253
+ };
@@ -54,10 +54,6 @@ describe("Menu", () => {
54
54
  });
55
55
 
56
56
  describe("AsMenu", () => {
57
- it("should match snapshot", () => {
58
- expect(render(<AsMenu />).baseElement).toMatchSnapshot();
59
- });
60
-
61
57
  it("should render items with menuitem role", () => {
62
58
  const { queryByRole, queryByDataQaLabel } = render(<AsMenu />);
63
59
  const firstItem = queryByRole(MENU_ITEM_ROLES.MENUITEM, {
@@ -3,7 +3,7 @@ import styled, { css } from "styled-components";
3
3
  import Box from "../Box";
4
4
  import type { TypeMenuItemProps } from "./index.flow";
5
5
  import type { TypeTheme } from "../types/theme.flow";
6
- import { disabled } from "../utils/mixins";
6
+ import { disabled, focusRing } from "../utils/mixins";
7
7
 
8
8
  export const MenuItemContainer = styled<
9
9
  typeof Box,
@@ -35,6 +35,13 @@ export const MenuItemContainer = styled<
35
35
  ${props.theme.typography[200]};
36
36
  `};
37
37
 
38
+ ${(props) =>
39
+ props.selected &&
40
+ !props.isCheckboxOrRadio &&
41
+ css`
42
+ font-weight: ${(props) => props.theme.fontWeights.semibold};
43
+ `}
44
+
38
45
  ${(props) =>
39
46
  props.active &&
40
47
  !props.disabled &&
@@ -48,13 +55,6 @@ export const MenuItemContainer = styled<
48
55
  `}
49
56
 
50
57
  ${(props) =>
51
- props.selected &&
52
- !props.isCheckboxOrRadio &&
53
- css`
54
- font-weight: ${(props) => props.theme.fontWeights.semibold};
55
- `}
56
-
57
- ${(props) =>
58
58
  !props.disabled &&
59
59
  css`
60
60
  &:focus,
@@ -86,5 +86,7 @@ export const MenuItemContainer = styled<
86
86
 
87
87
  export const MenuItemsContainer = styled<typeof Box, TypeTheme>(Box)`
88
88
  list-style-type: none;
89
- outline: 0;
89
+ &:focus {
90
+ ${focusRing}
91
+ }
90
92
  `;
@@ -91,9 +91,8 @@ var MenuItem = function MenuItem(_ref) {
91
91
  selected = _ref.selected,
92
92
  disabled = _ref.disabled,
93
93
  indeterminate = _ref.indeterminate,
94
- active = _ref.active,
95
94
  labelProp = _ref.label,
96
- props = _objectWithoutPropertiesLoose(_ref, ["id", "index", "as", "children", "role", "elemBefore", "elemAfter", "value", "onKeyPress", "onClick", "selected", "disabled", "indeterminate", "active", "label"]);
95
+ props = _objectWithoutPropertiesLoose(_ref, ["id", "index", "as", "children", "role", "elemBefore", "elemAfter", "value", "onKeyPress", "onClick", "selected", "disabled", "indeterminate", "label"]);
97
96
 
98
97
  var _useContext = (0, React.useContext)(_hooks2.MenuContext),
99
98
  menuRole = _useContext.role,
@@ -131,6 +130,11 @@ var MenuItem = function MenuItem(_ref) {
131
130
  var isHidden = filteredItems && !filteredItems.includes(index);
132
131
  var isFocused = index === selectionIndex;
133
132
  selectCallbacks.current[index] = onClick;
133
+
134
+ var _useState = (0, React.useState)(false),
135
+ keyPressed = _useState[0],
136
+ setKeyPressed = _useState[1];
137
+
134
138
  var isCheckboxOrRadio = [_constants.MENU_ITEM_ROLES.CHECKBOX, _constants.MENU_ITEM_ROLES.RADIO].includes(itemRole);
135
139
  var interactive = onClick || onKeyPress || [_constants.MENU_ITEM_ROLES.OPTION, _constants.MENU_ITEM_ROLES.MENUITEM, _constants.MENU_ITEM_ROLES.CHECKBOX, _constants.MENU_ITEM_ROLES.RADIO].includes(itemRole);
136
140
  /**
@@ -148,6 +152,13 @@ var MenuItem = function MenuItem(_ref) {
148
152
  }
149
153
  }
150
154
  }, [ref, isCheckboxOrRadio]);
155
+ (0, React.useEffect)(function () {
156
+ if (filteredItems) {
157
+ setKeyPressed(true);
158
+ } else if (selectionIndex !== 0) {
159
+ setKeyPressed(true);
160
+ }
161
+ }, [selectionIndex, filteredItems]);
151
162
  var handleClick = (0, React.useCallback)(function (e) {
152
163
  var _menuRef$current;
153
164
 
@@ -198,7 +209,7 @@ var MenuItem = function MenuItem(_ref) {
198
209
  return /*#__PURE__*/React.createElement(_styles.MenuItemContainer, _extends({
199
210
  "data-qa-menu-item": label
200
211
  }, props, {
201
- active: active || isFocused,
212
+ active: isFocused && keyPressed,
202
213
  id: id,
203
214
  "aria-label": labelProp,
204
215
  value: valueProp,
@@ -278,7 +289,6 @@ var MenuGroup = function MenuGroup(_ref2) {
278
289
  color: "text.headline",
279
290
  _css: isDisabled && _mixins.disabled
280
291
  }, title)), /*#__PURE__*/React.createElement(_Box.default, _extends({}, props, {
281
- m: 300,
282
292
  p: 300,
283
293
  role: "group"
284
294
  }), children));
@@ -371,14 +381,14 @@ var Menu = function Menu(_ref4) {
371
381
  descendants = _useDescendants[0],
372
382
  setDescendants = _useDescendants[1];
373
383
 
374
- var _useState = (0, React.useState)({
384
+ var _useState2 = (0, React.useState)({
375
385
  selectionIndex: 0,
376
386
  filterQuery: "",
377
387
  filteredItems: null,
378
388
  isFilterInputFocused: false
379
389
  }),
380
- state = _useState[0],
381
- setState = _useState[1];
390
+ state = _useState2[0],
391
+ setState = _useState2[1];
382
392
 
383
393
  var selectCallbacks = (0, React.useRef)([]);
384
394
  var menuRef = (0, React.useRef)(null);
@@ -437,9 +447,9 @@ var MenuButton = function MenuButton(_ref5) {
437
447
  placement = _ref5$placement === void 0 ? "bottom" : _ref5$placement,
438
448
  props = _objectWithoutPropertiesLoose(_ref5, ["content", "popoutProps", "children", "onClick", "closeOnItemClick", "id", "placement"]);
439
449
 
440
- var _useState2 = (0, React.useState)(false),
441
- isOpen = _useState2[0],
442
- setIsOpen = _useState2[1];
450
+ var _useState3 = (0, React.useState)(false),
451
+ isOpen = _useState3[0],
452
+ setIsOpen = _useState3[1];
443
453
 
444
454
  var closePopout = (0, React.useCallback)(function () {
445
455
  return setIsOpen(false);
@@ -34,16 +34,16 @@ var MenuItemContainer = (0, _styledComponents.default)(_Box.default).withConfig(
34
34
  return "6px " + props.theme.space[300];
35
35
  }, function (props) {
36
36
  return (0, _styledComponents.css)(["", ";"], props.theme.typography[200]);
37
+ }, function (props) {
38
+ return props.selected && !props.isCheckboxOrRadio && (0, _styledComponents.css)(["font-weight:", ";"], function (props) {
39
+ return props.theme.fontWeights.semibold;
40
+ });
37
41
  }, function (props) {
38
42
  return props.active && !props.disabled && (0, _styledComponents.css)(["color:", ";background-color:", ";.Icon-svg{color:", ";}"], function (props) {
39
43
  return props.theme.colors.text.inverse;
40
44
  }, props.theme.colors.listItem.background.selected, function (props) {
41
45
  return props.theme.colors.text.inverse;
42
46
  });
43
- }, function (props) {
44
- return props.selected && !props.isCheckboxOrRadio && (0, _styledComponents.css)(["font-weight:", ";"], function (props) {
45
- return props.theme.fontWeights.semibold;
46
- });
47
47
  }, function (props) {
48
48
  return !props.disabled && (0, _styledComponents.css)(["&:focus,&:hover{color:", ";background-color:", ";.Icon-svg{color:unset;}}"], function (props) {
49
49
  return props.theme.colors.text.body;
@@ -59,5 +59,5 @@ exports.MenuItemContainer = MenuItemContainer;
59
59
  var MenuItemsContainer = (0, _styledComponents.default)(_Box.default).withConfig({
60
60
  displayName: "styles__MenuItemsContainer",
61
61
  componentId: "fjvae4-1"
62
- })(["list-style-type:none;outline:0;"]);
62
+ })(["list-style-type:none;&:focus{", "}"], _mixins.focusRing);
63
63
  exports.MenuItemsContainer = MenuItemsContainer;