@jetbrains/ring-ui 4.1.0-beta.16 → 4.1.0-beta.17

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 (139) hide show
  1. package/components/alert/container.css +1 -1
  2. package/components/auth/auth.test.js +14 -7
  3. package/components/auth/auth__core.js +7 -0
  4. package/components/avatar/avatar.css +4 -1
  5. package/components/avatar/avatar.examples.js +3 -2
  6. package/components/avatar/avatar.js +31 -6
  7. package/components/avatar/fallback-avatar.js +136 -0
  8. package/components/avatar-editor-ng/avatar-editor-ng.css +2 -2
  9. package/components/button/button.css +2 -2
  10. package/components/button-group/button-group.js +1 -1
  11. package/components/button-group/caption.js +1 -1
  12. package/components/button-ng/button-ng.js +1 -1
  13. package/components/checkbox/checkbox.css +1 -1
  14. package/components/content-layout/content-layout.css +1 -1
  15. package/components/data-list/data-list.css +1 -1
  16. package/components/date-picker/date-input.js +5 -4
  17. package/components/date-picker/date-picker.css +10 -6
  18. package/components/date-picker/date-picker.js +16 -14
  19. package/components/date-picker/date-popup.js +8 -4
  20. package/components/date-picker/month-names.js +8 -5
  21. package/components/date-picker/month.js +6 -2
  22. package/components/date-picker/weekdays.js +10 -2
  23. package/components/dialog-ng/dialog-ng.js +1 -1
  24. package/components/dropdown/dropdown.examples.js +36 -1
  25. package/components/dropdown-menu/dropdown-menu.examples.js +47 -0
  26. package/components/dropdown-menu/dropdown-menu.js +117 -0
  27. package/components/dropdown-menu/dropdown-menu.test.js +76 -0
  28. package/components/error-bubble/error-bubble-legacy.css +1 -1
  29. package/components/error-bubble/error-bubble.css +1 -1
  30. package/components/error-page/error-page.css +2 -2
  31. package/components/form/form.css +2 -2
  32. package/components/global/global.css +1 -1
  33. package/components/global/variables.css +8 -1
  34. package/components/grid/grid.css +10 -9
  35. package/components/header/header.css +1 -1
  36. package/components/header/header.examples.js +7 -8
  37. package/components/header/profile.js +10 -11
  38. package/components/http/http.js +1 -1
  39. package/components/icon/icon.css +5 -4
  40. package/components/island/island.css +4 -3
  41. package/components/island-legacy/island-legacy.css +3 -1
  42. package/components/link/link.js +0 -4
  43. package/components/list/list.js +6 -6
  44. package/components/list/list__custom.js +2 -3
  45. package/components/list/list__item.js +8 -5
  46. package/components/loader-inline/loader-inline.css +1 -1
  47. package/components/loader-screen/loader-screen.css +1 -1
  48. package/components/message/message.css +1 -1
  49. package/components/pager/pager.js +5 -3
  50. package/components/permissions/permissions.js +1 -1
  51. package/components/popup-menu/popup-menu.js +1 -12
  52. package/components/progress-bar/progress-bar.css +1 -1
  53. package/components/query-assist/query-assist.css +1 -1
  54. package/components/select/select.css +4 -0
  55. package/components/select/select.examples.js +13 -0
  56. package/components/select/select.js +6 -6
  57. package/components/shortcuts-hint-ng/shortcuts-hint-ng.css +1 -1
  58. package/components/sidebar/sidebar.css +1 -0
  59. package/components/table-legacy/table-legacy.css +2 -2
  60. package/components/tag/tag.css +5 -2
  61. package/components/tags-input/tags-input.js +5 -2
  62. package/components/template-ng/template-ng.js +1 -1
  63. package/components/tooltip/tooltip.js +7 -2
  64. package/components/user-agreement/user-agreement.css +1 -1
  65. package/dist/_helpers/button-group.js +1 -1
  66. package/dist/_helpers/button__classes.js +1 -1
  67. package/dist/_helpers/checkbox.js +1 -1
  68. package/dist/_helpers/date-picker.js +1 -1
  69. package/dist/_helpers/footer.js +1 -1
  70. package/dist/_helpers/grid.js +1 -1
  71. package/dist/_helpers/header.js +1 -1
  72. package/dist/_helpers/icon.js +1 -1
  73. package/dist/_helpers/inject-styles.js +1 -1
  74. package/dist/_helpers/input.js +1 -1
  75. package/dist/_helpers/island.js +1 -1
  76. package/dist/_helpers/loader-screen.js +1 -1
  77. package/dist/_helpers/query-assist__suggestions.js +1 -1
  78. package/dist/_helpers/sidebar.js +1 -1
  79. package/dist/_helpers/table.js +1 -1
  80. package/dist/_helpers/tabs.js +1 -1
  81. package/dist/_helpers/title.js +1 -1
  82. package/dist/alert/container.js +1 -1
  83. package/dist/auth/auth__core.js +7 -1
  84. package/dist/auth-dialog/auth-dialog.js +1 -1
  85. package/dist/avatar/avatar.js +18 -5
  86. package/dist/avatar/fallback-avatar.js +141 -0
  87. package/dist/avatar-ng/avatar-ng.js +2 -0
  88. package/dist/date-picker/date-input.js +6 -4
  89. package/dist/date-picker/date-picker.js +24 -14
  90. package/dist/date-picker/date-popup.js +16 -7
  91. package/dist/date-picker/month-names.js +13 -6
  92. package/dist/date-picker/month.js +11 -5
  93. package/dist/date-picker/weekdays.js +11 -3
  94. package/dist/dropdown-menu/dropdown-menu.js +175 -0
  95. package/dist/error-bubble/error-bubble.js +1 -1
  96. package/dist/header/header.js +18 -16
  97. package/dist/header/profile.js +26 -23
  98. package/dist/header/smart-profile.js +16 -14
  99. package/dist/heading/heading.js +1 -1
  100. package/dist/link/link.js +1 -5
  101. package/dist/list/list.js +8 -7
  102. package/dist/list/list__custom.js +2 -3
  103. package/dist/list/list__item.js +11 -7
  104. package/dist/list/list__users-groups-source.js +1 -0
  105. package/dist/markdown/markdown.js +1 -1
  106. package/dist/message/message.js +1 -1
  107. package/dist/pager/pager.js +7 -4
  108. package/dist/pager-ng/pager-ng.js +2 -1
  109. package/dist/popup/popup.js +1 -1
  110. package/dist/popup-menu/popup-menu.js +2 -14
  111. package/dist/progress-bar/progress-bar.js +1 -1
  112. package/dist/query-assist/query-assist.js +1 -0
  113. package/dist/query-assist/query-assist__suggestions.js +1 -0
  114. package/dist/query-assist-ng/query-assist-ng.js +1 -0
  115. package/dist/select/select.js +7 -8
  116. package/dist/select/select__filter.js +1 -0
  117. package/dist/select/select__popup.js +1 -0
  118. package/dist/select-ng/select-ng.js +2 -1
  119. package/dist/select-ng/select-ng__lazy.js +2 -1
  120. package/dist/style.css +1 -1
  121. package/dist/table-legacy-ng/table-legacy-ng.js +2 -1
  122. package/dist/table-legacy-ng/table-legacy-ng__pager.js +2 -1
  123. package/dist/tabs/collapsible-more.js +1 -0
  124. package/dist/tabs/collapsible-tabs.js +1 -0
  125. package/dist/tabs/dumb-tabs.js +1 -0
  126. package/dist/tabs/smart-tabs.js +1 -0
  127. package/dist/tabs/tabs.js +1 -0
  128. package/dist/tag/tag.js +1 -1
  129. package/dist/tags-input/tags-input.js +6 -5
  130. package/dist/tags-input-ng/tags-input-ng.js +2 -1
  131. package/dist/tooltip/tooltip.js +7 -3
  132. package/dist/user-agreement/user-agreement.js +1 -1
  133. package/dist/user-card/card.js +2 -0
  134. package/dist/user-card/smart-user-card-tooltip.js +1 -0
  135. package/dist/user-card/tooltip.js +1 -0
  136. package/dist/user-card/user-card.js +2 -1
  137. package/dist/user-card-ng/user-card-ng.js +1 -0
  138. package/package.json +62 -62
  139. package/webpack.config.js +1 -1
