Skip to content

Commit 285f355

Browse files
feat: add sorter for DomEvents (#195)
Co-authored-by: Stephan Meijer <[email protected]>
1 parent 83cfad3 commit 285f355

File tree

7 files changed

+263
-38
lines changed

7 files changed

+263
-38
lines changed

devtools/src/manifest.json

+5-15
Original file line numberDiff line numberDiff line change
@@ -19,28 +19,18 @@
1919
"128": "icons/128-production.png"
2020
}
2121
},
22-
"web_accessible_resources": [
23-
"window/testing-library.js"
24-
],
22+
"web_accessible_resources": ["window/testing-library.js"],
2523
"devtools_page": "devtools/main.html",
2624
"content_security_policy": "script-src 'self' 'unsafe-eval' 'sha256-6UcmjVDygSSU8p+3s7E7Kz8EG/ARhPADPRUm9P90HLM='; object-src 'self'",
2725
"background": {
28-
"scripts": [
29-
"background/background.js"
30-
],
26+
"scripts": ["background/background.js"],
3127
"persistent": false
3228
},
33-
"permissions": [
34-
"clipboardWrite"
35-
],
29+
"permissions": ["clipboardWrite"],
3630
"content_scripts": [
3731
{
38-
"matches": [
39-
"<all_urls>"
40-
],
41-
"js": [
42-
"content-script/contentScript.js"
43-
],
32+
"matches": ["<all_urls>"],
33+
"js": ["content-script/contentScript.js"],
4434
"run_at": "document_start"
4535
}
4636
]

package-lock.json

+57
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
"@babel/preset-react": "^7.10.1",
6868
"@testing-library/jest-dom": "^5.9.0",
6969
"@testing-library/react": "^10.2.0",
70+
"@testing-library/react-hooks": "^3.3.0",
7071
"@types/fs-extra": "^9.0.1",
7172
"babel-eslint": "^10.1.0",
7273
"chrome-launch": "^1.1.4",
@@ -91,6 +92,7 @@
9192
"postcss-import": "^12.0.1",
9293
"postcss-modules": "^2.0.0",
9394
"prettier": "^2.0.5",
95+
"react-test-renderer": "^16.13.1",
9496
"rimraf": "^3.0.2",
9597
"tailwindcss": "^1.4.6",
9698
"workbox-build": "^5.1.3"

src/components/DomEvents.js

+54-22
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, { useRef, useCallback, useState } from 'react';
2-
32
import { eventMap } from '@testing-library/dom/dist/event-map';
3+
import { ChevronUpIcon, ChevronDownIcon } from '@primer/octicons-react';
44
import throttle from 'lodash.throttle';
55
import AutoSizer from 'react-virtualized-auto-sizer';
66
import { TrashcanIcon } from '@primer/octicons-react';
@@ -87,7 +87,7 @@ function addLoggingEvents(node, log) {
8787
}
8888

