feat: consistent table styling (#6697)
* feat: consistent table styling * Update VRT screenshots Auto-generated by VRT workflow PR: #6697 * Update VRT screenshots Auto-generated by VRT workflow PR: #6697 * Update VRT screenshots Auto-generated by VRT workflow PR: #6697 --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
@@ -162,4 +162,11 @@ export const styles: Record<string, any> = {
|
||||
padding: 16,
|
||||
cursor: 'pointer',
|
||||
},
|
||||
tableContainer: {
|
||||
flex: 1,
|
||||
border: '1px solid ' + theme.tableBorder,
|
||||
borderTopLeftRadius: 6,
|
||||
borderTopRightRadius: 6,
|
||||
overflow: 'hidden',
|
||||
},
|
||||
};
|
||||
|
||||
|
Before Width: | Height: | Size: 166 KiB After Width: | Height: | Size: 166 KiB |
|
Before Width: | Height: | Size: 161 KiB After Width: | Height: | Size: 161 KiB |
|
Before Width: | Height: | Size: 162 KiB After Width: | Height: | Size: 162 KiB |
|
Before Width: | Height: | Size: 147 KiB After Width: | Height: | Size: 147 KiB |
|
Before Width: | Height: | Size: 148 KiB After Width: | Height: | Size: 147 KiB |
|
Before Width: | Height: | Size: 145 KiB After Width: | Height: | Size: 146 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 107 KiB |
|
Before Width: | Height: | Size: 109 KiB After Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 108 KiB |
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 85 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 85 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 85 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 85 KiB |
@@ -11,6 +11,7 @@ import { Trans, useTranslation } from 'react-i18next';
|
||||
|
||||
import { Button } from '@actual-app/components/button';
|
||||
import { SpaceBetween } from '@actual-app/components/space-between';
|
||||
import { styles } from '@actual-app/components/styles';
|
||||
import { Text } from '@actual-app/components/text';
|
||||
import { theme } from '@actual-app/components/theme';
|
||||
import { View } from '@actual-app/components/view';
|
||||
@@ -342,7 +343,7 @@ export function ManageRules({
|
||||
onChange={onSearchChange}
|
||||
/>
|
||||
</View>
|
||||
<View style={{ flex: 1 }}>
|
||||
<View style={styles.tableContainer}>
|
||||
<RulesHeader />
|
||||
<InfiniteScrollWrapper loadMore={loadMore}>
|
||||
{filteredRules.length === 0 ? (
|
||||
|
||||
@@ -11,6 +11,7 @@ import { Trans, useTranslation } from 'react-i18next';
|
||||
import { Button } from '@actual-app/components/button';
|
||||
import { SvgLockOpen } from '@actual-app/components/icons/v1';
|
||||
import { SvgLockClosed } from '@actual-app/components/icons/v2';
|
||||
import { styles } from '@actual-app/components/styles';
|
||||
import { Text } from '@actual-app/components/text';
|
||||
import { theme } from '@actual-app/components/theme';
|
||||
import { View } from '@actual-app/components/view';
|
||||
@@ -168,7 +169,7 @@ function UserAccessContent({ isModal }: ManageUserAccessContentProps) {
|
||||
onChange={onSearchChange}
|
||||
/>
|
||||
</View>
|
||||
<View style={{ flex: 1 }}>
|
||||
<View style={styles.tableContainer}>
|
||||
<UserAccessHeader />
|
||||
<InfiniteScrollWrapper loadMore={loadMore}>
|
||||
<UserAccessList
|
||||
|
||||
@@ -10,6 +10,7 @@ import { Trans, useTranslation } from 'react-i18next';
|
||||
|
||||
import { Button } from '@actual-app/components/button';
|
||||
import { SpaceBetween } from '@actual-app/components/space-between';
|
||||
import { styles } from '@actual-app/components/styles';
|
||||
import { Text } from '@actual-app/components/text';
|
||||
import { theme } from '@actual-app/components/theme';
|
||||
import { View } from '@actual-app/components/view';
|
||||
@@ -279,7 +280,7 @@ function UserDirectoryContent({ isModal }: ManageUserDirectoryContentProps) {
|
||||
/>
|
||||
</View>
|
||||
|
||||
<View style={{ flex: 1 }}>
|
||||
<View style={styles.tableContainer}>
|
||||
<UserDirectoryHeader />
|
||||
<InfiniteScrollWrapper loadMore={loadMore}>
|
||||
{filteredUsers.length === 0 ? (
|
||||
|
||||
@@ -31,6 +31,7 @@ export function AccountsList({
|
||||
<View
|
||||
style={{
|
||||
minHeight: 'initial',
|
||||
marginBottom: -1,
|
||||
}}
|
||||
>
|
||||
{accounts.map(account => {
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Trans, useTranslation } from 'react-i18next';
|
||||
import { SvgRightArrow2 } from '@actual-app/components/icons/v0';
|
||||
import { SvgEquals } from '@actual-app/components/icons/v1';
|
||||
import { Select } from '@actual-app/components/select';
|
||||
import { styles } from '@actual-app/components/styles';
|
||||
import { Text } from '@actual-app/components/text';
|
||||
import { theme } from '@actual-app/components/theme';
|
||||
import { View } from '@actual-app/components/view';
|
||||
@@ -103,7 +104,7 @@ export function FieldMapping({
|
||||
</Trans>
|
||||
</Text>
|
||||
) : (
|
||||
<>
|
||||
<View style={styles.tableContainer}>
|
||||
<TableHeader>
|
||||
<Cell
|
||||
width={calculatedActualFieldWidth}
|
||||
@@ -136,11 +137,11 @@ export function FieldMapping({
|
||||
key={field.actualField}
|
||||
style={{
|
||||
fontSize: 13,
|
||||
backgroundColor: theme.tableRowBackgroundHover,
|
||||
backgroundColor: theme.tableBackground,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
border: '1px solid var(--color-tableBorder)',
|
||||
minHeight: '40px',
|
||||
borderTop: '1px solid ' + theme.tableBorder,
|
||||
}}
|
||||
collapsed
|
||||
>
|
||||
@@ -225,7 +226,7 @@ export function FieldMapping({
|
||||
</Row>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
</View>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -2,6 +2,7 @@ import { useCallback, useMemo, useState } from 'react';
|
||||
import { Trans, useTranslation } from 'react-i18next';
|
||||
|
||||
import { useResponsive } from '@actual-app/components/hooks/useResponsive';
|
||||
import { styles } from '@actual-app/components/styles';
|
||||
import { Text } from '@actual-app/components/text';
|
||||
import { View } from '@actual-app/components/view';
|
||||
|
||||
@@ -128,7 +129,7 @@ export function BankSync() {
|
||||
)}
|
||||
{Object.entries(groupedAccounts).map(([syncProvider, accounts]) => {
|
||||
return (
|
||||
<View key={syncProvider} style={{ minHeight: 'initial' }}>
|
||||
<View key={syncProvider} style={styles.tableContainer}>
|
||||
{Object.keys(groupedAccounts).length > 1 && (
|
||||
<Text
|
||||
style={{ fontWeight: 500, fontSize: 20, margin: '.5em 0' }}
|
||||
|
||||
@@ -11,6 +11,7 @@ import { Button, ButtonWithLoading } from '@actual-app/components/button';
|
||||
import { Input } from '@actual-app/components/input';
|
||||
import { Select } from '@actual-app/components/select';
|
||||
import { SpaceBetween } from '@actual-app/components/space-between';
|
||||
import { styles } from '@actual-app/components/styles';
|
||||
import { Text } from '@actual-app/components/text';
|
||||
import { theme } from '@actual-app/components/theme';
|
||||
import { View } from '@actual-app/components/view';
|
||||
@@ -828,11 +829,7 @@ export function ImportTransactionsModal({
|
||||
)}
|
||||
{(!error || !error.parsed) && (
|
||||
<View
|
||||
style={{
|
||||
flex: 'unset',
|
||||
height: 300,
|
||||
border: '1px solid ' + theme.tableBorder,
|
||||
}}
|
||||
style={{ ...styles.tableContainer, height: 300, flex: 'unset' }}
|
||||
>
|
||||
<TableHeader headers={headers} />
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Trans, useTranslation } from 'react-i18next';
|
||||
import { Button } from '@actual-app/components/button';
|
||||
import { useResponsive } from '@actual-app/components/hooks/useResponsive';
|
||||
import { SpaceBetween } from '@actual-app/components/space-between';
|
||||
import { styles } from '@actual-app/components/styles';
|
||||
import { Text } from '@actual-app/components/text';
|
||||
import { theme } from '@actual-app/components/theme';
|
||||
import { Tooltip } from '@actual-app/components/tooltip';
|
||||
@@ -329,11 +330,7 @@ export function SelectLinkedAccountsModal({
|
||||
</View>
|
||||
) : (
|
||||
<View
|
||||
style={{
|
||||
flex: 'unset',
|
||||
height: 300,
|
||||
border: '1px solid ' + theme.tableBorder,
|
||||
}}
|
||||
style={{ ...styles.tableContainer, height: 300, flex: 'unset' }}
|
||||
>
|
||||
<TableHeader>
|
||||
<Cell value={t('Institution to Sync')} width={175} />
|
||||
|
||||
@@ -10,6 +10,7 @@ import { Trans, useTranslation } from 'react-i18next';
|
||||
import { Button } from '@actual-app/components/button';
|
||||
import { SvgExpandArrow, SvgSubtract } from '@actual-app/components/icons/v0';
|
||||
import { Popover } from '@actual-app/components/popover';
|
||||
import { styles } from '@actual-app/components/styles';
|
||||
import { theme } from '@actual-app/components/theme';
|
||||
import { View } from '@actual-app/components/view';
|
||||
import memoizeOne from 'memoize-one';
|
||||
@@ -46,15 +47,7 @@ function PayeeTableHeader() {
|
||||
|
||||
return (
|
||||
<View>
|
||||
<TableHeader
|
||||
style={{
|
||||
backgroundColor: theme.tableBackground,
|
||||
color: theme.pageTextLight,
|
||||
zIndex: 200,
|
||||
userSelect: 'none',
|
||||
}}
|
||||
collapsed
|
||||
>
|
||||
<TableHeader collapsed>
|
||||
<SelectCell
|
||||
exposed
|
||||
focused={false}
|
||||
@@ -288,15 +281,7 @@ export const ManagePayees = ({
|
||||
</View>
|
||||
|
||||
<SelectedProvider instance={selected} fetchAllIds={getSelectableIds}>
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
border: '1px solid ' + theme.tableBorder,
|
||||
borderTopLeftRadius: 4,
|
||||
borderTopRightRadius: 4,
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
>
|
||||
<View style={styles.tableContainer}>
|
||||
<PayeeTableHeader />
|
||||
{filteredPayees.length === 0 ? (
|
||||
<View
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
type ComponentRef,
|
||||
} from 'react';
|
||||
|
||||
import { theme } from '@actual-app/components/theme';
|
||||
import { View } from '@actual-app/components/view';
|
||||
|
||||
import { type PayeeEntity } from 'loot-core/types/models';
|
||||
@@ -64,6 +65,7 @@ export const PayeeTable = forwardRef<
|
||||
navigator={tableNavigator}
|
||||
ref={ref}
|
||||
items={payees}
|
||||
backgroundColor={theme.tableBackground}
|
||||
renderItem={({ item, editing, focusedField, onEdit }) => {
|
||||
return (
|
||||
<PayeeTableRow
|
||||
|
||||
@@ -5,6 +5,7 @@ import { Trans, useTranslation } from 'react-i18next';
|
||||
import { ButtonWithLoading } from '@actual-app/components/button';
|
||||
import { Paragraph } from '@actual-app/components/paragraph';
|
||||
import { SpaceBetween } from '@actual-app/components/space-between';
|
||||
import { styles } from '@actual-app/components/styles';
|
||||
import { theme } from '@actual-app/components/theme';
|
||||
import { View } from '@actual-app/components/view';
|
||||
|
||||
@@ -117,7 +118,7 @@ function DiscoverSchedulesTable({
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={{ flex: 1 }}>
|
||||
<View style={styles.tableContainer}>
|
||||
<TableHeader height={ROW_HEIGHT} inset={15}>
|
||||
<SelectCell
|
||||
exposed={!loading}
|
||||
|
||||
@@ -7,6 +7,7 @@ import { useResponsive } from '@actual-app/components/hooks/useResponsive';
|
||||
import { InitialFocus } from '@actual-app/components/initial-focus';
|
||||
import { Input } from '@actual-app/components/input';
|
||||
import { SpaceBetween } from '@actual-app/components/space-between';
|
||||
import { styles } from '@actual-app/components/styles';
|
||||
import { Text } from '@actual-app/components/text';
|
||||
import { theme } from '@actual-app/components/theme';
|
||||
import { View } from '@actual-app/components/view';
|
||||
@@ -470,9 +471,7 @@ export function ScheduleEditForm({
|
||||
transactions={transactions}
|
||||
fields={['date', 'payee', 'notes', 'amount']}
|
||||
style={{
|
||||
border: '1px solid ' + theme.tableBorder,
|
||||
borderRadius: 4,
|
||||
overflow: 'hidden',
|
||||
...styles.tableContainer,
|
||||
marginTop: 5,
|
||||
maxHeight: 200,
|
||||
}}
|
||||
|
||||
@@ -7,6 +7,7 @@ import { SvgDotsHorizontalTriple } from '@actual-app/components/icons/v1';
|
||||
import { SvgCheck } from '@actual-app/components/icons/v2';
|
||||
import { Menu } from '@actual-app/components/menu';
|
||||
import { Popover } from '@actual-app/components/popover';
|
||||
import { styles } from '@actual-app/components/styles';
|
||||
import { Text } from '@actual-app/components/text';
|
||||
import { theme } from '@actual-app/components/theme';
|
||||
import { View } from '@actual-app/components/view';
|
||||
@@ -428,7 +429,7 @@ export function SchedulesTable({
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={{ flex: 1, ...tableStyle }}>
|
||||
<View style={{ ...styles.tableContainer, ...tableStyle }}>
|
||||
<TableHeader height={ROW_HEIGHT} inset={15}>
|
||||
<Field width="flex">
|
||||
<Trans>Name</Trans>
|
||||
|
||||
@@ -789,7 +789,6 @@ export function TableHeader({
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
borderRadius: '6px 6px 0 0',
|
||||
overflow: 'hidden',
|
||||
flexShrink: 0,
|
||||
}}
|
||||
@@ -956,7 +955,7 @@ export const Table = forwardRef(
|
||||
contentHeader,
|
||||
loading,
|
||||
rowHeight = ROW_HEIGHT,
|
||||
backgroundColor = theme.tableHeaderBackground,
|
||||
backgroundColor = theme.tableBackground,
|
||||
renderItem,
|
||||
renderEmpty,
|
||||
getItemKey,
|
||||
@@ -1088,6 +1087,7 @@ export const Table = forwardRef(
|
||||
...rowStyle,
|
||||
zIndex: editing || selected ? 101 : 'auto',
|
||||
transform: 'translateY(var(--pos))',
|
||||
backgroundColor,
|
||||
}}
|
||||
nativeStyle={{ '--pos': `${style.top - 1}px` }}
|
||||
data-focus-key={item.id}
|
||||
@@ -1156,6 +1156,7 @@ export const Table = forwardRef(
|
||||
style={{
|
||||
flex: 1,
|
||||
outline: 'none',
|
||||
overflow: 'hidden',
|
||||
...style,
|
||||
}}
|
||||
tabIndex={0}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { Button } from '@actual-app/components/button';
|
||||
import { SvgAdd } from '@actual-app/components/icons/v1';
|
||||
import { SvgSearchAlternate } from '@actual-app/components/icons/v2';
|
||||
import { SpaceBetween } from '@actual-app/components/space-between';
|
||||
import { styles } from '@actual-app/components/styles';
|
||||
import { Text } from '@actual-app/components/text';
|
||||
import { theme } from '@actual-app/components/theme';
|
||||
import { View } from '@actual-app/components/view';
|
||||
@@ -89,7 +90,7 @@ export function ManageTags() {
|
||||
onChange={setFilter}
|
||||
/>
|
||||
</SpaceBetween>
|
||||
<View style={{ flex: 1, marginTop: 12 }}>
|
||||
<View style={{ marginTop: 12, ...styles.tableContainer }}>
|
||||
<TagsHeader />
|
||||
{create && (
|
||||
<TagCreationRow onClose={() => setCreate(false)} tags={tags} />
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import React from 'react';
|
||||
|
||||
import { theme } from '@actual-app/components/theme';
|
||||
|
||||
import { type TagEntity } from 'loot-core/types/models';
|
||||
|
||||
import { TagRow } from './TagRow';
|
||||
@@ -29,7 +31,7 @@ export function TagsList({
|
||||
<Table
|
||||
navigator={tableNavigator}
|
||||
items={tags}
|
||||
backgroundColor="none"
|
||||
backgroundColor={theme.tableBackground}
|
||||
renderItem={({ item: tag, focusedField, onEdit }) => {
|
||||
const hovered = hoveredTag === tag.id;
|
||||
const selected = selectedItems.has(tag.id);
|
||||
|
||||
@@ -208,6 +208,7 @@ export function SimpleTransactionsTable({
|
||||
return (
|
||||
<Table
|
||||
style={style}
|
||||
backgroundColor={theme.tableBackground}
|
||||
items={serializedTransactions}
|
||||
renderEmpty={renderEmpty}
|
||||
headers={
|
||||
|
||||
@@ -184,7 +184,7 @@ const TransactionHeader = memo(
|
||||
fontWeight: 300,
|
||||
zIndex: 200,
|
||||
color: theme.tableHeaderText,
|
||||
backgroundColor: theme.tableBackground,
|
||||
backgroundColor: theme.tableHeaderBackground,
|
||||
paddingRight: `${5 + (scrollWidth ?? 0)}px`,
|
||||
borderTopWidth: 1,
|
||||
borderBottomWidth: 1,
|
||||
|
||||
6
upcoming-release-notes/6697.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: Enhancements
|
||||
authors: [aelxxs]
|
||||
---
|
||||
|
||||
Adds consistent styling (border, border radius, background colors) to tables
|
||||