bringing in the lastest updates

This commit is contained in:
Mike Clark
2025-02-10 20:11:08 +00:00
19 changed files with 522 additions and 420 deletions

View File

@@ -0,0 +1,24 @@
{
"name": "@actual-app/components",
"version": "0.0.1",
"license": "MIT",
"peerDependencies": {
"react": ">=18.2"
},
"dependencies": {
"@emotion/css": "^11.13.4",
"react-aria-components": "^1.4.1"
},
"devDependencies": {
"@types/react": "^18.2.0",
"react": "18.2.0"
},
"exports": {
"./icons/*": "./src/icons/*.tsx",
"./button": "./src/Button.tsx",
"./styles": "./src/styles.ts",
"./theme": "./src/theme.ts",
"./tokens": "./src/tokens.ts",
"./view": "./src/View.tsx"
}
}

View File

@@ -9,9 +9,9 @@ import { Button as ReactAriaButton } from 'react-aria-components';
import { css } from '@emotion/css';
import { AnimatedLoading } from '../../icons/AnimatedLoading';
import { styles, theme } from '../../style';
import { AnimatedLoading } from './icons/AnimatedLoading';
import { styles } from './styles';
import { theme } from './theme';
import { View } from './View';
const backgroundColor: {

View File

@@ -2,7 +2,7 @@ import React, { forwardRef, type HTMLProps, type Ref } from 'react';
import { css, cx } from '@emotion/css';
import { type CSSProperties } from '../../style';
import { type CSSProperties } from './styles';
type ViewProps = HTMLProps<HTMLDivElement> & {
className?: string;

View File

@@ -0,0 +1,26 @@
import React, { type SVGProps } from 'react';
import { css, keyframes } from '@emotion/css';
import { SvgLoading } from './Loading';
const rotation = keyframes({
'0%': { transform: 'rotate(-90deg)' },
'100%': { transform: 'rotate(666deg)' },
});
export function AnimatedLoading(props: SVGProps<SVGSVGElement>) {
return (
<span
className={css({
animationName: rotation,
animationDuration: '1.6s',
animationTimingFunction: 'cubic-bezier(0.17, 0.67, 0.83, 0.67)',
animationIterationCount: 'infinite',
lineHeight: 0,
})}
>
<SvgLoading {...props} />
</span>
);
}

View File

@@ -0,0 +1,33 @@
import React, { type SVGProps, useState } from 'react';
export const SvgLoading = (props: SVGProps<SVGSVGElement>) => {
const { color = 'currentColor' } = props;
const [gradientId] = useState('gradient-' + Math.random());
return (
<svg {...props} viewBox="0 0 38 38" style={{ ...props.style }}>
<defs>
<linearGradient
x1="8.042%"
y1="0%"
x2="65.682%"
y2="23.865%"
id={gradientId}
>
<stop stopColor={color} stopOpacity={0} offset="0%" />
<stop stopColor={color} stopOpacity={0.631} offset="63.146%" />
<stop stopColor={color} offset="100%" />
</linearGradient>
</defs>
<g transform="translate(1 2)" fill="none" fillRule="evenodd">
<path
d="M36 18c0-9.94-8.06-18-18-18"
stroke={'url(#' + gradientId + ')'}
strokeWidth={2}
fill="none"
/>
<circle fill={color} cx={36} cy={18} r={1} />
</g>
</svg>
);
};

View File

@@ -0,0 +1,151 @@
import { keyframes } from '@emotion/css';
import { theme } from './theme';
import { tokens } from './tokens';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type CSSProperties = Record<string, any>;
const MOBILE_MIN_HEIGHT = 40;
const shadowLarge = {
boxShadow: '0 15px 30px 0 rgba(0,0,0,0.11), 0 5px 15px 0 rgba(0,0,0,0.08)',
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const styles: Record<string, any> = {
incomeHeaderHeight: 70,
cardShadow: '0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24)',
monthRightPadding: 5,
menuBorderRadius: 4,
mobileMinHeight: MOBILE_MIN_HEIGHT,
mobileMenuItem: {
fontSize: 17,
fontWeight: 400,
paddingTop: 8,
paddingBottom: 8,
height: MOBILE_MIN_HEIGHT,
minHeight: MOBILE_MIN_HEIGHT,
},
mobileEditingPadding: 12,
altMenuMaxHeight: 250,
altMenuText: {
fontSize: 13,
},
altMenuHeaderText: {
fontSize: 13,
fontWeight: 700,
},
veryLargeText: {
fontSize: 30,
fontWeight: 600,
},
largeText: {
fontSize: 20,
fontWeight: 700,
letterSpacing: 0.5,
},
mediumText: {
fontSize: 15,
fontWeight: 500,
},
smallText: {
fontSize: 13,
},
verySmallText: {
fontSize: 12,
},
tinyText: {
fontSize: 10,
},
page: {
flex: 1,
'@media (max-height: 550px)': {
minHeight: 700, // ensure we can scroll on small screens
},
paddingTop: 8, // height of the titlebar
[`@media (min-width: ${tokens.breakpoint_small})`]: {
paddingTop: 36,
},
},
pageContent: {
paddingLeft: 2,
paddingRight: 2,
[`@media (min-width: ${tokens.breakpoint_small})`]: {
paddingLeft: 20,
paddingRight: 20,
},
},
settingsPageContent: {
padding: 20,
[`@media (min-width: ${tokens.breakpoint_small})`]: {
padding: 'inherit',
},
},
staticText: {
cursor: 'default',
userSelect: 'none',
},
shadow: {
boxShadow: '0 2px 4px 0 rgba(0,0,0,0.1)',
},
shadowLarge,
tnum: {
// eslint-disable-next-line rulesdir/typography
fontFeatureSettings: '"tnum"',
},
notFixed: { fontFeatureSettings: '' },
text: {
fontSize: 16,
// lineHeight: 22.4 // TODO: This seems like trouble, but what's the right value?
},
delayedFadeIn: {
animationName: keyframes({
'0%': { opacity: 0 },
'100%': { opacity: 1 },
}),
animationDuration: '1s',
animationFillMode: 'both',
animationDelay: '0.5s',
},
underlinedText: {
borderBottom: `2px solid`,
},
noTapHighlight: {
WebkitTapHighlightColor: 'transparent',
':focus': {
outline: 'none',
},
},
lineClamp: (lines: number) => {
return {
display: '-webkit-box',
WebkitLineClamp: lines,
WebkitBoxOrient: 'vertical',
overflow: 'hidden',
textOverflow: 'ellipsis',
wordBreak: 'break-word',
};
},
tooltip: {
padding: 5,
...shadowLarge,
borderWidth: 2,
borderRadius: 4,
borderStyle: 'solid',
borderColor: theme.tooltipBorder,
backgroundColor: theme.tooltipBackground,
color: theme.tooltipText,
overflow: 'auto',
},
popover: {
border: 'none',
backgroundColor: theme.menuBackground,
color: theme.menuItemText,
},
// Dynamically set
horizontalScrollbar: null as CSSProperties | null,
lightScrollbar: null as CSSProperties | null,
darkScrollbar: null as CSSProperties | null,
scrollbarWidth: null as number | null,
};

View File

@@ -0,0 +1,203 @@
export const theme = {
pageBackground: 'var(--color-pageBackground)',
pageBackgroundModalActive: 'var(--color-pageBackgroundModalActive)',
pageBackgroundTopLeft: 'var(--color-pageBackgroundTopLeft)',
pageBackgroundBottomRight: 'var(--color-pageBackgroundBottomRight)',
pageBackgroundLineTop: 'var(--color-pageBackgroundLineTop)',
pageBackgroundLineMid: 'var(--color-pageBackgroundLineMid)',
pageBackgroundLineBottom: 'var(--color-pageBackgroundLineBottom)',
pageText: 'var(--color-pageText)',
pageTextLight: 'var(--color-pageTextLight)',
pageTextSubdued: 'var(--color-pageTextSubdued)',
pageTextDark: 'var(--color-pageTextDark)',
pageTextPositive: 'var(--color-pageTextPositive)',
pageTextLink: 'var(--color-pageTextLink)',
pageTextLinkLight: 'var(--color-pageTextLinkLight)',
cardBackground: 'var(--color-cardBackground)',
cardBorder: 'var(--color-cardBorder)',
cardShadow: 'var(--color-cardShadow)',
tableBackground: 'var(--color-tableBackground)',
tableRowBackgroundHover: 'var(--color-tableRowBackgroundHover)',
tableText: 'var(--color-tableText)',
tableTextLight: 'var(--color-tableTextLight)',
tableTextSubdued: 'var(--color-tableTextSubdued)',
tableTextSelected: 'var(--color-tableTextSelected)',
tableTextHover: 'var(--color-tableTextHover)',
tableTextInactive: 'var(--color-tableTextInactive)',
tableHeaderText: 'var(--color-tableHeaderText)',
tableHeaderBackground: 'var(--color-tableHeaderBackground)',
tableBorder: 'var(--color-tableBorder)',
tableBorderSelected: 'var(--color-tableBorderSelected)',
tableBorderHover: 'var(--color-tableBorderHover)',
tableBorderSeparator: 'var(--color-tableBorderSeparator)',
tableRowBackgroundHighlight: 'var(--color-tableRowBackgroundHighlight)',
tableRowBackgroundHighlightText:
'var(--color-tableRowBackgroundHighlightText)',
tableRowHeaderBackground: 'var(--color-tableRowHeaderBackground)',
tableRowHeaderText: 'var(--color-tableRowHeaderText)',
sidebarBackground: 'var(--color-sidebarBackground)',
sidebarItemBackgroundPending: 'var(--color-sidebarItemBackgroundPending)',
sidebarItemBackgroundPositive: 'var(--color-sidebarItemBackgroundPositive)',
sidebarItemBackgroundFailed: 'var(--color-sidebarItemBackgroundFailed)',
sidebarItemAccentSelected: 'var(--color-sidebarItemAccentSelected)',
sidebarItemBackgroundHover: 'var(--color-sidebarItemBackgroundHover)',
sidebarItemText: 'var(--color-sidebarItemText)',
sidebarItemTextSelected: 'var(--color-sidebarItemTextSelected)',
menuBackground: 'var(--color-menuBackground)',
menuItemBackground: 'var(--color-menuItemBackground)',
menuItemBackgroundHover: 'var(--color-menuItemBackgroundHover)',
menuItemText: 'var(--color-menuItemText)',
menuItemTextHover: 'var(--color-menuItemTextHover)',
menuItemTextSelected: 'var(--color-menuItemTextSelected)',
menuItemTextHeader: 'var(--color-menuItemTextHeader)',
menuBorder: 'var(--color-menuBorder)',
menuBorderHover: 'var(--color-menuBorderHover)',
menuKeybindingText: 'var(--color-menuKeybindingText)',
menuAutoCompleteBackground: 'var(--color-menuAutoCompleteBackground)',
menuAutoCompleteBackgroundHover:
'var(--color-menuAutoCompleteBackgroundHover)',
menuAutoCompleteText: 'var(--color-menuAutoCompleteText)',
menuAutoCompleteTextHover: 'var(--color-menuAutoCompleteTextHover)',
menuAutoCompleteTextHeader: 'var(--color-menuAutoCompleteTextHeader)',
menuAutoCompleteItemTextHover: 'var(--color-menuAutoCompleteItemTextHover)',
menuAutoCompleteItemText: 'var(--color-menuAutoCompleteItemText)',
modalBackground: 'var(--color-modalBackground)',
modalBorder: 'var(--color-modalBorder)',
mobileHeaderBackground: 'var(--color-mobileHeaderBackground)',
mobileHeaderText: 'var(--color-mobileHeaderText)',
mobileHeaderTextSubdued: 'var(--color-mobileHeaderTextSubdued)',
mobileHeaderTextHover: 'var(--color-mobileHeaderTextHover)',
mobilePageBackground: 'var(--color-mobilePageBackground)',
mobileNavBackground: 'var(--color-mobileNavBackground)',
mobileNavItem: 'var(--color-mobileNavItem)',
mobileNavItemSelected: 'var(--color-mobileNavItemSelected)',
mobileAccountShadow: 'var(--color-mobileAccountShadow)',
mobileAccountText: 'var(--color-mobileAccountText)',
mobileTransactionSelected: 'var(--color-mobileTransactionSelected)',
mobileViewTheme: 'var(--color-mobileViewTheme)',
mobileConfigServerViewTheme: 'var(--color-mobileConfigServerViewTheme)',
markdownNormal: 'var(--color-markdownNormal)',
markdownDark: 'var(--color-markdownDark)',
markdownLight: 'var(--color-markdownLight)',
buttonMenuText: 'var(--color-buttonMenuText)',
buttonMenuTextHover: 'var(--color-buttonMenuTextHover)',
buttonMenuBackground: 'var(--color-buttonMenuBackground)',
buttonMenuBackgroundHover: 'var(--color-buttonMenuBackgroundHover)',
buttonMenuBorder: 'var(--color-buttonMenuBorder)',
buttonMenuSelectedText: 'var(--color-buttonMenuSelectedText)',
buttonMenuSelectedTextHover: 'var(--color-buttonMenuSelectedTextHover)',
buttonMenuSelectedBackground: 'var(--color-buttonMenuSelectedBackground)',
buttonMenuSelectedBackgroundHover:
'var(--color-buttonMenuSelectedBackgroundHover)',
buttonMenuSelectedBorder: 'var(--color-buttonMenuSelectedBorder)',
buttonPrimaryText: 'var(--color-buttonPrimaryText)',
buttonPrimaryTextHover: 'var(--color-buttonPrimaryTextHover)',
buttonPrimaryBackground: 'var(--color-buttonPrimaryBackground)',
buttonPrimaryBackgroundHover: 'var(--color-buttonPrimaryBackgroundHover)',
buttonPrimaryBorder: 'var(--color-buttonPrimaryBorder)',
buttonPrimaryShadow: 'var(--color-buttonPrimaryShadow)',
buttonPrimaryDisabledText: 'var(--color-buttonPrimaryDisabledText)',
buttonPrimaryDisabledBackground:
'var(--color-buttonPrimaryDisabledBackground)',
buttonPrimaryDisabledBorder: 'var(--color-buttonPrimaryDisabledBorder)',
buttonNormalText: 'var(--color-buttonNormalText)',
buttonNormalTextHover: 'var(--color-buttonNormalTextHover)',
buttonNormalBackground: 'var(--color-buttonNormalBackground)',
buttonNormalBackgroundHover: 'var(--color-buttonNormalBackgroundHover)',
buttonNormalBorder: 'var(--color-buttonNormalBorder)',
buttonNormalShadow: 'var(--color-buttonNormalShadow)',
buttonNormalSelectedText: 'var(--color-buttonNormalSelectedText)',
buttonNormalSelectedBackground: 'var(--color-buttonNormalSelectedBackground)',
buttonNormalDisabledText: 'var(--color-buttonNormalDisabledText)',
buttonNormalDisabledBackground: 'var(--color-buttonNormalDisabledBackground)',
buttonNormalDisabledBorder: 'var(--color-buttonNormalDisabledBorder)',
buttonBareText: 'var(--color-buttonBareText)',
buttonBareTextHover: 'var(--color-buttonBareTextHover)',
buttonBareBackground: 'var(--color-buttonBareBackground)',
buttonBareBackgroundHover: 'var(--color-buttonBareBackgroundHover)',
buttonBareBackgroundActive: 'var(--color-buttonBareBackgroundActive)',
buttonBareDisabledText: 'var(--color-buttonBareDisabledText)',
buttonBareDisabledBackground: 'var(--color-buttonBareDisabledBackground)',
calendarText: 'var(--color-calendarText)',
calendarBackground: 'var(--color-calendarBackground)',
calendarItemText: 'var(--color-calendarItemText)',
calendarItemBackground: 'var(--color-calendarItemBackground)',
calendarSelectedBackground: 'var(--color-calendarSelectedBackground)',
noticeBackground: 'var(--color-noticeBackground)',
noticeBackgroundLight: 'var(--color-noticeBackgroundLight)',
noticeBackgroundDark: 'var(--color-noticeBackgroundDark)',
noticeText: 'var(--color-noticeText)',
noticeTextLight: 'var(--color-noticeTextLight)',
noticeTextDark: 'var(--color-noticeTextDark)',
noticeTextMenu: 'var(--color-noticeTextMenu)',
noticeTextMenuHover: 'var(--color-noticeTextMenuHover)',
noticeBorder: 'var(--color-noticeBorder)',
warningBackground: 'var(--color-warningBackground)',
warningText: 'var(--color-warningText)',
warningTextLight: 'var(--color-warningTextLight)',
warningTextDark: 'var(--color-warningTextDark)',
warningBorder: 'var(--color-warningBorder)',
errorBackground: 'var(--color-errorBackground)',
errorText: 'var(--color-errorText)',
errorTextDark: 'var(--color-errorTextDark)',
errorTextDarker: 'var(--color-errorTextDarker)',
errorTextMenu: 'var(--color-errorTextMenu)',
errorBorder: 'var(--color-errorBorder)',
upcomingBackground: 'var(--color-upcomingBackground)',
upcomingText: 'var(--color-upcomingText)',
upcomingBorder: 'var(--color-upcomingBorder)',
formLabelText: 'var(--color-formLabelText)',
formLabelBackground: 'var(--color-formLabelBackground)',
formInputBackground: 'var(--color-formInputBackground)',
formInputBackgroundSelected: 'var(--color-formInputBackgroundSelected)',
formInputBackgroundSelection: 'var(--color-formInputBackgroundSelection)',
formInputBorder: 'var(--color-formInputBorder)',
formInputTextReadOnlySelection: 'var(--color-formInputTextReadOnlySelection)',
formInputBorderSelected: 'var(--color-formInputBorderSelected)',
formInputText: 'var(--color-formInputText)',
formInputTextSelected: 'var(--color-formInputTextSelected)',
formInputTextPlaceholder: 'var(--color-formInputTextPlaceholder)',
formInputTextPlaceholderSelected:
'var(--color-formInputTextPlaceholderSelected)',
formInputTextSelection: 'var(--color-formInputTextSelection)',
formInputShadowSelected: 'var(--color-formInputShadowSelected)',
formInputTextHighlight: 'var(--color-formInputTextHighlight)',
checkboxText: 'var(--color-checkboxText)',
checkboxBackgroundSelected: 'var(--color-checkboxBackgroundSelected)',
checkboxBorderSelected: 'var(--color-checkboxBorderSelected)',
checkboxShadowSelected: 'var(--color-checkboxShadowSelected)',
checkboxToggleBackground: 'var(--color-checkboxToggleBackground)',
checkboxToggleBackgroundSelected:
'var(--color-checkboxToggleBackgroundSelected)',
checkboxToggleDisabled: 'var(--color-checkboxToggleDisabled)',
pillBackground: 'var(--color-pillBackground)',
pillBackgroundLight: 'var(--color-pillBackgroundLight)',
pillText: 'var(--color-pillText)',
pillTextHighlighted: 'var(--color-pillTextHighlighted)',
pillBorder: 'var(--color-pillBorder)',
pillBorderDark: 'var(--color-pillBorderDark)',
pillBackgroundSelected: 'var(--color-pillBackgroundSelected)',
pillTextSelected: 'var(--color-pillTextSelected)',
pillBorderSelected: 'var(--color-pillBorderSelected)',
pillTextSubdued: 'var(--color-pillTextSubdued)',
reportsRed: 'var(--color-reportsRed)',
reportsBlue: 'var(--color-reportsBlue)',
reportsGreen: 'var(--color-reportsGreen)',
reportsGray: 'var(--color-reportsGray)',
reportsLabel: 'var(--color-reportsLabel)',
reportsInnerLabel: 'var(--color-reportsInnerLabel)',
noteTagBackground: 'var(--color-noteTagBackground)',
noteTagBackgroundHover: 'var(--color-noteTagBackgroundHover)',
noteTagText: 'var(--color-noteTagText)',
budgetOtherMonth: 'var(--color-budgetOtherMonth)',
budgetCurrentMonth: 'var(--color-budgetCurrentMonth)',
budgetHeaderOtherMonth: 'var(--color-budgetHeaderOtherMonth)',
budgetHeaderCurrentMonth: 'var(--color-budgetHeaderCurrentMonth)',
floatingActionBarBackground: 'var(--color-floatingActionBarBackground)',
floatingActionBarBorder: 'var(--color-floatingActionBarBorder)',
floatingActionBarText: 'var(--color-floatingActionBarText)',
tooltipText: 'var(--color-tooltipText)',
tooltipBackground: 'var(--color-tooltipBackground)',
tooltipBorder: 'var(--color-tooltipBorder)',
calendarCellBackground: 'var(--color-calendarCellBackground)',
};

View File

@@ -0,0 +1,35 @@
enum BreakpointNames {
small = 'small',
medium = 'medium',
wide = 'wide',
}
type NumericBreakpoints = {
[key in BreakpointNames]: number;
};
export const breakpoints: NumericBreakpoints = {
small: 512,
medium: 730,
wide: 1100,
};
type BreakpointsPx = {
[B in keyof NumericBreakpoints as `breakpoint_${B}`]: string;
};
// Provide the same breakpoints in a form usable by CSS media queries
// {
// breakpoint_small: '512px',
// breakpoint_medium: '740px',
// breakpoint_wide: '1100px',
// }
export const tokens: BreakpointsPx = Object.entries(
breakpoints,
).reduce<BreakpointsPx>(
(acc, [key, val]) => ({
...acc,
[`breakpoint_${key}`]: `${val}px`,
}),
{} as BreakpointsPx,
);

View File

@@ -6,6 +6,7 @@
"build"
],
"devDependencies": {
"@actual-app/components": "workspace:*",
"@emotion/css": "^11.13.4",
"@fontsource/redacted-script": "^5.0.21",
"@juggle/resize-observer": "^3.4.0",

View File

@@ -1,16 +1,17 @@
import React, { useState, type ReactNode } from 'react';
import { useTranslation, Trans } from 'react-i18next';
import { Button } from '@actual-app/components/button';
import { View } from '@actual-app/components/view';
import { LazyLoadFailedError } from 'loot-core/src/shared/errors';
import { Block } from './common/Block';
import { Button } from './common/Button2';
import { Link } from './common/Link';
import { Modal, ModalHeader } from './common/Modal';
import { Paragraph } from './common/Paragraph';
import { Stack } from './common/Stack';
import { Text } from './common/Text';
import { View } from './common/View';
import { Checkbox } from './forms';
type AppError = Error & {

View File

@@ -118,6 +118,7 @@ const _getActiveStyles = (type: ButtonType, bounce: boolean): CSSProperties => {
}
};
/** @deprecated please use `import { Button } from '@actual-app/components/button';` */
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
(
{

View File

@@ -0,0 +1,10 @@
import {
Button as ActualComponentButton,
ButtonWithLoading as ActualComponentButtonWithLoading,
} from '@actual-app/components/button';
/** @deprecated please import Button from '@actual-app/components/button' */
export const Button = ActualComponentButton;
/** @deprecated please import ButtonWithLoading from '@actual-app/components/button' */
export const ButtonWithLoading = ActualComponentButtonWithLoading;

View File

@@ -0,0 +1,4 @@
import { View as ActualComponentView } from '@actual-app/components/view';
/** @deprecated please import View from '@actual-app/components/view' */
export const View = ActualComponentView;

View File

@@ -1,26 +1 @@
import React, { type SVGProps } from 'react';
import { css, keyframes } from '@emotion/css';
import { SvgLoading } from './Loading';
const rotation = keyframes({
'0%': { transform: 'rotate(-90deg)' },
'100%': { transform: 'rotate(666deg)' },
});
export function AnimatedLoading(props: SVGProps<SVGSVGElement>) {
return (
<span
className={css({
animationName: rotation,
animationDuration: '1.6s',
animationTimingFunction: 'cubic-bezier(0.17, 0.67, 0.83, 0.67)',
animationIterationCount: 'infinite',
lineHeight: 0,
})}
>
<SvgLoading {...props} />
</span>
);
}
export * from '@actual-app/components/icons/AnimatedLoading';

View File

@@ -1,158 +1,12 @@
// @ts-strict-ignore
import { keyframes } from '@emotion/css';
import { styles as baseStyles } from '@actual-app/components/styles';
import * as Platform from 'loot-core/src/client/platform';
import { tokens } from '../tokens';
export { type CSSProperties } from '@actual-app/components/styles';
import { theme } from './theme';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type CSSProperties = Record<string, any>;
const MOBILE_MIN_HEIGHT = 40;
const shadowLarge = {
boxShadow: '0 15px 30px 0 rgba(0,0,0,0.11), 0 5px 15px 0 rgba(0,0,0,0.08)',
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const styles: Record<string, any> = {
incomeHeaderHeight: 70,
cardShadow: '0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24)',
monthRightPadding: 5,
menuBorderRadius: 4,
mobileMinHeight: MOBILE_MIN_HEIGHT,
mobileMenuItem: {
fontSize: 17,
fontWeight: 400,
paddingTop: 8,
paddingBottom: 8,
height: MOBILE_MIN_HEIGHT,
minHeight: MOBILE_MIN_HEIGHT,
},
mobileEditingPadding: 12,
altMenuMaxHeight: 250,
altMenuText: {
fontSize: 13,
},
altMenuHeaderText: {
fontSize: 13,
fontWeight: 700,
},
veryLargeText: {
fontSize: 30,
fontWeight: 600,
},
largeText: {
fontSize: 20,
fontWeight: 700,
letterSpacing: 0.5,
},
mediumText: {
fontSize: 15,
fontWeight: 500,
},
smallText: {
fontSize: 13,
},
verySmallText: {
fontSize: 12,
},
tinyText: {
fontSize: 10,
},
page: {
flex: 1,
'@media (max-height: 550px)': {
minHeight: 700, // ensure we can scroll on small screens
},
paddingTop: 8, // height of the titlebar
[`@media (min-width: ${tokens.breakpoint_small})`]: {
paddingTop: 36,
},
},
pageContent: {
paddingLeft: 2,
paddingRight: 2,
[`@media (min-width: ${tokens.breakpoint_small})`]: {
paddingLeft: 20,
paddingRight: 20,
},
},
settingsPageContent: {
padding: 20,
[`@media (min-width: ${tokens.breakpoint_small})`]: {
padding: 'inherit',
},
},
staticText: {
cursor: 'default',
userSelect: 'none',
},
shadow: {
boxShadow: '0 2px 4px 0 rgba(0,0,0,0.1)',
},
shadowLarge,
tnum: {
// eslint-disable-next-line rulesdir/typography
fontFeatureSettings: '"tnum"',
},
notFixed: { fontFeatureSettings: '' },
text: {
fontSize: 16,
// lineHeight: 22.4 // TODO: This seems like trouble, but what's the right value?
},
delayedFadeIn: {
animationName: keyframes({
'0%': { opacity: 0 },
'100%': { opacity: 1 },
}),
animationDuration: '1s',
animationFillMode: 'both',
animationDelay: '0.5s',
},
underlinedText: {
borderBottom: `2px solid`,
},
noTapHighlight: {
WebkitTapHighlightColor: 'transparent',
':focus': {
outline: 'none',
},
},
lineClamp: (lines: number) => {
return {
display: '-webkit-box',
WebkitLineClamp: lines,
WebkitBoxOrient: 'vertical',
overflow: 'hidden',
textOverflow: 'ellipsis',
wordBreak: 'break-word',
};
},
tooltip: {
padding: 5,
...shadowLarge,
borderWidth: 2,
borderRadius: 4,
borderStyle: 'solid',
borderColor: theme.tooltipBorder,
backgroundColor: theme.tooltipBackground,
color: theme.tooltipText,
overflow: 'auto',
},
popover: {
border: 'none',
backgroundColor: theme.menuBackground,
color: theme.menuItemText,
},
// Dynamically set
horizontalScrollbar: null as CSSProperties | null,
lightScrollbar: null as CSSProperties | null,
darkScrollbar: null as CSSProperties | null,
scrollbarWidth: null as number | null,
};
/** @deprecated please import styles from '@actual-app/components/styles' */
export const styles = baseStyles;
let hiddenScrollbars = false;

View File

@@ -96,206 +96,4 @@ export function ThemeStyle() {
return <style>{`:root {\n${css}}`}</style>;
}
export const theme = {
pageBackground: 'var(--color-pageBackground)',
pageBackgroundModalActive: 'var(--color-pageBackgroundModalActive)',
pageBackgroundTopLeft: 'var(--color-pageBackgroundTopLeft)',
pageBackgroundBottomRight: 'var(--color-pageBackgroundBottomRight)',
pageBackgroundLineTop: 'var(--color-pageBackgroundLineTop)',
pageBackgroundLineMid: 'var(--color-pageBackgroundLineMid)',
pageBackgroundLineBottom: 'var(--color-pageBackgroundLineBottom)',
pageText: 'var(--color-pageText)',
pageTextLight: 'var(--color-pageTextLight)',
pageTextSubdued: 'var(--color-pageTextSubdued)',
pageTextDark: 'var(--color-pageTextDark)',
pageTextPositive: 'var(--color-pageTextPositive)',
pageTextLink: 'var(--color-pageTextLink)',
pageTextLinkLight: 'var(--color-pageTextLinkLight)',
cardBackground: 'var(--color-cardBackground)',
cardBorder: 'var(--color-cardBorder)',
cardShadow: 'var(--color-cardShadow)',
tableBackground: 'var(--color-tableBackground)',
tableRowBackgroundHover: 'var(--color-tableRowBackgroundHover)',
tableText: 'var(--color-tableText)',
tableTextLight: 'var(--color-tableTextLight)',
tableTextSubdued: 'var(--color-tableTextSubdued)',
tableTextSelected: 'var(--color-tableTextSelected)',
tableTextHover: 'var(--color-tableTextHover)',
tableTextInactive: 'var(--color-tableTextInactive)',
tableHeaderText: 'var(--color-tableHeaderText)',
tableHeaderBackground: 'var(--color-tableHeaderBackground)',
tableBorder: 'var(--color-tableBorder)',
tableBorderSelected: 'var(--color-tableBorderSelected)',
tableBorderHover: 'var(--color-tableBorderHover)',
tableBorderSeparator: 'var(--color-tableBorderSeparator)',
tableRowBackgroundHighlight: 'var(--color-tableRowBackgroundHighlight)',
tableRowBackgroundHighlightText:
'var(--color-tableRowBackgroundHighlightText)',
tableRowHeaderBackground: 'var(--color-tableRowHeaderBackground)',
tableRowHeaderText: 'var(--color-tableRowHeaderText)',
sidebarBackground: 'var(--color-sidebarBackground)',
sidebarItemBackgroundPending: 'var(--color-sidebarItemBackgroundPending)',
sidebarItemBackgroundPositive: 'var(--color-sidebarItemBackgroundPositive)',
sidebarItemBackgroundFailed: 'var(--color-sidebarItemBackgroundFailed)',
sidebarItemAccentSelected: 'var(--color-sidebarItemAccentSelected)',
sidebarItemBackgroundHover: 'var(--color-sidebarItemBackgroundHover)',
sidebarItemText: 'var(--color-sidebarItemText)',
sidebarItemTextSelected: 'var(--color-sidebarItemTextSelected)',
menuBackground: 'var(--color-menuBackground)',
menuItemBackground: 'var(--color-menuItemBackground)',
menuItemBackgroundHover: 'var(--color-menuItemBackgroundHover)',
menuItemText: 'var(--color-menuItemText)',
menuItemTextHover: 'var(--color-menuItemTextHover)',
menuItemTextSelected: 'var(--color-menuItemTextSelected)',
menuItemTextHeader: 'var(--color-menuItemTextHeader)',
menuBorder: 'var(--color-menuBorder)',
menuBorderHover: 'var(--color-menuBorderHover)',
menuKeybindingText: 'var(--color-menuKeybindingText)',
menuAutoCompleteBackground: 'var(--color-menuAutoCompleteBackground)',
menuAutoCompleteBackgroundHover:
'var(--color-menuAutoCompleteBackgroundHover)',
menuAutoCompleteText: 'var(--color-menuAutoCompleteText)',
menuAutoCompleteTextHover: 'var(--color-menuAutoCompleteTextHover)',
menuAutoCompleteTextHeader: 'var(--color-menuAutoCompleteTextHeader)',
menuAutoCompleteItemTextHover: 'var(--color-menuAutoCompleteItemTextHover)',
menuAutoCompleteItemText: 'var(--color-menuAutoCompleteItemText)',
modalBackground: 'var(--color-modalBackground)',
modalBorder: 'var(--color-modalBorder)',
mobileHeaderBackground: 'var(--color-mobileHeaderBackground)',
mobileHeaderText: 'var(--color-mobileHeaderText)',
mobileHeaderTextSubdued: 'var(--color-mobileHeaderTextSubdued)',
mobileHeaderTextHover: 'var(--color-mobileHeaderTextHover)',
mobilePageBackground: 'var(--color-mobilePageBackground)',
mobileNavBackground: 'var(--color-mobileNavBackground)',
mobileNavItem: 'var(--color-mobileNavItem)',
mobileNavItemSelected: 'var(--color-mobileNavItemSelected)',
mobileAccountShadow: 'var(--color-mobileAccountShadow)',
mobileAccountText: 'var(--color-mobileAccountText)',
mobileTransactionSelected: 'var(--color-mobileTransactionSelected)',
mobileViewTheme: 'var(--color-mobileViewTheme)',
mobileConfigServerViewTheme: 'var(--color-mobileConfigServerViewTheme)',
markdownNormal: 'var(--color-markdownNormal)',
markdownDark: 'var(--color-markdownDark)',
markdownLight: 'var(--color-markdownLight)',
buttonMenuText: 'var(--color-buttonMenuText)',
buttonMenuTextHover: 'var(--color-buttonMenuTextHover)',
buttonMenuBackground: 'var(--color-buttonMenuBackground)',
buttonMenuBackgroundHover: 'var(--color-buttonMenuBackgroundHover)',
buttonMenuBorder: 'var(--color-buttonMenuBorder)',
buttonMenuSelectedText: 'var(--color-buttonMenuSelectedText)',
buttonMenuSelectedTextHover: 'var(--color-buttonMenuSelectedTextHover)',
buttonMenuSelectedBackground: 'var(--color-buttonMenuSelectedBackground)',
buttonMenuSelectedBackgroundHover:
'var(--color-buttonMenuSelectedBackgroundHover)',
buttonMenuSelectedBorder: 'var(--color-buttonMenuSelectedBorder)',
buttonPrimaryText: 'var(--color-buttonPrimaryText)',
buttonPrimaryTextHover: 'var(--color-buttonPrimaryTextHover)',
buttonPrimaryBackground: 'var(--color-buttonPrimaryBackground)',
buttonPrimaryBackgroundHover: 'var(--color-buttonPrimaryBackgroundHover)',
buttonPrimaryBorder: 'var(--color-buttonPrimaryBorder)',
buttonPrimaryShadow: 'var(--color-buttonPrimaryShadow)',
buttonPrimaryDisabledText: 'var(--color-buttonPrimaryDisabledText)',
buttonPrimaryDisabledBackground:
'var(--color-buttonPrimaryDisabledBackground)',
buttonPrimaryDisabledBorder: 'var(--color-buttonPrimaryDisabledBorder)',
buttonNormalText: 'var(--color-buttonNormalText)',
buttonNormalTextHover: 'var(--color-buttonNormalTextHover)',
buttonNormalBackground: 'var(--color-buttonNormalBackground)',
buttonNormalBackgroundHover: 'var(--color-buttonNormalBackgroundHover)',
buttonNormalBorder: 'var(--color-buttonNormalBorder)',
buttonNormalShadow: 'var(--color-buttonNormalShadow)',
buttonNormalSelectedText: 'var(--color-buttonNormalSelectedText)',
buttonNormalSelectedBackground: 'var(--color-buttonNormalSelectedBackground)',
buttonNormalDisabledText: 'var(--color-buttonNormalDisabledText)',
buttonNormalDisabledBackground: 'var(--color-buttonNormalDisabledBackground)',
buttonNormalDisabledBorder: 'var(--color-buttonNormalDisabledBorder)',
buttonBareText: 'var(--color-buttonBareText)',
buttonBareTextHover: 'var(--color-buttonBareTextHover)',
buttonBareBackground: 'var(--color-buttonBareBackground)',
buttonBareBackgroundHover: 'var(--color-buttonBareBackgroundHover)',
buttonBareBackgroundActive: 'var(--color-buttonBareBackgroundActive)',
buttonBareDisabledText: 'var(--color-buttonBareDisabledText)',
buttonBareDisabledBackground: 'var(--color-buttonBareDisabledBackground)',
calendarText: 'var(--color-calendarText)',
calendarBackground: 'var(--color-calendarBackground)',
calendarItemText: 'var(--color-calendarItemText)',
calendarItemBackground: 'var(--color-calendarItemBackground)',
calendarSelectedBackground: 'var(--color-calendarSelectedBackground)',
noticeBackground: 'var(--color-noticeBackground)',
noticeBackgroundLight: 'var(--color-noticeBackgroundLight)',
noticeBackgroundDark: 'var(--color-noticeBackgroundDark)',
noticeText: 'var(--color-noticeText)',
noticeTextLight: 'var(--color-noticeTextLight)',
noticeTextDark: 'var(--color-noticeTextDark)',
noticeTextMenu: 'var(--color-noticeTextMenu)',
noticeTextMenuHover: 'var(--color-noticeTextMenuHover)',
noticeBorder: 'var(--color-noticeBorder)',
warningBackground: 'var(--color-warningBackground)',
warningText: 'var(--color-warningText)',
warningTextLight: 'var(--color-warningTextLight)',
warningTextDark: 'var(--color-warningTextDark)',
warningBorder: 'var(--color-warningBorder)',
errorBackground: 'var(--color-errorBackground)',
errorText: 'var(--color-errorText)',
errorTextDark: 'var(--color-errorTextDark)',
errorTextDarker: 'var(--color-errorTextDarker)',
errorTextMenu: 'var(--color-errorTextMenu)',
errorBorder: 'var(--color-errorBorder)',
upcomingBackground: 'var(--color-upcomingBackground)',
upcomingText: 'var(--color-upcomingText)',
upcomingBorder: 'var(--color-upcomingBorder)',
formLabelText: 'var(--color-formLabelText)',
formLabelBackground: 'var(--color-formLabelBackground)',
formInputBackground: 'var(--color-formInputBackground)',
formInputBackgroundSelected: 'var(--color-formInputBackgroundSelected)',
formInputBackgroundSelection: 'var(--color-formInputBackgroundSelection)',
formInputBorder: 'var(--color-formInputBorder)',
formInputTextReadOnlySelection: 'var(--color-formInputTextReadOnlySelection)',
formInputBorderSelected: 'var(--color-formInputBorderSelected)',
formInputText: 'var(--color-formInputText)',
formInputTextSelected: 'var(--color-formInputTextSelected)',
formInputTextPlaceholder: 'var(--color-formInputTextPlaceholder)',
formInputTextPlaceholderSelected:
'var(--color-formInputTextPlaceholderSelected)',
formInputTextSelection: 'var(--color-formInputTextSelection)',
formInputShadowSelected: 'var(--color-formInputShadowSelected)',
formInputTextHighlight: 'var(--color-formInputTextHighlight)',
checkboxText: 'var(--color-checkboxText)',
checkboxBackgroundSelected: 'var(--color-checkboxBackgroundSelected)',
checkboxBorderSelected: 'var(--color-checkboxBorderSelected)',
checkboxShadowSelected: 'var(--color-checkboxShadowSelected)',
checkboxToggleBackground: 'var(--color-checkboxToggleBackground)',
checkboxToggleBackgroundSelected:
'var(--color-checkboxToggleBackgroundSelected)',
checkboxToggleDisabled: 'var(--color-checkboxToggleDisabled)',
pillBackground: 'var(--color-pillBackground)',
pillBackgroundLight: 'var(--color-pillBackgroundLight)',
pillText: 'var(--color-pillText)',
pillTextHighlighted: 'var(--color-pillTextHighlighted)',
pillBorder: 'var(--color-pillBorder)',
pillBorderDark: 'var(--color-pillBorderDark)',
pillBackgroundSelected: 'var(--color-pillBackgroundSelected)',
pillTextSelected: 'var(--color-pillTextSelected)',
pillBorderSelected: 'var(--color-pillBorderSelected)',
pillTextSubdued: 'var(--color-pillTextSubdued)',
reportsRed: 'var(--color-reportsRed)',
reportsBlue: 'var(--color-reportsBlue)',
reportsGreen: 'var(--color-reportsGreen)',
reportsGray: 'var(--color-reportsGray)',
reportsLabel: 'var(--color-reportsLabel)',
reportsInnerLabel: 'var(--color-reportsInnerLabel)',
noteTagBackground: 'var(--color-noteTagBackground)',
noteTagBackgroundHover: 'var(--color-noteTagBackgroundHover)',
noteTagText: 'var(--color-noteTagText)',
budgetOtherMonth: 'var(--color-budgetOtherMonth)',
budgetCurrentMonth: 'var(--color-budgetCurrentMonth)',
budgetHeaderOtherMonth: 'var(--color-budgetHeaderOtherMonth)',
budgetHeaderCurrentMonth: 'var(--color-budgetHeaderCurrentMonth)',
floatingActionBarBackground: 'var(--color-floatingActionBarBackground)',
floatingActionBarBorder: 'var(--color-floatingActionBarBorder)',
floatingActionBarText: 'var(--color-floatingActionBarText)',
tooltipText: 'var(--color-tooltipText)',
tooltipBackground: 'var(--color-tooltipBackground)',
tooltipBorder: 'var(--color-tooltipBorder)',
calendarCellBackground: 'var(--color-calendarCellBackground)',
};
export * from '@actual-app/components/theme';

View File

@@ -1,35 +1 @@
enum BreakpointNames {
small = 'small',
medium = 'medium',
wide = 'wide',
}
type NumericBreakpoints = {
[key in BreakpointNames]: number;
};
export const breakpoints: NumericBreakpoints = {
small: 512,
medium: 730,
wide: 1100,
};
type BreakpointsPx = {
[B in keyof NumericBreakpoints as `breakpoint_${B}`]: string;
};
// Provide the same breakpoints in a form usable by CSS media queries
// {
// breakpoint_small: '512px',
// breakpoint_medium: '740px',
// breakpoint_wide: '1100px',
// }
export const tokens: BreakpointsPx = Object.entries(
breakpoints,
).reduce<BreakpointsPx>(
(acc, [key, val]) => ({
...acc,
[`breakpoint_${key}`]: `${val}px`,
}),
{} as BreakpointsPx,
);
export * from '@actual-app/components/tokens';

View File

@@ -0,0 +1,6 @@
---
category: Maintenance
authors: [MatissJanis]
---
Introduce `@actual-app/components` - package with reusable components.

View File

@@ -38,6 +38,19 @@ __metadata:
languageName: unknown
linkType: soft
"@actual-app/components@workspace:*, @actual-app/components@workspace:packages/component-library":
version: 0.0.0-use.local
resolution: "@actual-app/components@workspace:packages/component-library"
dependencies:
"@emotion/css": "npm:^11.13.4"
"@types/react": "npm:^18.2.0"
react: "npm:18.2.0"
react-aria-components: "npm:^1.4.1"
peerDependencies:
react: ">=18.2"
languageName: unknown
linkType: soft
"@actual-app/crdt@npm:2.1.0":
version: 2.1.0
resolution: "@actual-app/crdt@npm:2.1.0"
@@ -77,6 +90,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "@actual-app/web@workspace:packages/desktop-client"
dependencies:
"@actual-app/components": "workspace:*"
"@emotion/css": "npm:^11.13.4"
"@fontsource/redacted-script": "npm:^5.0.21"
"@juggle/resize-observer": "npm:^3.4.0"