@atlaskit/user-picker 8.4.1 → 8.6.2

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 (85) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/cjs/analytics.js +4 -2
  3. package/dist/cjs/components/AddOptionAvatar.js +2 -2
  4. package/dist/cjs/components/AvatarItemOption.js +12 -18
  5. package/dist/cjs/components/EmailOption/main.js +2 -2
  6. package/dist/cjs/components/ExternalUserOption/ExternalAvatarItemOption.js +43 -0
  7. package/dist/cjs/components/ExternalUserOption/InfoIcon.js +57 -0
  8. package/dist/cjs/components/ExternalUserOption/main.js +11 -14
  9. package/dist/cjs/components/GroupOption/main.js +3 -3
  10. package/dist/cjs/components/PopupControl.js +2 -2
  11. package/dist/cjs/components/TeamOption/main.js +2 -2
  12. package/dist/cjs/components/UserOption.js +3 -3
  13. package/dist/cjs/components/UserPicker.js +26 -2
  14. package/dist/cjs/components/assets/github.js +1 -1
  15. package/dist/cjs/components/assets/google.js +4 -4
  16. package/dist/cjs/components/assets/microsoft.js +5 -5
  17. package/dist/cjs/components/assets/slack.js +9 -9
  18. package/dist/cjs/components/smart-user-picker/components/index.js +7 -6
  19. package/dist/cjs/components/smart-user-picker/config/index.js +3 -3
  20. package/dist/cjs/components/smart-user-picker/service/UsersClient.js +1 -1
  21. package/dist/cjs/components/smart-user-picker/service/recommendationClient.js +1 -1
  22. package/dist/cjs/components/smart-user-picker/service/users-transformer.js +1 -1
  23. package/dist/cjs/components/styles.js +6 -6
  24. package/dist/cjs/components/utils.js +13 -2
  25. package/dist/cjs/version.json +1 -1
  26. package/dist/es2019/analytics.js +4 -2
  27. package/dist/es2019/components/AddOptionAvatar.js +2 -2
  28. package/dist/es2019/components/AvatarItemOption.js +5 -11
  29. package/dist/es2019/components/EmailOption/main.js +2 -2
  30. package/dist/es2019/components/ExternalUserOption/ExternalAvatarItemOption.js +49 -0
  31. package/dist/es2019/components/ExternalUserOption/InfoIcon.js +22 -0
  32. package/dist/es2019/components/ExternalUserOption/main.js +9 -13
  33. package/dist/es2019/components/GroupOption/main.js +3 -3
  34. package/dist/es2019/components/PopupControl.js +2 -2
  35. package/dist/es2019/components/TeamOption/main.js +2 -2
  36. package/dist/es2019/components/UserOption.js +3 -3
  37. package/dist/es2019/components/UserPicker.js +19 -0
  38. package/dist/es2019/components/assets/github.js +1 -1
  39. package/dist/es2019/components/assets/google.js +4 -4
  40. package/dist/es2019/components/assets/microsoft.js +5 -5
  41. package/dist/es2019/components/assets/slack.js +9 -9
  42. package/dist/es2019/components/smart-user-picker/components/index.js +6 -4
  43. package/dist/es2019/components/smart-user-picker/config/index.js +3 -3
  44. package/dist/es2019/components/smart-user-picker/service/UsersClient.js +2 -2
  45. package/dist/es2019/components/smart-user-picker/service/recommendationClient.js +1 -1
  46. package/dist/es2019/components/smart-user-picker/service/users-transformer.js +1 -1
  47. package/dist/es2019/components/styles.js +6 -6
  48. package/dist/es2019/components/utils.js +10 -1
  49. package/dist/es2019/version.json +1 -1
  50. package/dist/esm/analytics.js +4 -2
  51. package/dist/esm/components/AddOptionAvatar.js +2 -2
  52. package/dist/esm/components/AvatarItemOption.js +12 -18
  53. package/dist/esm/components/EmailOption/main.js +2 -2
  54. package/dist/esm/components/ExternalUserOption/ExternalAvatarItemOption.js +24 -0
  55. package/dist/esm/components/ExternalUserOption/InfoIcon.js +33 -0
  56. package/dist/esm/components/ExternalUserOption/main.js +9 -13
  57. package/dist/esm/components/GroupOption/main.js +3 -3
  58. package/dist/esm/components/PopupControl.js +2 -2
  59. package/dist/esm/components/TeamOption/main.js +2 -2
  60. package/dist/esm/components/UserOption.js +3 -3
  61. package/dist/esm/components/UserPicker.js +22 -2
  62. package/dist/esm/components/assets/github.js +1 -1
  63. package/dist/esm/components/assets/google.js +4 -4
  64. package/dist/esm/components/assets/microsoft.js +5 -5
  65. package/dist/esm/components/assets/slack.js +9 -9
  66. package/dist/esm/components/smart-user-picker/components/index.js +7 -6
  67. package/dist/esm/components/smart-user-picker/config/index.js +3 -3
  68. package/dist/esm/components/smart-user-picker/service/UsersClient.js +2 -2
  69. package/dist/esm/components/smart-user-picker/service/recommendationClient.js +1 -1
  70. package/dist/esm/components/smart-user-picker/service/users-transformer.js +1 -1
  71. package/dist/esm/components/styles.js +6 -6
  72. package/dist/esm/components/utils.js +10 -1
  73. package/dist/esm/version.json +1 -1
  74. package/dist/types/components/AvatarItemOption.d.ts +1 -2
  75. package/dist/types/components/ExternalUserOption/ExternalAvatarItemOption.d.ts +8 -0
  76. package/dist/types/components/ExternalUserOption/InfoIcon.d.ts +3 -0
  77. package/dist/types/components/UserPicker.d.ts +3 -0
  78. package/dist/types/components/smart-user-picker/components/index.d.ts +13 -9
  79. package/dist/types/components/smart-user-picker/config/index.d.ts +3 -3
  80. package/dist/types/components/smart-user-picker/service/UsersClient.d.ts +2 -2
  81. package/dist/types/components/smart-user-picker/service/recommendationClient.d.ts +3 -2
  82. package/dist/types/components/smart-user-picker/service/users-transformer.d.ts +1 -1
  83. package/dist/types/components/utils.d.ts +2 -0
  84. package/docs/1-smart-user-picker.tsx +3 -2
  85. package/package.json +8 -2
