diff --git a/.eslintrc.js b/.eslintrc.js
index a74991b169..66d145e08e 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -254,6 +254,43 @@ const typescriptRules = {
'import/no-cycle': 'off',
};
+const TAILWIND_REPLACEMENTS = [
+ // inset
+ { pattern: 'left-*', fix: 'start-*' },
+ { pattern: 'right-*', fix: 'end-*' },
+ // margin
+ { pattern: 'ml-*', fix: 'ms-*' },
+ { pattern: 'mr-*', fix: 'me-*' },
+ // padding
+ { pattern: 'pl-*', fix: 'ps-*' },
+ { pattern: 'pr-*', fix: 'pe-*' },
+ // border
+ { pattern: 'border-l-*', fix: 'border-s-*' },
+ { pattern: 'border-r-*', fix: 'border-e-*' },
+ // border-radius
+ { pattern: 'rounded-l', fix: 'rounded-s' },
+ { pattern: 'rounded-r', fix: 'rounded-e' },
+ { pattern: 'rounded-tl', fix: 'rounded-ss' },
+ { pattern: 'rounded-tr', fix: 'rounded-se' },
+ { pattern: 'rounded-bl', fix: 'rounded-es' },
+ { pattern: 'rounded-br', fix: 'rounded-ee' },
+ { pattern: 'rounded-l-*', fix: 'rounded-s-*' },
+ { pattern: 'rounded-r-*', fix: 'rounded-e-*' },
+ { pattern: 'rounded-tl-*', fix: 'rounded-ss-*' },
+ { pattern: 'rounded-tr-*', fix: 'rounded-se-*' },
+ { pattern: 'rounded-bl-*', fix: 'rounded-es-*' },
+ { pattern: 'rounded-br-*', fix: 'rounded-ee-*' },
+ // text-align
+ { pattern: 'text-left', fix: 'text-start' },
+ { pattern: 'text-right', fix: 'text-end' },
+ // float
+ { pattern: 'float-left', fix: 'float-start' },
+ { pattern: 'float-right', fix: 'float-end' },
+ // clear
+ { pattern: 'clear-left', fix: 'clear-start' },
+ { pattern: 'clear-right', fix: 'clear-end' },
+];
+
module.exports = {
root: true,
settings: {
@@ -377,6 +414,15 @@ module.exports = {
pattern: '^\\*+:.*', // ex: "*:mx-0",
message: 'No child variants',
},
+ ...TAILWIND_REPLACEMENTS.map(item => {
+ const pattern = item.pattern.replace('*', '(.*)');
+ const fix = item.fix.replace('*', '$2');
+ return {
+ message: `Use logical property ${item.fix} instead of ${item.pattern}`,
+ pattern: `^(.*:)?${pattern}$`,
+ fix: `$1${fix}`,
+ };
+ }),
],
},
],
diff --git a/.prettierrc.js b/.prettierrc.js
index 3500e8cd2c..ebff2fb615 100644
--- a/.prettierrc.js
+++ b/.prettierrc.js
@@ -3,17 +3,11 @@
/** @type {import("prettier").Config} */
module.exports = {
+ plugins: ['prettier-plugin-tailwindcss'],
singleQuote: true,
arrowParens: 'avoid',
trailingComma: 'es5',
- overrides: [
- {
- files: ['./ts/axo/**.tsx'],
- plugins: ['prettier-plugin-tailwindcss'],
- options: {
- tailwindStylesheet: './stylesheets/tailwind-config.css',
- tailwindFunctions: ['tw'],
- },
- },
- ],
+ tailwindStylesheet: './stylesheets/tailwind-config.css',
+ tailwindFunctions: ['tw'],
+ tailwindAttributes: [],
};
diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx
index cb9b3bbc09..5815815f44 100644
--- a/.storybook/preview.tsx
+++ b/.storybook/preview.tsx
@@ -17,6 +17,7 @@ import { HourCyclePreference } from '../ts/types/I18N';
import { Provider } from 'react-redux';
import { Store, combineReducers, createStore } from 'redux';
import { Globals } from '@react-spring/web';
+import { AxoProvider } from '../ts/axo/AxoProvider';
import { StateType } from '../ts/state/reducer';
import {
ScrollerLockContext,
@@ -254,8 +255,17 @@ function withFunProvider(Story, context) {
);
}
+function withAxoProvider(Story, context) {
+ return (
+
{Array.from(variant.text, char => {
diff --git a/ts/axo/_internal/AxoBaseMenu.tsx b/ts/axo/_internal/AxoBaseMenu.tsx
index d4ad911e63..542d3891e1 100644
--- a/ts/axo/_internal/AxoBaseMenu.tsx
+++ b/ts/axo/_internal/AxoBaseMenu.tsx
@@ -9,13 +9,16 @@ import { AxoSymbol, type AxoSymbolName } from '../AxoSymbol';
export namespace AxoBaseMenu {
//
const baseContentStyles = tw(
- 'max-w-[300px] min-w-[200px] p-1.5',
+ 'max-w-[300px] min-w-[200px]',
'select-none',
'rounded-xl bg-elevated-background-tertiary shadow-elevation-3',
- 'data-[state=closed]:animate-fade-out'
+ 'data-[state=closed]:animate-fade-out',
+ 'forced-colors:border',
+ 'forced-colors:bg-[Canvas]',
+ 'forced-colors:text-[CanvasText]'
);
- const baseContentGridStyles = tw('grid grid-cols-[min-content_auto]');
+ const baseContentGridStyles = tw('grid grid-cols-[min-content_auto] p-1.5');
//
const baseGroupStyles = tw('col-span-full grid grid-cols-subgrid');
@@ -34,7 +37,12 @@ export namespace AxoBaseMenu {
'rounded-md type-body-medium',
'outline-0 data-[highlighted]:bg-fill-secondary-pressed',
'data-[disabled]:text-label-disabled',
- 'outline-0 outline-border-focused focused:outline-[2.5px]'
+ 'outline-0 outline-border-focused focused:outline-[2.5px]',
+ 'forced-colors:text-[CanvasText]',
+ 'forced-colors:data-[highlighted]:bg-[Highlight]',
+ 'forced-colors:data-[highlighted]:text-[HighlightText]',
+ 'forced-colors:data-[disabled]:text-[GrayText]',
+ 'forced-color-adjust-none'
);
/**
@@ -143,7 +151,10 @@ export namespace AxoBaseMenu {
): JSX.Element {
return (
{props.keyboardShortcut}
@@ -332,7 +343,9 @@ export namespace AxoBaseMenu {
export const menuSubTriggerStyles = tw(
navigableItemStyles,
- 'data-[state=open]:not-data-[highlighted]:bg-fill-secondary'
+ 'data-[state=open]:not-data-[highlighted]:bg-fill-secondary',
+ 'forced-colors:data-[state=open]:not-data-[highlighted]:bg-[Highlight]',
+ 'forced-colors:data-[state=open]:not-data-[highlighted]:text-[HighlightText]'
);
/**
diff --git a/ts/components/CallScreen.tsx b/ts/components/CallScreen.tsx
index dcbf8e542d..3e64e9849b 100644
--- a/ts/components/CallScreen.tsx
+++ b/ts/components/CallScreen.tsx
@@ -946,7 +946,7 @@ export function CallScreen({
{(isConnecting || isRinging) && (
<>
-
+
-
+
{i18n('icu:Preferences--backup-plan-not-found__description')}
@@ -466,7 +466,7 @@ export function renderBackupsSubscriptionSummary({
case 'not-found':
case 'expired':
return (
-
+
{i18n('icu:Preferences--backup-plan-not-found__description')}
diff --git a/ts/components/conversation/TypingBubble.tsx b/ts/components/conversation/TypingBubble.tsx
index 6ab7ecb63e..fcf13becdd 100644
--- a/ts/components/conversation/TypingBubble.tsx
+++ b/ts/components/conversation/TypingBubble.tsx
@@ -209,10 +209,7 @@ function TypingBubbleGroupAvatars({
{typingContactsOverflowCount > 0 && (
-
+
-
-
-
- @
-
-
-
-
+
+
+
+
+ @
+
+
+
+
+
);
diff --git a/ts/shims/renderClearingDataView.tsx b/ts/shims/renderClearingDataView.tsx
index 6684ff6af0..11bd7ff2e0 100644
--- a/ts/shims/renderClearingDataView.tsx
+++ b/ts/shims/renderClearingDataView.tsx
@@ -8,15 +8,18 @@ import { ClearingData } from '../components/ClearingData';
import { strictAssert } from '../util/assert';
import { deleteAllData } from './deleteAllData';
import { FunDefaultEnglishEmojiLocalizationProvider } from '../components/fun/FunEmojiLocalizationProvider';
+import { AxoProvider } from '../axo/AxoProvider';
export function renderClearingDataView(): void {
const appContainer = document.getElementById('app-container');
strictAssert(appContainer != null, 'No #app-container');
createRoot(appContainer).render(
-
-
-
+
+
+
+
+
);
}
diff --git a/ts/state/smart/Preferences.tsx b/ts/state/smart/Preferences.tsx
index 5484be6082..641591c009 100644
--- a/ts/state/smart/Preferences.tsx
+++ b/ts/state/smart/Preferences.tsx
@@ -88,6 +88,7 @@ import { SmartPreferencesChatFoldersPage } from './PreferencesChatFoldersPage';
import type { SmartPreferencesEditChatFolderPageProps } from './PreferencesEditChatFolderPage';
import { SmartPreferencesEditChatFolderPage } from './PreferencesEditChatFolderPage';
import { isProduction } from '../../util/version';
+import { AxoProvider } from '../../axo/AxoProvider';
const DEFAULT_NOTIFICATION_SETTING = 'message';
@@ -740,179 +741,183 @@ export function SmartPreferences(): JSX.Element | null {
return (
-
+
+
+
);
}
diff --git a/ts/util/longRunningTaskWrapper.tsx b/ts/util/longRunningTaskWrapper.tsx
index c965aa3955..d377d38fd9 100644
--- a/ts/util/longRunningTaskWrapper.tsx
+++ b/ts/util/longRunningTaskWrapper.tsx
@@ -10,6 +10,7 @@ import { ProgressModal } from '../components/ProgressModal';
import { clearTimeoutIfNecessary } from './clearTimeoutIfNecessary';
import { sleep } from './sleep';
import { FunDefaultEnglishEmojiLocalizationProvider } from '../components/fun/FunEmojiLocalizationProvider';
+import { AxoProvider } from '../axo/AxoProvider';
const log = createLogger('longRunningTaskWrapper');
@@ -37,9 +38,11 @@ export async function longRunningTaskWrapper({
progressRoot = createRoot(progressNode);
progressRoot.render(
-
-
-
+
+
+
+
+
);
spinnerStart = Date.now();
diff --git a/ts/util/showConfirmationDialog.tsx b/ts/util/showConfirmationDialog.tsx
index 0682e03467..700f5f35cf 100644
--- a/ts/util/showConfirmationDialog.tsx
+++ b/ts/util/showConfirmationDialog.tsx
@@ -5,6 +5,7 @@ import React, { StrictMode } from 'react';
import { createRoot, type Root } from 'react-dom/client';
import { ConfirmationDialog } from '../components/ConfirmationDialog';
import { FunDefaultEnglishEmojiLocalizationProvider } from '../components/fun/FunEmojiLocalizationProvider';
+import { AxoProvider } from '../axo/AxoProvider';
type ConfirmationDialogViewProps = {
onTopOfEverything?: boolean;
@@ -57,37 +58,39 @@ export function showConfirmationDialog(
confirmationDialogRoot = createRoot(confirmationDialogViewNode);
confirmationDialogRoot.render(
-
- {
- options.resolve();
+
+
+ {
+ options.resolve();
+ },
+ style: options.confirmStyle,
+ text: options.okText || window.i18n('icu:ok'),
},
- style: options.confirmStyle,
- text: options.okText || window.i18n('icu:ok'),
- },
- ]}
- cancelText={options.cancelText || window.i18n('icu:cancel')}
- i18n={window.i18n}
- onCancel={() => {
- if (options.reject) {
- options.reject(
- new Error('showConfirmationDialog: onCancel called')
- );
- }
- }}
- onClose={() => {
- removeConfirmationDialog();
- }}
- title={options.title}
- noMouseClose={options.noMouseClose}
- >
- {options.description}
-
-
+ ]}
+ cancelText={options.cancelText || window.i18n('icu:cancel')}
+ i18n={window.i18n}
+ onCancel={() => {
+ if (options.reject) {
+ options.reject(
+ new Error('showConfirmationDialog: onCancel called')
+ );
+ }
+ }}
+ onClose={() => {
+ removeConfirmationDialog();
+ }}
+ title={options.title}
+ noMouseClose={options.noMouseClose}
+ >
+ {options.description}
+
+
+
);
}
diff --git a/ts/windows/about/app.tsx b/ts/windows/about/app.tsx
index 8c024be739..70a32cd8cd 100644
--- a/ts/windows/about/app.tsx
+++ b/ts/windows/about/app.tsx
@@ -8,6 +8,7 @@ import { About } from '../../components/About';
import { i18n } from '../sandboxedInit';
import { strictAssert } from '../../util/assert';
import { FunDefaultEnglishEmojiLocalizationProvider } from '../../components/fun/FunEmojiLocalizationProvider';
+import { AxoProvider } from '../../axo/AxoProvider';
const { AboutWindowProps } = window.Signal;
@@ -18,15 +19,17 @@ strictAssert(app != null, 'No #app');
createRoot(app).render(
-
- window.SignalContext.executeMenuRole('close')}
- appEnv={AboutWindowProps.appEnv}
- platform={AboutWindowProps.platform}
- arch={AboutWindowProps.arch}
- i18n={i18n}
- version={window.SignalContext.getVersion()}
- />
-
+
+
+ window.SignalContext.executeMenuRole('close')}
+ appEnv={AboutWindowProps.appEnv}
+ platform={AboutWindowProps.platform}
+ arch={AboutWindowProps.arch}
+ i18n={i18n}
+ version={window.SignalContext.getVersion()}
+ />
+
+
);
diff --git a/ts/windows/debuglog/app.tsx b/ts/windows/debuglog/app.tsx
index caf8d63f20..2a62fbc4cc 100644
--- a/ts/windows/debuglog/app.tsx
+++ b/ts/windows/debuglog/app.tsx
@@ -7,6 +7,7 @@ import { DebugLogWindow } from '../../components/DebugLogWindow';
import { FunDefaultEnglishEmojiLocalizationProvider } from '../../components/fun/FunEmojiLocalizationProvider';
import { i18n } from '../sandboxedInit';
import { strictAssert } from '../../util/assert';
+import { AxoProvider } from '../../axo/AxoProvider';
const { DebugLogWindowProps } = window.Signal;
@@ -17,14 +18,16 @@ strictAssert(app != null, 'No #app');
createRoot(app).render(
-
- window.SignalContext.executeMenuRole('close')}
- downloadLog={DebugLogWindowProps.downloadLog}
- i18n={i18n}
- fetchLogs={DebugLogWindowProps.fetchLogs}
- uploadLogs={DebugLogWindowProps.uploadLogs}
- />
-
+
+
+ window.SignalContext.executeMenuRole('close')}
+ downloadLog={DebugLogWindowProps.downloadLog}
+ i18n={i18n}
+ fetchLogs={DebugLogWindowProps.fetchLogs}
+ uploadLogs={DebugLogWindowProps.uploadLogs}
+ />
+
+
);
diff --git a/ts/windows/permissions/app.tsx b/ts/windows/permissions/app.tsx
index e5d57f3dcc..00964a1c76 100644
--- a/ts/windows/permissions/app.tsx
+++ b/ts/windows/permissions/app.tsx
@@ -8,6 +8,7 @@ import { PermissionsPopup } from '../../components/PermissionsPopup';
import { i18n } from '../sandboxedInit';
import { strictAssert } from '../../util/assert';
import { FunDefaultEnglishEmojiLocalizationProvider } from '../../components/fun/FunEmojiLocalizationProvider';
+import { AxoProvider } from '../../axo/AxoProvider';
const { PermissionsWindowProps } = window.Signal;
@@ -31,13 +32,15 @@ strictAssert(app != null, 'No #app');
createRoot(app).render(
-
-
-
+
+
+
+
+
);
diff --git a/ts/windows/screenShare/app.tsx b/ts/windows/screenShare/app.tsx
index 18152c33ca..59f75278a1 100644
--- a/ts/windows/screenShare/app.tsx
+++ b/ts/windows/screenShare/app.tsx
@@ -10,6 +10,7 @@ import { strictAssert } from '../../util/assert';
import { drop } from '../../util/drop';
import { parseEnvironment, setEnvironment } from '../../environment';
import { FunDefaultEnglishEmojiLocalizationProvider } from '../../components/fun/FunEmojiLocalizationProvider';
+import { AxoProvider } from '../../axo/AxoProvider';
const { ScreenShareWindowProps } = window.Signal;
@@ -33,17 +34,19 @@ function render() {
createRoot(app).render(
-
-
-
-
-
+
+
+
+
+
+
+
);
}