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
421 changes: 421 additions & 0 deletions packages/script/src/registry-types.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,14 @@ const emits = defineEmits<{
error: []
}>()
defineSlots<{
default?: () => any
placeholder?: () => any
loading?: () => any
awaitingLoad?: () => any
error?: () => any
}>()
const apiKey = props.apiKey || scriptRuntimeConfig('googleMaps')?.apiKey
const runtimeConfig = useRuntimeConfig()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ const emit = defineEmits<{
zindex_changed: []
}>()
defineSlots<{
default?: () => any
}>()
const infoWindowEvents = [
'close',
'closeclick',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ const emit = defineEmits<{
*/
dragstart: [payload: google.maps.MapMouseEvent]
}>()
defineSlots<{
default?: () => any
content?: () => any
}>()
const dragEvents = ['drag', 'dragend', 'dragstart'] as const
const slots = useSlots()
const markerContent = useTemplateRef('marker-content')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ const emit = defineEmits<{
clusteringend: [payload: MarkerClustererInstance]
}>()

defineSlots<{
default?: () => any
renderer?: (props: { cluster: Cluster, stats: ClusterStats, map: google.maps.Map }) => any
}>()

const markerClustererEvents = [
'click',
'clusteringbegin',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ const props = withDefaults(defineProps<{
hideWhenClustered: true,
})

defineSlots<{
default?: () => any
}>()

const open = defineModel<boolean>('open', { default: undefined })

const markerContext = inject(MARKER_INJECTION_KEY, undefined)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ const props = withDefaults(defineProps<{
height: 400,
})

defineSlots<{
default?: (props: { src: string }) => any
}>()
const runtimeConfig = useRuntimeConfig()
const proxyConfig = (runtimeConfig.public['nuxt-scripts'] as any)?.googleStaticMapsProxy
const apiKey = props.apiKey || scriptRuntimeConfig('googleMaps')?.apiKey
Expand Down
6 changes: 6 additions & 0 deletions packages/script/src/runtime/components/ScriptBlueskyEmbed.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ const props = withDefaults(defineProps<{
imageProxyEndpoint: undefined,
})

defineSlots<{
default?: (props: NonNullable<typeof slotProps.value>) => any
loading?: () => any
error?: (props: { error: typeof error.value }) => any
}>()

const prefix = scriptsPrefix()

const resolvedApiEndpoint = computed((): string => props.apiEndpoint || `${prefix}/embed/bluesky`)
Expand Down
6 changes: 6 additions & 0 deletions packages/script/src/runtime/components/ScriptCarbonAds.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ const emit = defineEmits<{
ready: [HTMLScriptElement]
}>()

defineSlots<{
awaitingLoad?: () => any
loading?: () => any
error?: () => any
}>()

const attrId = `_carbonads_js`
const carbonadsEl = ref<HTMLElement | null>(import.meta.client ? document.getElementById(attrId) : null)
// syncs to useScript status
Expand Down
7 changes: 7 additions & 0 deletions packages/script/src/runtime/components/ScriptCrisp.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ const emits = defineEmits<{
error: []
}>()

defineSlots<{
default?: (props: { ready: boolean }) => any
awaitingLoad?: () => any
loading?: () => any
error?: () => any
}>()

const rootEl = ref(null)
const trigger = useScriptTriggerElement({ trigger: props.trigger, el: rootEl })

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ const emits = defineEmits<{
error: []
}>()

defineSlots<{
awaitingLoad?: () => any
loading?: () => any
error?: () => any
}>()

const rootEl = ref(null)
const trigger = useScriptTriggerElement({ trigger: props.trigger, el: rootEl })

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ const props = withDefaults(defineProps<{
apiEndpoint: undefined,
})
defineSlots<{
default?: (props: { html: string, shortcode: string | undefined, postUrl: string }) => any
loading?: () => any
error?: (props: { error: typeof error.value }) => any
}>()
const prefix = scriptsPrefix()
const apiEndpoint = computed(() => props.apiEndpoint || `${prefix}/embed/instagram`)
Expand Down
7 changes: 7 additions & 0 deletions packages/script/src/runtime/components/ScriptIntercom.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ const emits = defineEmits<{
error: []
}>()

defineSlots<{
default?: (props: { ready: boolean }) => any
awaitingLoad?: () => any
loading?: () => any
error?: () => any
}>()

const rootEl = ref(null)
const trigger = useScriptTriggerElement({ trigger: props.trigger, el: rootEl })

Expand Down
4 changes: 4 additions & 0 deletions packages/script/src/runtime/components/ScriptLemonSqueezy.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ const emits = defineEmits<{
lemonSqueezyEvent: [LemonSqueezyEventPayload]
}>()

defineSlots<{
default?: () => any
}>()

const rootEl = ref<HTMLElement | null>(null)
const trigger = useScriptTriggerElement({ trigger: props.trigger, el: rootEl })
const instance = useScriptLemonSqueezy({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@ const emit = defineEmits<{
error: [error: unknown]
}>()

defineSlots<{
default?: (props: { sdkInstance: SdkInstance<Components[]> | undefined }) => any
placeholder?: () => any
loading?: () => any
awaitingLoad?: () => any
error?: () => any
}>()

const el = ref<HTMLDivElement | null>(null)
const rootEl = ref<HTMLDivElement | null>(null)
const ready = ref(false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ const emit = defineEmits<{
error: [error: unknown]
}>()

defineSlots<{
default?: (props: { messagesSession: PayPalMessagesSession | undefined }) => any
placeholder?: () => any
loading?: () => any
awaitingLoad?: () => any
error?: () => any
}>()

const el = ref<HTMLDivElement | null>(null)
const rootEl = ref<HTMLDivElement | null>(null)
const ready = ref(false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ const emit = defineEmits<{
error: []
}>()

defineSlots<{
default?: () => any
loading?: () => any
awaitingLoad?: () => any
error?: () => any
}>()

const rootEl = ref<HTMLDivElement | undefined>()
const containerEl = ref<HTMLDivElement | undefined>()
const trigger = useScriptTriggerElement({ trigger: props.trigger, el: rootEl })
Expand Down
8 changes: 8 additions & 0 deletions packages/script/src/runtime/components/ScriptVimeoPlayer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@ const props = withDefaults(defineProps<{

const emits = defineEmits<TEmits>()

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

type EventMap<E extends keyof Vimeo.EventMap> = [event: Vimeo.EventMap[E], player: Vimeo]

interface TEmits {
Expand Down
6 changes: 6 additions & 0 deletions packages/script/src/runtime/components/ScriptXEmbed.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ const props = withDefaults(defineProps<{
imageProxyEndpoint: undefined,
})

defineSlots<{
default?: (props: NonNullable<typeof slotProps.value>) => any
loading?: () => any
error?: (props: { error: typeof error.value }) => any
}>()

const prefix = scriptsPrefix()

const apiEndpoint = computed(() => props.apiEndpoint || `${prefix}/embed/x`)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ const emits = defineEmits<{
'error': [e: YT.OnErrorEvent, target: YT.Player]
'api-change': [e: YT.PlayerEvent, target: YT.Player]
}>()
defineSlots<{
default?: () => any
placeholder?: (props: { placeholder: string }) => any
loading?: () => any
awaitingLoad?: () => any
error?: () => any
}>()

const events: (keyof YT.Events)[] = [
'onReady',
'onStateChange',
Expand Down
51 changes: 51 additions & 0 deletions scripts/generate-registry-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ interface ComponentMeta {
fields: SchemaFieldMeta[]
events: SchemaFieldMeta[]
models: SchemaFieldMeta[]
slots: SchemaFieldMeta[]
}

function resolveTSType(node: any, source: string): string {
Expand Down Expand Up @@ -340,6 +341,7 @@ function extractComponentMeta(scriptSource: string, fileName: string): Component
let propsResult: { code: string, defaults: Record<string, string>, fields: SchemaFieldMeta[] } | null = null
const events: SchemaFieldMeta[] = []
const models: SchemaFieldMeta[] = []
const slots: SchemaFieldMeta[] = []
const constArrays: Record<string, string[]> = {}

// First pass: collect `as const` arrays for event name resolution
Expand Down Expand Up @@ -480,6 +482,44 @@ function extractComponentMeta(scriptSource: string, fileName: string): Component
return
}

// defineSlots<{...}>()
if (node.callee?.name === 'defineSlots') {
const typeArg = node.typeArguments?.params?.[0]
if (typeArg?.type === 'TSTypeLiteral') {
const slotsCode = scriptSource.slice(typeArg.start, typeArg.end)
const slotsComments = parseSchemaComments(slotsCode)

for (const member of typeArg.members || []) {
if (member.type !== 'TSPropertySignature')
continue
const slotName = member.key?.name || member.key?.value
if (!slotName)
continue

// Extract slot props type from the function signature: (props: { ... }) => any
let propsType = '-'
const fnType = member.typeAnnotation?.typeAnnotation
if (fnType?.type === 'TSFunctionType' && fnType.params?.length) {
const param = fnType.params[0]
const paramType = param?.typeAnnotation?.typeAnnotation
if (paramType) {
const resolved = resolveTSType(paramType, scriptSource)
// Avoid leaking unresolvable `typeof` references from runtime variables
propsType = resolved.includes('typeof') ? 'object' : resolved
}
}

slots.push({
name: slotName,
type: propsType,
required: !member.optional,
description: slotsComments[slotName]?.description,
})
}
}
return
}

// defineProps / withDefaults(defineProps)
let definePropsCall: any = null
let defaultsObj: any = null
Expand Down Expand Up @@ -532,6 +572,7 @@ function extractComponentMeta(scriptSource: string, fileName: string): Component
fields: [...propsResult.fields, ...models],
events,
models,
slots,
}
}

Expand Down Expand Up @@ -649,6 +690,16 @@ for (const [componentName, meta] of Object.entries(componentMetas)) {
code: `interface ${componentName}Events {\n${meta.events.map(e => ` ${e.name}: ${e.type}`).join('\n')}\n}`,
})
}

// Store slots as schema fields under a separate key
if (meta.slots.length) {
schemaFields[`${componentName}Slots`] = meta.slots
types[slug].push({
name: `${componentName}Slots`,
kind: 'interface',
code: `interface ${componentName}Slots {\n${meta.slots.map(s => ` ${s.name}${s.required ? '' : '?'}: ${s.type === '-' ? '() => any' : `(props: ${s.type}) => any`}`).join('\n')}\n}`,
})
}
}

const output = {
Expand Down
Loading