@@ -32,7 +32,7 @@ var _react = _interopRequireDefault(require("react"));
32
32
 
33
33
  var _debounce = _interopRequireDefault(require("lodash/debounce"));
34
34
 
35
- var _v = _interopRequireDefault(require("uuid/v4"));
35
+ var _uuid = require("uuid");
36
36
 
37
37
  var _analyticsNext = require("@atlaskit/analytics-next");
38
38
 
@@ -61,7 +61,7 @@ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflec
61
61
  function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
62
62
 
63
63
  var hasContextChanged = function hasContextChanged(oldContext, newContext) {
64
- return oldContext.siteId !== newContext.siteId || oldContext.productKey !== newContext.productKey || oldContext.principalId !== newContext.principalId || oldContext.containerId !== newContext.containerId || oldContext.objectId !== newContext.objectId || oldContext.childObjectId !== newContext.childObjectId;
64
+ return oldContext.siteId !== newContext.siteId || oldContext.orgId !== newContext.orgId || oldContext.productKey !== newContext.productKey || oldContext.principalId !== newContext.principalId || oldContext.containerId !== newContext.containerId || oldContext.objectId !== newContext.objectId || oldContext.childObjectId !== newContext.childObjectId;
65
65
  };
66
66
 
67
67
  var stringContains = function stringContains(str, substr) {
@@ -110,7 +110,7 @@ function isOptionData(option) {
110
110
  return option.name !== undefined;
111
111
  }
112
112
  /**
113
- * @deprecated Please use @atlassian/smart-user-picker
113
+ * @deprecated Please use @atlaskit/smart-user-picker. Alternatively, @atlaskit/smart-hooks will be ready by end of FY22Q4. Contact #help-smart-experiences for further details.
114
114
  */
115
115
 
116
116
 
@@ -243,14 +243,14 @@ var SmartUserPicker = /*#__PURE__*/function (_React$Component) {
243
243
  });
244
244
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "memoizedFilterOptions", (0, _memoizeOne.default)(_this.filterOptions));
245
245
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getUsers", (0, _debounce.default)( /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
246
- var _this$state, query, sessionId, _this$props, containerId, childObjectId, objectId, principalId, productKey, siteId, baseUrl, includeUsers, includeGroups, includeTeams, maxOptions, searchQueryFilter, onEmpty, productAttributes, intl, maxNumberOfResults, startTime, recommendationsRequest, _yield$onEmpty, recommendedUsers, elapsedTimeMilli, displayedUsers, defaultUsers, _elapsedTimeMilli;
246
+ var _this$state, query, sessionId, _this$props, containerId, childObjectId, objectId, principalId, productKey, siteId, orgId, baseUrl, includeUsers, includeGroups, includeTeams, maxOptions, searchQueryFilter, onEmpty, productAttributes, intl, maxNumberOfResults, startTime, recommendationsRequest, _yield$onEmpty, recommendedUsers, elapsedTimeMilli, displayedUsers, defaultUsers, _elapsedTimeMilli;
247
247
 
