Skip to content

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

Merged
harlan-zw merged 2 commits into
mainfrom
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 into
mainfrom
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

vercelBot commented Mar 30, 2026

Copy link
Copy Markdown
Contributor

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

ProjectDeploymentActionsUpdated (UTC)
scripts-playgroundReadyReadyPreview, CommentMar 30, 2026 1:29pm

@pkg-pr-new

pkg-pr-newBot commented Mar 30, 2026

Copy link
Copy Markdown

Open in StackBlitz

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

commit: d02a4da

@harlan-zw
harlan-zw requested a review from CopilotMarch 30, 2026 13:19
@coderabbitai

coderabbitaiBot commented Mar 30, 2026

Copy link
Copy Markdown

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 nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring 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 nameStatusExplanation
Title check✅ PassedThe 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✅ PassedThe 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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

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:

<slotv-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

CopilotAI left a comment

Copy link
Copy Markdown

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 mainMar 30, 2026
16 of 17 checks passed
@harlan-zw
harlan-zw deleted the fix/define-slots-typing branch March 30, 2026 13:32
@harlan-zwharlan-zw mentioned this pull request Apr 15, 2026
Sign up for freeto 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

@harlan-zw