diff --git a/packages/runtime/src/components/Box.ts b/packages/runtime/src/components/Box.ts index ccba1ca..60a9f16 100644 --- a/packages/runtime/src/components/Box.ts +++ b/packages/runtime/src/components/Box.ts @@ -1,5 +1,6 @@ import { defineComponent, h, inject, type PropType } from "vue"; import { AppContextKey } from "../context.ts"; +import type { WithChildren } from "./with-children.ts"; type Spacing = number; type FlexDirection = "row" | "row-reverse" | "column" | "column-reverse"; @@ -63,7 +64,7 @@ export interface AriaState { selected?: boolean; } -export const Box = defineComponent({ +const BoxImpl = defineComponent({ name: "Box", props: { flexDirection: String as PropType, @@ -157,3 +158,5 @@ export const Box = defineComponent({ }; }, }); + +export const Box = BoxImpl as WithChildren; diff --git a/packages/runtime/src/components/Static.ts b/packages/runtime/src/components/Static.ts index 9055561..71d17ba 100644 --- a/packages/runtime/src/components/Static.ts +++ b/packages/runtime/src/components/Static.ts @@ -1,6 +1,7 @@ import { defineComponent, h, type PropType } from "vue"; +import type { WithChildren } from "./with-children.ts"; -export const Static = defineComponent({ +const StaticImpl = defineComponent({ name: "Static", props: { items: { type: Array as PropType, required: true }, @@ -22,3 +23,5 @@ export const Static = defineComponent({ }; }, }); + +export const Static = StaticImpl as WithChildren; diff --git a/packages/runtime/src/components/Text.ts b/packages/runtime/src/components/Text.ts index 01877af..d3f09d2 100644 --- a/packages/runtime/src/components/Text.ts +++ b/packages/runtime/src/components/Text.ts @@ -1,5 +1,6 @@ import { defineComponent, getCurrentInstance, h, inject, type PropType } from "vue"; import { AppContextKey } from "../context.ts"; +import type { WithChildren } from "./with-children.ts"; type Color = string | [number, number, number]; type WrapMode = @@ -10,7 +11,7 @@ type WrapMode = | "truncate-middle" | "truncate-start"; -export const Text = defineComponent({ +const TextImpl = defineComponent({ name: "Text", props: { color: [String, Array] as PropType, @@ -54,6 +55,8 @@ export const Text = defineComponent({ }, }); +export const Text = TextImpl as WithChildren; + function isInsideText(): boolean { let parent = getCurrentInstance()?.parent; while (parent) { diff --git a/packages/runtime/src/components/Transform.ts b/packages/runtime/src/components/Transform.ts index 596f4fc..8853c94 100644 --- a/packages/runtime/src/components/Transform.ts +++ b/packages/runtime/src/components/Transform.ts @@ -1,9 +1,10 @@ import { defineComponent, h, inject, type PropType } from "vue"; import { AppContextKey } from "../context.ts"; +import type { WithChildren } from "./with-children.ts"; type TransformFn = (line: string, lineIndex: number) => string; -export const Transform = defineComponent({ +const TransformImpl = defineComponent({ name: "Transform", props: { transform: { type: Function as PropType, required: true }, @@ -25,3 +26,5 @@ export const Transform = defineComponent({ }; }, }); + +export const Transform = TransformImpl as WithChildren; diff --git a/packages/runtime/src/components/with-children.ts b/packages/runtime/src/components/with-children.ts new file mode 100644 index 0000000..086fec6 --- /dev/null +++ b/packages/runtime/src/components/with-children.ts @@ -0,0 +1,11 @@ +/** + * Adds an optional `children` to a component's JSX `$props` so that TSX written + * under the automatic runtime (`jsx: "react-jsx"` + `jsxImportSource: "vue"`) + * accepts child content. Vue's JSX namespace defines no `ElementChildrenAttribute`, + * so the automatic runtime passes children as a `children` prop — which must be + * present on `$props` to type-check. Vue routes that prop to the default slot at + * runtime, so this is a type-only shim with no runtime effect. + */ +export type WithChildren = C & { + new (): { $props: { children?: T } }; +};