248
248
  return _regenerator.default.wrap(function _callee$(_context) {
249
249
  while (1) {
250
250
  switch (_context.prev = _context.next) {
251
251
  case 0:
252
252
  _this$state = _this.state, query = _this$state.query, sessionId = _this$state.sessionId;
253
- _this$props = _this.props, containerId = _this$props.containerId, childObjectId = _this$props.childObjectId, objectId = _this$props.objectId, principalId = _this$props.principalId, productKey = _this$props.productKey, siteId = _this$props.siteId, baseUrl = _this$props.baseUrl, includeUsers = _this$props.includeUsers, includeGroups = _this$props.includeGroups, includeTeams = _this$props.includeTeams, maxOptions = _this$props.maxOptions, searchQueryFilter = _this$props.searchQueryFilter, onEmpty = _this$props.onEmpty, productAttributes = _this$props.productAttributes, intl = _this$props.intl;
253
+ _this$props = _this.props, containerId = _this$props.containerId, childObjectId = _this$props.childObjectId, objectId = _this$props.objectId, principalId = _this$props.principalId, productKey = _this$props.productKey, siteId = _this$props.siteId, orgId = _this$props.orgId, baseUrl = _this$props.baseUrl, includeUsers = _this$props.includeUsers, includeGroups = _this$props.includeGroups, includeTeams = _this$props.includeTeams, maxOptions = _this$props.maxOptions, searchQueryFilter = _this$props.searchQueryFilter, onEmpty = _this$props.onEmpty, productAttributes = _this$props.productAttributes, intl = _this$props.intl;
254
254
  maxNumberOfResults = maxOptions || 100;
255
255
  startTime = window.performance.now();
256
256
  recommendationsRequest = {
@@ -262,6 +262,7 @@ var SmartUserPicker = /*#__PURE__*/function (_React$Component) {
262
262
  principalId: principalId,
263
263
  productKey: productKey,
264
264
  siteId: siteId,
265
+ orgId: orgId,
265
266
  childObjectId: childObjectId,
266
267
  sessionId: sessionId,
267
268
  productAttributes: productAttributes
@@ -522,7 +523,7 @@ var SmartUserPicker = /*#__PURE__*/function (_React$Component) {
522
523
  prefetch = this.props.prefetch;
523
524
 
524
525
  if (prefetch) {
525
- sessionId = (0, _v.default)();
526
+ sessionId = (0, _uuid.v4)();
526
527
  this.fireEvent(_analytics.mountedWithPrefetchEvent, {
527
528
  sessionId: sessionId
528
529
  });
@@ -24,14 +24,14 @@ var PRD_CONFIG = {
24
24
  }
25
25
  };
26
26
  /**
27
- * @deprecated Please use @atlassian/smart-user-picker
27
+ * @deprecated Please use @atlaskit/smart-user-picker. Alternatively, @atlaskit/smart-hooks will be ready by end of FY22Q4. Contact #help-smart-experiences for further details.
28
28
  */
29
29
 
30
30
  var setSmartUserPickerEnv = function setSmartUserPickerEnv(newEnv) {
31
31
  return env = newEnv;
32
32
  };
33
33
  /**
34
- * @deprecated Please use @atlassian/smart-user-picker
34
+ * @deprecated Please use @atlaskit/smart-user-picker. Alternatively, @atlaskit/smart-hooks will be ready by end of FY22Q4. Contact #help-smart-experiences for further details.
35
35
  */
36
36
 
37
37
 
@@ -41,7 +41,7 @@ var getConfig = function getConfig() {
41
41
  return env === 'local' ? LOCAL_CONFIG : PRD_CONFIG;
42
42
  };
43
43
  /**
44
- * @deprecated Please use @atlassian/smart-user-picker
44
+ * @deprecated Please use @atlaskit/smart-user-picker. Alternatively, @atlaskit/smart-hooks will be ready by end of FY22Q4. Contact #help-smart-experiences for further details.
45
45
  */
46
46
 
47
47
 
@@ -77,7 +77,7 @@ var transformConfluenceUser = function transformConfluenceUser(item) {
77
77
  };
78
78
  };
79
79
  /**
80
- * @deprecated Please use @atlassian/smart-user-picker
80
+ * @deprecated Please use @atlaskit/smart-user-picker. Alternatively, @atlaskit/smart-hooks will be ready by end of FY22Q4. Contact #help-smart-experiences for further details.
81
81
  */
82
82
 
83
83
 
@@ -67,7 +67,7 @@ var getUserRecommendations = function getUserRecommendations(request, intl) {
67
67
  });
68
68
  };
69
69
  /**
70
- * @deprecated Please use @atlassian/smart-user-picker
70
+ * @deprecated Please use @atlaskit/smart-user-picker. Alternatively, @atlaskit/smart-hooks will be ready by end of FY22Q4. Contact #help-smart-experiences for further details.
71
71
  */
72
72
 
73
73
 
@@ -81,7 +81,7 @@ var transformUser = function transformUser(item, intl) {
81
81
  return;
82
82
  };
83
83
  /**
84
- * @deprecated Please use @atlassian/smart-user-picker
84
+ * @deprecated Please use @atlaskit/smart-user-picker. Alternatively, @atlaskit/smart-hooks will be ready by end of FY22Q4. Contact #help-smart-experiences for further details.
85
85
  */
86
86
 
87
87
 
@@ -52,14 +52,14 @@ var getStyles = (0, _memoizeOne.default)(function (width, isMulti, overrideStyle
52
52
  var isMulti = state.selectProps.isMulti;
53
53
  return _objectSpread(_objectSpread({}, css), {}, {
54
54
  width: width,
55
- borderColor: state.isFocused ? (0, _tokens.token)('color.border.neutral', css.borderColor) : state.selectProps.subtle || state.selectProps.noBorder ? 'transparent' : (0, _tokens.token)('color.border.neutral', _colors.N40),
56
- backgroundColor: state.isFocused ? (0, _tokens.token)('color.background.default', css['backgroundColor']) : state.selectProps.subtle ? 'transparent' : state.selectProps.textFieldBackgroundColor ? (0, _tokens.token)('color.background.subtleBorderedNeutral.resting', _colors.N10) : (0, _tokens.token)('color.background.subtleNeutral.resting', _colors.N20),
55
+ borderColor: state.isFocused ? (0, _tokens.token)('color.border', css.borderColor) : state.selectProps.subtle || state.selectProps.noBorder ? 'transparent' : (0, _tokens.token)('color.border', _colors.N40),
56
+ backgroundColor: state.isFocused ? (0, _tokens.token)('elevation.surface', css['backgroundColor']) : state.selectProps.subtle ? 'transparent' : state.selectProps.textFieldBackgroundColor ? (0, _tokens.token)('color.background.input', _colors.N10) : (0, _tokens.token)('color.background.neutral', _colors.N20),
57
57
  '&:hover .fabric-user-picker__clear-indicator': {
58
58
  opacity: 1
59
59
  },
60
60
  ':hover': _objectSpread(_objectSpread({}, css[':hover']), {}, {
61
- borderColor: state.isFocused ? css[':hover'] ? (0, _tokens.token)('color.border.focus', css[':hover'].borderColor) : (0, _tokens.token)('color.border.focus', _colors.B100) : state.selectProps.subtle ? state.selectProps.hoveringClearIndicator ? (0, _tokens.token)('color.iconBorder.danger', _colors.R50) : (0, _tokens.token)('color.border.neutral', _colors.N30) : (0, _tokens.token)('color.border.neutral', _colors.N40),
62
- backgroundColor: state.selectProps.subtle && state.selectProps.hoveringClearIndicator ? (0, _tokens.token)('color.background.subtleDanger.resting', _colors.R50) : state.isFocused ? css[':hover'] ? (0, _tokens.token)('color.background.default', css[':hover'].backgroundColor) : (0, _tokens.token)('color.background.default', _colors.N0) : state.isDisabled ? (0, _tokens.token)('color.background.disabled', _colors.N10) : (0, _tokens.token)('color.background.default', _colors.N30)
61
+ borderColor: state.isFocused ? css[':hover'] ? (0, _tokens.token)('color.border.focused', css[':hover'].borderColor) : (0, _tokens.token)('color.border.focused', _colors.B100) : state.selectProps.subtle ? state.selectProps.hoveringClearIndicator ? (0, _tokens.token)('color.icon.danger', _colors.R50) : (0, _tokens.token)('color.border', _colors.N30) : (0, _tokens.token)('color.border', _colors.N40),
62
+ backgroundColor: state.selectProps.subtle && state.selectProps.hoveringClearIndicator ? (0, _tokens.token)('color.background.danger', _colors.R50) : state.isFocused ? css[':hover'] ? (0, _tokens.token)('elevation.surface', css[':hover'].backgroundColor) : (0, _tokens.token)('elevation.surface', _colors.N0) : state.isDisabled ? (0, _tokens.token)('color.background.disabled', _colors.N10) : (0, _tokens.token)('elevation.surface', _colors.N30)
63
63
  }),
64
64
  padding: 0,
65
65
  minHeight: isCompact ? 'none' : 44,
@@ -178,14 +178,14 @@ var getStyles = (0, _memoizeOne.default)(function (width, isMulti, overrideStyle
178
178
  paddingLeft: isMulti ? 0 : AVATAR_PADDING,
179
179
  '& input::placeholder': {
180
180
  /* Chrome, Firefox, Opera, Safari 10.1+ */
181
- color: (0, _tokens.token)('color.text.lowEmphasis', _colors.N100),
181
+ color: (0, _tokens.token)('color.text.subtlest', _colors.N100),
182
182
  opacity: 1
183
183
  /* Firefox */
184
184
 
185
185
  },
186
186
  '& input:-ms-input-placeholder': {
187
187
  /* Internet Explorer 10-11 */
188
- color: (0, _tokens.token)('color.text.lowEmphasis', _colors.N100)
188
+ color: (0, _tokens.token)('color.text.subtlest', _colors.N100)
189
189
  }
190
190
  });
191
191
  }
@@ -5,7 +5,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.optionToSelectableOptions = exports.optionToSelectableOption = exports.isUser = exports.isTeam = exports.isSingleValue = exports.isPopupUserPickerByProps = exports.isPopupUserPickerByComponent = exports.isIterable = exports.isGroup = exports.isExternalUser = exports.isEmail = exports.isChildInput = exports.hasValue = exports.getOptions = exports.getAvatarUrl = exports.getAvatarSize = exports.extractOptionValue = exports.callCallback = void 0;
8
+ exports.userPickerRenderedUfoExperience = exports.optionToSelectableOptions = exports.optionToSelectableOption = exports.isUser = exports.isTeam = exports.isSingleValue = exports.isPopupUserPickerByProps = exports.isPopupUserPickerByComponent = exports.isIterable = exports.isGroup = exports.isExternalUser = exports.isEmail = exports.isChildInput = exports.hasValue = exports.getOptions = exports.getAvatarUrl = exports.getAvatarSize = exports.extractOptionValue = exports.callCallback = void 0;
9
9
 
10
10
  var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
11
11
 
@@ -17,6 +17,8 @@ var _types = require("../types");
17
17
 
18
18
  var _select = require("@atlaskit/select");
19
19
 
20
+ var _ufo = require("@atlaskit/ufo");
21
+
20
22
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
21
23
 
22
24
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
@@ -176,4 +178,13 @@ var isPopupUserPickerByProps = function isPopupUserPickerByProps(selectProps) {
176
178
  return selectProps.searchThreshold === -1;
177
179
  };
178
180
 
179
- exports.isPopupUserPickerByProps = isPopupUserPickerByProps;
181
+ exports.isPopupUserPickerByProps = isPopupUserPickerByProps;
182
+ var COMPONENT_NAME = 'user-picker';
183
+ var userPickerRenderedUfoExperience = new _ufo.ConcurrentExperience('user-picker-rendered', {
184
+ platform: {
185
+ component: COMPONENT_NAME
186
+ },
187
+ type: _ufo.ExperienceTypes.Load,
188
+ performanceType: _ufo.ExperiencePerformanceTypes.PageSegmentLoad
189
+ });
190
+ exports.userPickerRenderedUfoExperience = userPickerRenderedUfoExperience;
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/user-picker",
3
- "version": "8.4.1",
3
+ "version": "8.6.2",
4
4
  "sideEffects": false
5
5
  }
@@ -1,12 +1,12 @@
1
1
  import { createAndFireEvent } from '@atlaskit/analytics-next';
2
- import uuid from 'uuid/v4';
2
+ import { v4 as uuidv4 } from 'uuid';
3
3
  import { name as packageName, version as packageVersion } from './version.json';
4
4
  import { isExternalUser } from './components/utils';
5
5
  const UUID_REGEXP_TEAMS_GROUPS = /^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/;
6
6
  const UUID_REGEXP_OLD_AAID = /^[a-fA-F0-9]{1,8}:[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/;
7
7
  const UUID_REGEXP_NEW_AAID = /^[a-fA-F0-9]{24,24}/;
8
8
  export const startSession = () => ({
9
- id: uuid(),
9
+ id: uuidv4(),
10
10
  start: Date.now(),
11
11
  inputChangeTime: Date.now(),
12
12
  upCount: 0,
@@ -122,6 +122,7 @@ const createDefaultSmartPickerAttributes = (props, state) => {
122
122
  productKey,
123
123
  principalId,
124
124
  siteId,
125
+ orgId,
125
126
  filterOptions
126
127
  } = props;
127
128
  const {
@@ -142,6 +143,7 @@ const createDefaultSmartPickerAttributes = (props, state) => {
142
143
  productKey,
143
144
  queryLength: (query || '').length,
144
145
  siteId,
146
+ orgId,
145
147
  sessionId
146
148
  };
147
149
  };
@@ -6,7 +6,7 @@ import styled from 'styled-components';
6
6
  const EmailAvatarWrapper = styled.span`
7
7
  padding: ${props => props.isLozenge ? 0 : 4}px;
8
8
 
9
- background-color: ${token('color.background.subtleNeutral.resting', N40)};
9
+ background-color: ${token('color.background.neutral', N40)};
10
10
  border-radius: 50%;
11
11
  display: flex;
12
12
  align-items: center;
@@ -20,6 +20,6 @@ export const AddOptionAvatar = ({
20
20
  }, /*#__PURE__*/React.createElement(EmailIcon, {
21
21
  label: label,
22
22
  size: isLozenge ? 'small' : 'medium',
23
- primaryColor: token('color.text.mediumEmphasis', N500)
23
+ primaryColor: token('color.text.subtle', N500)
24
24
  }));
25
25
  };
@@ -22,19 +22,16 @@ const Wrapper = styled.span`
22
22
  `;
23
23
  const Text = styled.span`
24
24
  margin: 0;
25
- color: ${token('color.text.selected', B400)};
25
+ color: ${token('color.text.brand', B400)};
26
26
  overflow-x: hidden;
27
27
  text-overflow: ellipsis;
28
28
  white-space: nowrap;
29
29
  ${({
30
30
  secondary
31
- }) => secondary && `color: ${token('color.text.selected', B400)}; font-size: 0.85em;`}
31
+ }) => secondary && `color: ${token('color.text.brand', B400)}; font-size: 0.85em;`}
32
32
  `;
33
33
  const AdditionalInfo = styled.span`
34
34
  float: right;
35
- ${({
36
- withTooltip
37
- }) => withTooltip && ` padding-top: 5px;`}
38
35
  `;
39
36
  export const TextWrapper = styled.span`
40
37
  color: ${({
@@ -48,8 +45,7 @@ export const AvatarItemOption = ({
48
45
  avatar,
49
46
  primaryText,
50
47
  secondaryText,
51
- lozenge,
52
- sourcesInfoTooltip
48
+ lozenge
53
49
  }) => /*#__PURE__*/React.createElement(Wrapper, null, avatar, /*#__PURE__*/React.createElement("div", {
54
50
  style: {
55
51
  maxWidth: '100%',
@@ -58,9 +54,7 @@ export const AvatarItemOption = ({
58
54
  lineHeight: '1.4',
59
55
  paddingLeft: '8px'
60
56
  }
61
- }, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Text, null, primaryText), /*#__PURE__*/React.createElement(AdditionalInfo, {
62
- withTooltip: Boolean(sourcesInfoTooltip)
63
- }, !sourcesInfoTooltip && (lozenge === null || lozenge === void 0 ? void 0 : lozenge.text) && (lozenge !== null && lozenge !== void 0 && lozenge.tooltip ?
57
+ }, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Text, null, primaryText), /*#__PURE__*/React.createElement(AdditionalInfo, null, (lozenge === null || lozenge === void 0 ? void 0 : lozenge.text) && (lozenge !== null && lozenge !== void 0 && lozenge.tooltip ?
64
58
  /*#__PURE__*/
65
59
  // Note that entire Lozenge must be wrapped in the Tooltip (rather than just the
66
60
  // Lozenge text) or tooltip won't work
@@ -68,6 +62,6 @@ React.createElement(React.Suspense, {
68
62
  fallback: /*#__PURE__*/React.createElement(Lozenge, lozenge, lozenge.text)
69
63
  }, /*#__PURE__*/React.createElement(AsyncTooltip, {
70
64
  content: lozenge.tooltip
71
- }, /*#__PURE__*/React.createElement(Lozenge, lozenge, lozenge.text))) : /*#__PURE__*/React.createElement(Lozenge, lozenge, lozenge.text)), sourcesInfoTooltip)), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Text, {
65
+ }, /*#__PURE__*/React.createElement(Lozenge, lozenge, lozenge.text))) : /*#__PURE__*/React.createElement(Lozenge, lozenge, lozenge.text)))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Text, {
72
66
  secondary: true
73
67
  }, secondaryText))));
@@ -25,13 +25,13 @@ export class EmailOption extends React.PureComponent {
25
25
  } = this.props;
26
26
  return /*#__PURE__*/React.createElement(TextWrapper, {
27
27
  key: "name",
28
- color: this.props.isSelected ? token('color.text.selected', B400) : token('color.text.highEmphasis', N800)
28
+ color: this.props.isSelected ? token('color.text.brand', B400) : token('color.text', N800)
29
29
  }, id);
30
30
  });
31
31
 
32
32
  _defineProperty(this, "renderSecondaryText", label => {
33
33
  return /*#__PURE__*/React.createElement(TextWrapper, {
34
- color: this.props.isSelected ? token('color.text.selected', B400) : token('color.text.lowEmphasis', N200)
34
+ color: this.props.isSelected ? token('color.text.brand', B400) : token('color.text.subtlest', N200)
35
35
  }, label);
36
36
  });
37
37
 
@@ -0,0 +1,49 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+ import { B400 } from '@atlaskit/theme/colors';
4
+ import { token } from '@atlaskit/tokens';
5
+ const OuterWrapper = styled.div`
6
+ align-items: center;
7
+ box-sizing: border-box;
8
+ display: flex;
9
+ line-height: 1;
10
+ outline: none;
11
+ margin: 0;
12
+ width: 100%;
13
+ cursor: pointer;
14
+ `;
15
+ const DetailsWrapper = styled.div`
16
+ display: flex;
17
+ max-width: 100%;
18
+ min-width: 0;
19
+ flex: 1 1 100%;
20
+ line-height: 1.4;
21
+ padding-left: 8px;
22
+ align-items: center;
23
+ `;
24
+ const TextSection = styled.div`
25
+ width: calc(100% - 32px);
26
+ flex: auto;
27
+ `;
28
+ const Text = styled.div`
29
+ display: flex;
30
+ max-width: 100%;
31
+ margin: 0;
32
+ color: ${token('color.text.selected', B400)};
33
+ ${({
34
+ secondary
35
+ }) => secondary && `color: ${token('color.text.selected', B400)}; font-size: 0.85em;`}
36
+ white-space: nowrap;
37
+
38
+ > span {
39
+ max-width: inherit;
40
+ }
41
+ `;
42
+ export const ExternalAvatarItemOption = ({
43
+ avatar,
44
+ primaryText,
45
+ secondaryText,
46
+ sourcesInfoTooltip
47
+ }) => /*#__PURE__*/React.createElement(OuterWrapper, null, avatar, /*#__PURE__*/React.createElement(DetailsWrapper, null, /*#__PURE__*/React.createElement(TextSection, null, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Text, null, primaryText)), secondaryText && /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Text, {
48
+ secondary: true
49
+ }, secondaryText))), /*#__PURE__*/React.createElement("div", null, sourcesInfoTooltip)));
@@ -0,0 +1,22 @@
1
+ import React, { useCallback, useState } from 'react';
2
+ import styled from 'styled-components';
3
+ import EditorPanelIcon from '@atlaskit/icon/glyph/editor/panel';
4
+ import { N50, N200 } from '@atlaskit/theme/colors';
5
+ import { token } from '@atlaskit/tokens';
6
+ const Wrapper = styled.div`
7
+ display: flex;
8
+ `;
9
+ export default (() => {
10
+ const [isMouseHovered, setHoverState] = useState(false);
11
+ const onMouseEnter = useCallback(() => setHoverState(true), [setHoverState]);
12
+ const onMouseLeave = useCallback(() => setHoverState(false), [setHoverState]);
13
+ return /*#__PURE__*/React.createElement(Wrapper, {
14
+ onMouseEnter: onMouseEnter,
15
+ onMouseLeave: onMouseLeave
16
+ }, /*#__PURE__*/React.createElement(EditorPanelIcon, {
17
+ testId: "source-icon",
18
+ label: "",
19
+ size: "large",
20
+ primaryColor: token('color.text.lowEmphasis', isMouseHovered ? N200 : N50)
21
+ }));
22
+ });
@@ -1,22 +1,23 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import React from 'react';
3
3
  import { FormattedMessage } from 'react-intl-next';
