Skip to content

Commit 7e536bd

Browse files
committed
🐛 fix: socials input box unfocusing on input
The event CANVAS_EDIT_SECTION gets called every time the value of the social input box gets changed to update the UI, which updates the currently selected secton, which in turn updates the editor panel, causing the input boxes to unnecessarily refresh, thus unfocusing. Memoizing fixes these unnecessary rebuilds. Fixes #139
1 parent 45a7e9f commit 7e536bd

1 file changed

Lines changed: 67 additions & 26 deletions

File tree

  • src/features/socials/panel/views/editing

src/features/socials/panel/views/editing/index.tsx

Lines changed: 67 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useRef } from 'react';
1+
import { useMemo, useRef } from 'react';
22
import { AnimatePresence, Reorder } from 'framer-motion';
33

44
import { GroupFields } from 'components';
@@ -13,6 +13,7 @@ import { useCanvas, useForceUpdate } from 'hooks';
1313
import { getDeepObjectProperty, getSocialImgUrl } from 'utils';
1414

1515
import { fields, getIconFields } from './fields';
16+
import React from 'react';
1617

1718
type Social = {
1819
icon: string;
@@ -23,6 +24,57 @@ type Socials = {
2324
[key: string]: Social;
2425
};
2526

27+
interface MemoizedIconEditorProps {
28+
social: string;
29+
props: Social;
30+
index: number;
31+
iconEditorRefs: React.MutableRefObject<IconEditorRef[]>;
32+
}
33+
34+
const MemoizedIconEditor = React.memo(
35+
function MemoizedIconEditor({
36+
social,
37+
props,
38+
index,
39+
iconEditorRefs,
40+
}: MemoizedIconEditorProps) {
41+
const { icon, short_name } = props;
42+
43+
return (
44+
<IconEditor
45+
key={social}
46+
id={social}
47+
label={short_name ?? social}
48+
baseEditPath="content.socials"
49+
img={{
50+
alt: `${social} ${icon} logo`,
51+
url: getSocialImgUrl('icon', social, { icon }),
52+
}}
53+
slots={{
54+
expansibleContent: () => (
55+
<>
56+
{getIconFields(social).map(group => (
57+
<GroupFields key={group.id} {...group} />
58+
))}
59+
</>
60+
),
61+
}}
62+
ref={ref => {
63+
iconEditorRefs.current[index] = ref!;
64+
}}
65+
refs={iconEditorRefs.current}
66+
/>
67+
);
68+
},
69+
(prevProps: MemoizedIconEditorProps, nextProps: MemoizedIconEditorProps) => {
70+
if (prevProps.social !== nextProps.social) return false;
71+
if (prevProps.index !== nextProps.index) return false;
72+
if (prevProps.props.icon !== nextProps.props.icon) return false;
73+
if (prevProps.props.short_name !== nextProps.props.short_name) return false;
74+
return true;
75+
}
76+
);
77+
2678
export function Editing() {
2779
const iconEditorRefs = useRef<IconEditorRef[]>([]);
2880

@@ -34,8 +86,15 @@ export function Editing() {
3486
'props.content.socials'
3587
)!;
3688

37-
const socials = Object.entries(selectedSocials);
38-
const socials_names = socials.map(social => social[0]);
89+
const socialsLength = Object.keys(selectedSocials).length;
90+
91+
const memoizedSocialData = useMemo(() => {
92+
const currentSocials = Object.entries(selectedSocials);
93+
const currentSocialsNames = currentSocials.map(social => social[0]);
94+
return { socials: currentSocials, socials_names: currentSocialsNames };
95+
}, [socialsLength]);
96+
97+
const { socials, socials_names } = memoizedSocialData;
3998

4099
function onReOrder(order: typeof socials_names) {
41100
const path = 'content.socials';
@@ -61,31 +120,13 @@ export function Editing() {
61120
<AnimatePresence>
62121
<Reorder.Group axis="y" values={socials_names} onReorder={onReOrder}>
63122
{socials.map(([social, props], index) => {
64-
const { icon, short_name } = props;
65-
66123
return (
67-
<IconEditor
124+
<MemoizedIconEditor
68125
key={social}
69-
id={social}
70-
label={short_name ?? social}
71-
baseEditPath="content.socials"
72-
img={{
73-
alt: `${social} ${icon} logo`,
74-
url: getSocialImgUrl('icon', social, { icon }),
75-
}}
76-
slots={{
77-
expansibleContent: () => (
78-
<>
79-
{getIconFields(social).map(group => (
80-
<GroupFields key={group.id} {...group} />
81-
))}
82-
</>
83-
),
84-
}}
85-
ref={ref => {
86-
iconEditorRefs.current[index] = ref!;
87-
}}
88-
refs={iconEditorRefs.current}
126+
social={social}
127+
props={props}
128+
index={index}
129+
iconEditorRefs={iconEditorRefs}
89130
/>
90131
);
91132
})}

0 commit comments

Comments
 (0)