Added toggle button to Tree > Element views
Brian Vaughn committed
Apr 9, 2019 at 18:10 UTC
b6df86c90c43a8346013a2d3b5a4ecde28c2eef8
3 files changed
+64
-4
src/devtools/views/ButtonIcon.js
+12
@@ -7,8 +7,10 @@ export type IconType =
7
| 'back'
8
| 'cancel'
9
| 'close'
10
+ | 'collapsed'
11
| 'copy'
12
| 'down'
13
+ | 'expanded'
14
| 'export'
15
| 'filter'
16
| 'import'
@@ -40,12 +42,18 @@ export default function ButtonIcon({ type }: Props) {
42
case 'close':
43
pathData = PATH_CLOSE;
44
break;
45
+ case 'collapsed':
46
+ pathData = PATH_COLLAPSED;
47
+ break;
48
case 'copy':
49
pathData = PATH_COPY;
50
break;
51
case 'down':
52
pathData = PATH_DOWN;
53
break;
54
+ case 'expanded':
55
+ pathData = PATH_EXPANDED;
56
+ break;
57
case 'export':
58
pathData = PATH_EXPORT;
59
break;
@@ -121,6 +129,8 @@ const PATH_CANCEL = `
129
const PATH_CLOSE =
130
'M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z';
131
132
+const PATH_COLLAPSED = 'M10 17l5-5-5-5v10z';
133
+
134
const PATH_COPY = `
135
M3 13h2v-2H3v2zm0 4h2v-2H3v2zm2 4v-2H3a2 2 0 0 0 2 2zM3 9h2V7H3v2zm12 12h2v-2h-2v2zm4-18H9a2 2 0 0 0-2
136
2v10a2 2 0 0 0 2 2h10c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 12H9V5h10v10zm-8 6h2v-2h-2v2zm-4 0h2v-2H7v2z
@@ -128,6 +138,8 @@ const PATH_COPY = `
138
139
const PATH_DOWN = 'M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z';
140
141
+const PATH_EXPANDED = 'M7 10l5 5 5-5z';
142
+
143
const PATH_EXPORT = 'M15.82,2.14v7H21l-9,9L3,9.18H8.18v-7ZM3,20.13H21v1.73H3Z';
144
145
const PATH_FILTER = 'M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z';
src/devtools/views/Components/Element.css
+10
@@ -7,6 +7,8 @@
7
align-items: center;
8
cursor: default;
9
user-select: none;
10
+
11
+ --color-expand-collapse-toggle: var(--color-dim);
12
}
13
.Element:hover {
14
background-color: var(--color-hover-background);
@@ -21,6 +23,7 @@
23
--color-jsx-arrow-brackets: var(--color-jsx-arrow-brackets-inverted);
24
--color-attribute-name: var(--color-hover-background);
25
--color-attribute-value: var(--color-component-name-inverted);
26
+ --color-expand-collapse-toggle: var(--color-component-name-inverted);
27
}
28
29
.DollarR {
@@ -55,3 +58,10 @@
58
.CurrentHighlight {
59
background-color: var(--color-search-match-current);
60
}
61
+
62
+.ExpandCollapseToggle {
63
+ display: inline-flex;
64
+ width: 1rem;
65
+ height: 1rem;
66
+ color: var(--color-expand-collapse-toggle);
67
+}
src/devtools/views/Components/Element.js
+42
-4
@@ -9,6 +9,8 @@ import React, {
9
useRef,
10
} from 'react';
11
import { ElementTypeClass, ElementTypeFunction } from 'src/devtools/types';
12
+import Store from 'src/devtools/store';
13
+import ButtonIcon from '../ButtonIcon';
14
import { createRegExp } from '../utils';
15
import { TreeContext } from './TreeContext';
16
import { BridgeContext, StoreContext } from '../context';
@@ -75,8 +77,6 @@ export default function ElementView({ data, index, style }: Props) {
77
}
78
}, [id, isSelected, lastScrolledIDRef]);
79
78
- // TODO Add click and key handlers for toggling element open/close state.
79
-
80
const handleMouseDown = useCallback(
81
({ metaKey }) => {
82
if (id !== null) {
@@ -114,8 +114,6 @@ export default function ElementView({ data, index, style }: Props) {
114
const showDollarR =
115
isSelected && (type === ElementTypeClass || type === ElementTypeFunction);
116
117
- // TODO styles.SelectedElement is 100% width but it doesn't take horizontal overflow into account.
118
-
117
return (
118
<div
119
className={isSelected ? styles.SelectedElement : styles.Element}
@@ -138,6 +136,7 @@ export default function ElementView({ data, index, style }: Props) {
136
marginBottom: `-${style.height}px`,
137
}}
138
>
139
+ <ExpandCollapseToggle element={element} store={store} />
140
<span className={styles.Component} ref={ref}>
141
<DisplayName displayName={displayName} id={((id: any): number)} />
142
{key && (
@@ -152,6 +151,45 @@ export default function ElementView({ data, index, style }: Props) {
151
);
152
}
153
154
+// Prevent double clicks on toggle from drilling into the owner list.
155
+const swallowDoubleClick = event => {
156
+ event.preventDefault();
157
+ event.stopPropagation();
158
+};
159
+
160
+type ExpandCollapseToggleProps = {|
161
+ element: Element,
162
+ store: Store,
163
+|};
164
+
165
+function ExpandCollapseToggle({ element, store }: ExpandCollapseToggleProps) {
166
+ const { children, id, isCollapsed } = element;
167
+
168
+ const toggleCollapsed = useCallback(
169
+ event => {
170
+ event.preventDefault();
171
+ event.stopPropagation();
172
+
173
+ store.toggleIsCollapsed(id, !isCollapsed);
174
+ },
175
+ [id, isCollapsed, store]
176
+ );
177
+
178
+ if (children.length === 0) {
179
+ return <div className={styles.ExpandCollapseToggle} />;
180
+ }
181
+
182
+ return (
183
+ <div
184
+ className={styles.ExpandCollapseToggle}
185
+ onClick={toggleCollapsed}
186
+ onDoubleClick={swallowDoubleClick}
187
+ >
188
+ <ButtonIcon type={isCollapsed ? 'collapsed' : 'expanded'} />
189
+ </div>
190
+ );
191
+}
192
+
193
type DisplayNameProps = {|
194
displayName: string | null,
195
id: number,