4
- import EditorPanelIcon from '@atlaskit/icon/glyph/editor/panel';
4
+ import styled from 'styled-components';
5
5
  import { ConfluenceIcon } from '@atlaskit/logo/confluence-icon';
6
6
  import { JiraIcon } from '@atlaskit/logo/jira-icon';
7
- import Tooltip from '@atlaskit/tooltip';
8
7
  import Spinner from '@atlaskit/spinner';
9
8
  import { B400, N200, N800 } from '@atlaskit/theme/colors';
10
9
  import { token } from '@atlaskit/tokens';
11
- import { AvatarItemOption, TextWrapper } from '../AvatarItemOption';
10
+ import Tooltip from '@atlaskit/tooltip';
11
+ import { TextWrapper } from '../AvatarItemOption';
12
12
  import { SizeableAvatar } from '../SizeableAvatar';
13
- import styled from 'styled-components';
14
13
  import { SlackIcon } from '../assets/slack';
15
14
  import { GoogleIcon } from '../assets/google';
16
15
  import { MicrosoftIcon } from '../assets/microsoft';
17
16
  import { GitHubIcon } from '../assets/github';
18
17
  import { messages } from '../i18n';
19
18
  import { ExternalUserSourcesContainer } from '../ExternalUserSourcesContainer';