@@ -1,7 +1,7 @@
1
1
  @import "../global/variables.css";
2
2
 
3
3
  @value unit from "../global/global.css";
4
- @value alert from './alert.css';
4
+ @value alert from "./alert.css";
5
5
 
6
6
  .alertContainer {
7
7
  position: fixed;
@@ -203,7 +203,8 @@ describe('Auth', () => {
203
203
  redirectUri: 'http://localhost:8080/hub',
204
204
  clientId: '1-1-1-1-1',
205
205
  scope: ['0-0-0-0-0', 'youtrack'],
206
- optionalScopes: ['youtrack']
206
+ optionalScopes: ['youtrack'],
207
+ waitForRedirectTimeout: 0
207
208
  });
208
209
  try {
209
210
  await auth.init();
@@ -226,7 +227,8 @@ describe('Auth', () => {
226
227
  auth = new Auth({
227
228
  serverUri: '',
228
229
  redirect: true,
229
- cleanHash: true
230
+ cleanHash: true,
231
+ waitForRedirectTimeout: 0
230
232
  });
231
233
 
232
234
  try {
@@ -245,7 +247,8 @@ describe('Auth', () => {
245
247
  auth = new Auth({
246
248
  serverUri: '',
247
249
  redirect: true,
248
- cleanHash: true
250
+ cleanHash: true,
251
+ waitForRedirectTimeout: 0
249
252
  });
250
253
 
251
254
  try {
@@ -265,7 +268,8 @@ describe('Auth', () => {
265
268
  auth = new Auth({
266
269
  serverUri: '',
267
270
  redirect: true,
268
- cleanHash: false
271
+ cleanHash: false,
272
+ waitForRedirectTimeout: 0
269
273
  });
270
274
 
271
275
  try {
@@ -284,7 +288,8 @@ describe('Auth', () => {
284
288
  serverUri: '',
285
289
  redirect: true,
286
290
  redirectUri: 'http://localhost:8080/hub',
287
- requestCredentials: 'skip'
291
+ requestCredentials: 'skip',
292
+ waitForRedirectTimeout: 0
288
293
  });
289
294
  try {
290
295
  await auth.init();
@@ -313,7 +318,8 @@ describe('Auth', () => {
313
318
  redirectUri: 'http://localhost:8080/hub',
314
319
  clientId: '1-1-1-1-1',
315
320
  scope: ['0-0-0-0-0', 'youtrack'],
316
- optionalScopes: ['youtrack']
321
+ optionalScopes: ['youtrack'],
322
+ waitForRedirectTimeout: 0
317
323
  });
318
324
 
319
325
  auth._storage._tokenStorage = auth._storage._stateStorage =
@@ -330,7 +336,8 @@ describe('Auth', () => {
330
336
  auth._storage.saveToken({
331
337
  accessToken: 'token',
332
338
  expires: TokenValidator._epoch() + HOUR,
333
- scopes: ['0-0-0-0-0']
339
+ scopes: ['0-0-0-0-0'],
340
+ waitForRedirectTimeout: 0
334
341
  });
335
342
  });
336
343
 
@@ -14,6 +14,7 @@ export const DEFAULT_EXPIRES_TIMEOUT = 40 * 60;
14
14
  export const DEFAULT_BACKGROUND_TIMEOUT = 10 * 1000;
15
15
  const DEFAULT_BACKEND_CHECK_TIMEOUT = 10 * 1000;
16
16
  const BACKGROUND_REDIRECT_TIMEOUT = 20 * 1000;
17
+ const DEFAULT_WAIT_FOR_REDIRECT_TIMEOUT = 5 * 1000;
17
18
  /* eslint-enable no-magic-numbers */
18
19
 
19
20
  export const USER_CHANGED_EVENT = 'userChange';
@@ -46,6 +47,7 @@ const DEFAULT_CONFIG = {
46
47
  onBackendDown: () => {},
47
48
 
48
49
  defaultExpiresIn: DEFAULT_EXPIRES_TIMEOUT,
50
+ waitForRedirectTimeout: DEFAULT_WAIT_FOR_REDIRECT_TIMEOUT,
49
51
  translations: {
50
52
  login: 'Log in',
51
53
  loginTo: 'Log in to %serviceName%',
@@ -311,6 +313,11 @@ export default class Auth {
311
313
  const authRequest = await this._requestBuilder.prepareAuthRequest();
312
314
  this._redirectCurrentPage(authRequest.url);
313
315
 
316
+ // HUB-10867 Since we already redirecting the page, there is no actual need to throw an error
317
+ // and scare user with flashing error
318
+ // But let's keep it just in case redirect was not successful
319
+ await new Promise(resolve => setTimeout(resolve, this.config.waitForRedirectTimeout));
320
+
314
321
  throw error;
315
322
  }
316
323
 
@@ -1,10 +1,13 @@
1
1
  @import "../global/variables.css";
2
2
 
3
3
  .avatar {
4
+ display: inline-block;
4
5
  object-fit: cover;
5
6
  object-position: center;
6
7
 
7
- border-radius: var(--ring-border-radius); /* This is a "graceful degradation" fallback, while the real value is controlled by JS */
8
+ /* This is a "graceful degradation" fallback, while the real value is controlled by JS */
9
+
10
+ border-radius: var(--ring-border-radius);
8
11
  }
9
12
 
10
13
  .subavatar {
@@ -21,7 +21,8 @@ export const avatar = () => {
21
21
  {Object.keys(Size).map(size => (
22
22
  <div className="avatar-demo" key={size}>
23
23
  <Avatar size={Size[size]} url={avatarDataUri}/>
24
- <Avatar size={Size[size]} url={avatarDataUri} round/>
24
+ <Avatar size={Size[size]} username="Jet Brains"/>
25
+ <Avatar size={Size[size]} username="Jet Brains" round/>
25
26
  <Avatar size={Size[size]}/>
26
27
  </div>
27
28
  ))}
@@ -38,7 +39,7 @@ avatar.parameters = {
38
39
  .avatar-demo {
39
40
  display: flex;
40
41
  justify-content: space-between;
41
- width: 200px;
42
+ width: 240px;
42
43
  margin-bottom: 16px;
43
44
  }
44
45
  </style>`
@@ -6,6 +6,7 @@ import {encodeURL, isDataURI, parseQueryString} from '../global/url';
6
6
  import {getPixelRatio} from '../global/dom';
7
7
 
8
8
  import styles from './avatar.css';
9
+ import FallbackAvatar from './fallback-avatar';
9
10
 
10
11
  /**
11
12
  * @name Avatar
@@ -15,6 +16,7 @@ export const Size = {
15
16
  Size18: 18,
16
17
  Size20: 20,
17
18
  Size24: 24,
19
+ Size28: 28,
18
20
  Size32: 32,
19
21
  Size40: 40,
20
22
  Size48: 48,
@@ -30,7 +32,9 @@ export default class Avatar extends PureComponent {
30
32
  url: PropTypes.string,
31
33
  round: PropTypes.bool,
32
34
  subavatar: PropTypes.string,
33
- subavatarSize: PropTypes.number
35
+ subavatarSize: PropTypes.number,
36
+ username: PropTypes.string,
37
+ skipParams: PropTypes.bool
34
38
  };
35
39
 
36
40
  static defaultProps = {
@@ -53,7 +57,18 @@ export default class Avatar extends PureComponent {
53
57
  };
54
58
 
55
59
  render() {
56
- const {size, url, dpr, style, round, subavatar, subavatarSize, ...restProps} = this.props;
60
+ const {
61
+ size,
62
+ url,
63
+ dpr,
64
+ style,
65
+ round,
66
+ subavatar,
67
+ subavatarSize,
68
+ username,
69
+ skipParams,
70
+ ...restProps
71
+ } = this.props;
57
72
  const sizeString = `${size}px`;
58
73
  const subavatarSizeString = `${subavatarSize}px`;
59
74
  const borderRadius = size <= Size.Size18 ? 'var(--ring-border-radius-small)' : 'var(--ring-border-radius)';
@@ -76,14 +91,24 @@ export default class Avatar extends PureComponent {
76
91
  <span
77
92
  {...restProps}
78
93
  data-test="avatar"
79
- className={classNames(styles.avatar, styles.empty, this.props.className)}
94
+ className={
95
+ classNames(styles.avatar, this.props.className, {[styles.empty]: username == null})
96
+ }
80
97
  style={styleObj}
81
- />
98
+ >{
99
+ username != null && (
100
+ <FallbackAvatar
101
+ size={size}
102
+ round={round}
103
+ username={username}
104
+ />
105
+ )
106
+ }</span>
82
107
  );
83
108
  }
84
109
 
85
110
  let src = url;
86
- if (!isDataURI(url)) {
111
+ if (!skipParams && !isDataURI(url)) {
87
112
  const [urlStart, query] = url.split('?');
88
113
  const queryParams = {
89
114
  ...parseQueryString(query),
@@ -102,7 +127,7 @@ export default class Avatar extends PureComponent {
102
127
  subavatarSizeString
103
128
  };
104
129
 
105
- subavatarSrc = encodeURL(urlStart, queryParams);
130
+ subavatarSrc = skipParams ? subavatar : encodeURL(urlStart, queryParams);
106
131
  return (
107
132
  <div>
108
133
  <img
@@ -0,0 +1,136 @@
1
+ import React, {useMemo} from 'react';
2
+ import PropTypes from 'prop-types';
3
+
4
+ import getUID from '../global/get-uid';
5
+
6
+ const colorPairs = [
7
+ ['#60A800', '#D5CA00'],
8
+ ['#21D370', '#03E9E1'],
9
+ ['#3BA1FF', '#36E97D'],
10
+ ['#00C243', '#00FFFF'],
11
+ ['#4BE098', '#627FFF'],
12
+ ['#168BFA', '#26F7C7'],
13
+ ['#9D4CFF', '#39D3C3'],
14
+ ['#0A81F6', '#0ACFF6'],
15
+ ['#765AF8', '#5A91F8'],
16
+ ['#9E54FF', '#0ACFF6'],
17
+ ['#B345F1', '#669DFF'],
18
+ ['#765AF8', '#C059EE'],
19
+ ['#9039D0', '#C239D0'],
20
+ ['#9F2AFF', '#FD56FD'],
21
+ ['#AB3AF2', '#E40568'],
22
+ ['#9F2AFF', '#E9A80B'],
23
+ ['#D50F6B', '#E73AE8'],
24
+ ['#ED5502', '#E73AE8'],
25
+ ['#ED358C', '#DBED18'],
26
+ ['#ED358C', '#F9902E'],
27
+ ['#FF7500', '#FFCA00']
28
+ ];
29
+
30
+ const Sizes = {
31
+ 18: {
32
+ radius: 2,
33
+ text: {x: 9, y: 13},
34
+ fontSize: '11px',
35
+ textAnchor: 'middle'
36
+ },
37
+ 24: {
38
+ radius: 3,
39
+ text: {x: 2, y: 13},
40
+ fontSize: '11px',
41
+ underscore: {x: 3, y: 17}
42
+ },
43
+ 32: {
44
+ radius: 3,
45
+ text: {x: 3, y: 17},
46
+ fontSize: '13px',
47
+ letterSpacing: 1,
48
+ underscore: {x: 4, y: 22}
49
+ },
50
+ 40: {
51
+ radius: 3,
52
+ text: {x: 5, y: 19},
53
+ fontSize: '15px',
54
+ letterSpacing: 1,
55
+ underscore: {x: 6, y: 28}
56
+ }
57
+ };
58
+
59
+ const sizeKeys = Object.keys(Sizes).map(Number);
60
+
61
+ function extractLetters(name) {
62
+ const names = name.split(/[\s._]+/).filter(Boolean);
63
+ if (names.length >= 2) {
64
+ return names[0][0].toUpperCase() + names[1][0].toUpperCase();
65
+ } else if (names.length === 1) {
66
+ if (names[0].length >= 2) {
67
+ return names[0].slice(0, 2).toUpperCase();
68
+ } else {
69
+ return `${names[0][0].toUpperCase()}X`;
70
+ }
71
+ } else {
72
+ return 'XX';
73
+ }
74
+ }
75
+
76
+ // https://gist.github.com/hyamamoto/fd435505d29ebfa3d9716fd2be8d42f0#gistcomment-2775538
77
+ const BASE = 32;
78
+ function hashCode(s) {
79
+ let h = 0;
80
+ for (let i = 0; i < s.length; i++) {
81
+ h = Math.imul(BASE - 1, h) + s.charCodeAt(i) | 0;
82
+ }
83
+
84
+ return h;
85
+ }
86
+
87
+ export default function FallbackAvatar({username, size, round}) {
88
+ const hash = Math.abs(hashCode(username.toLowerCase()));
89
+ const [fromColor, toColor] = colorPairs[hash % colorPairs.length];
90
+ const possibleSizeKeys = sizeKeys.filter(key => key >= size);
91
+ const sizeKey = possibleSizeKeys.length > 0
92
+ ? Math.min(...possibleSizeKeys)
93
+ : Math.max(...sizeKeys);
94
+ const sizes = Sizes[sizeKey];
95
+ const radius = round ? '50%' : sizes.radius;
96
+ const gradientId = useMemo(() => getUID('gradient-'), []);
97
+ return (
98
+ <svg viewBox={`0 0 ${sizeKey} ${sizeKey}`} xmlns="http://www.w3.org/2000/svg">
99
+ <defs>
100
+ <linearGradient id={gradientId} x1="0" y1="0" x2="0" y2="1">
101
+ <stop stopColor={fromColor} offset="0"/>
102
+ <stop stopColor={toColor} offset="1"/>
103
+ </linearGradient>
104
+ </defs>
105
+ <g>
106
+ <rect
107
+ fill={`url(#${gradientId})`}
108
+ x="0"
109
+ y="0"
110
+ width={sizeKey}
111
+ height={sizeKey}
112
+ rx={radius}
113
+ ry={radius}
114
+ />
115
+ <text
116
+ x={sizes.text.x}
117
+ y={sizes.text.y}
118
+ fontFamily="Arial, Helvetica, sans-serif"
119
+ fontSize={sizes.fontSize}
120
+ letterSpacing={sizes.letterSpacing}
121
+ fill="#FFFFFF"
122
+ textAnchor={sizes.textAnchor}
123
+ >
124
+ <tspan>{extractLetters(username)}</tspan>
125
+ {sizes.underscore && <tspan x={sizes.underscore.x} y={sizes.underscore.y}>{'_'}</tspan>}
126
+ </text>
127
+ </g>
128
+ </svg>
129
+ );
130
+ }
131
+
132
+ FallbackAvatar.propTypes = {
133
+ username: PropTypes.string.isRequired,
134
+ size: PropTypes.number.isRequired,
135
+ round: PropTypes.bool
136
+ };
@@ -19,7 +19,7 @@
19
19
  width: 0;
20
20
  height: calc(unit * 5);
21
21
 
22
- content: '';
22
+ content: "";
23
23
  vertical-align: middle;
24
24
  }
25
25
  }
@@ -49,7 +49,7 @@
49
49
  width: 100%;
50
50
  height: 100%;
51
51
 
52
- content: '';
52
+ content: "";
53
53
 
54
54
  background-color: rgba(0, 0, 0, 0.8);
55
55
  }
@@ -451,7 +451,7 @@
451
451
  width: calc(100% + loaderWidth);
452
452
  height: 100%;
453
453
 
454
- content: '';
454
+ content: "";
455
455
  animation: progress 1s linear infinite;
456
456
 
457
457
  background-repeat: repeat;
@@ -460,7 +460,7 @@
460
460
  }
461
461
 
462
462
  .delayed .content::after {
463
- content: '';
463
+ content: "";
464
464
  }
465
465
 
466
466
  .short {
@@ -12,7 +12,7 @@ export default class ButtonGroup extends PureComponent {
12
12
  static propTypes = {
13
13
  children: PropTypes.node,
14
14
  className: PropTypes.string
15
- }
15
+ };
16
16
 
17
17
  render() {
18
18
  const {className} = this.props;
@@ -7,7 +7,7 @@ import styles from './button-group.css';
7
7
  export default class Caption extends PureComponent {
8
8
  static propTypes = {
9
9
  className: PropTypes.node
10
- }
10
+ };
11
11
 
12
12
  render() {
13
13
  const {className} = this.props;
@@ -166,7 +166,7 @@ class ButtonController extends RingAngularComponent {
166
166
  }
167
167
 
168
168
  $compile(icon)($scope);
169
- }
169
+ };
170
170
  }
171
171
 
172
172
  function changeTheme(element, data) {
@@ -89,7 +89,7 @@
89
89
  /* stylelint-disable-next-line selector-max-specificity */
90
90
  &:checked + .cell,
91
91
  &:indeterminate[checked] + .cell,
92
- &:indeterminate[data-checked=true] + .cell {
92
+ &:indeterminate[data-checked="true"] + .cell {
93
93
  border-color: var(--ring-border-hover-color);
94
94
  background-color: var(--ring-selected-background-color);
95
95
  }
@@ -1,6 +1,6 @@
1
1
  @import "../global/variables.css";
2
2
 
3
- @value unit, extra-small-screen-media, small-screen-media from '../global/global.css';
3
+ @value unit, extra-small-screen-media, small-screen-media from "../global/global.css";
4
4
  @value sidebarWidth: calc(unit * 30);
5
5
 
6
6
  .contentLayout {
@@ -1,7 +1,7 @@
1
1
  @import "../global/variables.css";
2
2
 
3
3
  @value unit from "../global/global.css";
4
- @value height, compensate from '../table/table.css';
4
+ @value height, compensate from "../table/table.css";
5
5
 
6
6
  .dataListWrapper {
7
7
  position: relative;
@@ -25,7 +25,8 @@ export default class DateInput extends React.PureComponent {
25
25
  onInput: PropTypes.func,
26
26
  onActivate: PropTypes.func,
27
27
  onConfirm: PropTypes.func,
28
- onClear: PropTypes.func
28
+ onClear: PropTypes.func,
29
+ locale: PropTypes.object
29
30
  };
30
31
 
31
32
  static defaultProps = {
@@ -78,16 +79,16 @@ export default class DateInput extends React.PureComponent {
78
79
  time, name, hoverDate,
79
80
  date, displayFormat, translations,
80
81
  onActivate, onClear,
81
- fromPlaceholder, toPlaceholder, timePlaceholder
82
+ fromPlaceholder, toPlaceholder, timePlaceholder, locale
82
83
  } = this.props;
83
84
 
84
85
  let displayText = '';
85
86
  if (active && hoverDate) {
86
- displayText = displayFormat(hoverDate);
87
+ displayText = displayFormat(hoverDate, locale);
87
88
  } else if (active && text != null) {
88
89
  displayText = text;
89
90
  } else if (date) {
90
- displayText = displayFormat(date);
91
+ displayText = displayFormat(date, locale);
91
92
  } else if (name === 'time') {
92
93
  displayText = time || '';
93
94
  }
@@ -96,7 +96,7 @@
96
96
  position: absolute;
97
97
  right: unit;
98
98
 
99
- content: '';
99
+ content: "";
100
100
 
101
101
  line-height: calc(4 * unit - 2px);
102
102
  }
@@ -123,7 +123,7 @@
123
123
  position: absolute;
124
124
  left: calc(-1 * unit);
125
125
 
126
- content: ',';
126
+ content: ",";
127
127
 
128
128
  line-height: calc(4 * unit - 3px);
129
129
  }
@@ -198,6 +198,8 @@
198
198
 
199
199
  text-align: left;
200
200
 
201
+ text-transform: capitalize;
202
+
201
203
  font-weight: bold;
202
204
 
203
205
  @supports (flex-basis: 1px) {
@@ -282,7 +284,7 @@
282
284
  width: calc(unit * 2);
283
285
  height: 100%;
284
286
 
285
- content: '';
287
+ content: "";
286
288
  transition: background-color var(--ring-ease);
287
289
  }
288
290
 
@@ -325,7 +327,7 @@
325
327
  width: calc(unit * 23);
326
328
  height: calc(unit * 8);
327
329
 
328
- content: '';
330
+ content: "";
329
331
  transition: background-color var(--ring-ease);
330
332
  }
331
333
 
@@ -357,7 +359,7 @@
357
359
  width: calc(unit * 2);
358
360
  height: 100%;
359
361
 
360
- content: '';
362
+ content: "";
361
363
  transition: background-color var(--ring-ease);
362
364
  }
363
365
  }
@@ -409,7 +411,7 @@
409
411
  top: 0;
410
412
  left: calc(unit * 0.5);
411
413
 
412
- content: '';
414
+ content: "";
413
415
 
414
416
  font-size: var(--ring-font-size-smaller);
415
417
  }
@@ -453,6 +455,8 @@
453
455
  height: cellSize;
454
456
  padding-left: calc(unit * 1.5);
455
457
 
458
+ text-transform: capitalize;
459
+
456
460
  line-height: cellSize;
457
461
  }
458
462
 
@@ -90,7 +90,8 @@ export default class DatePicker extends PureComponent {
90
90
  disabled: PropTypes.bool,
91
91
  minDate: dateType,
92
92
  maxDate: dateType,
93
- translations: PropTypes.object
93
+ translations: PropTypes.object,
94
+ locale: PropTypes.object
94
95
  };
95
96
 
96
97
  static defaultProps = {
@@ -101,10 +102,10 @@ export default class DatePicker extends PureComponent {
101
102
  from: null,
102
103
  to: null,
103
104
  clear: false,
104
- displayFormat: date => (date ? formatDate(date, 'd MMM yyyy') : ''),
105
- displayMonthFormat: date => (date ? formatDate(date, 'd MMM') : ''),
106
- displayDayFormat: date => (date ? formatDate(date, 'd') : ''),
107
- displayTimeFormat: date => (date ? formatDate(date, 'HH:mm') : ''),
105
+ displayFormat: (date, locale) => (date ? formatDate(date, 'd MMM yyyy', {locale}) : ''),
106
+ displayMonthFormat: (date, locale) => (date ? formatDate(date, 'd MMM', {locale}) : ''),
107
+ displayDayFormat: (date, locale) => (date ? formatDate(date, 'd', {locale}) : ''),
108
+ displayTimeFormat: (date, locale) => (date ? formatDate(date, 'HH:mm', {locale}) : ''),
108
109
  datePlaceholder: 'Set a date',
109
110
  dateTimePlaceholder: 'Set date and time',
110
111
  rangePlaceholder: 'Set a period',
@@ -194,7 +195,8 @@ export default class DatePicker extends PureComponent {
194
195
  displayFormat,
195
196
  displayMonthFormat,
196
197
  displayDayFormat,
197
- translations
198
+ translations,
199
+ locale
198
200
  } = this.props;
199
201
 
200
202
  const date = this.parse(this.props.date);
@@ -204,27 +206,27 @@ export default class DatePicker extends PureComponent {
204
206
 
205
207
  let text;
206
208
  if (!range && !withTime) {
207
- text = date ? displayFormat(date) : datePlaceholder || translations.setDate;
209
+ text = date ? displayFormat(date, locale) : datePlaceholder || translations.setDate;
208
210
  } else if (!range && withTime) {
209
211
  if (!date && !time) {
210
212
  text = dateTimePlaceholder || translations.setDateTime;
211
213
  } else {
212
- text = `${date && displayFormat(date) || '—'}, ${time || '—'}`;
214
+ text = `${date && displayFormat(date, locale) || '—'}, ${time || '—'}`;
213
215
  }
214
216
  } else if (!from && !to) {
215
217
  text = rangePlaceholder || translations.setPeriod;
216
218
  } else if (!to) {
217
- text = `${displayFormat(from)} —`;
219
+ text = `${displayFormat(from, locale)} —`;
218
220
  } else if (!from) {
219
- text = `— ${displayFormat(to)}`;
221
+ text = `— ${displayFormat(to, locale)}`;
220
222
  } else if (!isSameYear(from, to)) {
221
- text = `${displayFormat(from)} — ${displayFormat(to)}`;
223
+ text = `${displayFormat(from, locale)} — ${displayFormat(to, locale)}`;
222
224
  } else if (!isSameMonth(from, to)) {
223
- text = `${displayMonthFormat(from)} — ${displayFormat(to)}`;
225
+ text = `${displayMonthFormat(from, locale)} — ${displayFormat(to, locale)}`;
224
226
  } else if (!isSameDay(from, to)) {
225
- text = `${displayDayFormat(from)} — ${displayFormat(to)}`;
227
+ text = `${displayDayFormat(from, locale)} — ${displayFormat(to, locale)}`;
226
228
  } else {
227
- text = `${displayFormat(to)}`;
229
+ text = `${displayFormat(to, locale)}`;
228
230
  }
229
231
 
230
232
  return text;
@@ -47,7 +47,8 @@ export default class DatePopup extends Component {
47
47
  hidden: PropTypes.bool,
48
48
  fromPlaceholder: PropTypes.string,
49
49
  toPlaceholder: PropTypes.string,
50
- timePlaceholder: PropTypes.string
50
+ timePlaceholder: PropTypes.string,
51
+ locale: PropTypes.object
51
52
  };
52
53
 
53
54
  static defaultProps = {
@@ -77,7 +78,7 @@ export default class DatePopup extends Component {
77
78
 
78
79
  componentDidMount() {
79
80
  if (this.componentRef.current) {
80
- this.componentRef.current.addEventListener('wheel', this.handleWheel);
81
+ this.componentRef.current.addEventListener('wheel', this.handleWheel, {passive: true});
81
82
  }
82
83
  }
83
84
 
@@ -297,7 +298,7 @@ export default class DatePopup extends Component {
297
298
  };
298
299
 
299
300
  render() {
300
- const {range, hidden, withTime, time} = this.props;
301
+ const {range, hidden, withTime, time, locale} = this.props;
301
302
  const parsedDate = this.parse(this.props.date, 'date');
302
303
  const parsedTo = this.parse(this.props.to, 'to');
303
304
 
@@ -391,6 +392,7 @@ export default class DatePopup extends Component {
391
392
  onInput={this.handleInput}
392
393
  onConfirm={this.handleConfirm(name)}
393
394
  onClear={onClear}
395
+ locale={locale}
394
396
  />
395
397
  );
396
398
  })}
@@ -413,12 +415,13 @@ export default class DatePopup extends Component {
413
415
  onInput={this.handleInput}
414
416
  onConfirm={this.handleConfirm('time')}
415
417
  onClear={clearable && this.onClear || undefined}
418
+ locale={locale}
416
419
  />
417
420
  )
418
421
  : ('')
419
422
  }
420
423
  </div>
421
- <Weekdays/>
424
+ <Weekdays locale={locale}/>
422
425
  <div
423
426
  className={styles.calendar}
424
427
  >
@@ -426,6 +429,7 @@ export default class DatePopup extends Component {
426
429
  {...calendarProps}
427
430
  onHover={this.hoverHandler}
428
431
  onSelect={this.selectHandler}
432
+ locale={locale}
429
433
  />
430
434
  <Years {...calendarProps}/>
431
435
  </div>