From 2aab469816c047df4059eb0dd95a33a6fe6b137e Mon Sep 17 00:00:00 2001
From: Linus Rath <139418639+rathlinus@users.noreply.github.com>
Date: Tue, 3 Nov 2026 14:38:21 +0100
Subject: [PATCH] fix: keep empty plugin frames rendered so they can report a
height, and out of the Tab order
---
.../plugin-iframe-slot-props.test.tsx | 45 ++++++++++++++++++-
components/plugins/plugin-iframe-slot.tsx | 9 ++--
2 files changed, 49 insertions(+), 5 deletions(-)
diff --git a/components/plugins/__tests__/plugin-iframe-slot-props.test.tsx b/components/plugins/__tests__/plugin-iframe-slot-props.test.tsx
index eb57628f3..37cc6919a 100644
--- a/components/plugins/__tests__/plugin-iframe-slot-props.test.tsx
+++ b/components/plugins/__tests__/plugin-iframe-slot-props.test.tsx
@@ -1,5 +1,5 @@
import { describe, it, expect, vi, beforeEach } from 'vitest';
-import { render, waitFor } from '@testing-library/react';
+import { act, render, waitFor } from '@testing-library/react';
import type { InstalledPlugin } from '@/lib/plugin-types';
const evaluateShouldShow = vi.fn(async () => true);
@@ -12,7 +12,11 @@ vi.mock('@/lib/plugin-sandbox/registry', () => ({
code: '',
tier: 'untrusted',
background: { evaluateShouldShow },
- slotOffers: [{ name: 'email-banner', hasShouldShow, order: 100 }, { name: 'composer-sidebar-right', hasShouldShow: false, order: 100, fill: true }],
+ slotOffers: [
+ { name: 'email-banner', hasShouldShow, order: 100 },
+ { name: 'composer-sidebar-right', hasShouldShow: false, order: 100, fill: true },
+ { name: 'toolbar-actions', hasShouldShow: false, order: 100 },
+ ],
}),
}));
@@ -87,6 +91,43 @@ describe('PluginIframeSlot', () => {
});
});
+describe('PluginIframeSlot with nothing to show yet', () => {
+ type SlotOptions = { onResize: (height: number, width?: number) => void };
+ const reportSize = (height: number, width?: number) => act(() => {
+ ((createSlotInstance.mock.calls[0] as unknown[])[0] as SlotOptions).onResize(height, width);
+ });
+
+ it.each([
+ ['block', 'email-banner', ['ui:email-banner']],
+ ['inline', 'toolbar-actions', ['ui:toolbar']],
+ ] as const)('keeps a %s frame rendered and out of the Tab order until it reports a height', async (_kind, slot, perms) => {
+ activePlugin = plugin([...perms]);
+ const { container } = render(