diff --git a/src/components/list.tsx b/src/components/list.tsx index 65be4cef4..a64f19450 100644 --- a/src/components/list.tsx +++ b/src/components/list.tsx @@ -16,16 +16,19 @@ const List: React.FC = ({ children }) => ( ); interface IListItem { + className?: string; label: React.ReactNode; hint?: React.ReactNode; to?: string; + href?: string; onClick?(): void; onSelect?(): void; isSelected?: boolean; children?: React.ReactNode; + size?: 'sm' | 'md'; } -const ListItem: React.FC = ({ label, hint, children, to, onClick, onSelect, isSelected }) => { +const ListItem: React.FC = ({ className, label, hint, children, to, href, onClick, onSelect, isSelected, size = 'md' }) => { const id = uuidv4(); const domId = `list-group-${id}`; @@ -35,7 +38,7 @@ const ListItem: React.FC = ({ label, hint, children, to, onClick, onS } }; - const LabelComp = to || onClick || onSelect ? 'span' : 'label'; + const LabelComp = to || href || onClick || onSelect ? 'span' : 'label'; const renderChildren = React.useCallback(() => React.Children.map(children, (child) => { if (React.isValidElement(child)) { @@ -53,9 +56,14 @@ const ListItem: React.FC = ({ label, hint, children, to, onClick, onS return null; }), [children, domId]); - const className = clsx('flex items-center justify-between overflow-hidden bg-gradient-to-r from-gradient-start/20 to-gradient-end/20 px-4 py-2 first:rounded-t-lg last:rounded-b-lg dark:from-gradient-start/10 dark:to-gradient-end/10', { - 'cursor-pointer hover:from-gradient-start/30 hover:to-gradient-end/30 dark:hover:from-gradient-start/5 dark:hover:to-gradient-end/5': typeof to !== 'undefined' || typeof onClick !== 'undefined' || typeof onSelect !== 'undefined', - }); + const classNames = clsx('flex items-center justify-between overflow-hidden bg-gradient-to-r from-gradient-start/20 to-gradient-end/20 first:rounded-t-lg last:rounded-b-lg dark:from-gradient-start/10 dark:to-gradient-end/10', + className, + { + 'px-4 py-2': size === 'md', + 'px-2 py-0.5': size === 'sm', + 'cursor-pointer hover:from-gradient-start/30 hover:to-gradient-end/30 dark:hover:from-gradient-start/5 dark:hover:to-gradient-end/5': typeof to !== 'undefined' || typeof onClick !== 'undefined' || typeof onSelect !== 'undefined', + }, + ); const body = ( <> @@ -67,7 +75,7 @@ const ListItem: React.FC = ({ label, hint, children, to, onClick, onS ) : null} - {(to || onClick) ? ( + {(to || href || onClick) ? ( {children} @@ -107,17 +115,17 @@ const ListItem: React.FC = ({ label, hint, children, to, onClick, onS ); if (to) return ( - + {body} ); - const Comp = onClick ? 'a' : 'div'; - const linkProps = onClick || onSelect ? { onClick: onClick || onSelect, onKeyDown, tabIndex: 0, role: 'link' } : {}; + const Comp = onClick || href ? 'a' : 'div'; + const linkProps = onClick || onSelect || href ? { onClick: onClick || onSelect, onKeyDown, tabIndex: 0, role: 'link', ...(href && { href, target: '_blank' }) } : {}; return ( {body} diff --git a/src/components/ui/layout/layout.tsx b/src/components/ui/layout/layout.tsx index 6a7c3d407..7bf282a2d 100644 --- a/src/components/ui/layout/layout.tsx +++ b/src/components/ui/layout/layout.tsx @@ -22,7 +22,7 @@ interface LayoutComponent extends React.FC { /** Layout container, to hold Sidebar, Main, and Aside. */ const Layout: LayoutComponent = ({ children }) => (
-
+
{children}
diff --git a/src/features/chats/components/chat-list-item.tsx b/src/features/chats/components/chat-list-item.tsx index cec30153a..93c395ce3 100644 --- a/src/features/chats/components/chat-list-item.tsx +++ b/src/features/chats/components/chat-list-item.tsx @@ -17,9 +17,9 @@ const messages = defineMessages({ blockedYou: { id: 'chat_list_item.blocked_you', defaultMessage: 'This user has blocked you' }, blocking: { id: 'chat_list_item.blocking', defaultMessage: 'You have blocked this user' }, leaveMessage: { id: 'chat_settings.leave.message', defaultMessage: 'Are you sure you want to leave this chat? Messages will be deleted for you and this chat will be removed from your inbox.' }, - leaveHeading: { id: 'chat_settings.leave.heading', defaultMessage: 'Leave Chat' }, - leaveConfirm: { id: 'chat_settings.leave.confirm', defaultMessage: 'Leave Chat' }, - leaveChat: { id: 'chat_settings.options.leave_chat', defaultMessage: 'Leave Chat' }, + leaveHeading: { id: 'chat_settings.leave.heading', defaultMessage: 'Leave chat' }, + leaveConfirm: { id: 'chat_settings.leave.confirm', defaultMessage: 'Leave chat' }, + leaveChat: { id: 'chat_settings.options.leave_chat', defaultMessage: 'Leave chat' }, }); interface IChatListItemInterface { diff --git a/src/features/chats/components/chat-page/components/chat-page-main.tsx b/src/features/chats/components/chat-page/components/chat-page-main.tsx index 59c4a6d60..c5c35b7c3 100644 --- a/src/features/chats/components/chat-page/components/chat-page-main.tsx +++ b/src/features/chats/components/chat-page/components/chat-page-main.tsx @@ -23,11 +23,11 @@ const messages = defineMessages({ unblockHeading: { id: 'chat_settings.unblock.heading', defaultMessage: 'Unblock @{acct}' }, unblockConfirm: { id: 'chat_settings.unblock.confirm', defaultMessage: 'Unblock' }, leaveMessage: { id: 'chat_settings.leave.message', defaultMessage: 'Are you sure you want to leave this chat? Messages will be deleted for you and this chat will be removed from your inbox.' }, - leaveHeading: { id: 'chat_settings.leave.heading', defaultMessage: 'Leave Chat' }, - leaveConfirm: { id: 'chat_settings.leave.confirm', defaultMessage: 'Leave Chat' }, + leaveHeading: { id: 'chat_settings.leave.heading', defaultMessage: 'Leave chat' }, + leaveConfirm: { id: 'chat_settings.leave.confirm', defaultMessage: 'Leave chat' }, blockUser: { id: 'chat_settings.options.block_user', defaultMessage: 'Block @{acct}' }, unblockUser: { id: 'chat_settings.options.unblock_user', defaultMessage: 'Unblock @{acct}' }, - leaveChat: { id: 'chat_settings.options.leave_chat', defaultMessage: 'Leave Chat' }, + leaveChat: { id: 'chat_settings.options.leave_chat', defaultMessage: 'Leave chat' }, }); const ChatPageMain = () => { diff --git a/src/features/chats/components/chat-widget/chat-settings.tsx b/src/features/chats/components/chat-widget/chat-settings.tsx index dff845e10..937abdbd0 100644 --- a/src/features/chats/components/chat-widget/chat-settings.tsx +++ b/src/features/chats/components/chat-widget/chat-settings.tsx @@ -18,12 +18,12 @@ const messages = defineMessages({ unblockHeading: { id: 'chat_settings.unblock.heading', defaultMessage: 'Unblock @{acct}' }, unblockConfirm: { id: 'chat_settings.unblock.confirm', defaultMessage: 'Unblock' }, leaveMessage: { id: 'chat_settings.leave.message', defaultMessage: 'Are you sure you want to leave this chat? Messages will be deleted for you and this chat will be removed from your inbox.' }, - leaveHeading: { id: 'chat_settings.leave.heading', defaultMessage: 'Leave Chat' }, - leaveConfirm: { id: 'chat_settings.leave.confirm', defaultMessage: 'Leave Chat' }, + leaveHeading: { id: 'chat_settings.leave.heading', defaultMessage: 'Leave chat' }, + leaveConfirm: { id: 'chat_settings.leave.confirm', defaultMessage: 'Leave chat' }, title: { id: 'chat_settings.title', defaultMessage: 'Chat Details' }, blockUser: { id: 'chat_settings.options.block_user', defaultMessage: 'Block @{acct}' }, unblockUser: { id: 'chat_settings.options.unblock_user', defaultMessage: 'Unblock @{acct}' }, - leaveChat: { id: 'chat_settings.options.leave_chat', defaultMessage: 'Leave Chat' }, + leaveChat: { id: 'chat_settings.options.leave_chat', defaultMessage: 'Leave chat' }, }); const ChatSettings = () => { diff --git a/src/features/ui/components/panels/sign-up-panel.tsx b/src/features/ui/components/panels/sign-up-panel.tsx index 4a70eb63d..8fac82c95 100644 --- a/src/features/ui/components/panels/sign-up-panel.tsx +++ b/src/features/ui/components/panels/sign-up-panel.tsx @@ -7,8 +7,10 @@ import { fetchInstance } from 'soapbox/actions/instance'; import { Button, Stack, Text } from 'soapbox/components/ui'; import LoginForm from 'soapbox/features/auth-login/components/login-form'; import OtpAuthForm from 'soapbox/features/auth-login/components/otp-auth-form'; +import ExternalLoginForm from 'soapbox/features/external-login/components/external-login-form'; import { useAppDispatch, useAppSelector, useInstance, useRegistrationStatus } from 'soapbox/hooks'; import { getRedirectUrl } from 'soapbox/utils/redirect'; +import { isStandalone } from 'soapbox/utils/state'; import type { PlfeResponse } from 'soapbox/api'; @@ -18,6 +20,7 @@ const SignUpPanel = () => { const instance = useInstance(); const { isOpen } = useRegistrationStatus(); const me = useAppSelector((state) => state.me); + const standalone = useAppSelector(isStandalone); const token = new URLSearchParams(window.location.search).get('token'); @@ -91,13 +94,26 @@ const SignUpPanel = () => { )} - - - - - + {standalone ? ( + <> + + + + + + ) : ( + <> + + {isOpen ? ( + + ) : ( + + )} + - + + + )} ); }; diff --git a/src/features/ui/components/profile-dropdown.tsx b/src/features/ui/components/profile-dropdown.tsx index 888e3bd27..d8d989949 100644 --- a/src/features/ui/components/profile-dropdown.tsx +++ b/src/features/ui/components/profile-dropdown.tsx @@ -109,7 +109,7 @@ const ProfileDropdown: React.FC = ({ account, children }) => { return ( <>