mirror of
https://github.com/signalapp/Signal-Desktop.git
synced 2025-12-20 02:08:57 +00:00
Init AxoSwitch/AxoCheckbox & forced-colors mode
This commit is contained in:
46
.eslintrc.js
46
.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}`,
|
||||
};
|
||||
}),
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -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'],
|
||||
},
|
||||
},
|
||||
],
|
||||
tailwindAttributes: [],
|
||||
};
|
||||
|
||||
@@ -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 (
|
||||
<AxoProvider dir={context.globals.direction ?? 'ltr'}>
|
||||
<Story {...context} />
|
||||
</AxoProvider>
|
||||
);
|
||||
}
|
||||
|
||||
export const decorators = [
|
||||
withStrictMode,
|
||||
withAxoProvider,
|
||||
withGlobalTypesProvider,
|
||||
withMockStoreProvider,
|
||||
withScrollLockProvider,
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
*/
|
||||
@custom-variant dark (&:where(.dark-theme, .dark-theme *));
|
||||
|
||||
@custom-variant hovered (&:hover:not(:disabled));
|
||||
@custom-variant pressed (&:active:not(:disabled));
|
||||
@custom-variant focused (.keyboard-mode &:focus);
|
||||
@custom-variant hovered (&:where(:hover:not(:disabled)));
|
||||
@custom-variant pressed (&:where(:active:not(:disabled)));
|
||||
@custom-variant focused (:where(.keyboard-mode) &:where(:focus));
|
||||
|
||||
/**
|
||||
* Color
|
||||
@@ -325,6 +325,9 @@
|
||||
/* box-shadow: inset */
|
||||
--inset-shadow-*: initial; /* reset defaults */
|
||||
|
||||
--inset-shadow-on-color:
|
||||
inset 0 0.5px 1px 0 --alpha(#000 / 12%);
|
||||
|
||||
/* filter: drop-shadow() */
|
||||
--drop-shadow-*: initial; /* reset defaults */
|
||||
--drop-shadow-elevation-0: var(--shadow-elevation-0);
|
||||
|
||||
@@ -11,7 +11,8 @@ const Namespace = 'AxoButton';
|
||||
|
||||
const baseAxoButtonStyles = tw(
|
||||
'flex items-center-safe justify-center-safe gap-1 truncate rounded-full select-none',
|
||||
'outline-0 outline-border-focused focused:outline-[2.5px]'
|
||||
'outline-0 outline-border-focused focused:outline-[2.5px]',
|
||||
'forced-colors:border'
|
||||
);
|
||||
|
||||
const AxoButtonTypes = {
|
||||
|
||||
40
ts/axo/AxoCheckbox.stories.tsx
Normal file
40
ts/axo/AxoCheckbox.stories.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright 2025 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
import React, { useState } from 'react';
|
||||
import type { Meta } from '@storybook/react';
|
||||
import { AxoCheckbox } from './AxoCheckbox';
|
||||
import { tw } from './tw';
|
||||
|
||||
export default {
|
||||
title: 'Axo/AxoCheckbox',
|
||||
} satisfies Meta;
|
||||
|
||||
function Template(props: {
|
||||
label: string;
|
||||
defaultChecked: boolean;
|
||||
disabled?: boolean;
|
||||
}): JSX.Element {
|
||||
const [checked, setChecked] = useState(props.defaultChecked);
|
||||
return (
|
||||
<label className={tw('my-2 flex items-center gap-2')}>
|
||||
<AxoCheckbox
|
||||
checked={checked}
|
||||
onCheckedChange={setChecked}
|
||||
disabled={props.disabled}
|
||||
/>
|
||||
{props.label}
|
||||
</label>
|
||||
);
|
||||
}
|
||||
|
||||
export function Basic(): JSX.Element {
|
||||
return (
|
||||
<>
|
||||
<h1 className={tw('type-title-large')}>AxoCheckbox</h1>
|
||||
<Template label="Unchecked" defaultChecked={false} />
|
||||
<Template label="Checked" defaultChecked />
|
||||
<Template label="Unchecked+Disabled" defaultChecked={false} disabled />
|
||||
<Template label="Checked+Disabled" defaultChecked disabled />
|
||||
</>
|
||||
);
|
||||
}
|
||||
57
ts/axo/AxoCheckbox.tsx
Normal file
57
ts/axo/AxoCheckbox.tsx
Normal file
@@ -0,0 +1,57 @@
|
||||
// Copyright 2025 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
import React, { memo } from 'react';
|
||||
import { Checkbox } from 'radix-ui';
|
||||
import { AxoSymbol } from './AxoSymbol';
|
||||
import { tw } from './tw';
|
||||
|
||||
const Namespace = 'AxoCheckbox';
|
||||
|
||||
type AxoCheckboxProps = Readonly<{
|
||||
id?: string;
|
||||
checked: boolean;
|
||||
onCheckedChange: (nextChecked: boolean) => void;
|
||||
disabled?: boolean;
|
||||
required?: boolean;
|
||||
}>;
|
||||
|
||||
// eslint-disable-next-line import/export
|
||||
export const AxoCheckbox = memo((props: AxoCheckboxProps) => {
|
||||
return (
|
||||
<Checkbox.Root
|
||||
id={props.id}
|
||||
checked={props.checked}
|
||||
onCheckedChange={props.onCheckedChange}
|
||||
disabled={props.disabled}
|
||||
required={props.required}
|
||||
className={tw(
|
||||
'flex size-5 items-center justify-center rounded-full',
|
||||
'border border-border-primary inset-shadow-on-color',
|
||||
'data-[state=unchecked]:bg-fill-primary',
|
||||
'data-[state=unchecked]:pressed:bg-fill-primary-pressed',
|
||||
'data-[state=checked]:bg-color-fill-primary',
|
||||
'data-[state=checked]:pressed:bg-color-fill-primary-pressed',
|
||||
'data-[disabled]:border-border-secondary',
|
||||
'outline-0 outline-border-focused focused:outline-[2.5px]',
|
||||
'overflow-hidden'
|
||||
)}
|
||||
>
|
||||
<Checkbox.Indicator
|
||||
className={tw(
|
||||
'data-[state=checked]:text-label-primary-on-color',
|
||||
'data-[state=checked]:data-[disabled]:text-label-disabled-on-color'
|
||||
)}
|
||||
>
|
||||
<AxoSymbol.Icon symbol="check" size={14} label={null} />
|
||||
</Checkbox.Indicator>
|
||||
</Checkbox.Root>
|
||||
);
|
||||
});
|
||||
|
||||
AxoCheckbox.displayName = `${Namespace}`;
|
||||
|
||||
// eslint-disable-next-line max-len
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace, @typescript-eslint/no-redeclare, import/export
|
||||
export namespace AxoCheckbox {
|
||||
export type Props = AxoCheckboxProps;
|
||||
}
|
||||
@@ -217,7 +217,7 @@ export namespace AxoContextMenu {
|
||||
</AxoBaseMenu.ItemLeadingSlot>
|
||||
<AxoBaseMenu.ItemContentSlot>
|
||||
{props.symbol && (
|
||||
<span className={tw('mr-2')}>
|
||||
<span className={tw('me-2')}>
|
||||
<AxoBaseMenu.ItemSymbol symbol={props.symbol} />
|
||||
</span>
|
||||
)}
|
||||
@@ -352,7 +352,7 @@ export namespace AxoContextMenu {
|
||||
)}
|
||||
<AxoBaseMenu.ItemContentSlot>
|
||||
<AxoBaseMenu.ItemText>{props.children}</AxoBaseMenu.ItemText>
|
||||
<span className={tw('ml-auto')}>
|
||||
<span className={tw('ms-auto')}>
|
||||
<AxoSymbol.Icon size={14} symbol="chevron-[end]" label={null} />
|
||||
</span>
|
||||
</AxoBaseMenu.ItemContentSlot>
|
||||
|
||||
@@ -231,7 +231,7 @@ export namespace AxoDropdownMenu {
|
||||
</AxoBaseMenu.ItemLeadingSlot>
|
||||
<AxoBaseMenu.ItemContentSlot>
|
||||
{props.symbol && (
|
||||
<span className={tw('mr-2')}>
|
||||
<span className={tw('me-2')}>
|
||||
<AxoBaseMenu.ItemSymbol symbol={props.symbol} />
|
||||
</span>
|
||||
)}
|
||||
@@ -366,7 +366,7 @@ export namespace AxoDropdownMenu {
|
||||
)}
|
||||
<AxoBaseMenu.ItemContentSlot>
|
||||
<AxoBaseMenu.ItemText>{props.children}</AxoBaseMenu.ItemText>
|
||||
<span className={tw('ml-auto')}>
|
||||
<span className={tw('ms-auto')}>
|
||||
<AxoSymbol.Icon size={14} symbol="chevron-[end]" label={null} />
|
||||
</span>
|
||||
</AxoBaseMenu.ItemContentSlot>
|
||||
|
||||
18
ts/axo/AxoProvider.tsx
Normal file
18
ts/axo/AxoProvider.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright 2025 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
import type { FC, ReactNode } from 'react';
|
||||
import React, { memo } from 'react';
|
||||
import { Direction } from 'radix-ui';
|
||||
|
||||
type AxoProviderProps = Readonly<{
|
||||
dir: 'ltr' | 'rtl';
|
||||
children: ReactNode;
|
||||
}>;
|
||||
|
||||
export const AxoProvider: FC<AxoProviderProps> = memo(props => {
|
||||
return (
|
||||
<Direction.Provider dir={props.dir}>{props.children}</Direction.Provider>
|
||||
);
|
||||
});
|
||||
|
||||
AxoProvider.displayName = 'AxoProvider';
|
||||
@@ -82,7 +82,8 @@ export namespace AxoSelect {
|
||||
'flex',
|
||||
'rounded-full py-[5px] ps-3 pe-2.5 type-body-medium text-label-primary',
|
||||
'disabled:text-label-disabled',
|
||||
'outline-0 outline-border-focused focused:outline-[2.5px]'
|
||||
'outline-0 outline-border-focused focused:outline-[2.5px]',
|
||||
'forced-colors:border'
|
||||
);
|
||||
|
||||
const TriggerVariants = {
|
||||
@@ -137,7 +138,7 @@ export namespace AxoSelect {
|
||||
{props.children}
|
||||
</Select.Value>
|
||||
</AxoBaseMenu.ItemText>
|
||||
<Select.Icon className={tw('ml-2')}>
|
||||
<Select.Icon className={tw('ms-2')}>
|
||||
<AxoSymbol.Icon symbol="chevron-down" size={14} label={null} />
|
||||
</Select.Icon>
|
||||
</Select.Trigger>
|
||||
|
||||
40
ts/axo/AxoSwitch.stories.tsx
Normal file
40
ts/axo/AxoSwitch.stories.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright 2025 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
import React, { useState } from 'react';
|
||||
import type { Meta } from '@storybook/react';
|
||||
import { AxoSwitch } from './AxoSwitch';
|
||||
import { tw } from './tw';
|
||||
|
||||
export default {
|
||||
title: 'Axo/AxoSwitch',
|
||||
} satisfies Meta;
|
||||
|
||||
function Template(props: {
|
||||
label: string;
|
||||
defaultChecked: boolean;
|
||||
disabled?: boolean;
|
||||
}): JSX.Element {
|
||||
const [checked, setChecked] = useState(props.defaultChecked);
|
||||
return (
|
||||
<label className={tw('my-2 flex items-center gap-2')}>
|
||||
<AxoSwitch
|
||||
checked={checked}
|
||||
onCheckedChange={setChecked}
|
||||
disabled={props.disabled}
|
||||
/>
|
||||
{props.label}
|
||||
</label>
|
||||
);
|
||||
}
|
||||
|
||||
export function Basic(): JSX.Element {
|
||||
return (
|
||||
<>
|
||||
<h1 className={tw('type-title-large')}>AxoSwitch</h1>
|
||||
<Template label="Unchecked" defaultChecked={false} />
|
||||
<Template label="Checked" defaultChecked />
|
||||
<Template label="UncheckedDisabled" defaultChecked={false} disabled />
|
||||
<Template label="CheckedDisabled" defaultChecked disabled />
|
||||
</>
|
||||
);
|
||||
}
|
||||
83
ts/axo/AxoSwitch.tsx
Normal file
83
ts/axo/AxoSwitch.tsx
Normal file
@@ -0,0 +1,83 @@
|
||||
// Copyright 2025 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
import React, { memo } from 'react';
|
||||
import { Switch } from 'radix-ui';
|
||||
import { tw } from './tw';
|
||||
import { AxoSymbol } from './AxoSymbol';
|
||||
|
||||
const Namespace = 'AxoSwitch';
|
||||
|
||||
type AxoSwitchProps = Readonly<{
|
||||
checked: boolean;
|
||||
onCheckedChange: (nextChecked: boolean) => void;
|
||||
disabled?: boolean;
|
||||
required?: boolean;
|
||||
}>;
|
||||
|
||||
// eslint-disable-next-line import/export
|
||||
export const AxoSwitch = memo((props: AxoSwitchProps) => {
|
||||
return (
|
||||
<Switch.Root
|
||||
checked={props.checked}
|
||||
onCheckedChange={props.onCheckedChange}
|
||||
disabled={props.disabled}
|
||||
required={props.required}
|
||||
className={tw(
|
||||
'group relative z-0 flex h-[18px] w-8 items-center rounded-full',
|
||||
'border border-border-secondary inset-shadow-on-color',
|
||||
'bg-fill-secondary',
|
||||
'data-[disabled]:bg-fill-primary',
|
||||
'pressed:bg-fill-secondary-pressed',
|
||||
'outline-0 outline-border-focused focused:outline-[2.5px]',
|
||||
'overflow-hidden'
|
||||
)}
|
||||
>
|
||||
<span
|
||||
className={tw(
|
||||
'absolute top-0 bottom-0',
|
||||
'w-5.5 rounded-s-full',
|
||||
'group-data-[disabled]:w-7.5 group-data-[disabled]:rounded-full',
|
||||
'opacity-0 group-data-[state=checked]:opacity-100',
|
||||
'-translate-x-3.5 group-data-[state=checked]:translate-x-0 rtl:translate-x-3.5',
|
||||
'bg-color-fill-primary group-pressed:bg-color-fill-primary-pressed',
|
||||
'transition-all duration-200 ease-out-cubic',
|
||||
'forced-colors:bg-[AccentColor]',
|
||||
'forced-colors:group-data-[disabled]:bg-[GrayText]'
|
||||
)}
|
||||
/>
|
||||
<span
|
||||
className={tw(
|
||||
'invisible forced-colors:visible',
|
||||
'absolute start-0.5 z-0 text-[12px]',
|
||||
'forced-color-adjust-none',
|
||||
'forced-colors:text-[AccentColorText]'
|
||||
)}
|
||||
>
|
||||
<AxoSymbol.InlineGlyph symbol="check" label={null} />
|
||||
</span>
|
||||
<Switch.Thumb
|
||||
className={tw(
|
||||
'z-10 block size-4 rounded-full',
|
||||
// eslint-disable-next-line better-tailwindcss/no-restricted-classes
|
||||
'shadow-[#000]/12',
|
||||
'shadow-[0.5px_0_0.5px_0.5px,-0.5px_0_0.5px_0.5px]',
|
||||
'bg-label-primary-on-color',
|
||||
'data-[disabled]:bg-label-disabled-on-color',
|
||||
'transition-all duration-200 ease-out-cubic',
|
||||
'data-[state=checked]:translate-x-3.5',
|
||||
'rtl:data-[state=checked]:-translate-x-3.5',
|
||||
'forced-colors:border',
|
||||
'forced-colors:data-[disabled]:bg-[ButtonFace]'
|
||||
)}
|
||||
/>
|
||||
</Switch.Root>
|
||||
);
|
||||
});
|
||||
|
||||
AxoSwitch.displayName = `${Namespace}`;
|
||||
|
||||
// eslint-disable-next-line max-len
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace, @typescript-eslint/no-redeclare, import/export
|
||||
export namespace AxoSwitch {
|
||||
export type Props = AxoSwitchProps;
|
||||
}
|
||||
@@ -43,12 +43,12 @@ const SymbolInfo = memo(function SymbolInfo(props: {
|
||||
{variant.title}
|
||||
</span>
|
||||
<span className={tw('text-[20px] leading-none')}>
|
||||
<Direction.DirectionProvider dir={variant.dir}>
|
||||
<Direction.Provider dir={variant.dir}>
|
||||
<AxoSymbol.InlineGlyph
|
||||
symbol={props.symbolName}
|
||||
label={null}
|
||||
/>
|
||||
</Direction.DirectionProvider>
|
||||
</Direction.Provider>
|
||||
</span>
|
||||
<code className={tw('type-caption text-label-secondary')}>
|
||||
{Array.from(variant.text, char => {
|
||||
|
||||
@@ -9,13 +9,16 @@ import { AxoSymbol, type AxoSymbolName } from '../AxoSymbol';
|
||||
export namespace AxoBaseMenu {
|
||||
// <Content/SubContent>
|
||||
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');
|
||||
|
||||
// <Group/RadioGroup>
|
||||
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 (
|
||||
<span
|
||||
className={tw('ml-auto px-1 type-body-medium text-label-secondary')}
|
||||
dir="auto"
|
||||
className={tw(
|
||||
'ms-auto px-1 type-body-medium text-label-secondary forced-colors:text-[inherit]'
|
||||
)}
|
||||
>
|
||||
{props.keyboardShortcut}
|
||||
</span>
|
||||
@@ -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]'
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -209,10 +209,7 @@ function TypingBubbleGroupAvatars({
|
||||
<div className="module-message__author-avatar-container module-message__author-avatar-container--typing">
|
||||
<div className="module-message__typing-avatar-spacer" />
|
||||
{typingContactsOverflowCount > 0 && (
|
||||
<div
|
||||
className="module-message__typing-avatar module-message__typing-avatar--overflow-count
|
||||
"
|
||||
>
|
||||
<div className="module-message__typing-avatar module-message__typing-avatar--overflow-count">
|
||||
<div
|
||||
aria-label={i18n('icu:TypingBubble__avatar--overflow-count', {
|
||||
count: typingContactsOverflowCount,
|
||||
|
||||
@@ -9,6 +9,7 @@ import { Emojify } from '../../components/conversation/Emojify';
|
||||
import { normalizeAci } from '../../util/normalizeAci';
|
||||
import type { MentionBlotValue } from '../util';
|
||||
import { FunEmojiLocalizationProvider } from '../../components/fun/FunEmojiLocalizationProvider';
|
||||
import { AxoProvider } from '../../axo/AxoProvider';
|
||||
|
||||
export class MentionBlot extends EmbedBlot {
|
||||
static override blotName = 'mention';
|
||||
@@ -48,6 +49,7 @@ export class MentionBlot extends EmbedBlot {
|
||||
|
||||
createRoot(mentionSpan).render(
|
||||
<StrictMode>
|
||||
<AxoProvider dir={window.i18n.getLocaleDirection()}>
|
||||
<FunEmojiLocalizationProvider i18n={window.i18n}>
|
||||
<span className="module-composition-input__at-mention">
|
||||
<bdi>
|
||||
@@ -56,6 +58,7 @@ export class MentionBlot extends EmbedBlot {
|
||||
</bdi>
|
||||
</span>
|
||||
</FunEmojiLocalizationProvider>
|
||||
</AxoProvider>
|
||||
</StrictMode>
|
||||
);
|
||||
|
||||
|
||||
@@ -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(
|
||||
<StrictMode>
|
||||
<AxoProvider dir={window.i18n.getLocaleDirection()}>
|
||||
<FunDefaultEnglishEmojiLocalizationProvider>
|
||||
<ClearingData deleteAllData={deleteAllData} i18n={window.i18n} />
|
||||
</FunDefaultEnglishEmojiLocalizationProvider>
|
||||
</AxoProvider>
|
||||
</StrictMode>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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,6 +741,7 @@ export function SmartPreferences(): JSX.Element | null {
|
||||
|
||||
return (
|
||||
<StrictMode>
|
||||
<AxoProvider dir={i18n.getLocaleDirection()}>
|
||||
<Preferences
|
||||
accountEntropyPool={accountEntropyPool}
|
||||
addCustomColor={addCustomColor}
|
||||
@@ -750,7 +752,9 @@ export function SmartPreferences(): JSX.Element | null {
|
||||
availableSpeakers={availableSpeakers}
|
||||
backupFeatureEnabled={backupFeatureEnabled}
|
||||
backupKeyViewed={backupKeyViewed}
|
||||
backupSubscriptionStatus={backupSubscriptionStatus ?? { status: 'off' }}
|
||||
backupSubscriptionStatus={
|
||||
backupSubscriptionStatus ?? { status: 'off' }
|
||||
}
|
||||
backupMediaDownloadStatus={{
|
||||
completedBytes: backupMediaDownloadCompletedBytes ?? 0,
|
||||
totalBytes: backupMediaDownloadTotalBytes ?? 0,
|
||||
@@ -913,6 +917,7 @@ export function SmartPreferences(): JSX.Element | null {
|
||||
__dangerouslyRunAbitraryReadOnlySqlQuery
|
||||
}
|
||||
/>
|
||||
</AxoProvider>
|
||||
</StrictMode>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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<T>({
|
||||
progressRoot = createRoot(progressNode);
|
||||
progressRoot.render(
|
||||
<StrictMode>
|
||||
<AxoProvider dir={window.i18n.getLocaleDirection()}>
|
||||
<FunDefaultEnglishEmojiLocalizationProvider>
|
||||
<ProgressModal i18n={window.i18n} />
|
||||
</FunDefaultEnglishEmojiLocalizationProvider>
|
||||
</AxoProvider>
|
||||
</StrictMode>
|
||||
);
|
||||
spinnerStart = Date.now();
|
||||
|
||||
@@ -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,6 +58,7 @@ export function showConfirmationDialog(
|
||||
confirmationDialogRoot = createRoot(confirmationDialogViewNode);
|
||||
confirmationDialogRoot.render(
|
||||
<StrictMode>
|
||||
<AxoProvider dir={window.i18n.getLocaleDirection()}>
|
||||
<FunDefaultEnglishEmojiLocalizationProvider>
|
||||
<ConfirmationDialog
|
||||
dialogName={options.dialogName}
|
||||
@@ -88,6 +90,7 @@ export function showConfirmationDialog(
|
||||
{options.description}
|
||||
</ConfirmationDialog>
|
||||
</FunDefaultEnglishEmojiLocalizationProvider>
|
||||
</AxoProvider>
|
||||
</StrictMode>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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,6 +19,7 @@ strictAssert(app != null, 'No #app');
|
||||
|
||||
createRoot(app).render(
|
||||
<StrictMode>
|
||||
<AxoProvider dir={i18n.getLocaleDirection()}>
|
||||
<FunDefaultEnglishEmojiLocalizationProvider>
|
||||
<About
|
||||
closeAbout={() => window.SignalContext.executeMenuRole('close')}
|
||||
@@ -28,5 +30,6 @@ createRoot(app).render(
|
||||
version={window.SignalContext.getVersion()}
|
||||
/>
|
||||
</FunDefaultEnglishEmojiLocalizationProvider>
|
||||
</AxoProvider>
|
||||
</StrictMode>
|
||||
);
|
||||
|
||||
@@ -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,6 +18,7 @@ strictAssert(app != null, 'No #app');
|
||||
|
||||
createRoot(app).render(
|
||||
<StrictMode>
|
||||
<AxoProvider dir={i18n.getLocaleDirection()}>
|
||||
<FunDefaultEnglishEmojiLocalizationProvider>
|
||||
<DebugLogWindow
|
||||
closeWindow={() => window.SignalContext.executeMenuRole('close')}
|
||||
@@ -26,5 +28,6 @@ createRoot(app).render(
|
||||
uploadLogs={DebugLogWindowProps.uploadLogs}
|
||||
/>
|
||||
</FunDefaultEnglishEmojiLocalizationProvider>
|
||||
</AxoProvider>
|
||||
</StrictMode>
|
||||
);
|
||||
|
||||
@@ -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,6 +32,7 @@ strictAssert(app != null, 'No #app');
|
||||
|
||||
createRoot(app).render(
|
||||
<StrictMode>
|
||||
<AxoProvider dir={i18n.getLocaleDirection()}>
|
||||
<FunDefaultEnglishEmojiLocalizationProvider>
|
||||
<PermissionsPopup
|
||||
i18n={i18n}
|
||||
@@ -39,5 +41,6 @@ createRoot(app).render(
|
||||
onClose={PermissionsWindowProps.onClose}
|
||||
/>
|
||||
</FunDefaultEnglishEmojiLocalizationProvider>
|
||||
</AxoProvider>
|
||||
</StrictMode>
|
||||
);
|
||||
|
||||
@@ -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,6 +34,7 @@ function render() {
|
||||
|
||||
createRoot(app).render(
|
||||
<StrictMode>
|
||||
<AxoProvider dir={i18n.getLocaleDirection()}>
|
||||
<FunDefaultEnglishEmojiLocalizationProvider>
|
||||
<div className="App dark-theme">
|
||||
<CallingScreenSharingController
|
||||
@@ -44,6 +46,7 @@ function render() {
|
||||
/>
|
||||
</div>
|
||||
</FunDefaultEnglishEmojiLocalizationProvider>
|
||||
</AxoProvider>
|
||||
</StrictMode>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user