diff --git a/desktop/app/src/devices/BaseDevice.tsx b/desktop/app/src/devices/BaseDevice.tsx index 0e99f6bbc..27bb89cad 100644 --- a/desktop/app/src/devices/BaseDevice.tsx +++ b/desktop/app/src/devices/BaseDevice.tsx @@ -190,7 +190,8 @@ export default class BaseDevice { if (plugin instanceof _SandyPluginDefinition) { return ( plugin.isDevicePlugin && - plugin.asDevicePluginModule().supportsDevice(this as any) + (plugin.asDevicePluginModule().supportsDevice?.(this as any) ?? + false) ); } else { return plugin.supportsDevice(this); diff --git a/desktop/app/src/sandy-chrome/appinspect/PluginList.tsx b/desktop/app/src/sandy-chrome/appinspect/PluginList.tsx index 7114905c7..22dd7b8e1 100644 --- a/desktop/app/src/sandy-chrome/appinspect/PluginList.tsx +++ b/desktop/app/src/sandy-chrome/appinspect/PluginList.tsx @@ -490,6 +490,9 @@ const PluginMenu = styled(Menu)({ overflow: 'hidden', textOverflow: 'ellipsis', }, + '.ant-menu-sub.ant-menu-inline': { + background: theme.backgroundDefault, + }, '.ant-menu-inline .ant-menu-item, .ant-menu-inline .ant-menu-submenu-title ': { width: '100%', // reset to remove weird bonus pixel from ANT }, @@ -518,8 +521,9 @@ const PluginMenu = styled(Menu)({ right: 8, }, '.ant-badge-count': { - color: theme.textColorPrimary, - background: theme.backgroundTransparentHover, + color: theme.textColorSecondary, + // border: `1px solid ${theme.dividerColor}`, + background: 'transparent', fontWeight: 'bold', padding: `0 10px`, boxShadow: 'none', diff --git a/desktop/flipper-plugin/src/plugin/SandyPluginDefinition.tsx b/desktop/flipper-plugin/src/plugin/SandyPluginDefinition.tsx index ef9f53976..c82955530 100644 --- a/desktop/flipper-plugin/src/plugin/SandyPluginDefinition.tsx +++ b/desktop/flipper-plugin/src/plugin/SandyPluginDefinition.tsx @@ -16,7 +16,7 @@ import {DevicePluginPredicate, DevicePluginFactory} from './DevicePlugin'; */ export type FlipperDevicePluginModule = { /** predicate that determines if this plugin applies to the currently selcted device */ - supportsDevice: DevicePluginPredicate; // TODO T84453692: remove this function after some transition period in favor of BaseDevice.supportsPlugin. + supportsDevice?: DevicePluginPredicate; // TODO T84453692: remove this function after some transition period in favor of BaseDevice.supportsPlugin. /** the factory function that initializes a plugin instance */ devicePlugin: DevicePluginFactory; /** the component type that can render this plugin */ diff --git a/desktop/flipper-plugin/src/state/datasource/DataSource.tsx b/desktop/flipper-plugin/src/state/datasource/DataSource.tsx index 3fb32c547..906296827 100644 --- a/desktop/flipper-plugin/src/state/datasource/DataSource.tsx +++ b/desktop/flipper-plugin/src/state/datasource/DataSource.tsx @@ -145,8 +145,8 @@ export class DataSource< /** * Returns a defensive copy of the current output. - * Sort, filter, reverse and window are applied, but windowing isn't. - * Start and end behave like slice, and default to the current window + * Sort, filter, reverse and are applied. + * Start and end behave like slice, and default to the currently active window. */ public getOutput( start = this.windowStart, @@ -308,8 +308,7 @@ export class DataSource< setReversed(reverse: boolean) { if (this.reverse !== reverse) { this.reverse = reverse; - // TODO: not needed anymore - this.rebuildOutput(); + this.notifyReset(this.output.length); } } @@ -380,11 +379,11 @@ export class DataSource< }); } - notifyItemShift(viewIndex: number, delta: number) { + notifyItemShift(index: number, delta: number) { if (!this.outputChangeListener) { return; } - viewIndex = this.normalizeIndex(viewIndex); + let viewIndex = this.normalizeIndex(index); if (this.reverse && delta < 0) { viewIndex -= delta; // we need to correct for normalize already using the new length after applying this change } @@ -502,10 +501,7 @@ export class DataSource< entry.visible = true; }); this.output = output; - this.outputChangeListener?.({ - type: 'reset', - newCount: output.length, - }); + this.notifyReset(output.length); } private sortHelper = (a: Entry) => diff --git a/desktop/flipper-plugin/src/ui/datatable/ColumnFilter.tsx b/desktop/flipper-plugin/src/ui/datatable/ColumnFilter.tsx index 6ea29edf1..fc4763fb5 100644 --- a/desktop/flipper-plugin/src/ui/datatable/ColumnFilter.tsx +++ b/desktop/flipper-plugin/src/ui/datatable/ColumnFilter.tsx @@ -8,12 +8,13 @@ */ import {useMemo, useState} from 'react'; +import styled from '@emotion/styled'; import React from 'react'; -import {theme} from '../theme'; -import type {DataTableColumn} from './DataTable'; - import {Button, Checkbox, Dropdown, Menu, Typography, Input} from 'antd'; import {FilterFilled, MinusCircleOutlined} from '@ant-design/icons'; + +import {theme} from '../theme'; +import type {DataTableColumn} from './DataTable'; import {Layout} from '../Layout'; const {Text} = Typography; @@ -127,18 +128,25 @@ export function FilterIcon({ ); return ( - - - +
+ + + + + +
); } + +export const FilterButton = styled.div<{isActive?: boolean}>(({isActive}) => ({ + backgroundColor: theme.backgroundWash, + visibility: isActive ? 'visible' : 'hidden', + color: isActive ? theme.primaryColor : theme.disabledColor, + cursor: 'pointer', + marginRight: 4, + zIndex: 1, + '&:hover': { + color: theme.primaryColor, + backgroundColor: theme.backgroundWash, + }, +})); diff --git a/desktop/flipper-plugin/src/ui/datatable/TableHead.tsx b/desktop/flipper-plugin/src/ui/datatable/TableHead.tsx index 9aceab1cb..0bf2292e9 100644 --- a/desktop/flipper-plugin/src/ui/datatable/TableHead.tsx +++ b/desktop/flipper-plugin/src/ui/datatable/TableHead.tsx @@ -24,7 +24,7 @@ import {Typography} from 'antd'; import {CaretDownFilled, CaretUpFilled} from '@ant-design/icons'; import {Layout} from '../Layout'; import {Sorting, OnColumnResize, SortDirection} from './useDataTableManager'; -import {ColumnFilterHandlers, FilterIcon} from './ColumnFilter'; +import {ColumnFilterHandlers, FilterButton, FilterIcon} from './ColumnFilter'; const {Text} = Typography; @@ -98,8 +98,8 @@ const TableHeadColumnContainer = styled.div<{ [`:hover ${SortIconsContainer}`]: { visibility: 'visible', }, - [`&:hover button`]: { - visibility: 'visible !important' as any, + [`&:hover ${FilterButton}`]: { + visibility: 'visible', }, })); TableHeadColumnContainer.displayName = 'TableHead:TableHeadColumnContainer'; @@ -166,10 +166,13 @@ function TableHeadColumn({
{ e.stopPropagation(); - onSort( - column.key, - sorted === 'asc' ? 'desc' : sorted === 'desc' ? undefined : 'asc', - ); + const newDirection = + sorted === undefined + ? 'asc' + : sorted === 'asc' + ? 'desc' + : undefined; + onSort(column.key, newDirection); }} role="button" tabIndex={0}> diff --git a/desktop/flipper-plugin/src/ui/datatable/TableSearch.tsx b/desktop/flipper-plugin/src/ui/datatable/TableSearch.tsx index d03a1b746..ffe554dad 100644 --- a/desktop/flipper-plugin/src/ui/datatable/TableSearch.tsx +++ b/desktop/flipper-plugin/src/ui/datatable/TableSearch.tsx @@ -9,9 +9,13 @@ import {MenuOutlined} from '@ant-design/icons'; import {Button, Dropdown, Input} from 'antd'; -import React, {memo} from 'react'; +import React, {memo, useState} from 'react'; +import styled from '@emotion/styled'; + import {Layout} from '../Layout'; import {theme} from '../theme'; +import {debounce} from 'lodash'; +import {useAssertStableRef} from '../../utils/useAssertStableRef'; export const TableSearch = memo(function TableSearch({ onSearch, @@ -23,14 +27,23 @@ export const TableSearch = memo(function TableSearch({ hasSelection?: boolean; contextMenu?: React.ReactElement; }) { + useAssertStableRef(onSearch, 'onSearch'); + const [search, setSearch] = useState(''); + const [performSearch] = useState(() => + debounce(onSearch, 200, {leading: true}), + ); return ( - - + + { + setSearch(e.target.value); + performSearch(e.target.value); + }} + /> {extraActions} {contextMenu && ( @@ -39,6 +52,15 @@ export const TableSearch = memo(function TableSearch({ )} - + ); }); + +const Searchbar = styled(Layout.Horizontal)({ + backgroundColor: theme.backgroundWash, + padding: theme.space.small, + '.ant-btn': { + padding: `${theme.space.tiny}px ${theme.space.small}px`, + background: 'transparent', + }, +}); diff --git a/desktop/flipper-plugin/src/utils/useAssertStableRef.tsx b/desktop/flipper-plugin/src/utils/useAssertStableRef.tsx index 14bfe2f43..cf72cdac6 100644 --- a/desktop/flipper-plugin/src/utils/useAssertStableRef.tsx +++ b/desktop/flipper-plugin/src/utils/useAssertStableRef.tsx @@ -10,7 +10,7 @@ import {useRef} from 'react'; /** - * This hook will throw in development builds if the value passed in is stable. + * This hook will throw in development builds if the value passed in is unstable. * Use this if to make sure consumers aren't creating or changing certain props over time * (intentionally or accidentally) */