19
+ import InfoIcon from './InfoIcon';
20
+ import { ExternalAvatarItemOption } from './ExternalAvatarItemOption';
20
21
  export const ImageContainer = styled.span`
21
22
  height: 16px;
22
23
  width: 16px;
@@ -78,7 +79,7 @@ export class ExternalUserOption extends React.PureComponent {
78
79
  } = this.props;
79
80
  return /*#__PURE__*/React.createElement(TextWrapper, {
80
81
  key: "name",
81
- color: this.props.isSelected ? token('color.text.selected', B400) : token('color.text.highEmphasis', N800)
82
+ color: this.props.isSelected ? token('color.text.brand', B400) : token('color.text', N800)
82
83
  }, name);
83
84
  });
84
85
 
@@ -94,7 +95,7 @@ export class ExternalUserOption extends React.PureComponent {
94
95
  const [emailUser, emailDomain] = email.split('@');
95
96
  const emailDomainWithAt = `@${emailDomain}`;
96
97
  return /*#__PURE__*/React.createElement(TextWrapper, {
97
- color: this.props.isSelected ? token('color.text.selected', B400) : token('color.text.lowEmphasis', N200)
98
+ color: this.props.isSelected ? token('color.text.brand', B400) : token('color.text.subtlest', N200)
98
99
  }, emailUser, /*#__PURE__*/React.createElement(EmailDomainWrapper, null, emailDomainWithAt));
99
100
  });
100
101
 
@@ -117,16 +118,11 @@ export class ExternalUserOption extends React.PureComponent {
117
118
  _defineProperty(this, "getSourcesInfoTooltip", () => this.props.user.isExternal ? /*#__PURE__*/React.createElement(Tooltip, {
118
119
  content: this.formattedTooltipContent(),
119
120
  position: 'right-start'
120
- }, /*#__PURE__*/React.createElement(EditorPanelIcon, {
121
- testId: "source-icon",
122
- label: "",
123
- size: "large",
124
- primaryColor: token('color.text.lowEmphasis', N200)
125
- })) : undefined);
121
+ }, /*#__PURE__*/React.createElement(InfoIcon, null)) : undefined);
126
122
  }
127
123
 
128
124
  render() {
129
- return /*#__PURE__*/React.createElement(AvatarItemOption, {
125
+ return /*#__PURE__*/React.createElement(ExternalAvatarItemOption, {
130
126
  avatar: this.renderAvatar(),
131
127
  primaryText: this.getPrimaryText(),
132
128
  secondaryText: this.renderSecondaryText(),
@@ -12,7 +12,7 @@ export const GroupOptionIconWrapper = styled.span`
12
12
  padding: 2px;
