Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ type GlobalSettings = {
interface ThemePreviewProps {
settings: GlobalSettings;
url: string;
// Hidden previews stay mounted and laid out, so revealing one needs no reflow.
isVisible?: boolean;
}

function getPreviewData({
Expand Down Expand Up @@ -71,7 +73,7 @@ function getPreviewData({
return params.toString();
}

const ThemePreview: React.FC<ThemePreviewProps> = ({ settings, url }) => {
const ThemePreview: React.FC<ThemePreviewProps> = ({ settings, url, isVisible = true }) => {
const previewData = getPreviewData({ ...settings });

const injectContentIntoIframe = useCallback(
Expand Down Expand Up @@ -133,7 +135,7 @@ const ThemePreview: React.FC<ThemePreviewProps> = ({ settings, url }) => {
className="absolute -top-px -left-px size-[calc(110%_+_3px)] origin-top-left scale-[.90909] bg-white max-[1600px]:size-[calc(130%_+_3px)] max-[1600px]:scale-[.76923]"
generateContent={injectContentIntoIframe}
height="100%"
parentClassName="relative h-full w-full overflow-hidden"
parentClassName={`absolute inset-0 overflow-hidden ${isVisible ? 'z-10 opacity-100' : 'z-0 opacity-0 pointer-events-none'}`}
testId="theme-preview"
width="100%"
/>
Expand Down
48 changes: 26 additions & 22 deletions apps/admin/src/settings/site/design-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -191,30 +191,34 @@ const DesignModal: React.FC = () => {
}
};

let selectedTabURL = getHomepageUrl(siteData);
switch (selectedPreviewTab) {
case 'homepage':
selectedTabURL = getHomepageUrl(siteData);
break;
case 'post':
selectedTabURL = latestPost.url;
break;
}
// One preview per tab, all mounted up front, so switching needs no refetch.
const previewTargets = [
{ id: 'homepage', url: getHomepageUrl(siteData) },
...(latestPost ? [{ id: 'post', url: latestPost.url }] : []),
];

const previewSettings = {
description,
accentColor,
icon,
logo,
coverImage,
themeSettings: formState.themeSettings,
headingFont,
bodyFont,
};

const rawPreviewContent = (
<ThemePreview
settings={{
description,
accentColor,
icon,
logo,
coverImage,
themeSettings: formState.themeSettings,
headingFont,
bodyFont,
}}
url={selectedTabURL}
/>
<div className="relative size-full">
{previewTargets.map(({ id, url }) => (
<ThemePreview
key={id}
isVisible={selectedPreviewTab === id}
settings={previewSettings}
url={url}
/>
))}
</div>
);
const previewContent =
previewDevice === 'desktop' ? (
Expand Down
3 changes: 2 additions & 1 deletion apps/admin/src/settings/site/design.acceptance.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,10 @@ describe('Design settings', () => {
await renderAdminApp('/settings/design/edit');

const modal = settingsScreen.designModal();
// Both previews are fetched up front, before either tab is selected.
await expect(homepagePreview).toHaveRequestedPreview({ custom: '{}' });
await settingsScreen.designToolbar().getByRole('tab', { name: 'Post' }).click();
await expect(postPreview!).toHaveRequestedPreview({ custom: '{}' });
await settingsScreen.designToolbar().getByRole('tab', { name: 'Post' }).click();

await modal.getByRole('radio', { name: 'Mobile' }).click();
await expect.element(settingsScreen.previewMobile()).toBeVisible();
Expand Down
Loading