@jetbrains/ring-ui 5.0.143 → 5.0.144

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.
@@ -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)
@@ -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';
@@ -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)
@@ -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.144",
4
4
  "description": "JetBrains UI library",
5
5
  "author": "JetBrains",
6
6
  "license": "Apache-2.0",