8989
function EventRecord({ index, style, data }) {
90-
const { id, event, target } = data[index];
90+
const { id, type, name, element, selector } = data[index];
9191

9292
return (
9393
<div
@@ -98,31 +98,47 @@ function EventRecord({ index, style, data }) {
9898
>
9999
<div className="p-2 flex-none w-16">{id}</div>
100100

101-
<div className="p-2 flex-none w-32">{event.EventType}</div>
102-
<div className="p-2 flex-none w-32">{event.name}</div>
101+
<div className="p-2 flex-none w-32">{type}</div>
102+
<div className="p-2 flex-none w-32">{name}</div>
103103

104-
<div className="p-2 flex-none w-40">{target.tagName}</div>
105-
<div className="p-2 flex-auto whitespace-no-wrap">
106-
{target.toString()}
107-
</div>
104+
<div className="p-2 flex-none w-40">{element}</div>
105+
<div className="p-2 flex-auto whitespace-no-wrap">{selector}</div>
108106
</div>
109107
);
110108
}
111109

112-
const noop = () => {};
113110
function DomEvents() {
111+
const buffer = useRef([]);
112+
const previewRef = useRef();
113+
const listRef = useRef();
114+
115+
const sortDirection = useRef('asc');
116+
const [appendMode, setAppendMode] = useState('bottom');
114117
const [{ markup, result }, dispatch] = usePlayground({
115118
onChange: onStateChange,
116119
...initialValues,
117120
});
118121

119-
const buffer = useRef([]);
120-
const previewRef = useRef();
121-
const listRef = useRef();
122-
123122
const [eventCount, setEventCount] = useState(0);
124123
const [eventListeners, setEventListeners] = useState([]);
125124

125+
const getSortIcon = () => (
126+
<IconButton>
127+
{sortDirection.current === 'desc' ? (
128+
<ChevronDownIcon />
129+
) : (
130+
<ChevronUpIcon />
131+
)}
132+
</IconButton>
133+
);
134+
135+
const changeSortDirection = () => {
136+
const newDirection = sortDirection.current === 'desc' ? 'asc' : 'desc';
137+
buffer.current = buffer.current.reverse();
138+
setAppendMode(newDirection === 'desc' ? 'top' : 'bottom');
139+
sortDirection.current = newDirection;
140+
};
141+
126142
const reset = () => {
127143
buffer.current = [];
128144
setEventCount(0);
@@ -144,8 +160,19 @@ function DomEvents() {
144160
if (node) {
145161
previewRef.current = node;
146162
const eventListeners = addLoggingEvents(node, (event) => {
147-
event.id = buffer.current.length;
148-
buffer.current.push(event);
163+
const log = {
164+
id: buffer.current.length + 1,
165+
type: event.event.EventType,
166+
name: event.event.name,
167+
element: event.target.tagName,
168+
selector: event.target.toString(),
169+
};
170+
if (sortDirection.current === 'desc') {
171+
buffer.current.splice(0, 0, log);
172+
} else {
173+
buffer.current.push(log);
174+
}
175+
149176
setTimeout(flush, 0);
150177
});
151178
setEventListeners(eventListeners);
@@ -170,7 +197,7 @@ function DomEvents() {
170197
markup={markup}
171198
elements={result.elements}
172199
accessibleRoles={result.accessibleRoles}
173-
dispatch={noop}
200+
dispatch={dispatch}
174201
variant="minimal"
175202
/>
176203
</div>
@@ -181,12 +208,17 @@ function DomEvents() {
181208
<div className="editor p-4 md:h-56 flex-auto overflow-hidden">
182209
<div className="h-56 md:h-full w-full flex flex-col">
183210
<div className="h-8 flex items-center w-full text-sm font-bold">
184-
<div className="p-2 w-16">#</div>
211+
<div
212+
className="p-2 w-16 cursor-pointer flex justify-between items-center"
213+
onClick={changeSortDirection}
214+
>
215+
# {getSortIcon()}
216+
</div>
185217

186-
<div className="p-2 w-32">type</div>
187-
<div className="p-2 w-32">name</div>
218+
<div className="p-2 w-32 ">type</div>
219+
<div className="p-2 w-32 ">name</div>
188220

189-
<div className="p-2 w-40">element</div>
221+
<div className="p-2 w-40 ">element</div>
190222
<div className="flex-auto p-2 flex justify-between">
191223
<span>selector</span>
192224
<div>
@@ -203,15 +235,15 @@ function DomEvents() {
203235
</div>
204236

205237
<div className="flex-auto relative overflow-hidden">
206-
{eventCount === 0 ? (
238+
{buffer.current.length === 0 ? (
207239
<div className="flex w-full h-full opacity-50 items-end justify-center">
208240
<EmptyStreetImg height="80%" />
209241
</div>
210242
) : (
211243
<AutoSizer>
212244
{({ width, height }) => (
213245
<StickyList
214-
mode="bottom"
246+
mode={appendMode}
215247
ref={listRef}
216248
height={height}
217249
itemCount={eventCount}

src/components/StickyList.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ function StickyList(
2929
} else {
3030
ref.current.scrollTo(0);
3131
}
32-
}, [itemCount]);
32+
}, [itemCount, mode]);
3333

3434
return (
3535
<List

src/hooks/useSorter.js

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import React from 'react';
2+
3+
function defaultSorter(data, sortBy, direction) {
4+
return [...data].sort((row1, row2) => {
5+
const sortInt = `${row1[sortBy]}`.localeCompare(
6+
`${row2[sortBy]}`,
7+
undefined,
8+
{ numeric: true },
9+
);
10+
return direction === 'desc' ? -sortInt : sortInt;
11+
});
12+
}
13+
14+
function useSorter({
15+
rows = [],
16+
sortBy,
17+
sortDirection = 'desc',
18+
sortByFn = defaultSorter,
19+
}) {
20+
if (!Array.isArray(rows)) {
21+
throw TypeError('rows should be an array');
22+
}
23+
24+
if (sortDirection !== 'desc' && sortDirection !== 'asc') {
25+
throw Error('sort direction can be desc or asc');
26+
}
27+
28+
const sortedRows = React.useMemo(() => {
29+
const sortedRows = sortByFn(rows, sortBy, sortDirection);
30+
return sortedRows;
31+
}, [JSON.stringify(rows), sortBy, sortByFn, sortDirection]);
32+
33+
return [sortedRows, rows];
34+
}
35+
36+
export default useSorter;

0 commit comments

Comments
 (0)