13
13
 
14
14
  > span {
15
- background-color: ${token('color.background.subtleNeutral.resting', N20)};
15
+ background-color: ${token('color.background.neutral', N20)};
16
16
  border-radius: 50%;
17
17
  padding: 4px;
18
18
  }
@@ -31,7 +31,7 @@ export class GroupOption extends React.PureComponent {
31
31
  } = this.props;
32
32
  return [/*#__PURE__*/React.createElement(TextWrapper, {
33
33
  key: "name",
34
- color: isSelected ? token('color.text.selected', B400) : token('color.text.highEmphasis', N800)
34
+ color: isSelected ? token('color.text.brand', B400) : token('color.text', N800)
35
35
  }, /*#__PURE__*/React.createElement(HighlightText, {
36
36
  highlights: highlight && highlight.name
37
37
  }, name))];
@@ -47,7 +47,7 @@ export class GroupOption extends React.PureComponent {
47
47
  isSelected
48
48
  } = this.props;
49
49
  return /*#__PURE__*/React.createElement(TextWrapper, {
50
- color: isSelected ? token('color.text.selected', B400) : token('color.text.lowEmphasis', N200)
50
+ color: isSelected ? token('color.text.brand', B400) : token('color.text.subtlest', N200)
51
51
  }, /*#__PURE__*/React.createElement(FormattedMessage, messages.groupByline));
