Separate viewport and containerDimensions
This commit is contained in:
parent
c22e86233b
commit
82e64d56bb
5 changed files with 320 additions and 110 deletions
|
|
@ -113,7 +113,8 @@ describe("App <-> AppBridge integration", () => {
|
|||
const testHostContext = {
|
||||
theme: "dark" as const,
|
||||
locale: "en-US",
|
||||
viewport: { width: 800, height: 600, maxHeight: 600 },
|
||||
viewport: { width: 800, height: 600 },
|
||||
containerDimensions: { width: 800, maxHeight: 600 },
|
||||
};
|
||||
const newBridge = new AppBridge(
|
||||
createMockClient() as Client,
|
||||
|
|
@ -337,7 +338,8 @@ describe("App <-> AppBridge integration", () => {
|
|||
const initialContext = {
|
||||
theme: "light" as const,
|
||||
locale: "en-US",
|
||||
viewport: { width: 800, height: 600, maxHeight: 600 },
|
||||
viewport: { width: 800, height: 600 },
|
||||
containerDimensions: { width: 800, maxHeight: 600 },
|
||||
};
|
||||
const newBridge = new AppBridge(
|
||||
createMockClient() as Client,
|
||||
|
|
@ -354,22 +356,26 @@ describe("App <-> AppBridge integration", () => {
|
|||
newBridge.sendHostContextChange({ theme: "dark" });
|
||||
await flush();
|
||||
|
||||
// Send another partial update: only viewport changes
|
||||
// Send another partial update: only viewport and containerDimensions change
|
||||
newBridge.sendHostContextChange({
|
||||
viewport: { width: 1024, height: 768, maxHeight: 768 },
|
||||
viewport: { width: 1024, height: 768 },
|
||||
containerDimensions: { width: 1024, maxHeight: 768 },
|
||||
});
|
||||
await flush();
|
||||
|
||||
// getHostContext should have accumulated all updates:
|
||||
// - locale from initial (unchanged)
|
||||
// - theme from first partial update
|
||||
// - viewport from second partial update
|
||||
// - viewport and containerDimensions from second partial update
|
||||
const context = newApp.getHostContext();
|
||||
expect(context?.theme).toBe("dark");
|
||||
expect(context?.locale).toBe("en-US");
|
||||
expect(context?.viewport).toEqual({
|
||||
width: 1024,
|
||||
height: 768,
|
||||
});
|
||||
expect(context?.containerDimensions).toEqual({
|
||||
width: 1024,
|
||||
maxHeight: 768,
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1008,7 +1008,8 @@ export class AppBridge extends Protocol<
|
|||
* ```typescript
|
||||
* bridge.setHostContext({
|
||||
* theme: "dark",
|
||||
* viewport: { width: 800, maxHeight: 600 }
|
||||
* viewport: { width: 800, height: 600 },
|
||||
* containerDimensions: { maxHeight: 600, width: 800 }
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
|
|
|
|||
267
src/generated/schema.json
generated
267
src/generated/schema.json
generated
|
|
@ -632,12 +632,77 @@
|
|||
"type": "string"
|
||||
}
|
||||
},
|
||||
"containerDimensions": {
|
||||
"description": "Container dimensions. Represents the dimensions of the iframe or other\ncontainer holding the app. Specify either width or maxWidth, and either height or maxHeight.",
|
||||
"allOf": [
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"height": {
|
||||
"description": "Fixed container height in pixels.",
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": ["height"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"maxHeight": {
|
||||
"description": "Maximum container height in pixels.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"width": {
|
||||
"description": "Fixed container width in pixels.",
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": ["width"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"maxWidth": {
|
||||
"description": "Maximum container width in pixels.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"viewport": {
|
||||
"description": "Current and maximum dimensions available to the UI.",
|
||||
"description": "Window viewport dimensions. Represents the host window's viewport size,\nwhich provides additional information apps can use to make responsive layout decisions.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"width": {
|
||||
"description": "Viewport width in pixels (if fixed). Only pass width or maxWidth, not both.",
|
||||
"description": "Window viewport width in pixels.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
|
|
@ -646,25 +711,7 @@
|
|||
]
|
||||
},
|
||||
"height": {
|
||||
"description": "Viewport height in pixels (if fixed). Only pass height or maxHeight, not both.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{}
|
||||
]
|
||||
},
|
||||
"maxWidth": {
|
||||
"description": "Maximum available viewport width in pixels (if constrained). Only pass width or maxWidth, not both.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{}
|
||||
]
|
||||
},
|
||||
"maxHeight": {
|
||||
"description": "Maximum available viewport height in pixels (if constrained). Only pass height or maxHeight, not both.",
|
||||
"description": "Window viewport height in pixels.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
|
|
@ -1281,12 +1328,77 @@
|
|||
"type": "string"
|
||||
}
|
||||
},
|
||||
"containerDimensions": {
|
||||
"description": "Container dimensions. Represents the dimensions of the iframe or other\ncontainer holding the app. Specify either width or maxWidth, and either height or maxHeight.",
|
||||
"allOf": [
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"height": {
|
||||
"description": "Fixed container height in pixels.",
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": ["height"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"maxHeight": {
|
||||
"description": "Maximum container height in pixels.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"width": {
|
||||
"description": "Fixed container width in pixels.",
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": ["width"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"maxWidth": {
|
||||
"description": "Maximum container width in pixels.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"viewport": {
|
||||
"description": "Current and maximum dimensions available to the UI.",
|
||||
"description": "Window viewport dimensions. Represents the host window's viewport size,\nwhich provides additional information apps can use to make responsive layout decisions.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"width": {
|
||||
"description": "Viewport width in pixels (if fixed). Only pass width or maxWidth, not both.",
|
||||
"description": "Window viewport width in pixels.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
|
|
@ -1295,25 +1407,7 @@
|
|||
]
|
||||
},
|
||||
"height": {
|
||||
"description": "Viewport height in pixels (if fixed). Only pass height or maxHeight, not both.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{}
|
||||
]
|
||||
},
|
||||
"maxWidth": {
|
||||
"description": "Maximum available viewport width in pixels (if constrained). Only pass width or maxWidth, not both.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{}
|
||||
]
|
||||
},
|
||||
"maxHeight": {
|
||||
"description": "Maximum available viewport height in pixels (if constrained). Only pass height or maxHeight, not both.",
|
||||
"description": "Window viewport height in pixels.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
|
|
@ -2467,12 +2561,77 @@
|
|||
"type": "string"
|
||||
}
|
||||
},
|
||||
"containerDimensions": {
|
||||
"description": "Container dimensions. Represents the dimensions of the iframe or other\ncontainer holding the app. Specify either width or maxWidth, and either height or maxHeight.",
|
||||
"allOf": [
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"height": {
|
||||
"description": "Fixed container height in pixels.",
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": ["height"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"maxHeight": {
|
||||
"description": "Maximum container height in pixels.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"width": {
|
||||
"description": "Fixed container width in pixels.",
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": ["width"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"maxWidth": {
|
||||
"description": "Maximum container width in pixels.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"viewport": {
|
||||
"description": "Current and maximum dimensions available to the UI.",
|
||||
"description": "Window viewport dimensions. Represents the host window's viewport size,\nwhich provides additional information apps can use to make responsive layout decisions.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"width": {
|
||||
"description": "Viewport width in pixels (if fixed). Only pass width or maxWidth, not both.",
|
||||
"description": "Window viewport width in pixels.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
|
|
@ -2481,25 +2640,7 @@
|
|||
]
|
||||
},
|
||||
"height": {
|
||||
"description": "Viewport height in pixels (if fixed). Only pass height or maxHeight, not both.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{}
|
||||
]
|
||||
},
|
||||
"maxWidth": {
|
||||
"description": "Maximum available viewport width in pixels (if constrained). Only pass width or maxWidth, not both.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{}
|
||||
]
|
||||
},
|
||||
"maxHeight": {
|
||||
"description": "Maximum available viewport height in pixels (if constrained). Only pass height or maxHeight, not both.",
|
||||
"description": "Window viewport height in pixels.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
|
|
|
|||
72
src/generated/schema.ts
generated
72
src/generated/schema.ts
generated
|
|
@ -563,40 +563,64 @@ export const McpUiHostContextSchema = z.looseObject({
|
|||
.array(z.string())
|
||||
.optional()
|
||||
.describe("Display modes the host supports."),
|
||||
/** @description Current and maximum dimensions available to the UI. */
|
||||
/**
|
||||
* @description Container dimensions. Represents the dimensions of the iframe or other
|
||||
* container holding the app. Specify either width or maxWidth, and either height or maxHeight.
|
||||
*/
|
||||
containerDimensions: z
|
||||
.union([
|
||||
z.object({
|
||||
/** @description Fixed container height in pixels. */
|
||||
height: z.number().describe("Fixed container height in pixels."),
|
||||
}),
|
||||
z.object({
|
||||
/** @description Maximum container height in pixels. */
|
||||
maxHeight: z
|
||||
.union([z.number(), z.undefined()])
|
||||
.optional()
|
||||
.describe("Maximum container height in pixels."),
|
||||
}),
|
||||
])
|
||||
.and(
|
||||
z.union([
|
||||
z.object({
|
||||
/** @description Fixed container width in pixels. */
|
||||
width: z.number().describe("Fixed container width in pixels."),
|
||||
}),
|
||||
z.object({
|
||||
/** @description Maximum container width in pixels. */
|
||||
maxWidth: z
|
||||
.union([z.number(), z.undefined()])
|
||||
.optional()
|
||||
.describe("Maximum container width in pixels."),
|
||||
}),
|
||||
]),
|
||||
)
|
||||
.optional()
|
||||
.describe(
|
||||
"Container dimensions. Represents the dimensions of the iframe or other\ncontainer holding the app. Specify either width or maxWidth, and either height or maxHeight.",
|
||||
),
|
||||
/**
|
||||
* @description Window viewport dimensions. Represents the host window's viewport size,
|
||||
* which provides additional information apps can use to make responsive layout decisions.
|
||||
*/
|
||||
viewport: z
|
||||
.object({
|
||||
/** @description Viewport width in pixels (if fixed). Only pass width or maxWidth, not both. */
|
||||
/** @description Window viewport width in pixels. */
|
||||
width: z
|
||||
.union([z.number(), z.undefined()])
|
||||
.optional()
|
||||
.describe(
|
||||
"Viewport width in pixels (if fixed). Only pass width or maxWidth, not both.",
|
||||
),
|
||||
/** @description Viewport height in pixels (if fixed). Only pass height or maxHeight, not both. */
|
||||
.describe("Window viewport width in pixels."),
|
||||
/** @description Window viewport height in pixels. */
|
||||
height: z
|
||||
.union([z.number(), z.undefined()])
|
||||
.optional()
|
||||
.describe(
|
||||
"Viewport height in pixels (if fixed). Only pass height or maxHeight, not both.",
|
||||
),
|
||||
/** @description Maximum available viewport width in pixels (if constrained). Only pass width or maxWidth, not both.*/
|
||||
maxWidth: z
|
||||
.union([z.number(), z.undefined()])
|
||||
.optional()
|
||||
.describe(
|
||||
"Maximum available viewport width in pixels (if constrained). Only pass width or maxWidth, not both.",
|
||||
),
|
||||
/** @description Maximum available viewport height in pixels (if constrained). Only pass height or maxHeight, not both. */
|
||||
maxHeight: z
|
||||
.union([z.number(), z.undefined()])
|
||||
.optional()
|
||||
.describe(
|
||||
"Maximum available viewport height in pixels (if constrained). Only pass height or maxHeight, not both.",
|
||||
),
|
||||
.describe("Window viewport height in pixels."),
|
||||
})
|
||||
.optional()
|
||||
.describe("Current and maximum dimensions available to the UI."),
|
||||
.describe(
|
||||
"Window viewport dimensions. Represents the host window's viewport size,\nwhich provides additional information apps can use to make responsive layout decisions.",
|
||||
),
|
||||
/** @description User's language and region preference in BCP 47 format. */
|
||||
locale: z
|
||||
.string()
|
||||
|
|
|
|||
|
|
@ -325,16 +325,39 @@ export interface McpUiHostContext {
|
|||
displayMode?: McpUiDisplayMode;
|
||||
/** @description Display modes the host supports. */
|
||||
availableDisplayModes?: string[];
|
||||
/** @description Current and maximum dimensions available to the UI. */
|
||||
/**
|
||||
* @description Container dimensions. Represents the dimensions of the iframe or other
|
||||
* container holding the app. Specify either width or maxWidth, and either height or maxHeight.
|
||||
*/
|
||||
containerDimensions?: (
|
||||
| {
|
||||
/** @description Fixed container height in pixels. */
|
||||
height: number;
|
||||
}
|
||||
| {
|
||||
/** @description Maximum container height in pixels. */
|
||||
maxHeight?: number | undefined;
|
||||
}
|
||||
) &
|
||||
(
|
||||
| {
|
||||
/** @description Fixed container width in pixels. */
|
||||
width: number;
|
||||
}
|
||||
| {
|
||||
/** @description Maximum container width in pixels. */
|
||||
maxWidth?: number | undefined;
|
||||
}
|
||||
);
|
||||
/**
|
||||
* @description Window viewport dimensions. Represents the host window's viewport size,
|
||||
* which provides additional information apps can use to make responsive layout decisions.
|
||||
*/
|
||||
viewport?: {
|
||||
/** @description Viewport width in pixels (if fixed). Only pass width or maxWidth, not both. */
|
||||
/** @description Window viewport width in pixels. */
|
||||
width?: number | undefined;
|
||||
/** @description Viewport height in pixels (if fixed). Only pass height or maxHeight, not both. */
|
||||
/** @description Window viewport height in pixels. */
|
||||
height?: number | undefined;
|
||||
/** @description Maximum available viewport width in pixels (if constrained). Only pass width or maxWidth, not both.*/
|
||||
maxWidth?: number | undefined;
|
||||
/** @description Maximum available viewport height in pixels (if constrained). Only pass height or maxHeight, not both. */
|
||||
maxHeight?: number | undefined;
|
||||
};
|
||||
/** @description User's language and region preference in BCP 47 format. */
|
||||
locale?: string;
|
||||
|
|
|
|||
Loading…
Reference in a new issue