react-aria-components 0.0.4 → 1.0.0-alpha.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 (91) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +12 -29
  3. package/dist/import.mjs +5223 -0
  4. package/dist/main.js +5345 -0
  5. package/dist/main.js.map +1 -0
  6. package/dist/module.js +5223 -0
  7. package/dist/module.js.map +1 -0
  8. package/dist/types.d.ts +1481 -0
  9. package/dist/types.d.ts.map +1 -0
  10. package/package.json +36 -44
  11. package/src/Breadcrumbs.tsx +90 -0
  12. package/src/Button.tsx +79 -0
  13. package/src/Calendar.tsx +471 -0
  14. package/src/Checkbox.tsx +240 -0
  15. package/src/Collection.tsx +787 -0
  16. package/src/ComboBox.tsx +129 -0
  17. package/src/DateField.tsx +244 -0
  18. package/src/DatePicker.tsx +178 -0
  19. package/src/Dialog.tsx +95 -0
  20. package/src/GridList.tsx +411 -0
  21. package/src/Group.tsx +69 -0
  22. package/src/Header.tsx +34 -0
  23. package/src/Heading.tsx +35 -0
  24. package/src/Input.tsx +73 -0
  25. package/src/Keyboard.tsx +24 -0
  26. package/src/Label.tsx +30 -0
  27. package/src/Link.tsx +98 -0
  28. package/src/ListBox.tsx +406 -0
  29. package/src/Menu.tsx +227 -0
  30. package/src/Meter.tsx +73 -0
  31. package/src/Modal.tsx +192 -0
  32. package/src/NumberField.tsx +79 -0
  33. package/src/OverlayArrow.tsx +70 -0
  34. package/src/Popover.tsx +125 -0
  35. package/src/ProgressBar.tsx +81 -0
  36. package/src/RadioGroup.tsx +219 -0
  37. package/src/SearchField.tsx +78 -0
  38. package/src/Select.tsx +180 -0
  39. package/src/Separator.tsx +53 -0
  40. package/src/Slider.tsx +217 -0
  41. package/src/Switch.tsx +127 -0
  42. package/src/Table.tsx +917 -0
  43. package/src/Tabs.tsx +282 -0
  44. package/src/Text.tsx +30 -0
  45. package/src/TextField.tsx +62 -0
  46. package/src/ToggleButton.tsx +59 -0
  47. package/src/Tooltip.tsx +135 -0
  48. package/src/index.ts +94 -0
  49. package/src/useDragAndDrop.tsx +172 -0
  50. package/src/utils.tsx +235 -0
  51. package/.babelrc +0 -17
  52. package/.eslintrc +0 -12
  53. package/src/accordion/accordion.css +0 -4
  54. package/src/accordion/accordion.js +0 -20
  55. package/src/accordion/index.js +0 -2
  56. package/src/accordion/section.css +0 -21
  57. package/src/accordion/section.js +0 -85
  58. package/src/examples/accordion-example.js +0 -73
  59. package/src/examples/example.js +0 -21
  60. package/src/examples/grid-cells/fancy-input-grid-cell.js +0 -206
  61. package/src/examples/grid-cells/input-grid-cell.js +0 -44
  62. package/src/examples/grid-example.css +0 -23
  63. package/src/examples/grid-example.js +0 -231
  64. package/src/examples/index.html +0 -10
  65. package/src/examples/index.js +0 -53
  66. package/src/examples/tabs-example.js +0 -52
  67. package/src/grid/column-header.css +0 -4
  68. package/src/grid/column-header.js +0 -29
  69. package/src/grid/grid-cell.css +0 -16
  70. package/src/grid/grid-cell.js +0 -104
  71. package/src/grid/grid-context.js +0 -3
  72. package/src/grid/grid.css +0 -4
  73. package/src/grid/grid.js +0 -110
  74. package/src/grid/index.js +0 -6
  75. package/src/grid/interactive-grid-cell.js +0 -96
  76. package/src/grid/row-headers.css +0 -6
  77. package/src/grid/row-headers.js +0 -22
  78. package/src/grid/row.css +0 -5
  79. package/src/grid/row.js +0 -21
  80. package/src/prop-types/ref.js +0 -3
  81. package/src/tabs/index.js +0 -4
  82. package/src/tabs/tab-list.css +0 -6
  83. package/src/tabs/tab-list.js +0 -103
  84. package/src/tabs/tab-panels.js +0 -35
  85. package/src/tabs/tab.css +0 -10
  86. package/src/tabs/tab.js +0 -45
  87. package/src/tabs/tabs.js +0 -52
  88. package/src/utils/debounce.js +0 -12
  89. package/src/utils/event-handlers-factory.js +0 -42
  90. package/src/utils/unique-id.js +0 -6
  91. package/webpack.config.js +0 -43
