Floating Action Button: Fix transition (#6440)

This commit is contained in:
Alexander Zinchuk 2025-11-06 11:36:48 +01:00
parent 5e68196c0c
commit a652cf97ae
33 changed files with 136 additions and 205 deletions

View File

@ -427,9 +427,8 @@ const GroupCall: FC<OwnProps & StateProps> = ({
onClick={handleInviteMember}
className={styles.addParticipantButton}
ariaLabel={lang('VoipGroupInviteMember')}
>
<Icon name="add-user-filled" />
</FloatingActionButton>
iconName="add-user-filled"
/>
</div>
<div className={styles.mainVideoContainer}>

View File

@ -0,0 +1,16 @@
.root {
--icon-size: 1.5rem;
width: var(--icon-size);
height: var(--icon-size);
}
.spinner {
--spinner-size: var(--icon-size);
margin: 0 !important;
}
.icon {
font-size: var(--icon-size);
}

View File

@ -0,0 +1,28 @@
import { memo } from '../../lib/teact/teact';
import type { IconName } from '../../types/icons';
import Spinner from '../ui/Spinner';
import Transition from '../ui/Transition';
import Icon from './icons/Icon';
import styles from './IconWithSpinner.module.scss';
type OwnProps = {
iconName: IconName;
isLoading?: boolean;
};
const IconWithSpinner = ({ iconName, isLoading }: OwnProps) => {
return (
<Transition className={styles.root} activeKey={isLoading ? 0 : 1} name="fade">
{isLoading ? (
<Spinner className={styles.spinner} color="white" />
) : (
<Icon className={styles.icon} name={iconName} />
)}
</Transition>
);
};
export default memo(IconWithSpinner);

View File

@ -13,7 +13,6 @@ import useHistoryBack from '../../../hooks/useHistoryBack';
import useInfiniteScroll from '../../../hooks/useInfiniteScroll';
import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import PrivateChatInfo from '../../common/PrivateChatInfo';
import FloatingActionButton from '../../ui/FloatingActionButton';
import InfiniteScroll from '../../ui/InfiniteScroll';
@ -100,9 +99,8 @@ const ContactList: FC<OwnProps & StateProps> = ({
isShown
onClick={openNewContactDialog}
ariaLabel={lang('CreateNewContact')}
>
<Icon name="add-user-filled" />
</FloatingActionButton>
iconName="add-user-filled"
/>
</InfiniteScroll>
);
};

View File

@ -122,9 +122,8 @@ const NewChatStep1: FC<OwnProps & StateProps> = ({
isShown
onClick={handleNextStep}
ariaLabel={isChannel ? 'Continue To Channel Info' : 'Continue To Group Info'}
>
<Icon name="arrow-right" />
</FloatingActionButton>
iconName="arrow-right"
/>
</div>
</div>
);

View File

@ -21,7 +21,6 @@ import Button from '../../ui/Button';
import FloatingActionButton from '../../ui/FloatingActionButton';
import InputText from '../../ui/InputText';
import ListItem from '../../ui/ListItem';
import Spinner from '../../ui/Spinner';
export type OwnProps = {
isChannel?: boolean;
@ -210,13 +209,9 @@ const NewChatStep2: FC<OwnProps & StateProps> = ({
onClick={isChannel ? handleCreateChannel : handleCreateGroup}
disabled={isLoading}
ariaLabel={isChannel ? lang('ChannelIntro.CreateChannel') : 'Create Group'}
>
{isLoading ? (
<Spinner color="white" />
) : (
<Icon name="arrow-right" />
)}
</FloatingActionButton>
iconName="arrow-right"
isLoading={isLoading}
/>
</div>
);
};

View File

@ -22,14 +22,12 @@ import useMedia from '../../../hooks/useMedia';
import useOldLang from '../../../hooks/useOldLang';
import usePreviousDeprecated from '../../../hooks/usePreviousDeprecated';
import Icon from '../../common/icons/Icon';
import ManageUsernames from '../../common/ManageUsernames';
import SafeLink from '../../common/SafeLink';
import UsernameInput from '../../common/UsernameInput';
import AvatarEditable from '../../ui/AvatarEditable';
import FloatingActionButton from '../../ui/FloatingActionButton';
import InputText from '../../ui/InputText';
import Spinner from '../../ui/Spinner';
import TextArea from '../../ui/TextArea';
type OwnProps = {
@ -289,13 +287,9 @@ const SettingsEditProfile: FC<OwnProps & StateProps> = ({
onClick={handleProfileSave}
disabled={isLoading}
ariaLabel={lang('Save')}
>
{isLoading ? (
<Spinner color="white" />
) : (
<Icon name="check" />
)}
</FloatingActionButton>
iconName="check"
isLoading={isLoading}
/>
</div>
);
};

View File

@ -16,7 +16,6 @@ import useOldLang from '../../../hooks/useOldLang';
import Avatar from '../../common/Avatar';
import FullNameTitle from '../../common/FullNameTitle';
import Icon from '../../common/icons/Icon';
import FloatingActionButton from '../../ui/FloatingActionButton';
import ListItem from '../../ui/ListItem';
import Loading from '../../ui/Loading';
@ -144,9 +143,8 @@ const SettingsPrivacyBlockedUsers: FC<OwnProps & StateProps> = ({
className="block-user-button"
onClick={openBlockUserModal}
ariaLabel={lang('BlockContact')}
>
<Icon name="add" />
</FloatingActionButton>
iconName="add"
/>
<BlockUserModal
isOpen={isBlockUserModalOpen}
onClose={closeBlockUserModal}

View File

@ -23,7 +23,6 @@ import useHistoryBack from '../../../hooks/useHistoryBack';
import useLang from '../../../hooks/useLang';
import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import PeerPicker from '../../common/pickers/PeerPicker';
import FloatingActionButton from '../../ui/FloatingActionButton';
@ -208,9 +207,8 @@ const SettingsPrivacyVisibilityExceptionList: FC<OwnProps & StateProps> = ({
isShown={isSubmitShown}
onClick={handleSubmit}
ariaLabel={isAllowList ? oldLang('AlwaysAllow') : oldLang('NeverAllow')}
>
<Icon name="check" />
</FloatingActionButton>
iconName="check"
/>
</div>
);
};

View File

@ -18,7 +18,6 @@ import useHistoryBack from '../../../../hooks/useHistoryBack';
import useLastCallback from '../../../../hooks/useLastCallback';
import useOldLang from '../../../../hooks/useOldLang';
import Icon from '../../../common/icons/Icon';
import PeerPicker from '../../../common/pickers/PeerPicker';
import FloatingActionButton from '../../../ui/FloatingActionButton';
import Loading from '../../../ui/Loading';
@ -162,9 +161,8 @@ const SettingsFoldersChatFilters: FC<OwnProps & StateProps> = ({
isShown={isTouched}
onClick={onSaveFilter}
ariaLabel={lang('Save')}
>
<Icon name="check" />
</FloatingActionButton>
iconName="check"
/>
</div>
);
};

View File

@ -34,7 +34,6 @@ import PrivateChatInfo from '../../../common/PrivateChatInfo';
import FloatingActionButton from '../../../ui/FloatingActionButton';
import InputText from '../../../ui/InputText';
import ListItem from '../../../ui/ListItem';
import Spinner from '../../../ui/Spinner';
type OwnProps = {
state: FoldersState;
@ -461,13 +460,9 @@ const SettingsFoldersEdit: FC<OwnProps & StateProps> = ({
disabled={state.isLoading}
onClick={handleSubmit}
ariaLabel={state.mode === 'edit' ? 'Save changes' : 'Create folder'}
>
{state.isLoading ? (
<Spinner color="white" />
) : (
<Icon name="check" />
)}
</FloatingActionButton>
iconName="check"
isLoading={state.isLoading}
/>
</div>
);
};

View File

@ -24,11 +24,9 @@ import useLastCallback from '../../../../hooks/useLastCallback';
import useOldLang from '../../../../hooks/useOldLang';
import AnimatedIcon from '../../../common/AnimatedIcon';
import Icon from '../../../common/icons/Icon';
import LinkField from '../../../common/LinkField';
import PeerPicker from '../../../common/pickers/PeerPicker';
import FloatingActionButton from '../../../ui/FloatingActionButton';
import Spinner from '../../../ui/Spinner';
type OwnProps = {
isActive?: boolean;
@ -198,13 +196,9 @@ const SettingsShareChatlist: FC<OwnProps & StateProps> = ({
disabled={isDisabled}
onClick={handleSubmit}
ariaLabel="Save changes"
>
{isLoading ? (
<Spinner color="white" />
) : (
<Icon name="check" />
)}
</FloatingActionButton>
iconName="check"
isLoading={isLoading}
/>
</div>
);
};

View File

@ -21,10 +21,8 @@ import useHistoryBack from '../../hooks/useHistoryBack';
import useOldLang from '../../hooks/useOldLang';
import usePreviousDeprecated from '../../hooks/usePreviousDeprecated';
import Icon from '../common/icons/Icon';
import PeerPicker from '../common/pickers/PeerPicker';
import FloatingActionButton from '../ui/FloatingActionButton';
import Spinner from '../ui/Spinner';
import './AddChatMembers.scss';
@ -144,13 +142,9 @@ const AddChatMembers: FC<OwnProps & StateProps> = ({
disabled={isLoading}
ariaLabel={lang('lng_channel_add_users')}
onClick={handleNextStep}
>
{isLoading ? (
<Spinner color="white" />
) : (
<Icon name="arrow-right" />
)}
</FloatingActionButton>
iconName="arrow-right"
isLoading={isLoading}
/>
</div>
</div>
);

View File

@ -19,11 +19,9 @@ import useHistoryBack from '../../hooks/useHistoryBack';
import useOldLang from '../../hooks/useOldLang';
import CustomEmojiPicker from '../common/CustomEmojiPicker';
import Icon from '../common/icons/Icon';
import TopicIcon from '../common/TopicIcon';
import FloatingActionButton from '../ui/FloatingActionButton';
import InputText from '../ui/InputText';
import Spinner from '../ui/Spinner';
import Transition from '../ui/Transition';
import styles from './ManageTopic.module.scss';
@ -158,13 +156,9 @@ const CreateTopic: FC<OwnProps & StateProps> = ({
disabled={isLoading}
onClick={handleCreateTopic}
ariaLabel={lang('Save')}
>
{isLoading ? (
<Spinner color="white" />
) : (
<Icon name="check" />
)}
</FloatingActionButton>
iconName="check"
isLoading={isLoading}
/>
</div>
);
};

View File

@ -19,12 +19,10 @@ import useHistoryBack from '../../hooks/useHistoryBack';
import useOldLang from '../../hooks/useOldLang';
import CustomEmojiPicker from '../common/CustomEmojiPicker';
import Icon from '../common/icons/Icon';
import TopicIcon from '../common/TopicIcon';
import FloatingActionButton from '../ui/FloatingActionButton';
import InputText from '../ui/InputText';
import Loading from '../ui/Loading';
import Spinner from '../ui/Spinner';
import Transition from '../ui/Transition';
import styles from './ManageTopic.module.scss';
@ -174,13 +172,9 @@ const EditTopic: FC<OwnProps & StateProps> = ({
disabled={isLoading}
onClick={handleEditTopic}
ariaLabel={lang('Save')}
>
{isLoading ? (
<Spinner color="white" />
) : (
<Icon name="check" />
)}
</FloatingActionButton>
iconName="check"
isLoading={isLoading}
/>
</div>
);
};

View File

@ -1224,9 +1224,8 @@ const Profile = ({
isShown={canRenderContent}
onClick={handleNewMemberDialogOpen}
ariaLabel={oldLang('lng_channel_add_users')}
>
<Icon name="add-user-filled" />
</FloatingActionButton>
iconName="add-user-filled"
/>
)}
{canDeleteMembers && (
<DeleteMemberModal

View File

@ -26,13 +26,11 @@ import useLastCallback from '../../../hooks/useLastCallback';
import useMedia from '../../../hooks/useMedia';
import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import AvatarEditable from '../../ui/AvatarEditable';
import FloatingActionButton from '../../ui/FloatingActionButton';
import InputText from '../../ui/InputText';
import ListItem from '../../ui/ListItem';
import SelectAvatar from '../../ui/SelectAvatar';
import Spinner from '../../ui/Spinner';
import TextArea from '../../ui/TextArea';
import './Management.scss';
@ -231,13 +229,9 @@ const ManageBot: FC<OwnProps & StateProps> = ({
onClick={handleProfileSave}
disabled={isLoading}
ariaLabel={lang('Save')}
>
{isLoading ? (
<Spinner color="white" />
) : (
<Icon name="check" />
)}
</FloatingActionButton>
iconName="check"
isLoading={isLoading}
/>
<SelectAvatar
onChange={handleSelectAvatar}
inputRef={inputRef}

View File

@ -21,13 +21,11 @@ import useLastCallback from '../../../hooks/useLastCallback';
import useMedia from '../../../hooks/useMedia';
import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import AvatarEditable from '../../ui/AvatarEditable';
import ConfirmDialog from '../../ui/ConfirmDialog';
import FloatingActionButton from '../../ui/FloatingActionButton';
import InputText from '../../ui/InputText';
import ListItem from '../../ui/ListItem';
import Spinner from '../../ui/Spinner';
import Switcher from '../../ui/Switcher';
import TextArea from '../../ui/TextArea';
@ -358,13 +356,9 @@ const ManageChannel: FC<OwnProps & StateProps> = ({
onClick={handleUpdateChannel}
disabled={isLoading}
ariaLabel={lang('Save')}
>
{isLoading ? (
<Spinner color="white" />
) : (
<Icon name="check" />
)}
</FloatingActionButton>
iconName="check"
isLoading={isLoading}
/>
<ConfirmDialog
isOpen={isDeleteDialogOpen}
onClose={closeDeleteDialog}

View File

@ -13,7 +13,6 @@ import useHistoryBack from '../../../hooks/useHistoryBack';
import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import PrivateChatInfo from '../../common/PrivateChatInfo';
import Checkbox from '../../ui/Checkbox';
import FloatingActionButton from '../../ui/FloatingActionButton';
@ -149,9 +148,8 @@ const ManageChatAdministrators: FC<OwnProps & StateProps> = ({
isShown={canAddNewAdmins}
onClick={handleAddAdminClick}
ariaLabel={lang('Channel.Management.AddModerator')}
>
<Icon name="add-user-filled" />
</FloatingActionButton>
iconName="add-user-filled"
/>
</div>
{canToggleSignatures && (

View File

@ -21,7 +21,6 @@ import useHistoryBack from '../../../hooks/useHistoryBack';
import useOldLang from '../../../hooks/useOldLang';
import usePreviousDeprecated from '../../../hooks/usePreviousDeprecated';
import Icon from '../../common/icons/Icon';
import LinkField from '../../common/LinkField';
import ManageUsernames from '../../common/ManageUsernames';
import SafeLink from '../../common/SafeLink';
@ -31,7 +30,6 @@ import FloatingActionButton from '../../ui/FloatingActionButton';
import ListItem from '../../ui/ListItem';
import Loading from '../../ui/Loading';
import RadioGroup from '../../ui/RadioGroup';
import Spinner from '../../ui/Spinner';
type PrivacyType = 'private' | 'public';
@ -281,13 +279,9 @@ const ManageChatPrivacyType: FC<OwnProps & StateProps> = ({
disabled={isLoading}
ariaLabel={lang('Save')}
onClick={handleSave}
>
{isLoading ? (
<Spinner color="white" />
) : (
<Icon name="check" />
)}
</FloatingActionButton>
iconName="check"
isLoading={isLoading}
/>
<ConfirmDialog
isOpen={isUsernameLostDialogOpen}
onClose={closeUsernameLostDialog}

View File

@ -12,7 +12,6 @@ import useFlag from '../../../hooks/useFlag';
import useHistoryBack from '../../../hooks/useHistoryBack';
import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import PrivateChatInfo from '../../common/PrivateChatInfo';
import FloatingActionButton from '../../ui/FloatingActionButton';
import ListItem, { type MenuItemContextAction } from '../../ui/ListItem';
@ -106,9 +105,8 @@ const ManageChatRemovedUsers: FC<OwnProps & StateProps> = ({
isShown
onClick={openRemoveUserModal}
ariaLabel={lang('Channel.EditAdmin.Permission.BanUsers')}
>
<Icon name="add-user-filled" />
</FloatingActionButton>
iconName="add-user-filled"
/>
)}
{chat && canDeleteMembers && (
<RemoveGroupUserModal

View File

@ -28,14 +28,12 @@ import useLastCallback from '../../../hooks/useLastCallback';
import useMedia from '../../../hooks/useMedia';
import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import AvatarEditable from '../../ui/AvatarEditable';
import Checkbox from '../../ui/Checkbox';
import ConfirmDialog from '../../ui/ConfirmDialog';
import FloatingActionButton from '../../ui/FloatingActionButton';
import InputText from '../../ui/InputText';
import ListItem from '../../ui/ListItem';
import Spinner from '../../ui/Spinner';
import Switcher from '../../ui/Switcher';
import TextArea from '../../ui/TextArea';
@ -469,13 +467,9 @@ const ManageGroup: FC<OwnProps & StateProps> = ({
onClick={handleUpdateGroup}
disabled={isLoading}
ariaLabel={lang('Save')}
>
{isLoading ? (
<Spinner color="white" />
) : (
<Icon name="check" />
)}
</FloatingActionButton>
iconName="check"
isLoading={isLoading}
/>
<ConfirmDialog
isOpen={isDeleteDialogOpen}
onClose={closeDeleteDialog}

View File

@ -17,14 +17,12 @@ import useFlag from '../../../hooks/useFlag';
import useHistoryBack from '../../../hooks/useHistoryBack';
import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import PrivateChatInfo from '../../common/PrivateChatInfo';
import Checkbox from '../../ui/Checkbox';
import ConfirmDialog from '../../ui/ConfirmDialog';
import FloatingActionButton from '../../ui/FloatingActionButton';
import InputText from '../../ui/InputText';
import ListItem from '../../ui/ListItem';
import Spinner from '../../ui/Spinner';
type OwnProps = {
chatId: string;
@ -401,13 +399,9 @@ const ManageGroupAdminRights: FC<OwnProps & StateProps> = ({
onClick={handleSavePermissions}
ariaLabel={lang('Save')}
disabled={isLoading}
>
{isLoading ? (
<Spinner color="white" />
) : (
<Icon name="check" />
)}
</FloatingActionButton>
iconName="check"
isLoading={isLoading}
/>
{!isNewAdmin && (
<ConfirmDialog

View File

@ -24,7 +24,6 @@ import useKeyboardListNavigation from '../../../hooks/useKeyboardListNavigation'
import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import NothingFound from '../../common/NothingFound';
import PrivateChatInfo from '../../common/PrivateChatInfo';
import FloatingActionButton from '../../ui/FloatingActionButton';
@ -258,9 +257,8 @@ const ManageGroupMembers: FC<OwnProps & StateProps> = ({
isShown
onClick={handleNewMemberDialogOpen}
ariaLabel={lang('lng_channel_add_users')}
>
<Icon name="add-user-filled" />
</FloatingActionButton>
iconName="add-user-filled"
/>
)}
{canDeleteMembers && (
<DeleteMemberModal

View File

@ -25,13 +25,11 @@ import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang';
import useManagePermissions from '../hooks/useManagePermissions';
import Icon from '../../common/icons/Icon';
import PaidMessagePrice from '../../common/paidMessage/PaidMessagePrice';
import PrivateChatInfo from '../../common/PrivateChatInfo';
import PermissionCheckboxList from '../../main/PermissionCheckboxList';
import FloatingActionButton from '../../ui/FloatingActionButton';
import ListItem from '../../ui/ListItem';
import Spinner from '../../ui/Spinner';
import Switcher from '../../ui/Switcher';
type OwnProps = {
@ -340,13 +338,9 @@ const ManageGroupPermissions: FC<OwnProps & StateProps> = ({
onClick={handleUpdatePermissions}
ariaLabel={lang('Save')}
disabled={arePermissionsLoading}
>
{arePermissionsLoading ? (
<Spinner color="white" />
) : (
<Icon name="check" />
)}
</FloatingActionButton>
iconName="check"
isLoading={arePermissionsLoading}
/>
</div>
);
};

View File

@ -16,13 +16,11 @@ import useLang from '../../../hooks/useLang';
import useOldLang from '../../../hooks/useOldLang';
import useManagePermissions from '../hooks/useManagePermissions';
import Icon from '../../common/icons/Icon';
import PrivateChatInfo from '../../common/PrivateChatInfo';
import PermissionCheckboxList from '../../main/PermissionCheckboxList';
import ConfirmDialog from '../../ui/ConfirmDialog';
import FloatingActionButton from '../../ui/FloatingActionButton';
import ListItem from '../../ui/ListItem';
import Spinner from '../../ui/Spinner';
type OwnProps = {
chatId: string;
@ -177,13 +175,9 @@ const ManageGroupUserPermissions: FC<OwnProps & StateProps> = ({
onClick={handleSavePermissions}
ariaLabel={oldLang('Save')}
disabled={isLoading}
>
{isLoading ? (
<Spinner color="white" />
) : (
<Icon name="check" />
)}
</FloatingActionButton>
iconName="check"
isLoading={isLoading}
/>
<ConfirmDialog
isOpen={isBanConfirmationDialogOpen}

View File

@ -16,7 +16,6 @@ import useOldLang from '../../../hooks/useOldLang';
import useSyncEffect from '../../../hooks/useSyncEffect';
import CalendarModal from '../../common/CalendarModal';
import Icon from '../../common/icons/Icon';
import Button from '../../ui/Button';
import Checkbox from '../../ui/Checkbox';
import FloatingActionButton from '../../ui/FloatingActionButton';
@ -251,9 +250,8 @@ const ManageInvite: FC<OwnProps & StateProps> = ({
onClick={handleSaveClick}
disabled={isSubmitBlocked}
ariaLabel={editingInvite ? lang('SaveLink') : lang('CreateLink')}
>
<Icon name="check" />
</FloatingActionButton>
iconName="check"
/>
</div>
<CalendarModal
isOpen={isCalendarOpened}

View File

@ -16,13 +16,11 @@ import { selectChat, selectChatFullInfo } from '../../../global/selectors';
import useHistoryBack from '../../../hooks/useHistoryBack';
import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import ReactionStaticEmoji from '../../common/reactions/ReactionStaticEmoji';
import Checkbox from '../../ui/Checkbox';
import FloatingActionButton from '../../ui/FloatingActionButton';
import RadioGroup from '../../ui/RadioGroup';
import RangeSlider from '../../ui/RangeSlider';
import Spinner from '../../ui/Spinner';
type OwnProps = {
chatId: string;
@ -254,13 +252,9 @@ const ManageReactions: FC<OwnProps & StateProps> = ({
onClick={handleSaveReactions}
ariaLabel={lang('Save')}
disabled={isLoading}
>
{isLoading ? (
<Spinner color="white" />
) : (
<Icon name="check" />
)}
</FloatingActionButton>
iconName="check"
isLoading={isLoading}
/>
</div>
);
};

View File

@ -27,7 +27,6 @@ import useLang from '../../../hooks/useLang';
import useOldLang from '../../../hooks/useOldLang';
import Avatar from '../../common/Avatar';
import Icon from '../../common/icons/Icon';
import PrivateChatInfo from '../../common/PrivateChatInfo';
import Checkbox from '../../ui/Checkbox';
import ConfirmDialog from '../../ui/ConfirmDialog';
@ -35,7 +34,6 @@ import FloatingActionButton from '../../ui/FloatingActionButton';
import InputText from '../../ui/InputText';
import ListItem from '../../ui/ListItem';
import SelectAvatar from '../../ui/SelectAvatar';
import Spinner from '../../ui/Spinner';
import TextArea from '../../ui/TextArea';
import './Management.scss';
@ -315,13 +313,9 @@ const ManageUser: FC<OwnProps & StateProps> = ({
onClick={handleProfileSave}
disabled={isLoading}
ariaLabel={oldLang('Save')}
>
{isLoading ? (
<Spinner color="white" />
) : (
<Icon name="check" />
)}
</FloatingActionButton>
iconName="check"
isLoading={isLoading}
/>
<ConfirmDialog
isOpen={isDeleteDialogOpen}
onClose={closeDeleteDialog}

View File

@ -14,11 +14,9 @@ import useHistoryBack from '../../../hooks/useHistoryBack.ts';
import useLang from '../../../hooks/useLang.ts';
import useLastCallback from '../../../hooks/useLastCallback.ts';
import Icon from '../../common/icons/Icon.tsx';
import AvatarEditable from '../../ui/AvatarEditable.tsx';
import FloatingActionButton from '../../ui/FloatingActionButton.tsx';
import InputText from '../../ui/InputText.tsx';
import Spinner from '../../ui/Spinner.tsx';
type OwnProps = {
chatId: string;
@ -113,13 +111,9 @@ const NewDiscussionGroup: FC<OwnProps & StateProps> = ({
onClick={handleCreateGroup}
disabled={isLoading}
ariaLabel={lang('DiscussionCreateGroup')}
>
{isLoading ? (
<Spinner color="white" />
) : (
<Icon name="arrow-right" />
)}
</FloatingActionButton>
iconName="arrow-right"
isLoading={isLoading}
/>
</div>
</div>
</div>

View File

@ -13,7 +13,6 @@ import useEffectWithPrevDeps from '../../../hooks/useEffectWithPrevDeps';
import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import PeerPicker from '../../common/pickers/PeerPicker';
import FloatingActionButton from '../../ui/FloatingActionButton';
@ -85,9 +84,8 @@ function CloseFriends({
isShown={isSubmitShown}
onClick={handleSubmit}
ariaLabel={lang('Save')}
>
<Icon name="check" />
</FloatingActionButton>
iconName="check"
/>
</div>
</>
);

View File

@ -1,11 +1,18 @@
.FloatingActionButton {
--transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1), background-color 0.15s, color 0.15s, opacity 0.15s;
position: absolute;
z-index: 2;
right: 1rem;
bottom: 1rem;
transform: translateY(5rem);
transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
transition: var(--transition);
&:active,
&.clicked {
transition: var(--transition) !important;
}
body.no-page-transitions & {
transition: none !important;

View File

@ -1,35 +1,36 @@
import type { FC } from '../../lib/teact/teact';
import type React from '../../lib/teact/teact';
import type { IconName } from '../../types/icons';
import type { OwnProps as ButtonProps } from './Button';
import buildClassName from '../../util/buildClassName';
import useOldLang from '../../hooks/useOldLang';
import IconWithSpinner from '../common/IconWithSpinner';
import Button from './Button';
import './FloatingActionButton.scss';
type OwnProps = {
isShown: boolean;
iconName: IconName;
className?: string;
color?: ButtonProps['color'];
ariaLabel?: ButtonProps['ariaLabel'];
disabled?: boolean;
isLoading?: boolean;
onClick: () => void;
children: React.ReactNode;
};
const FloatingActionButton: FC<OwnProps> = ({
const FloatingActionButton = ({
isShown,
iconName,
className,
color = 'primary',
ariaLabel,
disabled,
isLoading,
onClick,
children,
}) => {
}: OwnProps) => {
const lang = useOldLang();
const buttonClassName = buildClassName(
@ -49,7 +50,7 @@ const FloatingActionButton: FC<OwnProps> = ({
tabIndex={-1}
isRtl={lang.isRtl}
>
{children}
<IconWithSpinner iconName={iconName} isLoading={isLoading} />
</Button>
);
};