From 432a8c10c26692a34c41e1d16786bf2c278ab231 Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Thu, 4 Jun 2026 10:37:39 -0300 Subject: [PATCH 1/3] VideoPress: replace black Notice.ActionButton upgrade CTA with primary Button The ContextualUpgradeTrigger migration to a @wordpress/ui Notice (#48909) rendered its CTA via Notice.ActionButton, which base-ui styles as a dark/high-contrast button that looks out of place on the VideoPress admin page. Swap it for the standard primary Button already imported from @automattic/jetpack-components, restoring the primary CTA the legacy trigger rendered. The click handler is unchanged, so the jetpack_videopress_upgrade_trigger_link_click Tracks event and the checkout 'run' workflow both still fire. The Notice container and the always-rendered Notice.Description (VIDP-245 base-ui ref-merge invariant) are preserved. --- .../changelog/fix-videopress-upgrade-cta-black-button | 4 ++++ .../src/client/admin/components/admin-page/index.tsx | 9 ++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 projects/packages/videopress/changelog/fix-videopress-upgrade-cta-black-button diff --git a/projects/packages/videopress/changelog/fix-videopress-upgrade-cta-black-button b/projects/packages/videopress/changelog/fix-videopress-upgrade-cta-black-button new file mode 100644 index 000000000000..e2be1578ed0c --- /dev/null +++ b/projects/packages/videopress/changelog/fix-videopress-upgrade-cta-black-button @@ -0,0 +1,4 @@ +Significance: patch +Type: fixed + +Fix the upgrade notice CTA rendering as an out-of-place dark button; restore the standard primary button styling. diff --git a/projects/packages/videopress/src/client/admin/components/admin-page/index.tsx b/projects/packages/videopress/src/client/admin/components/admin-page/index.tsx index ebe083924eb0..387a021bb613 100644 --- a/projects/packages/videopress/src/client/admin/components/admin-page/index.tsx +++ b/projects/packages/videopress/src/client/admin/components/admin-page/index.tsx @@ -271,7 +271,14 @@ const UpgradeTrigger = ( { hasUsedVideo = false }: { hasUsedVideo: boolean } ) = { description } - { cta } + { /* Render a standard primary Button rather than `Notice.ActionButton`: + base-ui styles the latter as a dark/high-contrast button, which looks + out of place here (see PR #48909). This restores the primary CTA the + legacy `ContextualUpgradeTrigger` rendered. The click handler still + records the Tracks event and runs the checkout workflow. */ } + ); From 6dce0f90b347131d4d46908430713cb42bd73e6c Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Thu, 4 Jun 2026 11:21:58 -0300 Subject: [PATCH 2/3] Render VideoPress upgrade CTA as Notice.ActionLink instead of a filled button --- .../fix-videopress-upgrade-cta-black-button | 2 +- .../admin/components/admin-page/index.tsx | 24 +++++++++++++------ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/projects/packages/videopress/changelog/fix-videopress-upgrade-cta-black-button b/projects/packages/videopress/changelog/fix-videopress-upgrade-cta-black-button index e2be1578ed0c..7f4c5bc8e036 100644 --- a/projects/packages/videopress/changelog/fix-videopress-upgrade-cta-black-button +++ b/projects/packages/videopress/changelog/fix-videopress-upgrade-cta-black-button @@ -1,4 +1,4 @@ Significance: patch Type: fixed -Fix the upgrade notice CTA rendering as an out-of-place dark button; restore the standard primary button styling. +Fix the upgrade notice CTA rendering as an out-of-place dark button; restore the lightweight text-link styling. diff --git a/projects/packages/videopress/src/client/admin/components/admin-page/index.tsx b/projects/packages/videopress/src/client/admin/components/admin-page/index.tsx index 387a021bb613..b961cf6a03c5 100644 --- a/projects/packages/videopress/src/client/admin/components/admin-page/index.tsx +++ b/projects/packages/videopress/src/client/admin/components/admin-page/index.tsx @@ -271,14 +271,24 @@ const UpgradeTrigger = ( { hasUsedVideo = false }: { hasUsedVideo: boolean } ) = { description } - { /* Render a standard primary Button rather than `Notice.ActionButton`: - base-ui styles the latter as a dark/high-contrast button, which looks - out of place here (see PR #48909). This restores the primary CTA the - legacy `ContextualUpgradeTrigger` rendered. The click handler still - records the Tracks event and runs the checkout workflow. */ } - + ); From d50fd1cf1f1954bfb6923df2f2471ec6f7975f34 Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Thu, 4 Jun 2026 14:35:48 -0300 Subject: [PATCH 3/3] VideoPress: restructure upgrade notice as Title + Description + ActionButton MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per PR #49400 review (keoshi, simison): replace the long text-link CTA with a concise "Upgrade" Notice.ActionButton, and split the notice copy into two balanced lines — a Notice.Title contextual heads-up and a Notice.Description upsell pitch — following simison's structure example. ActionButton takes onClick directly, so the prior ActionLink href="#" + preventDefault workaround (gutenberg#77098) is dropped entirely. VIDP-245 invariant preserved: Title, Description and Actions are all rendered unconditionally; only the title text varies on hasUsedVideo, keeping the Notice.Root subtree shape stable so base-ui's ref-merge hook does not misalign and crash on the next video upload/delete. --- .../fix-videopress-upgrade-cta-black-button | 2 +- .../admin/components/admin-page/index.tsx | 49 ++++++------------- 2 files changed, 17 insertions(+), 34 deletions(-) diff --git a/projects/packages/videopress/changelog/fix-videopress-upgrade-cta-black-button b/projects/packages/videopress/changelog/fix-videopress-upgrade-cta-black-button index 7f4c5bc8e036..95f1259d38cb 100644 --- a/projects/packages/videopress/changelog/fix-videopress-upgrade-cta-black-button +++ b/projects/packages/videopress/changelog/fix-videopress-upgrade-cta-black-button @@ -1,4 +1,4 @@ Significance: patch Type: fixed -Fix the upgrade notice CTA rendering as an out-of-place dark button; restore the lightweight text-link styling. +Restructure the free-plan upgrade notice into a balanced Notice.Title heads-up line, a Notice.Description upsell pitch, and a concise "Upgrade" Notice.ActionButton, replacing the out-of-place dark button. diff --git a/projects/packages/videopress/src/client/admin/components/admin-page/index.tsx b/projects/packages/videopress/src/client/admin/components/admin-page/index.tsx index b961cf6a03c5..72e6f6e2d63b 100644 --- a/projects/packages/videopress/src/client/admin/components/admin-page/index.tsx +++ b/projects/packages/videopress/src/client/admin/components/admin-page/index.tsx @@ -223,6 +223,10 @@ const UPGRADE_TRIGGER_FREE_PLAN_TEXT = __( 'The free plan includes one video upload.', 'jetpack-videopress-pkg' ); +const UPGRADE_TRIGGER_UNLOCK_TEXT = __( + 'Unlock unlimited videos, 1TB of storage, and more!', + 'jetpack-videopress-pkg' +); const UpgradeTrigger = ( { hasUsedVideo = false }: { hasUsedVideo: boolean } ) => { const { adminUri, siteSuffix } = window.jetpackVideoPressInitialState; @@ -252,43 +256,22 @@ const UpgradeTrigger = ( { hasUsedVideo = false }: { hasUsedVideo: boolean } ) = // VIDP-245: keep the `Notice.Root` children shape invariant across the // `hasUsedVideo` flip. base-ui@1.4.1's `useRenderElement` swaps between two // different ref-merge hooks depending on subtree shape, so conditionally - // mounting `` (as this did before) misaligns its stored - // fork-ref and crashes on the next upload/delete. Always render the - // Description — mirroring the modern dashboard's `free-tier-notice.tsx` — - // varying only its text, with a non-empty fallback nudge before the first - // upload so we never render an empty styled row. The two strings are hoisted - // to module scope (above) to avoid the terser i18n ternary-fold. - const description = hasUsedVideo - ? UPGRADE_TRIGGER_USED_VIDEO_TEXT - : UPGRADE_TRIGGER_FREE_PLAN_TEXT; - - const cta = __( - 'Upgrade now to unlock unlimited videos, 1TB of storage, and more!', - 'jetpack-videopress-pkg' - ); + // mounting/unmounting a `Notice` subcomponent across the flip misaligns its + // stored fork-ref and crashes on the next upload/delete. Therefore always + // render `Notice.Title`, `Notice.Description` and `Notice.Actions` — never + // wrap any of them in a `hasUsedVideo && (...)` conditional. Vary only the + // TEXT: the `title` line carries the contextual heads-up (non-empty in both + // states) while the Description holds the constant upsell pitch. The strings + // are hoisted to module scope (above) to avoid the terser i18n ternary-fold. + const title = hasUsedVideo ? UPGRADE_TRIGGER_USED_VIDEO_TEXT : UPGRADE_TRIGGER_FREE_PLAN_TEXT; + const cta = __( 'Upgrade', 'jetpack-videopress-pkg' ); return ( - { description } + { title } + { UPGRADE_TRIGGER_UNLOCK_TEXT } - { /* Render the CTA as `Notice.ActionLink` rather than a filled Button: - base-ui's `Notice.ActionButton` styles as a dark/high-contrast button - and a filled primary Button carries too much weight for an upgrade - nudge (see PR #48909). The lightweight text link matches the legacy - `ContextualUpgradeTrigger` look and the modern dashboard's - `free-tier-notice.tsx`. `ActionLink` is an anchor, so the placeholder - `href="#"` is cancelled in the click handler; the wrapped - `onButtonClickHandler` still records the Tracks event and then runs the - checkout workflow. */ } - { - event.preventDefault(); - onButtonClickHandler(); - } } - > - { cta } - + { cta } );