52
52
  });
53
53
 
@@ -16,8 +16,8 @@ const ControlWrapper = styled.div`
16
16
  padding: 0px ${spacing}px ${spacing}px;
17
17
  `;
18
18
  const getColor = themed({
19
- light: token('color.text.lowEmphasis', N200),
20
- dark: token('color.text.lowEmphasis', DN90)
19
+ light: token('color.text.subtlest', N200),
20
+ dark: token('color.text.subtlest', DN90)
21
21
  });
22
22
 
23
23
  const getPadding = () => {
@@ -21,7 +21,7 @@ export class TeamOption extends React.PureComponent {
21
21
  } = this.props;
22
22
  return [/*#__PURE__*/React.createElement(TextWrapper, {
23
23
  key: "name",
24
- color: this.props.isSelected ? token('color.text.selected', B400) : token('color.text.highEmphasis', N800)
24
+ color: this.props.isSelected ? token('color.text.brand', B400) : token('color.text', N800)
25
25
  }, /*#__PURE__*/React.createElement(HighlightText, {
26
26
  highlights: highlight && highlight.name
27
27
  }, name))];
@@ -64,7 +64,7 @@ export class TeamOption extends React.PureComponent {
64
64
  });
65
65
 
66
66
  _defineProperty(this, "getBylineComponent", (isSelected, message) => /*#__PURE__*/React.createElement(TextWrapper, {
67
- color: isSelected ? token('color.text.selected', B400) : token('color.text.lowEmphasis', N200)
67
+ color: isSelected ? token('color.text.brand', B400) : token('color.text.subtlest', N200)
68
68
  }, message));
69
69
 
