Skip to content

fix: add defineSlots to all components for proper slot type inference#684

Merged
harlan-zw merged 2 commits intomainfrom
fix/define-slots-typing
Mar 30, 2026
Merged

fix: add defineSlots to all components for proper slot type inference#684
harlan-zw merged 2 commits intomainfrom
fix/define-slots-typing

Conversation

@harlan-zw
Copy link
Copy Markdown
Collaborator

🔗 Linked issue

N/A (user-reported: clusterer renderer slot typed as any)

❓ Type of change

  • 📖 Documentation
  • 🐞 Bug fix
  • 👌 Enhancement
  • ✨ New feature
  • 🧹 Chore
  • ⚠️ Breaking change

📚 Description

All 19 components with slots were missing defineSlots, so slot props were typed as any in consuming templates. This adds proper defineSlots type definitions to every component, giving IDEs autocomplete and type checking for slot bindings like #renderer="{ cluster, stats, map }".

Components with typed slot props: ScriptGoogleMapsMarkerClusterer (renderer), ScriptXEmbed, ScriptBlueskyEmbed, ScriptInstagramEmbed (default + error), ScriptGoogleMapsStaticMap (default), ScriptCrisp, ScriptIntercom (default), ScriptPayPalButtons, ScriptPayPalMessages (default), ScriptYouTubePlayer, ScriptVimeoPlayer (placeholder), plus 7 components with no-prop slots.

All 19 components with slots were missing defineSlots, meaning slot
props were typed as any. This adds proper type definitions so IDEs
provide autocomplete and type checking for slot bindings.
@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Mar 30, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
scripts-playground Ready Ready Preview, Comment Mar 30, 2026 1:29pm

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Mar 30, 2026

Open in StackBlitz

npm i https://pkg.pr.new/@nuxt/scripts@684

commit: d02a4da

@harlan-zw harlan-zw requested a review from Copilot March 30, 2026 13:19
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 30, 2026

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

This pull request adds explicit defineSlots type declarations to multiple Vue components in packages/script/src/runtime/components/, formalizing named and default slot signatures and slot prop types. It also updates scripts/generate-registry-types.ts to extract slot metadata and emits corresponding slot interfaces and schema entries into packages/script/src/registry-types.json. Changes are type-level only and do not alter runtime control flow, events, or template rendering.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding defineSlots declarations to components for proper TypeScript slot type inference, which is the primary focus of this PR.
Description check ✅ Passed The description is directly related to the changeset, explaining the root cause (missing defineSlots causing slot props typed as any), the solution (adding defineSlots to 19 components), and listing affected components with examples of improved typing.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/define-slots-typing

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/script/src/runtime/components/ScriptVimeoPlayer.vue (1)

70-77: Placeholder slot type is incomplete — missing v-bind="payload" props.

Line 301 spreads payload (the oEmbed response) in addition to :placeholder:

<slot v-if="!ready" v-bind="payload" :placeholder="placeholder" name="placeholder">

The slot type only declares placeholder, so consumers won't get autocomplete for other oEmbed properties like thumbnail_url, title, author_name, etc.

🔧 Suggested fix to include payload properties

You could either type the full oEmbed response or at minimum document that additional props are available:

 defineSlots<{
   default?: () => any
-  placeholder?: (props: { placeholder: string | undefined }) => any
+  placeholder?: (props: { placeholder: string | undefined } & Partial<VimeoOEmbedResponse>) => any
   loading?: () => any
   awaitingLoad?: () => any
   error?: () => any
 }>()

Where VimeoOEmbedResponse captures the relevant oEmbed fields, or use a looser type like Record<string, unknown> if the exact shape isn't worth maintaining.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/script/src/runtime/components/ScriptVimeoPlayer.vue` around lines 70
- 77, The placeholder slot typing is too narrow: update the defineSlots generic
so the placeholder slot includes the full oEmbed payload (or a loose map) in
addition to placeholder; specifically modify the defineSlots declaration that
currently types placeholder as (props: { placeholder: string | undefined }) =>
any to accept props: { placeholder?: string | undefined } & VimeoOEmbedResponse
(or Record<string, unknown>) so consumers get properties from payload (refer to
defineSlots, placeholder slot, and the payload variable used in the template).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/script/src/runtime/components/ScriptVimeoPlayer.vue`:
- Around line 70-77: The placeholder slot typing is too narrow: update the
defineSlots generic so the placeholder slot includes the full oEmbed payload (or
a loose map) in addition to placeholder; specifically modify the defineSlots
declaration that currently types placeholder as (props: { placeholder: string |
undefined }) => any to accept props: { placeholder?: string | undefined } &
VimeoOEmbedResponse (or Record<string, unknown>) so consumers get properties
from payload (refer to defineSlots, placeholder slot, and the payload variable
used in the template).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 786151e4-e31f-4821-9f1e-aa09fad50cde

📥 Commits

Reviewing files that changed from the base of the PR and between a44e8c9 and 2159adb.

📒 Files selected for processing (19)
  • packages/script/src/runtime/components/GoogleMaps/ScriptGoogleMaps.vue
  • packages/script/src/runtime/components/GoogleMaps/ScriptGoogleMapsInfoWindow.vue
  • packages/script/src/runtime/components/GoogleMaps/ScriptGoogleMapsMarker.vue
  • packages/script/src/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.vue
  • packages/script/src/runtime/components/GoogleMaps/ScriptGoogleMapsOverlayView.vue
  • packages/script/src/runtime/components/GoogleMaps/ScriptGoogleMapsStaticMap.vue
  • packages/script/src/runtime/components/ScriptBlueskyEmbed.vue
  • packages/script/src/runtime/components/ScriptCarbonAds.vue
  • packages/script/src/runtime/components/ScriptCrisp.vue
  • packages/script/src/runtime/components/ScriptGoogleAdsense.vue
  • packages/script/src/runtime/components/ScriptInstagramEmbed.vue
  • packages/script/src/runtime/components/ScriptIntercom.vue
  • packages/script/src/runtime/components/ScriptLemonSqueezy.vue
  • packages/script/src/runtime/components/ScriptPayPalButtons.vue
  • packages/script/src/runtime/components/ScriptPayPalMessages.vue
  • packages/script/src/runtime/components/ScriptStripePricingTable.vue
  • packages/script/src/runtime/components/ScriptVimeoPlayer.vue
  • packages/script/src/runtime/components/ScriptXEmbed.vue
  • packages/script/src/runtime/components/ScriptYouTubePlayer.vue

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot reviewed 19 out of 19 changed files in this pull request and generated no comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Adds slot extraction to generate-registry-types.ts, producing
{Component}Slots declarations and schema fields. Updates
ScriptTypes.vue to render a Slots tab alongside Props and Events.
@harlan-zw harlan-zw merged commit 4df13ed into main Mar 30, 2026
16 of 17 checks passed
@harlan-zw harlan-zw deleted the fix/define-slots-typing branch March 30, 2026 13:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants