From 8b40dc7a328d790b443a9a64401f895093d6b24b Mon Sep 17 00:00:00 2001 From: Papageorgiou Nikos Date: Mon, 6 Nov 2023 13:08:18 +0200 Subject: [PATCH] chore(clerk-js): Replace Avatar preview in OrganizationProfileAvatarUploader with Upload Button (#2014) --- .changeset/dull-stingrays-fix.md | 5 ++ .../CreateOrganizationForm.tsx | 35 +++++++++++-- .../src/ui/elements/AvatarUploader.tsx | 11 +++- packages/clerk-js/src/ui/icons/index.ts | 51 ++++++++++--------- packages/clerk-js/src/ui/icons/upload.svg | 1 + 5 files changed, 73 insertions(+), 30 deletions(-) create mode 100644 .changeset/dull-stingrays-fix.md create mode 100644 packages/clerk-js/src/ui/icons/upload.svg diff --git a/.changeset/dull-stingrays-fix.md b/.changeset/dull-stingrays-fix.md new file mode 100644 index 0000000000..7c2e680bba --- /dev/null +++ b/.changeset/dull-stingrays-fix.md @@ -0,0 +1,5 @@ +--- +'@clerk/clerk-js': patch +--- + +Enhance `CreateOrganizationForm` by replacing `AvatarPreview` with an upload button to prevent layout shifts \ No newline at end of file diff --git a/packages/clerk-js/src/ui/components/CreateOrganization/CreateOrganizationForm.tsx b/packages/clerk-js/src/ui/components/CreateOrganization/CreateOrganizationForm.tsx index cb999c8527..c5cbfceef8 100644 --- a/packages/clerk-js/src/ui/components/CreateOrganization/CreateOrganizationForm.tsx +++ b/packages/clerk-js/src/ui/components/CreateOrganization/CreateOrganizationForm.tsx @@ -3,11 +3,12 @@ import React from 'react'; import { useWizard, Wizard } from '../../common'; import { useCoreOrganization, useCoreOrganizationList } from '../../contexts'; -import { ContentPage, Form, FormButtonContainer, SuccessPage, useCardState } from '../../elements'; -import { QuestionMark } from '../../icons'; +import { Icon } from '../../customizables'; +import { ContentPage, Form, FormButtonContainer, IconButton, SuccessPage, useCardState } from '../../elements'; +import { QuestionMark, Upload } from '../../icons'; import type { LocalizationKey } from '../../localization'; import { localizationKeys } from '../../localization'; -import { createSlug, handleError, useFormControl } from '../../utils'; +import { colors, createSlug, handleError, useFormControl } from '../../utils'; import { InviteMembersForm } from '../OrganizationProfile/InviteMembersForm'; import { InvitationsSentMessage } from '../OrganizationProfile/InviteMembersPage'; import { OrganizationProfileAvatarUploader } from '../OrganizationProfile/OrganizationProfileAvatarUploader'; @@ -121,6 +122,34 @@ export const CreateOrganizationForm = (props: CreateOrganizationFormProps) => { organization={{ name: nameField.value }} onAvatarChange={async file => await setFile(file)} onAvatarRemove={file ? onAvatarRemove : null} + avatarPreviewPlaceholder={ + ({ + transitionDuration: theme.transitionDuration.$controls, + })} + /> + } + sx={theme => ({ + width: theme.sizes.$11, + height: theme.sizes.$11, + borderRadius: theme.radii.$md, + backgroundColor: theme.colors.$avatarBackground, + ':hover': { + backgroundColor: colors.makeTransparent(theme.colors.$avatarBackground, 0.2), + svg: { + transform: 'scale(1.2)', + }, + }, + })} + /> + } /> Promise; onAvatarRemove?: (() => void) | null; + avatarPreviewPlaceholder?: React.ReactElement | null; }; export const fileToBase64 = (file: File): Promise => { @@ -27,7 +28,7 @@ export const AvatarUploader = (props: AvatarUploaderProps) => { const [objectUrl, setObjectUrl] = React.useState(); const card = useCardState(); - const { onAvatarChange, onAvatarRemove, title, avatarPreview, ...rest } = props; + const { onAvatarChange, onAvatarRemove, title, avatarPreview, avatarPreviewPlaceholder, ...rest } = props; const toggle = () => { setShowUpload(!showUpload); @@ -54,6 +55,12 @@ export const AvatarUploader = (props: AvatarUploaderProps) => { return onAvatarRemove?.(); }; + const previewElement = objectUrl + ? React.cloneElement(avatarPreview, { imageUrl: objectUrl }) + : avatarPreviewPlaceholder + ? React.cloneElement(avatarPreviewPlaceholder, { onClick: toggle }) + : avatarPreview; + return ( { align='center' {...rest} > - {objectUrl ? React.cloneElement(avatarPreview, { imageUrl: objectUrl }) : avatarPreview} + {previewElement} \ No newline at end of file