70
70
  _defineProperty(this, "renderAvatar", () => {
@@ -20,7 +20,7 @@ export class UserOption extends React.PureComponent {
20
20
  } = this.props;
21
21
  const result = [/*#__PURE__*/React.createElement(TextWrapper, {
22
22
  key: "name",
23
- color: this.props.isSelected ? token('color.text.selected', B400) : token('color.text.highEmphasis', N800)
23
+ color: this.props.isSelected ? token('color.text.brand', B400) : token('color.text', N800)
24
24
  }, /*#__PURE__*/React.createElement(HighlightText, {
25
25
  highlights: highlight && highlight.name
26
26
  }, name))];
@@ -29,7 +29,7 @@ export class UserOption extends React.PureComponent {
29
29
  result.push( /*#__PURE__*/React.createElement(React.Fragment, {
30
30
  key: "publicName"
31
31
  }, ' ', /*#__PURE__*/React.createElement(TextWrapper, {
32
- color: this.props.isSelected ? token('color.text.selected', B400) : token('color.text.lowEmphasis', N200)
32
+ color: this.props.isSelected ? token('color.text.brand', B400) : token('color.text.subtlest', N200)
33
33
  }, "(", /*#__PURE__*/React.createElement(HighlightText, {
34
34
  highlights: highlight && highlight.publicName
35
35
  }, publicName), ")")));
@@ -39,7 +39,7 @@ export class UserOption extends React.PureComponent {
39
39
  });
40
40
 
41
41
  _defineProperty(this, "renderSecondaryText", () => this.props.user.byline ? /*#__PURE__*/React.createElement(TextWrapper, {
42
- color: this.props.isSelected ? token('color.text.selected', B400) : token('color.text.lowEmphasis', N200)
42
+ color: this.props.isSelected ? token('color.text.brand', B400) : token('color.text.subtlest', N200)
43
43
  }, this.props.user.byline) : undefined);
44
44
 
45
45
  _defineProperty(this, "renderAvatar", () => {
@@ -10,7 +10,26 @@ import { getCreatableProps } from './creatable';
10
10
  import { getCreatableSuggestedEmailProps } from './creatableEmailSuggestion';
11
11
  import MessagesIntlProvider from './MessagesIntlProvider';
12
12
  import { ExusUserSourceProvider } from './../clients/UserSourceProvider';
13
+ import { userPickerRenderedUfoExperience as experience } from './utils';
14
+ import { v4 as uuidv4 } from 'uuid';
13
15
  export class UserPickerWithoutAnalytics extends React.Component {
16
+ constructor(props) {
17
+ super(props);
18
+ this.ufoId = uuidv4();
19
+
20
+ if (this.ufoId) {
21
+ const experienceForId = experience.getInstance(this.ufoId);
22
+ experienceForId.start();
23
+ }
24
+ }
25
+
26
+ componentDidMount() {
27
+ if (this.ufoId) {
28
+ const experienceForId = experience.getInstance(this.ufoId);
29
+ experienceForId.success();
30
+ }
31
+ }
32
+
14
33
  render() {
15
34
  const {
16
35
  emailLabel,
@@ -12,6 +12,6 @@ export function GitHubIcon(props) {
12
12
  fillRule: "evenodd",
13
13
  clipRule: "evenodd",
14
14
  d: "M11.9778 0C5.3635 0 0 5.45261 0 12.179C0 17.5601 3.432 22.1253 8.19114 23.7357C8.78975 23.8484 9.00952 23.4715 9.00952 23.1498C9.00952 22.8594 8.99841 21.9 8.99326 20.8823C5.66103 21.6191 4.95789 19.4454 4.95789 19.4454C4.41303 18.0376 3.62796 17.6633 3.62796 17.6633C2.54122 16.9074 3.70988 16.923 3.70988 16.923C4.91266 17.0089 5.54598 18.178 5.54598 18.178C6.61428 20.0399 8.34803 19.5016 9.03154 19.1904C9.13904 18.4033 9.44945 17.866 9.792 17.5619C7.13157 17.2539 4.33487 16.2096 4.33487 11.5429C4.33487 10.2133 4.80278 9.12682 5.56899 8.27391C5.44463 7.96716 5.03464 6.72844 5.68502 5.05087C5.68502 5.05087 6.69084 4.72354 8.97976 6.29927C9.9352 6.02942 10.9599 5.89409 11.9778 5.88945C12.9957 5.89409 14.0212 6.02942 14.9784 6.29927C17.2645 4.72354 18.269 5.05087 18.269 5.05087C18.9209 6.72844 18.5107 7.96716 18.3864 8.27391C19.1544 9.12682 19.6191 10.2133 19.6191 11.5429C19.6191 16.2207 16.8171 17.2507 14.1499 17.5522C14.5795 17.9301 14.9623 18.6713 14.9623 19.8076C14.9623 21.4371 14.9484 22.7487 14.9484 23.1498C14.9484 23.4739 15.164 23.8537 15.7712 23.7341C20.5277 22.1219 23.9554 17.5582 23.9554 12.179C23.9554 5.45261 18.5927 0 11.9778 0Z",
15
- fill: token('color.text.onBold', 'white')
15
+ fill: token('color.text.inverse', 'white')
16
16
  }));
17
17
  }
@@ -12,21 +12,21 @@ export function GoogleIcon(props) {
12
12
  fillRule: "evenodd",
13
13
  clipRule: "evenodd",
14
14
  d: "M8.32062 3.21332L10.014 1.55999C8.97396 0.593331 7.62063 0 6.00062 0C3.65396 0 1.62729 1.34666 0.640625 3.30665L2.58062 4.81331C3.06729 3.36665 4.41396 2.31999 6.00062 2.31999C7.12729 2.31999 7.88729 2.80665 8.32062 3.21332Z",
15
- fill: token('color.text.onBold', 'white')
15
+ fill: token('color.text.inverse', 'white')
16
16
  }), /*#__PURE__*/React.createElement("path", {
17
17
  fillRule: "evenodd",
18
18
  clipRule: "evenodd",
19
19
  d: "M11.76 6.13291C11.76 5.63958 11.72 5.27958 11.6333 4.90625H6V7.13291H9.30667C9.24 7.68624 8.88 8.51957 8.08 9.07957L9.97333 10.5462C11.1067 9.49956 11.76 7.95957 11.76 6.13291V6.13291V6.13291Z",
20
- fill: token('color.text.onBold', 'white')
20
+ fill: token('color.text.inverse', 'white')
21
21
  }), /*#__PURE__*/React.createElement("path", {
22
22
  fillRule: "evenodd",
23
23
  clipRule: "evenodd",
24
24
  d: "M2.58667 7.18662C2.46 6.81329 2.38667 6.41329 2.38667 5.99996C2.38667 5.58663 2.46 5.18663 2.58 4.8133L0.64 3.30664C0.233333 4.11997 0 5.0333 0 5.99996C0 6.96662 0.233333 7.87995 0.64 8.69328L2.58667 7.18662V7.18662Z",
25
- fill: token('color.text.onBold', 'white')
25
+ fill: token('color.text.inverse', 'white')
26
26
  }), /*#__PURE__*/React.createElement("path", {
27
27
  fillRule: "evenodd",
28
28
  clipRule: "evenodd",
29
29
  d: "M6.00079 12.0008C7.62079 12.0008 8.98079 11.4675 9.97413 10.5475L8.08079 9.08083C7.57413 9.43416 6.89413 9.68082 6.00079 9.68082C4.41413 9.68082 3.06746 8.63416 2.58746 7.1875L0.647461 8.69416C1.63413 10.6542 3.65413 12.0008 6.00079 12.0008V12.0008V12.0008Z",
30
- fill: token('color.text.onBold', 'white')
30
+ fill: token('color.text.inverse', 'white')
31
31
  }));
32
32
  }
@@ -12,21 +12,21 @@ export function MicrosoftIcon(props) {
12
12
  clipPath: "url(#clip0)"
13
13
  }, /*#__PURE__*/React.createElement("path", {
14
14
  d: "M0 0H5.70233V5.7023H0V0Z",
15
- fill: token('color.text.onBold', 'white')
15
+ fill: token('color.text.inverse', 'white')
16
16
  }), /*#__PURE__*/React.createElement("path", {
17
17
  d: "M6.29785 0H12.0002V5.7023H6.29785V0Z",
18
- fill: token('color.text.onBold', 'white')
18
+ fill: token('color.text.inverse', 'white')
19
19
  }), /*#__PURE__*/React.createElement("path", {
20
20
  d: "M0 6.29688H5.70233V11.9992H0V6.29688Z",
21
- fill: token('color.text.onBold', 'white')
21
+ fill: token('color.text.inverse', 'white')
22
22
  }), /*#__PURE__*/React.createElement("path", {
23
23
  d: "M6.29785 6.29688H12.0002V11.9992H6.29785V6.29688Z",
24
- fill: token('color.text.onBold', 'white')
24
+ fill: token('color.text.inverse', 'white')
25
25
  })), /*#__PURE__*/React.createElement("defs", null, /*#__PURE__*/React.createElement("clipPath", {
26
26
  id: "clip0"
27
27
  }, /*#__PURE__*/React.createElement("rect", {
28
28
  width: "12",
29
29
  height: "11.9999",
30
- fill: token('color.text.onBold', 'white')
30
+ fill: token('color.text.inverse', 'white')
31
31
  }))));
32
32
  }