@@ -1,104 +0,0 @@
1
- import PropTypes from 'prop-types';
2
- import React from 'react';
3
-
4
- import GridContext from './grid-context.js';
5
- import RefType from '../prop-types/ref.js';
6
-
7
- import styles from './grid-cell.css';
8
-
9
- class GridCell extends React.Component {
10
- constructor(props) {
11
- super(props);
12
-
13
- this.onBlur = this.onBlur.bind(this);
14
- this.onClick = this.onClick.bind(this);
15
- this.onFocus = this.onFocus.bind(this);
16
- this.onKeyDown = this.onKeyDown.bind(this);
17
-
18
- this.state = {
19
- tabIndex: -1,
20
- };
21
- }
22
-
23
- onBlur(event) {
24
- const focusWithinCell = this.props.gridCellRef.current === event.relatedTarget
25
- || this.props.gridCellRef.current.contains(event.relatedTarget);
26
- if (focusWithinCell) return;
27
-
28
- const focusWithinGrid = this.props.gridCellRefs.some(rows => (
29
- rows.some(cellRef => cellRef.current === event.relatedTarget) // `relatedTarget` is not supported in IE 11 :( https://github.com/facebook/react/issues/3751
30
- ));
31
- if (focusWithinGrid) this.setState({ tabIndex: -1 });
32
-
33
- this.props.onBlur(event);
34
- }
35
-
36
- onClick(event) {
37
- this.props.onClick(event);
38
- }
39
-
40
- onFocus(event) {
41
- this.setState({ tabIndex: 0 });
42
- this.props.onFocus(event);
43
- }
44
-
45
- onKeyDown(event) {
46
- this.props.onKeyDown(event);
47
- }
48
-
49
- render() {
50
- return (
51
- <div // eslint-disable-line jsx-a11y/no-static-element-interactions
52
- className={this.props.className}
53
- onBlur={this.onBlur}
54
- onClick={this.onClick}
55
- onFocus={this.onFocus}
56
- onKeyDown={this.onKeyDown}
57
- ref={this.props.gridCellRef}
58
- role={this.props.role}
59
- tabIndex={this.state.tabIndex}
60
- >
61
- {this.props.children}
62
- </div>
63
- );
64
- }
65
- }
66
-
67
- GridCell.defaultProps = {
68
- className: styles.container,
69
- onBlur: () => {},
70
- onClick: () => {},
71
- onFocus: () => {},
72
- onKeyDown: () => {},
73
- role: 'gridcell',
74
- };
75
-
76
- GridCell.propTypes = {
77
- className: PropTypes.string,
78
- children: PropTypes.node.isRequired,
79
- gridCellRef: RefType.isRequired,
80
- gridCellRefs: PropTypes.arrayOf(PropTypes.arrayOf(RefType)).isRequired,
81
- onBlur: PropTypes.func,
82
- onClick: PropTypes.func,
83
- onFocus: PropTypes.func,
84
- onKeyDown: PropTypes.func,
85
- role: PropTypes.oneOf(['columnheader', 'gridcell']),
86
- };
87
-
88
- export default function FocusableGridCell(props) {
89
- const {
90
- idX,
91
- idY,
92
- } = props;
93
-
94
- return (
95
- <GridContext.Consumer>
96
- {gridRefs => <GridCell {...props} gridCellRefs={gridRefs} gridCellRef={gridRefs[idY][idX]} />}
97
- </GridContext.Consumer>
98
- );
99
- }
100
-
101
- FocusableGridCell.propTypes = {
102
- idX: PropTypes.number.isRequired,
103
- idY: PropTypes.number.isRequired,
104
- };
@@ -1,3 +0,0 @@
1
- import React from 'react';
2
-
3
- export default React.createContext();
package/src/grid/grid.css DELETED
@@ -1,4 +0,0 @@
1
- .container {
2
- position: relative;
3
- transform: translate3d(0, 0, 0);
4
- }
package/src/grid/grid.js DELETED
@@ -1,110 +0,0 @@
1
- import PropTypes from 'prop-types';
2
- import React from 'react';
3
-
4
- import GridContext from './grid-context.js';
5
- import RefType from '../prop-types/ref.js';
6
- import styles from './grid.css';
7
-
8
- export default class Grid extends React.Component {
9
- constructor(props) {
10
- super(props);
11
-
12
- this.state = {
13
- rowIndex: -1,
14
- columnIndex: -1,
15
- };
16
-
17
- this.onFocus = this.onFocus.bind(this);
18
- this.onKeyDown = this.onKeyDown.bind(this);
19
- }
20
-
21
- componentDidUpdate() {
22
- this.props.gridRefs[this.state.rowIndex][this.state.columnIndex].current.focus();
23
- }
24
-
25
- onFocus(event) {
26
- let newColumnIndex;
27
- const newRowIndex = this.props.gridRefs.findIndex((rows) => {
28
- newColumnIndex = rows.findIndex(cellRef => cellRef.current === event.target);
29
- return newColumnIndex > -1;
30
- });
31
-
32
- // If the click event does not match any of grid cell containers,
33
- // it must be within the active cell.
34
- if (newRowIndex === -1 || newColumnIndex === -1) { return; }
35
-
36
- this.setState({
37
- columnIndex: newColumnIndex,
38
- rowIndex: newRowIndex,
39
- });
40
- }
41
-
42
- onKeyDown(event) {
43
- switch (event.key) {
44
- case 'ArrowDown': {
45
- event.preventDefault();
46
- this.setState(state => ({
47
- columnIndex: Math.max(state.columnIndex, 0),
48
- rowIndex: Math.min(state.rowIndex + 1, this.props.gridRefs.length - 1),
49
- }));
50
-
51
- return true;
52
- }
53
- case 'ArrowLeft': {
54
- event.preventDefault();
55
- this.setState(state => ({
56
- columnIndex: Math.max(state.columnIndex - 1, 0),
57
- rowIndex: Math.max(state.rowIndex, 0),
58
- }));
59
-
60
- return true;
61
- }
62
- case 'ArrowRight': {
63
- event.preventDefault();
64
- this.setState(state => ({
65
- columnIndex: Math.min(state.columnIndex + 1, this.props.gridRefs[0].length - 1),
66
- rowIndex: Math.max(state.rowIndex, 0),
67
- }));
68
-
69
- return true;
70
- }
71
- case 'ArrowUp': {
72
- event.preventDefault();
73
- this.setState(state => ({
74
- columnIndex: Math.max(state.columnIndex, 0),
75
- rowIndex: Math.max(state.rowIndex - 1, 0),
76
- }));
77
-
78
- return true;
79
- }
80
- default:
81
- return true;
82
- }
83
- }
84
-
85
- render() {
86
- return (
87
- <GridContext.Provider value={this.props.gridRefs}>
88
- <div // eslint-disable-line jsx-a11y/interactive-supports-focus
89
- className={this.props.className}
90
- role="grid"
91
- onFocus={this.onFocus}
92
- onKeyDown={this.onKeyDown}
93
- tabIndex="0"
94
- >
95
- {this.props.children}
96
- </div>
97
- </GridContext.Provider>
98
- );
99
- }
100
- }
101
-
102
- Grid.defaultProps = {
103
- className: styles.container,
104
- };
105
-
106
- Grid.propTypes = {
107
- className: PropTypes.string,
108
- children: PropTypes.node.isRequired,
109
- gridRefs: PropTypes.arrayOf(PropTypes.arrayOf(RefType)).isRequired,
110
- };
package/src/grid/index.js DELETED
@@ -1,6 +0,0 @@
1
- export { default as ColumnHeader } from './column-header.js';
2
- export { default as InteractiveGridCell } from './interactive-grid-cell.js';
3
- export { default as GridCell } from './grid-cell.js';
4
- export { default as Grid } from './grid.js';
5
- export { default as RowHeaders } from './row-headers.js';
6
- export { default as Row } from './row.js';
@@ -1,96 +0,0 @@
1
- import PropTypes from 'prop-types';
2
- import React from 'react';
3
-
4
- import GridCell from './grid-cell.js';
5
- import GridContext from './grid-context.js';
6
- import RefType from '../prop-types/ref.js';
7
-
8
- class InteractiveGridCell extends React.Component {
9
- constructor(props) {
10
- super(props);
11
-
12
- this.onBlur = this.onBlur.bind(this);
13
- this.onClick = this.onClick.bind(this);
14
- this.onKeyDown = this.onKeyDown.bind(this);
15
-
16
- this.state = {
17
- interactive: false,
18
- };
19
- }
20
-
21
- componentDidUpdate(props, state) {
22
- if (state.interactive && !this.state.interactive) {
23
- this.props.gridCellRef.current.focus();
24
- }
25
- }
26
-
27
- onBlur(event) {
28
- const focusWithinCell = this.props.gridCellRef.current === event.relatedTarget
29
- || this.props.gridCellRef.current.contains(event.relatedTarget);
30
- if (focusWithinCell) return;
31
-
32
- this.setState({ interactive: false });
33
- }
34
-
35
- onClick() {
36
- this.setState({ interactive: true });
37
- }
38
-
39
- onKeyDown(event) {
40
- switch (event.key) {
41
- case 'Enter': {
42
- this.setState(state => ({ interactive: !state.interactive }));
43
- break;
44
- }
45
- case 'Escape': {
46
- this.setState({ interactive: false });
47
- break;
48
- }
49
- default: {
50
- // Do not use keyboard navigation while interactive
51
- if (this.state.interactive) {
52
- event.stopPropagation();
53
- }
54
- }
55
- }
56
- }
57
-
58
- render() {
59
- return (
60
- <GridCell
61
- {...this.props}
62
- onBlur={this.onBlur}
63
- onClick={this.onClick}
64
- onKeyDown={this.onKeyDown}
65
- >
66
- {this.props.children(this.state.interactive)}
67
- </GridCell>
68
- );
69
- }
70
- }
71
-
72
- InteractiveGridCell.defaultProps = {
73
- };
74
-
75
- InteractiveGridCell.propTypes = {
76
- children: PropTypes.func.isRequired,
77
- gridCellRef: RefType.isRequired,
78
- };
79
-
80
- export default function FocusableInteractiveGridCell(props) {
81
- const {
82
- idX,
83
- idY,
84
- } = props;
85
-
86
- return (
87
- <GridContext.Consumer>
88
- {gridRefs => <InteractiveGridCell {...props} gridCellRef={gridRefs[idY][idX]} />}
89
- </GridContext.Consumer>
90
- );
91
- }
92
-
93
- FocusableInteractiveGridCell.propTypes = {
94
- idX: PropTypes.number.isRequired,
95
- idY: PropTypes.number.isRequired,
96
- };
@@ -1,6 +0,0 @@
1
- .container {
2
- composes: container from './row.css';
3
- position: sticky;
4
- top: 0;
5
- z-index: 2;
6
- }
@@ -1,22 +0,0 @@
1
- import PropTypes from 'prop-types';
2
- import React from 'react';
3
-
4
- import Row from './row.js';
5
- import styles from './row-headers.css';
6
-
7
- export default function RowHeaders(props) {
8
- return (
9
- <Row className={props.className}>
10
- {props.children}
11
- </Row>
12
- );
13
- }
14
-
15
- RowHeaders.defaultProps = {
16
- className: styles.container,
17
- };
18
-
19
- RowHeaders.propTypes = {
20
- className: PropTypes.string,
21
- children: PropTypes.node.isRequired,
22
- };
package/src/grid/row.css DELETED
@@ -1,5 +0,0 @@
1
- .container {
2
- display: flex;
3
- flex-direction: row;
4
- width: fit-content;
5
- }
package/src/grid/row.js DELETED
@@ -1,21 +0,0 @@
1
- import PropTypes from 'prop-types';
2
- import React from 'react';
3
-
4
- import styles from './row.css';
5
-
6
- export default function Row(props) {
7
- return (
8
- <div className={props.className} role="row">
9
- {props.children}
10
- </div>
11
- );
12
- }
13
-
14
- Row.defaultProps = {
15
- className: styles.container,
16
- };
17
-
18
- Row.propTypes = {
19
- className: PropTypes.string,
20
- children: PropTypes.node.isRequired,
21
- };
@@ -1,3 +0,0 @@
1
- import PropTypes from 'prop-types';
2
-
3
- export default PropTypes.object;
package/src/tabs/index.js DELETED
@@ -1,4 +0,0 @@
1
- export { default as TabList } from './tab-list.js';
2
- export { default as TabPanels } from './tab-panels.js';
3
- export { default as Tab } from './tab.js';
4
- export { default as Tabs } from './tabs.js';
@@ -1,6 +0,0 @@
1
- .container {
2
- display: flex;
3
- list-style: none;
4
- margin: 0;
5
- padding: 0;
6
- }
@@ -1,103 +0,0 @@
1
- import PropTypes from 'prop-types';
2
- import React from 'react';
3
- import Tab from './tab.js';
4
- import styles from './tab-list.css';
5
-
6
- export default class TabList extends React.Component {
7
- constructor(props) {
8
- super(props);
9
-
10
- const childrenCount = React.Children.count(props.children);
11
-
12
- this.handleKeyPress = this.handleKeyPress.bind(this);
13
- this.tabRefs = new Array(childrenCount).fill(0).map(() => React.createRef());
14
- this.handlers = this.getHandlers(props.vertical);
15
- }
16
-
17
- componentDidUpdate(prevProps) {
18
- if (prevProps.activeIndex !== this.props.activeIndex) {
19
- this.tabRefs[this.props.activeIndex].current.focus();
20
- }
21
- }
22
-
23
- getHandlers(vertical) {
24
- if (vertical) {
25
- return {
26
- ArrowDown: this.next.bind(this),
27
- ArrowUp: this.previous.bind(this),
28
- };
29
- }
30
- return {
31
- ArrowLeft: this.previous.bind(this),
32
- ArrowRight: this.next.bind(this),
33
- };
34
- }
35
-
36
- wrapIndex(index) {
37
- const count = React.Children.count(this.props.children);
38
- return (index + count) % count;
39
- }
40
-
41
- handleKeyPress(event) {
42
- const handler = this.handlers[event.key];
43
- if (handler) { handler(); }
44
- }
45
-
46
- previous() {
47
- const newIndex = this.wrapIndex(this.props.activeIndex - 1);
48
- this.props.onActivateTab(newIndex);
49
- }
50
-
51
- next() {
52
- const newIndex = this.wrapIndex(this.props.activeIndex + 1);
53
- this.props.onActivateTab(newIndex);
54
- }
55
-
56
- render() {
57
- const {
58
- accessibleId,
59
- activeIndex,
60
- children,
61
- className,
62
- onActivateTab,
63
- } = this.props;
64
-
65
- return (
66
- <ul className={className} onKeyUp={this.handleKeyPress} role="tablist">
67
- {React.Children.map(children, (child, index) => {
68
- if (child.type !== Tab) {
69
- throw new Error('Direct children of a <TabList> must be a <Tab>');
70
- }
71
-
72
- const active = index === activeIndex;
73
- const tabRef = this.tabRefs[index];
74
-
75
- return React.cloneElement(child, {
76
- accessibleId: active ? accessibleId : undefined,
77
- active,
78
- tabRef,
79
- onActivate: () => onActivateTab(index),
80
- });
81
- })}
82
- </ul>
83
- );
84
- }
85
- }
86
-
87
- TabList.propTypes = {
88
- accessibleId: PropTypes.string,
89
- activeIndex: PropTypes.number,
90
- children: PropTypes.node,
91
- className: PropTypes.string,
92
- onActivateTab: PropTypes.func,
93
- vertical: PropTypes.bool,
94
- };
95
-
96
- TabList.defaultProps = {
97
- accessibleId: undefined,
98
- activeIndex: 0,
99
- children: null,
100
- className: styles.container,
101
- onActivateTab: () => {},
102
- vertical: false,
103
- };
@@ -1,35 +0,0 @@
1
- import PropTypes from 'prop-types';
2
- import React from 'react';
3
-
4
- export default function TabPanels({
5
- accessibleId,
6
- activeIndex,
7
- children,
8
- className,
9
- hasFocusableContent,
10
- }) {
11
- return (
12
- <div
13
- aria-labelledby={accessibleId}
14
- role="tabpanel"
15
- className={className}
16
- tabIndex={hasFocusableContent ? undefined : 0}
17
- >
18
- {React.Children.toArray(children)[activeIndex]}
19
- </div>
20
- );
21
- }
22
-
23
- TabPanels.propTypes = {
24
- accessibleId: PropTypes.string,
25
- activeIndex: PropTypes.number,
26
- children: PropTypes.node.isRequired,
27
- className: PropTypes.string,
28
- hasFocusableContent: PropTypes.bool.isRequired,
29
- };
30
-
31
- TabPanels.defaultProps = {
32
- accessibleId: undefined,
33
- activeIndex: 0,
34
- className: null,
35
- };
package/src/tabs/tab.css DELETED
@@ -1,10 +0,0 @@
1
- .container {
2
- background-color: lightgrey;
3
- border: 1px solid darkgrey;
4
- cursor: pointer;
5
- padding: 0 3px;
6
- }
7
-
8
- .container[aria-selected=true] {
9
- background-color: white;
10
- }
package/src/tabs/tab.js DELETED
@@ -1,45 +0,0 @@
1
- import PropTypes from 'prop-types';
2
- import React from 'react';
3
- import RefType from '../prop-types/ref.js';
4
- import styles from './tab.css';
5
-
6
- export default function Tab({
7
- accessibleId,
8
- active,
9
- children,
10
- className,
11
- onActivate,
12
- tabRef,
13
- }) {
14
- return (
15
- <li
16
- aria-selected={active}
17
- className={className}
18
- id={accessibleId}
19
- onClick={onActivate}
20
- onKeyDown={() => {}}
21
- ref={tabRef}
22
- role="tab"
23
- tabIndex={active ? 0 : undefined}
24
- >
25
- {children}
26
- </li>
27
- );
28
- }
29
-
30
- Tab.propTypes = {
31
- accessibleId: PropTypes.string,
32
- active: PropTypes.bool,
33
- children: PropTypes.node.isRequired,
34
- className: PropTypes.string,
35
- onActivate: PropTypes.func,
36
- tabRef: RefType,
37
- };
38
-
39
- Tab.defaultProps = {
40
- accessibleId: undefined,
41
- active: false,
42
- className: styles.container,
43
- onActivate: undefined,
44
- tabRef: undefined,
45
- };
package/src/tabs/tabs.js DELETED
@@ -1,52 +0,0 @@
1
- import PropTypes from 'prop-types';
2
- import React from 'react';
3
- import uniqueId from '../utils/unique-id';
4
- import TabList from './tab-list';
5
- import TabPanels from './tab-panels';
6
-
7
- export default class Tabs extends React.Component {
8
- constructor() {
9
- super();
10
- this.accessibleId = uniqueId();
11
- }
12
-
13
- render() {
14
- const {
15
- activeIndex,
16
- children,
17
- className,
18
- onActivateTab,
19
- } = this.props;
20
- const accessibleId = this.accessibleId;
21
-
22
- return (
23
- <div className={className}>
24
- {React.Children.map(children, (child) => {
25
- if (!child) { return child; }
26
-
27
- switch (child.type) {
28
- case TabList:
29
- return React.cloneElement(child, { accessibleId, activeIndex, onActivateTab });
30
- case TabPanels:
31
- return React.cloneElement(child, { accessibleId, activeIndex });
32
- default:
33
- return child;
34
- }
35
- })}
36
- </div>
37
- );
38
- }
39
- }
40
-
41
- Tabs.propTypes = {
42
- activeIndex: PropTypes.number.isRequired,
43
- children: PropTypes.node,
44
- className: PropTypes.string,
45
- onActivateTab: PropTypes.func,
46
- };
47
-
48
- Tabs.defaultProps = {
49
- children: null,
50
- className: undefined,
51
- onActivateTab: () => {},
52
- };
@@ -1,12 +0,0 @@
1
- export default function debounce(funk) {
2
- let lastCalled = 0;
3
-
4
- return function debounced(...args) {
5
- const now = Date.now();
6
- const timeSinceLastCalled = now - lastCalled;
7
- if (timeSinceLastCalled >= 1000) {
8
- lastCalled = now;
9
- funk(...args);
10
- }
11
- }
12
- }