1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-01-25 00:07:47 +01:00

Refactored feature toggles table (#951)

* refactor: simplify table toolbar

* refactor: table links and padding

* fix: header icons colors

* fix: minor table style changes
This commit is contained in:
Tymoteusz Czech 2022-05-06 12:21:31 +02:00 committed by GitHub
parent 7785e2c717
commit 5ecc83f1b4
34 changed files with 600 additions and 220 deletions

View File

@ -4,6 +4,9 @@ export const useStyles = makeStyles()(theme => ({
tableCellHeaderSortable: {
padding: 0,
position: 'relative',
'&:hover, &:focus': {
backgroundColor: theme.palette.grey[400],
},
},
sortButton: {
all: 'unset',
@ -15,9 +18,6 @@ export const useStyles = makeStyles()(theme => ({
},
display: 'flex',
alignItems: 'center',
'&:hover': {
backgroundColor: theme.palette.grey[400],
},
boxSizing: 'inherit',
cursor: 'pointer',
},

View File

@ -14,8 +14,4 @@ export const useStyles = makeStyles()(theme => ({
},
},
},
icon: {
marginLeft: theme.spacing(0.5),
fontSize: 18,
},
}));

View File

@ -0,0 +1,8 @@
import { FC } from 'react';
import { Box, Table as MUITable } from '@mui/material';
export const Table: FC = ({ children }) => (
<Box sx={{ p: 4, pb: 0 }}>
<MUITable>{children}</MUITable>
</Box>
);

View File

@ -14,6 +14,9 @@ interface ITableActionsProps {
isSeparated?: boolean;
}
/**
* @deprecated
*/
export const TableActions: FC<ITableActionsProps> = ({
initialSearchValue: search,
onSearch = () => {},

View File

@ -0,0 +1,7 @@
import { makeStyles } from 'tss-react/mui';
export const useStyles = makeStyles()(theme => ({
tableCell: {
padding: 0,
},
}));

View File

@ -0,0 +1,9 @@
import { FC } from 'react';
import { TableCell as MUITableCell, TableCellProps } from '@mui/material';
import { useStyles } from './TableCell.styles';
export const TableCell: FC<TableCellProps> = ({ ...props }) => {
const { classes: styles } = useStyles();
return <MUITableCell className={styles.tableCell} {...props} />;
};

View File

@ -7,8 +7,4 @@ export const useStyles = makeStyles()(theme => ({
borderRadius: theme.spacing(1.5),
paddingBottom: theme.spacing(4),
},
content: {
padding: theme.spacing(4),
paddingBottom: 0,
},
}));

View File

@ -0,0 +1,15 @@
import { forwardRef } from 'react';
import { Paper, PaperProps } from '@mui/material';
import { useStyles } from './TableContainer.styles';
export const TableContainer = forwardRef<HTMLDivElement, PaperProps>(
({ children, ...props }, ref) => {
const { classes } = useStyles();
return (
<Paper ref={ref} className={classes.panel} {...props}>
{children}
</Paper>
);
}
);

View File

@ -1,18 +0,0 @@
import { forwardRef, ReactNode } from 'react';
import { Paper } from '@mui/material';
import { Box } from '@mui/material';
import { useStyles } from './TablePanel.styles';
export const TablePanel = forwardRef<
HTMLDivElement,
{ children: ReactNode; header?: ReactNode }
>(({ header, children, ...props }, ref) => {
const { classes: styles } = useStyles();
return (
<Paper ref={ref} className={styles.panel} {...props}>
{header}
<Box className={styles.content}>{children}</Box>
</Paper>
);
});

View File

@ -8,7 +8,6 @@ export const useStyles = makeStyles()(theme => ({
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
marginTop: theme.spacing(4),
marginBottom: theme.spacing(4),
margin: theme.spacing(4),
},
}));

View File

@ -2,10 +2,8 @@ import { FC } from 'react';
import { Box } from '@mui/material';
import { useStyles } from 'component/common/Table/TablePlaceholder/TablePlaceholder.styles';
const TablePlaceholder: FC = ({ children }) => {
export const TablePlaceholder: FC = ({ children }) => {
const { classes: styles } = useStyles();
return <Box className={styles.emptyStateListItem}>{children}</Box>;
};
export default TablePlaceholder;

View File

@ -0,0 +1,59 @@
import { makeStyles } from 'tss-react/mui';
export const useStyles = makeStyles()(theme => ({
searchField: {
width: '45px',
'& .search-icon': {
marginRight: 0,
},
'& .input-container, .clear-container': {
width: 0,
},
'& input::placeholder': {
color: 'transparent',
transition: 'color 0.6s',
},
'& input:focus-within::placeholder': {
color: theme.palette.text.primary,
},
},
searchFieldEnter: {
width: '250px',
transition: 'width 0.6s',
'& .search-icon': {
marginRight: '8px',
},
'& .input-container': {
width: '100%',
transition: 'width 0.6s',
},
'& .clear-container': {
width: '30px',
transition: 'width 0.6s',
},
'& .search-container': {
borderColor: theme.palette.grey[300],
},
},
searchFieldLeave: {
width: '45px',
transition: 'width 0.6s',
'& .search-icon': {
marginRight: 0,
transition: 'margin-right 0.6s',
},
'& .input-container, .clear-container': {
width: 0,
transition: 'width 0.6s',
},
'& .search-container': {
borderColor: 'transparent',
},
},
searchButton: {
marginTop: '-4px',
marginBottom: '-4px',
marginRight: '-4px',
marginLeft: '-4px',
},
}));

View File

@ -0,0 +1,75 @@
import { FC, useState } from 'react';
import { IconButton, Tooltip } from '@mui/material';
import { Search } from '@mui/icons-material';
import { useAsyncDebounce } from 'react-table';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import AnimateOnMount from 'component/common/AnimateOnMount/AnimateOnMount';
import { TableSearchField } from './TableSearchField/TableSearchField';
import { useStyles } from './TableSearch.styles';
interface ITableSearchProps {
initialValue?: string;
onChange?: (value: string) => void;
placeholder?: string;
}
export const TableSearch: FC<ITableSearchProps> = ({
initialValue,
onChange = () => {},
placeholder = 'Search',
}) => {
const [searchInputState, setSearchInputState] = useState(initialValue);
const [isSearchExpanded, setIsSearchExpanded] = useState(
Boolean(initialValue)
);
const [isAnimating, setIsAnimating] = useState(false);
const debouncedOnSearch = useAsyncDebounce(onChange, 200);
const { classes: styles } = useStyles();
const onBlur = (clear = false) => {
if (!searchInputState || clear) {
setIsSearchExpanded(false);
}
};
const onSearchChange = (value: string) => {
debouncedOnSearch(value);
setSearchInputState(value);
};
return (
<>
<AnimateOnMount
mounted={isSearchExpanded}
start={styles.searchField}
enter={styles.searchFieldEnter}
leave={styles.searchFieldLeave}
onStart={() => setIsAnimating(true)}
onEnd={() => setIsAnimating(false)}
>
<TableSearchField
value={searchInputState!}
onChange={onSearchChange}
placeholder={`${placeholder}`}
onBlur={onBlur}
/>
</AnimateOnMount>
<ConditionallyRender
condition={!isSearchExpanded && !isAnimating}
show={
<Tooltip title={placeholder} arrow>
<IconButton
aria-label={placeholder}
onClick={() => setIsSearchExpanded(true)}
size="large"
className={styles.searchButton}
>
<Search />
</IconButton>
</Tooltip>
}
/>
</>
);
};

View File

@ -0,0 +1,43 @@
import { makeStyles } from 'tss-react/mui';
export const useStyles = makeStyles()(theme => ({
container: {
display: 'flex',
alignItems: 'center',
flexWrap: 'wrap',
gap: '1rem',
},
search: {
display: 'flex',
alignItems: 'center',
backgroundColor: theme.palette.background.paper,
border: `1px solid ${theme.palette.grey[300]}`,
borderRadius: '25px',
padding: '3px 5px 3px 12px',
maxWidth: '450px',
[theme.breakpoints.down('sm')]: {
width: '100%',
},
'&.search-container:focus-within': {
borderColor: theme.palette.primary.light,
boxShadow: theme.boxShadows.main,
},
},
searchIcon: {
marginRight: 8,
color: theme.palette.grey[600],
},
clearContainer: {
width: '30px',
'& > button': {
padding: '7px',
},
},
clearIcon: {
color: theme.palette.grey[600],
fontSize: '18px',
},
inputRoot: {
width: '100%',
},
}));

View File

@ -0,0 +1,73 @@
import { IconButton, InputBase, Tooltip } from '@mui/material';
import { Search, Close } from '@mui/icons-material';
import classnames from 'classnames';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { useStyles } from './TableSearchField.styles';
interface ITableSearchFieldProps {
value: string;
onChange: (value: string) => void;
className?: string;
placeholder: string;
onBlur?: (clear?: boolean) => void;
}
export const TableSearchField = ({
value = '',
onChange,
className,
placeholder,
onBlur,
}: ITableSearchFieldProps) => {
const { classes: styles } = useStyles();
return (
<div className={styles.container}>
<div
className={classnames(
styles.search,
className,
'search-container'
)}
>
<Search
className={classnames(styles.searchIcon, 'search-icon')}
/>
<InputBase
autoFocus
placeholder={placeholder}
classes={{
root: classnames(styles.inputRoot, 'input-container'),
}}
inputProps={{ 'aria-label': placeholder }}
value={value}
onChange={e => onChange(e.target.value)}
onBlur={() => onBlur?.()}
/>
<div
className={classnames(
styles.clearContainer,
'clear-container'
)}
>
<ConditionallyRender
condition={Boolean(value)}
show={
<Tooltip title="Clear search query" arrow>
<IconButton
size="small"
onClick={() => {
onChange('');
onBlur?.(true);
}}
>
<Close className={styles.clearIcon} />
</IconButton>
</Tooltip>
}
/>
</div>
</div>
</div>
);
};

View File

@ -1,12 +1,30 @@
import { makeStyles } from 'tss-react/mui';
export const useStyles = makeStyles()(theme => ({
root: {
toolbar: {
paddingLeft: theme.spacing(4),
paddingRight: theme.spacing(4),
paddingTop: theme.spacing(2.5),
paddingBottom: theme.spacing(2.5),
paddingTop: theme.spacing(2),
paddingBottom: theme.spacing(2),
borderBottom: `1px solid ${theme.palette.divider}`,
justifyContent: 'space-between',
display: 'flex',
flexWrap: 'wrap',
alignItems: 'center',
},
actions: {
flex: 1,
display: 'flex',
justifyContent: 'flex-end',
alignItems: 'center',
},
verticalSeparator: {
height: '100%',
backgroundColor: theme.palette.grey[500],
width: '1px',
display: 'inline-block',
marginLeft: theme.spacing(2),
marginRight: theme.spacing(4),
padding: '10px 0',
verticalAlign: 'middle',
},
}));

View File

@ -1,20 +1,32 @@
import { FC } from 'react';
import { Toolbar, Typography } from '@mui/material';
import { FC, VFC } from 'react';
import { Box, Toolbar, Typography } from '@mui/material';
import { useStyles } from './TableToolbar.styles';
interface ITableToolbarProps {
title: string;
}
export const TableToolbar: FC<ITableToolbarProps> = ({ title, children }) => {
export const TableToolbarComponent: FC<ITableToolbarProps> & {
Divider: VFC;
} = ({ title, children }) => {
const { classes: styles } = useStyles();
return (
<Toolbar className={styles.root}>
<Typography variant="h1" component="h1" data-loading>
<Toolbar className={styles.toolbar}>
<Typography variant="h1" data-loading>
{title}
</Typography>
{children}
<Box className={styles.actions}>{children}</Box>
</Toolbar>
);
};
const Divider: VFC = () => {
const { classes: styles } = useStyles();
return <Box className={styles.verticalSeparator} />;
};
TableToolbarComponent.Divider = Divider;
export const TableToolbar = TableToolbarComponent;

View File

@ -0,0 +1,8 @@
export { TableContainer } from './TableContainer/TableContainer';
export { TableToolbar } from './TableToolbar/TableToolbar';
export { TableSearch } from './TableSearch/TableSearch';
export { Table } from './Table';
export { SortableTableHeader } from './SortableTableHeader/SortableTableHeader';
export { TableBody, TableRow } from '@mui/material';
export { TableCell } from './TableCell/TableCell';
export { TablePlaceholder } from './TablePlaceholder/TablePlaceholder';

View File

@ -2,7 +2,7 @@ import { useFeatures } from 'hooks/api/getters/useFeatures/useFeatures';
import { FeatureSchema } from 'openapi';
import { FeatureToggleListTable } from './FeatureToggleListTable/FeatureToggleListTable';
const featuresPlaceholder: FeatureSchema[] = Array(7).fill({
const featuresPlaceholder: FeatureSchema[] = Array(15).fill({
name: 'Name of the feature',
description: 'Short description of the feature',
type: '-',

View File

@ -2,7 +2,7 @@ import { VFC } from 'react';
import { useLocationSettings } from 'hooks/useLocationSettings';
import { formatDateYMD, formatDateYMDHMS } from 'utils/formatDate';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { Tooltip } from '@mui/material';
import { Box, Tooltip } from '@mui/material';
interface IDateCellProps {
value?: Date | null;
@ -12,21 +12,26 @@ export const DateCell: VFC<IDateCellProps> = ({ value }) => {
const { locationSettings } = useLocationSettings();
return (
<ConditionallyRender
condition={Boolean(value)}
show={
<Tooltip
title={formatDateYMDHMS(
value as Date,
locationSettings.locale
)}
arrow
>
<span data-loading>
{formatDateYMD(value as Date, locationSettings.locale)}
</span>
</Tooltip>
}
/>
<Box sx={{ py: 1.5, px: 2 }}>
<ConditionallyRender
condition={Boolean(value)}
show={
<Tooltip
title={formatDateYMDHMS(
value as Date,
locationSettings.locale
)}
arrow
>
<span data-loading role="tooltip">
{formatDateYMD(
value as Date,
locationSettings.locale
)}
</span>
</Tooltip>
}
/>
</Box>
);
};

View File

@ -1,6 +1,15 @@
import { makeStyles } from 'tss-react/mui';
export const useStyles = makeStyles()(theme => ({
container: {
paddingTop: theme.spacing(1.5),
paddingBottom: theme.spacing(1.5),
paddingLeft: theme.spacing(2),
paddingRight: theme.spacing(2),
display: 'flex',
alignItems: 'center',
minHeight: '62px',
},
description: {
color: theme.palette.grey[800],
fontSize: 'inherit',

View File

@ -0,0 +1,55 @@
import { FC } from 'react';
import { Link, Typography } from '@mui/material';
import { Link as RouterLink } from 'react-router-dom';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { useStyles } from './FeatureLinkCell.styles';
import { Highlighter } from 'component/common/Highlighter/Highlighter';
import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext';
interface IFeatureLinkCellProps {
title?: string;
to: string;
subtitle?: string;
}
export const FeatureLinkCell: FC<IFeatureLinkCellProps> = ({
title,
to,
subtitle,
}) => {
const { classes: styles } = useStyles();
const search = useSearchHighlightContext();
return (
<Link
component={RouterLink}
to={to}
underline="hover"
className={styles.container}
>
<div>
<span data-loading>
<Highlighter search={search}>{title}</Highlighter>
</span>
<ConditionallyRender
condition={Boolean(subtitle)}
show={
<>
<br />
<Typography
className={styles.description}
component="span"
data-loading
>
<Highlighter search={search}>
{subtitle}
</Highlighter>
</Typography>
</>
}
/>
</div>
</Link>
);
};

View File

@ -1,53 +0,0 @@
import { FC } from 'react';
import { Link, Typography } from '@mui/material';
import { Link as RouterLink } from 'react-router-dom';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { useStyles } from './FeatureNameCell.styles';
import { Highlighter } from 'component/common/Highlighter/Highlighter';
import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext';
interface IFeatureNameCellProps {
name?: string;
project?: string;
description?: string;
}
export const FeatureNameCell: FC<IFeatureNameCellProps> = ({
name,
project,
description,
}) => {
const { classes: styles } = useStyles();
const search = useSearchHighlightContext();
return (
<>
<Link
component={RouterLink}
to={`/projects/${project}/features/${name}`}
underline="hover"
data-loading
>
<Highlighter search={search}>{name}</Highlighter>
</Link>
<ConditionallyRender
condition={Boolean(description)}
show={
<>
<br />
<Typography
className={styles.description}
component="span"
data-loading
>
<Highlighter search={search}>
{description}
</Highlighter>
</Typography>
</>
}
/>
</>
);
};

View File

@ -2,6 +2,10 @@ import { makeStyles } from 'tss-react/mui';
export const useStyles = makeStyles()(theme => ({
container: {
display: 'flex',
padding: theme.spacing(1.5),
},
box: {
width: '38px',
height: '38px',
background: 'gray',

View File

@ -63,15 +63,18 @@ const Wrapper: FC<{ unit?: string; tooltip: string }> = ({
const getColor = useFeatureColor();
return (
<Tooltip title={tooltip} arrow>
<div
className={styles.container}
style={{ background: getColor(unit) }}
data-loading
>
{children}
</div>
</Tooltip>
<div className={styles.container}>
<Tooltip title={tooltip} arrow describeChild>
<div
role="tooltip"
className={styles.box}
style={{ background: getColor(unit) }}
data-loading
>
{children}
</div>
</Tooltip>
</div>
);
};

View File

@ -1,5 +1,5 @@
import { VFC } from 'react';
import { Typography } from '@mui/material';
import { Box, Typography } from '@mui/material';
import { useStyles } from './FeatureStaleCell.styles';
import classnames from 'classnames';
@ -10,12 +10,14 @@ interface IFeatureStaleCellProps {
export const FeatureStaleCell: VFC<IFeatureStaleCellProps> = ({ value }) => {
const { classes: styles } = useStyles();
return (
<Typography
component="span"
className={classnames(styles.status, value && styles.stale)}
data-loading
>
{value ? 'Stale' : 'Active'}
</Typography>
<Box sx={{ py: 1.5, px: 2 }}>
<Typography
component="span"
className={classnames(styles.status, value && styles.stale)}
data-loading
>
{value ? 'Stale' : 'Active'}
</Typography>
</Box>
);
};

View File

@ -1,28 +1,25 @@
import { useEffect, useMemo, VFC } from 'react';
import {
Link,
Table,
TableBody,
TableCell,
TableRow,
useMediaQuery,
useTheme,
} from '@mui/material';
import { Link, useMediaQuery, useTheme } from '@mui/material';
import { Link as RouterLink } from 'react-router-dom';
import { useGlobalFilter, useSortBy, useTable } from 'react-table';
import useLoading from 'hooks/useLoading';
import { SortableTableHeader } from 'component/common/Table/SortableTableHeader/SortableTableHeader';
import { TableActions } from 'component/common/Table/TableActions/TableActions';
import { TablePanel } from 'component/common/Table/TablePanel/TablePanel';
import { TableToolbar } from 'component/common/Table/TableToolbar/TableToolbar';
import TablePlaceholder from 'component/common/Table/TablePlaceholder/TablePlaceholder';
import {
TableContainer,
TableToolbar,
Table,
SortableTableHeader,
TableBody,
TableCell,
TableRow,
TablePlaceholder,
TableSearch,
} from 'component/common/Table';
import { SearchHighlightProvider } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext';
import { DateCell } from './DateCell/DateCell';
import { FeatureNameCell } from './FeatureNameCell/FeatureNameCell';
import { FeatureLinkCell } from './FeatureLinkCell/FeatureLinkCell';
import { FeatureSeenCell } from './FeatureSeenCell/FeatureSeenCell';
import { FeatureStaleCell } from './FeatureStaleCell/FeatureStaleCell';
import { FeatureTypeCell } from './FeatureTypeCell/FeatureTypeCell';
import { LinkCell } from './LinkCell/LinkCell';
import { CreateFeatureButton } from '../../CreateFeatureButton/CreateFeatureButton';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
@ -51,17 +48,29 @@ const columns = [
accessor: 'lastSeenAt',
Cell: FeatureSeenCell,
sortType: 'date',
totalWidth: 120,
},
{
Header: 'Type',
accessor: 'type',
Cell: FeatureTypeCell,
totalWidth: 120,
},
{
Header: 'Feature toggle name',
accessor: 'name',
// @ts-expect-error // TODO: props type
Cell: ({ row: { original } }) => <FeatureNameCell {...original} />,
Cell: ({
row: {
// @ts-expect-error -- props type
original: { name, description, project },
},
}) => (
<FeatureLinkCell
title={name}
subtitle={description}
to={`/projects/${project}/features/${name}`}
/>
),
sortType: 'alphanumeric',
},
{
@ -74,7 +83,7 @@ const columns = [
Header: 'Project ID',
accessor: 'project',
Cell: ({ value }: { value: string }) => (
<LinkCell to={`/projects/${value}`}>{value}</LinkCell>
<FeatureLinkCell title={value} to={`/projects/${value}`} />
),
sortType: 'alphanumeric',
},
@ -123,6 +132,7 @@ export const FeatureToggleListTable: VFC<IExperimentProps> = ({
initialState,
sortTypes,
autoResetGlobalFilter: false,
disableSortRemove: true,
},
useGlobalFilter,
useSortBy
@ -130,7 +140,13 @@ export const FeatureToggleListTable: VFC<IExperimentProps> = ({
useEffect(() => {
if (isSmallScreen) {
setHiddenColumns(['lastSeenAt', 'type', 'stale', 'description']);
setHiddenColumns([
'lastSeenAt',
'type',
'stale',
'description',
'createdAt',
]);
} else if (isMediumScreen) {
setHiddenColumns(['lastSeenAt', 'stale', 'description']);
} else {
@ -139,27 +155,26 @@ export const FeatureToggleListTable: VFC<IExperimentProps> = ({
}, [setHiddenColumns, isSmallScreen, isMediumScreen]);
return (
<TablePanel
ref={ref}
header={
<TableToolbar title={`Feature Flags (${data.length})`}>
<TableActions isSeparated onSearch={setGlobalFilter}>
<Link
component={RouterLink}
to="/archive"
underline="always"
sx={{ marginRight: 3 }}
>
View archive
</Link>
<CreateFeatureButton
loading={false}
filter={{ query: '', project: 'default' }}
/>
</TableActions>
</TableToolbar>
}
>
<TableContainer ref={ref}>
<TableToolbar title={`Feature toggles (${data.length})`}>
<TableSearch
initialValue={globalFilter}
onChange={setGlobalFilter}
/>
<TableToolbar.Divider />
<Link
component={RouterLink}
to="/archive"
underline="always"
sx={{ marginRight: 3 }}
>
View archive
</Link>
<CreateFeatureButton
loading={false}
filter={{ query: '', project: 'default' }}
/>
</TableToolbar>
<SearchHighlightProvider value={globalFilter}>
<Table {...getTableProps()}>
<SortableTableHeader headerGroups={headerGroups} />
@ -182,12 +197,24 @@ export const FeatureToggleListTable: VFC<IExperimentProps> = ({
<ConditionallyRender
condition={rows.length === 0}
show={
<TablePlaceholder>
No features available. Get started by adding a new
feature toggle.
</TablePlaceholder>
<ConditionallyRender
condition={globalFilter?.length > 0}
show={
<TablePlaceholder>
No features or projects found matching &ldquo;
{globalFilter}
&rdquo;
</TablePlaceholder>
}
elseShow={
<TablePlaceholder>
No features available. Get started by adding a
new feature toggle.
</TablePlaceholder>
}
/>
}
/>
</TablePanel>
</TableContainer>
);
};

View File

@ -1,6 +1,12 @@
import { makeStyles } from 'tss-react/mui';
export const useStyles = makeStyles()(theme => ({
container: {
padding: theme.spacing(1.5),
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
},
icon: {
marginTop: theme.spacing(0.5),
color: theme.palette.grey[600],

View File

@ -20,8 +20,10 @@ export const FeatureTypeCell: VFC<IFeatureTypeProps> = ({ value }) => {
const title = `This is a "${typeName || value}" toggle`;
return (
<Tooltip arrow placement="right" title={title}>
<IconComponent data-loading className={styles.icon} />
</Tooltip>
<div className={styles.container}>
<Tooltip arrow placement="right" title={title} describeChild>
<IconComponent data-loading className={styles.icon} />
</Tooltip>
</div>
);
};

View File

@ -1,20 +0,0 @@
import { VFC } from 'react';
import { Link as RouterLink } from 'react-router-dom';
import { Link } from '@mui/material';
import { Highlighter } from 'component/common/Highlighter/Highlighter';
import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext';
interface ILinkCellProps {
to: string;
children?: string;
}
export const LinkCell: VFC<ILinkCellProps> = ({ children, to }) => {
const search = useSearchHighlightContext();
return (
<Link component={RouterLink} to={to} data-loading underline="hover">
<Highlighter search={search}>{children}</Highlighter>
</Link>
);
};

View File

@ -83,7 +83,7 @@ export const useStyles = makeStyles()(theme => ({
color: '#000',
},
icon: {
color: theme.palette.grey[600],
color: theme.palette.grey[700],
},
wideButton: {
borderRadius: 100,

View File

@ -15,6 +15,6 @@ export const useStyles = makeStyles()(theme => ({
},
},
icon: {
color: theme.palette.grey[600],
color: theme.palette.grey[700],
},
}));

View File

@ -51,22 +51,6 @@ export default createTheme({
light: colors.purple[700],
dark: colors.purple[900],
},
grey: colors.grey,
neutral: {
main: '#18243e',
},
chips: {
main: '#b0bec5',
},
searchField: {
main: '#fff',
},
iconButtons: {
main: '#fff',
},
tabs: {
main: '#efefef',
},
success: {
light: colors.green[100],
main: colors.green[700],
@ -82,6 +66,22 @@ export default createTheme({
main: colors.red[700],
dark: colors.red[800],
},
grey: colors.grey,
// neutral: {
// main: '#18243e',
// },
chips: {
main: '#b0bec5',
},
searchField: {
main: '#fff',
},
iconButtons: {
main: '#fff',
},
tabs: {
main: '#efefef',
},
division: {
main: '#f1f1f1',
},
@ -97,5 +97,12 @@ export default createTheme({
},
},
},
MuiLink: {
styleOverrides: {
root: {
color: colors.purple[900],
},
},
},
},
});

View File

@ -2,6 +2,9 @@ import { SimplePaletteColorOptions } from '@mui/material';
declare module '@mui/material/styles' {
interface CustomTheme {
/**
* @deprecated
*/
fontSizes: {
mainHeader: string;
subHeader: string;
@ -9,12 +12,18 @@ declare module '@mui/material/styles' {
smallBody: string;
smallerBody: string;
};
/**
* @deprecated
*/
fontWeight: {
thin: number;
medium: number;
semi: number;
bold: number;
};
/**
* @deprecated
*/
code: {
main: string;
diffAdd: string;
@ -23,21 +32,44 @@ declare module '@mui/material/styles' {
edited: string;
background: string;
};
/**
* @deprecated
*/
borderRadius: {
main: string;
};
/**
* @deprecated
*/
boxShadows: {
main: string;
};
}
interface CustomPalette {
neutral: SimplePaletteColorOptions;
/**
* @deprecated
*/
chips: SimplePaletteColorOptions;
/**
* @deprecated
*/
searchField: SimplePaletteColorOptions;
/**
* @deprecated
*/
iconButtons: SimplePaletteColorOptions;
/**
* @deprecated
*/
tabs: SimplePaletteColorOptions;
/**
* @deprecated
*/
division: SimplePaletteColorOptions;
/**
* @deprecated
*/
footer: SimplePaletteColorOptions;
}