Improve multiple element selector UI
Summary: Layer selection is pretty easy to miss, as reported in for example: https://fb.workplace.com/groups/flippersupport/permalink/1098169193997071/ Moved the layer selection to the top of the view and gave it some highlighting + dynamic height. The section is no longer collapsible. Changelog: [Layout] Make the layer selection more prominent Reviewed By: priteshrnandgaonkar Differential Revision: D27708650 fbshipit-source-id: c86a55c3a20794aee86e64b6766b2ca4dd6b563f
This commit is contained in:
committed by
Facebook GitHub Bot
parent
5db2ef1275
commit
0fe879c838
@@ -13,19 +13,13 @@ import {
|
||||
PluginClient,
|
||||
ElementsInspector,
|
||||
ElementSearchResultSet,
|
||||
FlexColumn,
|
||||
styled,
|
||||
} from 'flipper';
|
||||
import {debounce} from 'lodash';
|
||||
import {Component} from 'react';
|
||||
import {PersistedState, ElementMap} from './';
|
||||
import React from 'react';
|
||||
import MultipleSelectorSection from './MultipleSelectionSection';
|
||||
|
||||
const ElementsInspectorContainer = styled(FlexColumn)({
|
||||
width: '100%',
|
||||
justifyContent: 'space-between',
|
||||
});
|
||||
import {Layout} from 'flipper-plugin';
|
||||
|
||||
type GetNodesOptions = {
|
||||
force?: boolean;
|
||||
@@ -448,7 +442,17 @@ export default class Inspector extends Component<Props, State> {
|
||||
: this.state.elementSelector;
|
||||
|
||||
return this.root() ? (
|
||||
<ElementsInspectorContainer>
|
||||
<Layout.Top>
|
||||
{selectorData && selectorData.leaves.length > 1 ? (
|
||||
<MultipleSelectorSection
|
||||
initialSelectedElement={this.selected()}
|
||||
elements={selectorData.elements}
|
||||
onElementSelected={this.onElementSelectedAndExpanded}
|
||||
onElementHovered={this.onElementHovered}
|
||||
/>
|
||||
) : (
|
||||
<div />
|
||||
)}
|
||||
<ElementsInspector
|
||||
onElementSelected={this.onElementSelectedAtMainSection}
|
||||
onElementHovered={this.onElementHovered}
|
||||
@@ -460,15 +464,7 @@ export default class Inspector extends Component<Props, State> {
|
||||
focused={this.focused()}
|
||||
contextMenuExtensions={this.getAXContextMenuExtensions}
|
||||
/>
|
||||
{selectorData && selectorData.leaves.length > 1 ? (
|
||||
<MultipleSelectorSection
|
||||
initialSelectedElement={this.selected()}
|
||||
elements={selectorData.elements}
|
||||
onElementSelected={this.onElementSelectedAndExpanded}
|
||||
onElementHovered={this.onElementHovered}
|
||||
/>
|
||||
) : null}
|
||||
</ElementsInspectorContainer>
|
||||
</Layout.Top>
|
||||
) : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,41 +7,16 @@
|
||||
* @format
|
||||
*/
|
||||
|
||||
import {
|
||||
FlexColumn,
|
||||
FlexBox,
|
||||
Element,
|
||||
ElementID,
|
||||
ElementsInspector,
|
||||
Glyph,
|
||||
colors,
|
||||
styled,
|
||||
} from 'flipper';
|
||||
import {Typography} from 'antd';
|
||||
import {Element, ElementID, ElementsInspector, styled} from 'flipper';
|
||||
import {Layout, theme} from 'flipper-plugin';
|
||||
import React, {memo, useState} from 'react';
|
||||
|
||||
const MultipleSelectorSectionContainer = styled(FlexColumn)({
|
||||
maxHeight: 100,
|
||||
});
|
||||
|
||||
const MultipleSelectorSectionTitle = styled(FlexBox)({
|
||||
cursor: 'pointer',
|
||||
backgroundColor: '#f6f7f9',
|
||||
padding: '2px',
|
||||
paddingLeft: '9px',
|
||||
width: '325px',
|
||||
height: '20px',
|
||||
fontWeight: 500,
|
||||
boxShadow: '2px 2px 2px #ccc',
|
||||
border: `1px solid ${colors.light20}`,
|
||||
borderTopLeftRadius: '4px',
|
||||
borderTopRightRadius: '4px',
|
||||
textAlign: 'center',
|
||||
});
|
||||
|
||||
const Chevron = styled(Glyph)({
|
||||
marginRight: 4,
|
||||
marginLeft: -2,
|
||||
marginBottom: 1,
|
||||
const MultipleSelectorSectionContainer = styled(Layout.Container)({
|
||||
padding: theme.space.medium,
|
||||
background: theme.backgroundWash,
|
||||
borderTop: `${theme.space.tiny}px solid ${theme.warningColor}`,
|
||||
borderBottom: `${theme.space.tiny}px solid ${theme.warningColor}`,
|
||||
});
|
||||
|
||||
type MultipleSelectorSectionProps = {
|
||||
@@ -65,29 +40,24 @@ const MultipleSelectorSection: React.FC<MultipleSelectorSectionProps> = memo(
|
||||
const [selectedId, setSelectedId] = useState<ElementID | null | undefined>(
|
||||
initialSelectedElement,
|
||||
);
|
||||
const [collapsed, setCollapsed] = useState(false);
|
||||
return (
|
||||
<MultipleSelectorSectionContainer>
|
||||
<MultipleSelectorSectionTitle
|
||||
onClick={() => {
|
||||
setCollapsed(!collapsed);
|
||||
}}>
|
||||
<Chevron name={collapsed ? 'chevron-up' : 'chevron-down'} size={12} />
|
||||
Multiple elements found at the target coordinates
|
||||
</MultipleSelectorSectionTitle>
|
||||
{!collapsed && (
|
||||
<ElementsInspector
|
||||
onElementSelected={(key: string) => {
|
||||
setSelectedId(key);
|
||||
onElementSelected(key);
|
||||
}}
|
||||
onElementHovered={onElementHovered}
|
||||
onElementExpanded={() => {}}
|
||||
root={null}
|
||||
selected={selectedId}
|
||||
elements={elements}
|
||||
/>
|
||||
)}
|
||||
<MultipleSelectorSectionContainer gap>
|
||||
<Typography.Text>
|
||||
Multiple elements were found at the target coordinates. Please select
|
||||
one:
|
||||
</Typography.Text>
|
||||
<ElementsInspector
|
||||
onElementSelected={(key: string) => {
|
||||
setSelectedId(key);
|
||||
onElementSelected(key);
|
||||
}}
|
||||
onElementHovered={onElementHovered}
|
||||
onElementExpanded={() => {}}
|
||||
root={null}
|
||||
selected={selectedId}
|
||||
elements={elements}
|
||||
scrollable={false}
|
||||
/>
|
||||
</MultipleSelectorSectionContainer>
|
||||
);
|
||||
},
|
||||
|
||||
@@ -40,30 +40,6 @@ test('rendering a single element', () => {
|
||||
expect(res.queryAllByText(name).length).toBe(1);
|
||||
});
|
||||
|
||||
test('collapsing an element', () => {
|
||||
const id = 'id1';
|
||||
const name = 'id_name';
|
||||
const element: Element = {...dummyElmentData, id, name};
|
||||
const res = render(
|
||||
<MultipleSelectorSection
|
||||
initialSelectedElement={null}
|
||||
elements={{[id]: element}}
|
||||
onElementSelected={() => {}}
|
||||
onElementHovered={null}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(res.queryAllByText(name).length).toBe(1);
|
||||
|
||||
// collapse the view
|
||||
fireEvent.click(res.getByText(TITLE_STRING));
|
||||
expect(res.queryAllByText(name).length).toBe(0);
|
||||
|
||||
// re-expand the view
|
||||
fireEvent.click(res.getByText(TITLE_STRING));
|
||||
expect(res.queryAllByText(name).length).toBe(1);
|
||||
});
|
||||
|
||||
test('clicking on elements', () => {
|
||||
const ids = ['id1', 'id2', 'id3'];
|
||||
const names = ['id_name_first', 'id_name_second', 'id_name_third'];
|
||||
|
||||
Reference in New Issue
Block a user