@jetbrains/ring-ui 5.0.143 → 5.0.145

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.
@@ -67,7 +67,7 @@ export default class DatePopup extends Component {
67
67
  }
68
68
  componentDidMount() {
69
69
  if (this.componentRef.current) {
70
- this.componentRef.current.addEventListener('wheel', this.handleWheel, { passive: true });
70
+ this.componentRef.current.addEventListener('wheel', this.handleWheel);
71
71
  }
72
72
  }
73
73
  componentDidUpdate(prevProps, prevState) {
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useEffect, useMemo, useRef } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import addMonths from 'date-fns/addMonths';
4
4
  import getDay from 'date-fns/getDay';
@@ -8,6 +8,7 @@ import subMonths from 'date-fns/subMonths';
8
8
  import endOfMonth from 'date-fns/endOfMonth';
9
9
  import scheduleRAF from '../global/schedule-raf';
10
10
  import linearFunction from '../global/linear-function';
11
+ import useEventCallback from '../global/use-event-callback';
11
12
  import Month from './month';
12
13
  import MonthNames from './month-names';
13
14
  import styles from './date-picker.css';
@@ -37,38 +38,54 @@ export default function Months(props) {
37
38
  const { scrollDate } = props;
38
39
  const monthDate = scrollDate instanceof Date ? scrollDate : new Date(scrollDate);
39
40
  const monthStart = startOfMonth(monthDate);
40
- let month = subMonths(monthStart, MONTHSBACK);
41
- const months = [month];
42
- for (let i = 0; i < MONTHSBACK * DOUBLE; i++) {
43
- month = addMonths(month, 1);
44
- months.push(month);
45
- }
41
+ const months = useMemo(() => {
42
+ let month = subMonths(monthStart, MONTHSBACK);
43
+ const result = [month];
44
+ for (let i = 0; i < MONTHSBACK * DOUBLE; i++) {
45
+ month = addMonths(month, 1);
46
+ result.push(month);
47
+ }
48
+ return result;
49
+ }, [monthStart]);
46
50
  const currentSpeed = scrollSpeed(scrollDate);
47
51
  const pxToDate = linearFunction(0, Number(scrollDate), currentSpeed);
48
52
  const offset = pxToDate.x(Number(monthStart)); // is a negative number
49
53
  const bottomOffset = monthHeight(scrollDate) + offset;
50
- return (<div className={styles.months} onWheel={function handleWheel(e) {
51
- e.preventDefault();
52
- dy += e.deltaY;
53
- scrollSchedule(() => {
54
- let date;
55
- // adjust scroll speed to prevent glitches
56
- if (dy < offset) {
57
- date = pxToDate.y(offset) + (dy - offset) * scrollSpeed(months[1]);
58
- }
59
- else if (dy > bottomOffset) {
60
- date =
61
- pxToDate.y(bottomOffset) +
62
- (dy - bottomOffset) *
63
- scrollSpeed(months[MONTHSBACK + 1]);
64
- }
65
- else {
66
- date = pxToDate.y(dy);
67
- }
68
- props.onScroll(date);
69
- dy = 0;
70
- });
71
- }}>
54
+ const componentRef = useRef(null);
55
+ const handleWheel = useEventCallback((e) => {
56
+ e.preventDefault();
57
+ dy += e.deltaY;
58
+ scrollSchedule(() => {
59
+ let date;
60
+ // adjust scroll speed to prevent glitches
61
+ if (dy < offset) {
62
+ date = pxToDate.y(offset) + (dy - offset) * scrollSpeed(months[1]);
63
+ }
64
+ else if (dy > bottomOffset) {
65
+ date =
66
+ pxToDate.y(bottomOffset) +
67
+ (dy - bottomOffset) *
68
+ scrollSpeed(months[MONTHSBACK + 1]);
69
+ }
70
+ else {
71
+ date = pxToDate.y(dy);
72
+ }
73
+ props.onScroll(date);
74
+ dy = 0;
75
+ });
76
+ });
77
+ useEffect(() => {
78
+ const current = componentRef.current;
79
+ if (current !== null) {
80
+ current.addEventListener('wheel', handleWheel, { passive: false });
81
+ }
82
+ return () => {
83
+ if (current !== null) {
84
+ current.removeEventListener('wheel', handleWheel);
85
+ }
86
+ };
87
+ }, [handleWheel]);
88
+ return (<div className={styles.months} ref={componentRef}>
72
89
  <div style={{
73
90
  top: Math.
74
91
  floor(calHeight * HALF - monthHeight(months[0]) - monthHeight(months[1]) + offset)
@@ -13,9 +13,13 @@ export default class Years extends PureComponent<CalendarProps> {
13
13
  state: {
14
14
  scrollDate: null;
15
15
  };
16
+ componentDidMount(): void;
16
17
  componentDidUpdate(prevProps: CalendarProps, prevState: YearsState): void;
18
+ componentWillUnmount(): void;
17
19
  stoppedScrolling?: boolean;
18
20
  setYear(date: number): void;
21
+ componentRef: React.RefObject<HTMLDivElement>;
22
+ handleWheel: (e: WheelEvent) => void;
19
23
  render(): React.JSX.Element;
20
24
  }
21
25
  export {};
@@ -1,4 +1,4 @@
1
- import React, { PureComponent } from 'react';
1
+ import React, { createRef, PureComponent } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import classNames from 'classnames';
4
4
  import addYears from 'date-fns/addYears';
@@ -23,9 +23,19 @@ export default class Years extends PureComponent {
23
23
  onScrollChange: PropTypes.func
24
24
  };
25
25
  state = { scrollDate: null };
26
+ componentDidMount() {
27
+ if (this.componentRef.current) {
28
+ this.componentRef.current.addEventListener('wheel', this.handleWheel);
29
+ }
30
+ }
26
31
  componentDidUpdate(prevProps, prevState) {
27
32
  this.stoppedScrolling = prevState.scrollDate != null && !this.state.scrollDate;
28
33
  }
34
+ componentWillUnmount() {
35
+ if (this.componentRef.current) {
36
+ this.componentRef.current.removeEventListener('wheel', this.handleWheel);
37
+ }
38
+ }
29
39
  stoppedScrolling;
30
40
  setYear(date) {
31
41
  if (scrollTO) {
@@ -35,6 +45,20 @@ export default class Years extends PureComponent {
35
45
  this.setState({ scrollDate: null });
36
46
  this.props.onScroll(Number(setYear(this.props.scrollDate, getYear(date))));
37
47
  }
48
+ componentRef = createRef();
49
+ handleWheel = (e) => {
50
+ const { scrollDate } = this.props;
51
+ const date = this.state.scrollDate || scrollDate;
52
+ e.preventDefault();
53
+ const newScrollDate = linearFunction(0, Number(date), yearDuration / yearHeight).y(e.deltaY);
54
+ this.setState({
55
+ scrollDate: newScrollDate
56
+ });
57
+ if (scrollTO) {
58
+ window.clearTimeout(scrollTO);
59
+ }
60
+ scrollTO = window.setTimeout(() => this.setYear(newScrollDate), scrollDelay);
61
+ };
38
62
  render() {
39
63
  const { onScrollChange, scrollDate } = this.props;
40
64
  const date = this.state.scrollDate || scrollDate;
@@ -46,19 +70,7 @@ export default class Years extends PureComponent {
46
70
  years.push(year);
47
71
  }
48
72
  const pxToDate = linearFunction(0, Number(years[0]), yearDuration / yearHeight);
49
- const handleWheel = (e) => {
50
- e.preventDefault();
51
- const newScrollDate = linearFunction(0, Number(date), yearDuration / yearHeight).
52
- y(e.deltaY);
53
- this.setState({
54
- scrollDate: newScrollDate
55
- });
56
- if (scrollTO) {
57
- window.clearTimeout(scrollTO);
58
- }
59
- scrollTO = window.setTimeout(() => this.setYear(newScrollDate), scrollDelay);
60
- };
61
- return (<div className={styles.years} onWheel={handleWheel} style={{
73
+ return (<div className={styles.years} ref={this.componentRef} style={{
62
74
  transition: this.stoppedScrolling ? 'top .2s ease-out 0s' : 'none',
63
75
  top: Math.floor(calHeight * HALF - pxToDate.x(Number(date)))
64
76
  }}>
@@ -0,0 +1 @@
1
+ export default function useEventCallback<I extends unknown[], O>(fn: (...args: I) => O): (...args: I) => O;
@@ -0,0 +1,14 @@
1
+ import { useCallback, useLayoutEffect, useRef } from 'react';
2
+ export default function useEventCallback(fn) {
3
+ const ref = useRef();
4
+ useLayoutEffect(() => {
5
+ ref.current = fn;
6
+ });
7
+ return useCallback((...args) => {
8
+ const { current } = ref;
9
+ if (current == null) {
10
+ throw new Error('callback created in useEventCallback can only be called from event handlers');
11
+ }
12
+ return current(...args);
13
+ }, []);
14
+ }
@@ -68,6 +68,7 @@ import 'date-fns/startOfMonth';
68
68
  import 'date-fns/subMonths';
69
69
  import 'date-fns/endOfMonth';
70
70
  import '../global/linear-function.js';
71
+ import '../global/use-event-callback.js';
71
72
  import './month.js';
72
73
  import 'date-fns/addDays';
73
74
  import 'date-fns/setDay';
@@ -42,6 +42,7 @@ import 'date-fns/subMonths';
42
42
  import 'date-fns/endOfMonth';
43
43
  import '../global/schedule-raf.js';
44
44
  import '../global/linear-function.js';
45
+ import '../global/use-event-callback.js';
45
46
  import './month.js';
46
47
  import 'date-fns/addDays';
47
48
  import 'date-fns/format';
@@ -126,9 +127,7 @@ class DatePopup extends Component {
126
127
  }
127
128
  componentDidMount() {
128
129
  if (this.componentRef.current) {
129
- this.componentRef.current.addEventListener('wheel', this.handleWheel, {
130
- passive: true
131
- });
130
+ this.componentRef.current.addEventListener('wheel', this.handleWheel);
132
131
  }
133
132
  }
134
133
  componentDidUpdate(prevProps, prevState) {
@@ -1,5 +1,5 @@
1
1
  import { _ as _extends } from '../_helpers/_rollupPluginBabelHelpers.js';
2
- import React from 'react';
2
+ import React, { useMemo, useRef, useEffect } from 'react';
3
3
  import PropTypes from 'prop-types';
4
4
  import addMonths from 'date-fns/addMonths';
5
5
  import getDay from 'date-fns/getDay';
@@ -9,6 +9,7 @@ import subMonths from 'date-fns/subMonths';
9
9
  import endOfMonth from 'date-fns/endOfMonth';
10
10
  import scheduleRAF from '../global/schedule-raf.js';
11
11
  import linearFunction from '../global/linear-function.js';
12
+ import useEventCallback from '../global/use-event-callback.js';
12
13
  import Month from './month.js';
13
14
  import MonthNames from './month-names.js';
14
15
  import { m as modules_0c7b7d96 } from '../_helpers/date-picker.js';
@@ -63,35 +64,53 @@ function Months(props) {
63
64
  } = props;
64
65
  const monthDate = scrollDate instanceof Date ? scrollDate : new Date(scrollDate);
65
66
  const monthStart = startOfMonth(monthDate);
66
- let month = subMonths(monthStart, MONTHSBACK);
67
- const months = [month];
68
- for (let i = 0; i < MONTHSBACK * DOUBLE; i++) {
69
- month = addMonths(month, 1);
70
- months.push(month);
71
- }
67
+ const months = useMemo(() => {
68
+ let month = subMonths(monthStart, MONTHSBACK);
69
+ const result = [month];
70
+ for (let i = 0; i < MONTHSBACK * DOUBLE; i++) {
71
+ month = addMonths(month, 1);
72
+ result.push(month);
73
+ }
74
+ return result;
75
+ }, [monthStart]);
72
76
  const currentSpeed = scrollSpeed(scrollDate);
73
77
  const pxToDate = linearFunction(0, Number(scrollDate), currentSpeed);
74
78
  const offset = pxToDate.x(Number(monthStart)); // is a negative number
75
79
  const bottomOffset = monthHeight(scrollDate) + offset;
76
- return /*#__PURE__*/React.createElement("div", {
77
- className: modules_0c7b7d96.months,
78
- onWheel: function handleWheel(e) {
79
- e.preventDefault();
80
- dy += e.deltaY;
81
- scrollSchedule(() => {
82
- let date;
83
- // adjust scroll speed to prevent glitches
84
- if (dy < offset) {
85
- date = pxToDate.y(offset) + (dy - offset) * scrollSpeed(months[1]);
86
- } else if (dy > bottomOffset) {
87
- date = pxToDate.y(bottomOffset) + (dy - bottomOffset) * scrollSpeed(months[MONTHSBACK + 1]);
88
- } else {
89
- date = pxToDate.y(dy);
90
- }
91
- props.onScroll(date);
92
- dy = 0;
80
+ const componentRef = useRef(null);
81
+ const handleWheel = useEventCallback(e => {
82
+ e.preventDefault();
83
+ dy += e.deltaY;
84
+ scrollSchedule(() => {
85
+ let date;
86
+ // adjust scroll speed to prevent glitches
87
+ if (dy < offset) {
88
+ date = pxToDate.y(offset) + (dy - offset) * scrollSpeed(months[1]);
89
+ } else if (dy > bottomOffset) {
90
+ date = pxToDate.y(bottomOffset) + (dy - bottomOffset) * scrollSpeed(months[MONTHSBACK + 1]);
91
+ } else {
92
+ date = pxToDate.y(dy);
93
+ }
94
+ props.onScroll(date);
95
+ dy = 0;
96
+ });
97
+ });
98
+ useEffect(() => {
99
+ const current = componentRef.current;
100
+ if (current !== null) {
101
+ current.addEventListener('wheel', handleWheel, {
102
+ passive: false
93
103
  });
94
104
  }
105
+ return () => {
106
+ if (current !== null) {
107
+ current.removeEventListener('wheel', handleWheel);
108
+ }
109
+ };
110
+ }, [handleWheel]);
111
+ return /*#__PURE__*/React.createElement("div", {
112
+ className: modules_0c7b7d96.months,
113
+ ref: componentRef
95
114
  }, /*#__PURE__*/React.createElement("div", {
96
115
  style: {
97
116
  top: Math.floor(calHeight * HALF - monthHeight(months[0]) - monthHeight(months[1]) + offset)
@@ -13,9 +13,13 @@ export default class Years extends PureComponent<CalendarProps> {
13
13
  state: {
14
14
  scrollDate: null;
15
15
  };
16
+ componentDidMount(): void;
16
17
  componentDidUpdate(prevProps: CalendarProps, prevState: YearsState): void;
18
+ componentWillUnmount(): void;
17
19
  stoppedScrolling?: boolean;
18
20
  setYear(date: number): void;
21
+ componentRef: React.RefObject<HTMLDivElement>;
22
+ handleWheel: (e: WheelEvent) => void;
19
23
  render(): React.JSX.Element;
20
24
  }
21
25
  export {};
@@ -1,4 +1,4 @@
1
- import React, { PureComponent } from 'react';
1
+ import React, { PureComponent, createRef } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import classNames from 'classnames';
4
4
  import addYears from 'date-fns/addYears';
@@ -11,7 +11,7 @@ import startOfYear from 'date-fns/startOfYear';
11
11
  import subYears from 'date-fns/subYears';
12
12
  import linearFunction from '../global/linear-function.js';
13
13
  import { m as modules_0c7b7d96 } from '../_helpers/date-picker.js';
14
- import units, { dateType, DOUBLE, HALF, yearDuration } from './consts.js';
14
+ import units, { dateType, yearDuration, DOUBLE, HALF } from './consts.js';
15
15
  import 'date-fns/add';
16
16
 
17
17
  const {
@@ -30,9 +30,19 @@ class Years extends PureComponent {
30
30
  state = {
31
31
  scrollDate: null
32
32
  };
33
+ componentDidMount() {
34
+ if (this.componentRef.current) {
35
+ this.componentRef.current.addEventListener('wheel', this.handleWheel);
36
+ }
37
+ }
33
38
  componentDidUpdate(prevProps, prevState) {
34
39
  this.stoppedScrolling = prevState.scrollDate != null && !this.state.scrollDate;
35
40
  }
41
+ componentWillUnmount() {
42
+ if (this.componentRef.current) {
43
+ this.componentRef.current.removeEventListener('wheel', this.handleWheel);
44
+ }
45
+ }
36
46
  stoppedScrolling;
37
47
  setYear(date) {
38
48
  if (scrollTO) {
@@ -44,6 +54,22 @@ class Years extends PureComponent {
44
54
  });
45
55
  this.props.onScroll(Number(setYear(this.props.scrollDate, getYear(date))));
46
56
  }
57
+ componentRef = /*#__PURE__*/createRef();
58
+ handleWheel = e => {
59
+ const {
60
+ scrollDate
61
+ } = this.props;
62
+ const date = this.state.scrollDate || scrollDate;
63
+ e.preventDefault();
64
+ const newScrollDate = linearFunction(0, Number(date), yearDuration / yearHeight).y(e.deltaY);
65
+ this.setState({
66
+ scrollDate: newScrollDate
67
+ });
68
+ if (scrollTO) {
69
+ window.clearTimeout(scrollTO);
70
+ }
71
+ scrollTO = window.setTimeout(() => this.setYear(newScrollDate), scrollDelay);
72
+ };
47
73
  render() {
48
74
  const {
49
75
  onScrollChange,
@@ -58,20 +84,9 @@ class Years extends PureComponent {
58
84
  years.push(year);
59
85
  }
60
86
  const pxToDate = linearFunction(0, Number(years[0]), yearDuration / yearHeight);
61
- const handleWheel = e => {
62
- e.preventDefault();
63
- const newScrollDate = linearFunction(0, Number(date), yearDuration / yearHeight).y(e.deltaY);
64
- this.setState({
65
- scrollDate: newScrollDate
66
- });
67
- if (scrollTO) {
68
- window.clearTimeout(scrollTO);
69
- }
70
- scrollTO = window.setTimeout(() => this.setYear(newScrollDate), scrollDelay);
71
- };
72
87
  return /*#__PURE__*/React.createElement("div", {
73
88
  className: modules_0c7b7d96.years,
74
- onWheel: handleWheel,
89
+ ref: this.componentRef,
75
90
  style: {
76
91
  transition: this.stoppedScrolling ? 'top .2s ease-out 0s' : 'none',
77
92
  top: Math.floor(calHeight * HALF - pxToDate.x(Number(date)))
@@ -0,0 +1 @@
1
+ export default function useEventCallback<I extends unknown[], O>(fn: (...args: I) => O): (...args: I) => O;
@@ -0,0 +1,19 @@
1
+ import { useRef, useLayoutEffect, useCallback } from 'react';
2
+
3
+ function useEventCallback(fn) {
4
+ const ref = useRef();
5
+ useLayoutEffect(() => {
6
+ ref.current = fn;
7
+ });
8
+ return useCallback(function () {
9
+ const {
10
+ current
11
+ } = ref;
12
+ if (current == null) {
13
+ throw new Error('callback created in useEventCallback can only be called from event handlers');
14
+ }
15
+ return current(...arguments);
16
+ }, []);
17
+ }
18
+
19
+ export { useEventCallback as default };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jetbrains/ring-ui",
3
- "version": "5.0.143",
3
+ "version": "5.0.145",
4
4
  "description": "JetBrains UI library",
5
5
  "author": "JetBrains",
6
6
  "license": "Apache-2.0",
@@ -126,7 +126,7 @@
126
126
  "core-js": "^3.30.2",
127
127
  "cpy-cli": "^3.1.1",
128
128
  "enzyme": "^3.11.0",
129
- "eslint": "^8.41.0",
129
+ "eslint": "^8.42.0",
130
130
  "eslint-import-resolver-webpack": "^0.13.2",
131
131
  "eslint-plugin-angular": "^4.1.0",
132
132
  "eslint-plugin-bdd": "^2.1.1",
@@ -176,8 +176,8 @@
176
176
  "terser-webpack-plugin": "^5.3.9",
177
177
  "typescript": "~5.1.3",
178
178
  "wallaby-webpack": "^3.9.16",
179
- "webpack": "^5.85.0",
180
- "webpack-cli": "^5.1.1",
179
+ "webpack": "^5.85.1",
180
+ "webpack-cli": "^5.1.3",
181
181
  "xmlappend": "^1.0.4"
182
182
  },
183
183
  "peerDependencies": {