diff --git a/app/soapbox/components/autosuggest-input.tsx b/app/soapbox/components/autosuggest-input.tsx index 35460131a..c4bf49d72 100644 --- a/app/soapbox/components/autosuggest-input.tsx +++ b/app/soapbox/components/autosuggest-input.tsx @@ -8,7 +8,6 @@ import AutosuggestEmoji, { Emoji } from 'soapbox/components/autosuggest-emoji'; import Icon from 'soapbox/components/icon'; import { Input } from 'soapbox/components/ui'; import AutosuggestAccount from 'soapbox/features/compose/components/autosuggest-account'; -import { isRtl } from 'soapbox/rtl'; import { textAtCursorMatchesToken } from 'soapbox/utils/suggestions'; import type { Menu, MenuItem } from 'soapbox/components/dropdown-menu'; @@ -264,14 +263,8 @@ export default class AutosuggestInput extends ImmutablePureComponent @@ -290,7 +283,6 @@ export default class AutosuggestInput extends ImmutablePureComponent render() { const { value, suggestions, disabled, placeholder, onKeyUp, autoFocus, children, condensed, id } = this.props; const { suggestionsHidden } = this.state; - const style = { direction: 'ltr', minRows: 10 }; - - if (isRtl(value)) { - style.direction = 'rtl'; - } return [
@@ -256,7 +250,6 @@ class AutosuggestTextarea extends ImmutablePureComponent onFocus={this.onFocus} onBlur={this.onBlur} onPaste={this.onPaste} - style={style as any} aria-autocomplete='list' /> diff --git a/app/soapbox/components/ui/toast/toast.tsx b/app/soapbox/components/ui/toast/toast.tsx index a7e26c98c..1aec2a2b6 100644 --- a/app/soapbox/components/ui/toast/toast.tsx +++ b/app/soapbox/components/ui/toast/toast.tsx @@ -6,6 +6,7 @@ import { Link } from 'react-router-dom'; import { ToastText, ToastType } from 'soapbox/toast'; +import HStack from '../hstack/hstack'; import Icon from '../icon/icon'; const renderText = (text: ToastText) => { @@ -63,7 +64,7 @@ const Toast = (props: IToast) => { }; const renderAction = () => { - const classNames = 'ml-3 mt-0.5 flex-shrink-0 rounded-full text-sm font-medium text-primary-600 dark:text-accent-blue hover:underline focus:outline-none'; + const classNames = 'mt-0.5 flex-shrink-0 rounded-full text-sm font-medium text-primary-600 dark:text-accent-blue hover:underline focus:outline-none'; if (action && actionLabel) { return ( @@ -102,43 +103,41 @@ const Toast = (props: IToast) => { data-testid='toast' className={ classNames({ - 'pointer-events-auto w-full max-w-sm overflow-hidden rounded-lg bg-white dark:bg-gray-900 shadow-lg dark:ring-2 dark:ring-gray-800': true, + 'p-4 pointer-events-auto w-full max-w-sm overflow-hidden rounded-lg bg-white dark:bg-gray-900 shadow-lg dark:ring-2 dark:ring-gray-800': true, 'animate-enter': t.visible, 'animate-leave': !t.visible, }) } > -
-
-
-
-
- {renderIcon()} -
- -

- {renderText(message)} -

+ + + +
+ {renderIcon()}
- {/* Action */} - {renderAction()} -
+

+ {renderText(message)} +

+ - {/* Dismiss Button */} -
- -
+ {/* Action */} + {renderAction()} + + + {/* Dismiss Button */} +
+
-
+
); }; diff --git a/app/soapbox/containers/soapbox.tsx b/app/soapbox/containers/soapbox.tsx index 53a0b684d..8ce48f7e2 100644 --- a/app/soapbox/containers/soapbox.tsx +++ b/app/soapbox/containers/soapbox.tsx @@ -53,8 +53,6 @@ import ErrorBoundary from '../components/error-boundary'; import UI from '../features/ui'; import { store } from '../store'; -const RTL_LOCALES = ['ar', 'ckb', 'fa', 'he']; - // Configure global functions for developers createGlobals(store); @@ -211,7 +209,7 @@ const SoapboxLoad: React.FC = ({ children }) => { const me = useAppSelector(state => state.me); const account = useOwnAccount(); const swUpdating = useAppSelector(state => state.meta.swUpdating); - const locale = useLocale(); + const { locale } = useLocale(); const [messages, setMessages] = useState>({}); const [localeLoading, setLocaleLoading] = useState(true); @@ -262,7 +260,7 @@ interface ISoapboxHead { /** Injects metadata into site head with Helmet. */ const SoapboxHead: React.FC = ({ children }) => { - const locale = useLocale(); + const { locale, direction } = useLocale(); const settings = useSettings(); const soapboxConfig = useSoapboxConfig(); @@ -281,7 +279,7 @@ const SoapboxHead: React.FC = ({ children }) => { <> - + {themeCss && } {darkMode && } diff --git a/app/soapbox/hooks/useLocale.ts b/app/soapbox/hooks/useLocale.ts index 1be278002..14dedaf16 100644 --- a/app/soapbox/hooks/useLocale.ts +++ b/app/soapbox/hooks/useLocale.ts @@ -2,15 +2,38 @@ import MESSAGES from 'soapbox/locales/messages'; import { useSettings } from './useSettings'; +import type { CSSProperties } from 'react'; + +/** Locales which should be presented in right-to-left. */ +const RTL_LOCALES = ['ar', 'ckb', 'fa', 'he']; + /** Ensure the given locale exists in our codebase */ const validLocale = (locale: string): boolean => Object.keys(MESSAGES).includes(locale); -/** Get valid locale from settings. */ -const useLocale = (fallback = 'en') => { - const settings = useSettings(); - const locale = settings.get('locale'); +interface UseLocaleResult { + locale: string + direction: CSSProperties['direction'] +} - return validLocale(locale) ? locale : fallback; +/** Get valid locale from settings. */ +const useLocale = (fallback = 'en'): UseLocaleResult => { + const settings = useSettings(); + const userLocale = settings.get('locale') as unknown; + + const locale = + (typeof userLocale === 'string' && validLocale(userLocale)) + ? userLocale + : fallback; + + const direction: CSSProperties['direction'] = + RTL_LOCALES.includes(locale) + ? 'rtl' + : undefined; + + return { + locale, + direction, + }; }; export { useLocale }; diff --git a/app/styles/components/datepicker.scss b/app/styles/components/datepicker.scss index e66698bea..7d56b67ea 100644 --- a/app/styles/components/datepicker.scss +++ b/app/styles/components/datepicker.scss @@ -137,6 +137,10 @@ @apply bg-primary-50 hover:bg-primary-100 dark:bg-gray-700 dark:hover:bg-gray-600 text-primary-600 dark:text-primary-400; } +.react-datepicker__close-icon { + @apply rtl:left-0 rtl:right-auto rtl:pr-0 rtl:pl-[6px]; +} + .react-datepicker__close-icon::after { @apply bg-transparent text-gray-600 dark:text-gray-400 text-base; font-family: 'Font Awesome 5 Free';