Remove viewport
This commit is contained in:
parent
e90c7945bc
commit
dc226be962
8 changed files with 13 additions and 143 deletions
|
|
@ -25,7 +25,7 @@ export interface WidgetProps<TToolInput = Record<string, unknown>> {
|
||||||
toolInputsPartial: TToolInput | null;
|
toolInputsPartial: TToolInput | null;
|
||||||
/** Tool execution result from the server */
|
/** Tool execution result from the server */
|
||||||
toolResult: CallToolResult | null;
|
toolResult: CallToolResult | null;
|
||||||
/** Host context (theme, viewport, locale, etc.) */
|
/** Host context (theme, dimensions, locale, etc.) */
|
||||||
hostContext: McpUiHostContext | null;
|
hostContext: McpUiHostContext | null;
|
||||||
/** Call a tool on the MCP server */
|
/** Call a tool on the MCP server */
|
||||||
callServerTool: App["callServerTool"];
|
callServerTool: App["callServerTool"];
|
||||||
|
|
@ -65,7 +65,7 @@ function McpAppWrapper() {
|
||||||
app.ontoolresult = (params) => {
|
app.ontoolresult = (params) => {
|
||||||
setToolResult(params as CallToolResult);
|
setToolResult(params as CallToolResult);
|
||||||
};
|
};
|
||||||
// Host context changes (theme, viewport, etc.)
|
// Host context changes (theme, dimensions, etc.)
|
||||||
app.onhostcontextchanged = (params) => {
|
app.onhostcontextchanged = (params) => {
|
||||||
setHostContext(params);
|
setHostContext(params);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -469,13 +469,6 @@ interface HostContext {
|
||||||
| { width: number } // If specified, container is fixed at this width
|
| { width: number } // If specified, container is fixed at this width
|
||||||
| { maxWidth?: number } // Otherwise, container width is determined by the UI width, up to this maximum width (if defined)
|
| { maxWidth?: number } // Otherwise, container width is determined by the UI width, up to this maximum width (if defined)
|
||||||
);
|
);
|
||||||
/** Host window viewport dimensions */
|
|
||||||
viewport?: {
|
|
||||||
/** Window viewport width in pixels. */
|
|
||||||
width?: number;
|
|
||||||
/** Window viewport height in pixels. */
|
|
||||||
height?: number;
|
|
||||||
};
|
|
||||||
/** User's language/region preference (BCP 47, e.g., "en-US") */
|
/** User's language/region preference (BCP 47, e.g., "en-US") */
|
||||||
locale?: string;
|
locale?: string;
|
||||||
/** User's timezone (IANA, e.g., "America/New_York") */
|
/** User's timezone (IANA, e.g., "America/New_York") */
|
||||||
|
|
@ -525,20 +518,17 @@ Example:
|
||||||
},
|
},
|
||||||
"displayMode": "inline",
|
"displayMode": "inline",
|
||||||
"containerDimensions": { "width": 400, "maxHeight": 600 }
|
"containerDimensions": { "width": 400, "maxHeight": 600 }
|
||||||
"viewport": { "width": 1920, "height": 1080 },
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Viewport and Dimensions
|
### Container Dimensions
|
||||||
|
|
||||||
The `HostContext` provides two separate fields for sizing information:
|
The `HostContext` provides sizing information via `containerDimensions`:
|
||||||
|
|
||||||
- **`containerDimensions`**: The dimensions of the container that holds the app. This controls the actual space the app occupies within the host. Each dimension (height and width) operates independently and can be either **fixed** or **flexible**.
|
- **`containerDimensions`**: The dimensions of the container that holds the app. This controls the actual space the app occupies within the host. Each dimension (height and width) operates independently and can be either **fixed** or **flexible**.
|
||||||
|
|
||||||
- **`viewport`**: The host window's dimensions (e.g., `window.innerWidth` and `window.innerHeight`). Apps can use this to make responsive layout decisions based on the overall screen size.
|
|
||||||
|
|
||||||
#### Dimension Modes
|
#### Dimension Modes
|
||||||
|
|
||||||
| Mode | Dimensions Field | Meaning |
|
| Mode | Dimensions Field | Meaning |
|
||||||
|
|
@ -578,12 +568,6 @@ if (containerDimensions) {
|
||||||
}
|
}
|
||||||
// If neither, width is unbounded
|
// If neither, width is unbounded
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apps can also use viewport for additional data to make responsive layout decisions
|
|
||||||
const viewport = hostContext.viewport;
|
|
||||||
if (viewport?.width && viewport.width < 768) {
|
|
||||||
// Apply mobile-friendly layout
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Host Behavior
|
#### Host Behavior
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,6 @@ describe("App <-> AppBridge integration", () => {
|
||||||
const testHostContext = {
|
const testHostContext = {
|
||||||
theme: "dark" as const,
|
theme: "dark" as const,
|
||||||
locale: "en-US",
|
locale: "en-US",
|
||||||
viewport: { width: 800, height: 600 },
|
|
||||||
containerDimensions: { width: 800, maxHeight: 600 },
|
containerDimensions: { width: 800, maxHeight: 600 },
|
||||||
};
|
};
|
||||||
const newBridge = new AppBridge(
|
const newBridge = new AppBridge(
|
||||||
|
|
@ -338,7 +337,6 @@ describe("App <-> AppBridge integration", () => {
|
||||||
const initialContext = {
|
const initialContext = {
|
||||||
theme: "light" as const,
|
theme: "light" as const,
|
||||||
locale: "en-US",
|
locale: "en-US",
|
||||||
viewport: { width: 800, height: 600 },
|
|
||||||
containerDimensions: { width: 800, maxHeight: 600 },
|
containerDimensions: { width: 800, maxHeight: 600 },
|
||||||
};
|
};
|
||||||
const newBridge = new AppBridge(
|
const newBridge = new AppBridge(
|
||||||
|
|
@ -356,9 +354,8 @@ describe("App <-> AppBridge integration", () => {
|
||||||
newBridge.sendHostContextChange({ theme: "dark" });
|
newBridge.sendHostContextChange({ theme: "dark" });
|
||||||
await flush();
|
await flush();
|
||||||
|
|
||||||
// Send another partial update: only viewport and containerDimensions change
|
// Send another partial update: only containerDimensions change
|
||||||
newBridge.sendHostContextChange({
|
newBridge.sendHostContextChange({
|
||||||
viewport: { width: 1024, height: 768 },
|
|
||||||
containerDimensions: { width: 1024, maxHeight: 768 },
|
containerDimensions: { width: 1024, maxHeight: 768 },
|
||||||
});
|
});
|
||||||
await flush();
|
await flush();
|
||||||
|
|
@ -366,14 +363,10 @@ describe("App <-> AppBridge integration", () => {
|
||||||
// getHostContext should have accumulated all updates:
|
// getHostContext should have accumulated all updates:
|
||||||
// - locale from initial (unchanged)
|
// - locale from initial (unchanged)
|
||||||
// - theme from first partial update
|
// - theme from first partial update
|
||||||
// - viewport and containerDimensions from second partial update
|
// - containerDimensions from second partial update
|
||||||
const context = newApp.getHostContext();
|
const context = newApp.getHostContext();
|
||||||
expect(context?.theme).toBe("dark");
|
expect(context?.theme).toBe("dark");
|
||||||
expect(context?.locale).toBe("en-US");
|
expect(context?.locale).toBe("en-US");
|
||||||
expect(context?.viewport).toEqual({
|
|
||||||
width: 1024,
|
|
||||||
height: 768,
|
|
||||||
});
|
|
||||||
expect(context?.containerDimensions).toEqual({
|
expect(context?.containerDimensions).toEqual({
|
||||||
width: 1024,
|
width: 1024,
|
||||||
maxHeight: 768,
|
maxHeight: 768,
|
||||||
|
|
|
||||||
|
|
@ -356,7 +356,7 @@ export class AppBridge extends Protocol<
|
||||||
* adjust the iframe container dimensions based on the Guest UI's content.
|
* adjust the iframe container dimensions based on the Guest UI's content.
|
||||||
*
|
*
|
||||||
* Note: This is for Guest UI → Host communication. To notify the Guest UI of
|
* Note: This is for Guest UI → Host communication. To notify the Guest UI of
|
||||||
* host viewport changes, use {@link app.App.sendSizeChanged}.
|
* host container dimension changes, use {@link setHostContext}.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```typescript
|
* ```typescript
|
||||||
|
|
@ -1008,7 +1008,6 @@ export class AppBridge extends Protocol<
|
||||||
* ```typescript
|
* ```typescript
|
||||||
* bridge.setHostContext({
|
* bridge.setHostContext({
|
||||||
* theme: "dark",
|
* theme: "dark",
|
||||||
* viewport: { width: 800, height: 600 },
|
|
||||||
* containerDimensions: { maxHeight: 600, width: 800 }
|
* containerDimensions: { maxHeight: 600, width: 800 }
|
||||||
* });
|
* });
|
||||||
* ```
|
* ```
|
||||||
|
|
|
||||||
12
src/app.ts
12
src/app.ts
|
|
@ -154,7 +154,7 @@ type RequestHandlerExtra = Parameters<
|
||||||
* - `ontoolinput` - Complete tool arguments from host
|
* - `ontoolinput` - Complete tool arguments from host
|
||||||
* - `ontoolinputpartial` - Streaming partial tool arguments
|
* - `ontoolinputpartial` - Streaming partial tool arguments
|
||||||
* - `ontoolresult` - Tool execution results
|
* - `ontoolresult` - Tool execution results
|
||||||
* - `onhostcontextchanged` - Host context changes (theme, viewport, etc.)
|
* - `onhostcontextchanged` - Host context changes (theme, locale, etc.)
|
||||||
*
|
*
|
||||||
* These setters are convenience wrappers around `setNotificationHandler()`.
|
* These setters are convenience wrappers around `setNotificationHandler()`.
|
||||||
* Both patterns work; use whichever fits your coding style better.
|
* Both patterns work; use whichever fits your coding style better.
|
||||||
|
|
@ -293,7 +293,7 @@ export class App extends Protocol<AppRequest, AppNotification, AppResult> {
|
||||||
* Get the host context discovered during initialization.
|
* Get the host context discovered during initialization.
|
||||||
*
|
*
|
||||||
* Returns the host context that was provided in the initialization response,
|
* Returns the host context that was provided in the initialization response,
|
||||||
* including tool info, theme, viewport, locale, and other environment details.
|
* including tool info, theme, locale, and other environment details.
|
||||||
* This context is automatically updated when the host sends
|
* This context is automatically updated when the host sends
|
||||||
* `ui/notifications/host-context-changed` notifications.
|
* `ui/notifications/host-context-changed` notifications.
|
||||||
*
|
*
|
||||||
|
|
@ -478,12 +478,12 @@ export class App extends Protocol<AppRequest, AppNotification, AppResult> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience handler for host context changes (theme, viewport, locale, etc.).
|
* Convenience handler for host context changes (theme, locale, etc.).
|
||||||
*
|
*
|
||||||
* Set this property to register a handler that will be called when the host's
|
* Set this property to register a handler that will be called when the host's
|
||||||
* context changes, such as theme switching (light/dark), viewport size changes,
|
* context changes, such as theme switching (light/dark), locale changes, or
|
||||||
* locale changes, or other environmental updates. Apps should respond by
|
* other environmental updates. Apps should respond by updating their UI
|
||||||
* updating their UI accordingly.
|
* accordingly.
|
||||||
*
|
*
|
||||||
* This setter is a convenience wrapper around `setNotificationHandler()` that
|
* This setter is a convenience wrapper around `setNotificationHandler()` that
|
||||||
* automatically handles the notification schema and extracts the params for you.
|
* automatically handles the notification schema and extracts the params for you.
|
||||||
|
|
|
||||||
75
src/generated/schema.json
generated
75
src/generated/schema.json
generated
|
|
@ -697,31 +697,6 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"viewport": {
|
|
||||||
"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": "Window viewport width in pixels.",
|
|
||||||
"anyOf": [
|
|
||||||
{
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
{}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"height": {
|
|
||||||
"description": "Window viewport height in pixels.",
|
|
||||||
"anyOf": [
|
|
||||||
{
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
{}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"locale": {
|
"locale": {
|
||||||
"description": "User's language and region preference in BCP 47 format.",
|
"description": "User's language and region preference in BCP 47 format.",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
|
@ -1393,31 +1368,6 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"viewport": {
|
|
||||||
"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": "Window viewport width in pixels.",
|
|
||||||
"anyOf": [
|
|
||||||
{
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
{}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"height": {
|
|
||||||
"description": "Window viewport height in pixels.",
|
|
||||||
"anyOf": [
|
|
||||||
{
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
{}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"locale": {
|
"locale": {
|
||||||
"description": "User's language and region preference in BCP 47 format.",
|
"description": "User's language and region preference in BCP 47 format.",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
|
@ -2626,31 +2576,6 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"viewport": {
|
|
||||||
"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": "Window viewport width in pixels.",
|
|
||||||
"anyOf": [
|
|
||||||
{
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
{}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"height": {
|
|
||||||
"description": "Window viewport height in pixels.",
|
|
||||||
"anyOf": [
|
|
||||||
{
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
{}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"locale": {
|
"locale": {
|
||||||
"description": "User's language and region preference in BCP 47 format.",
|
"description": "User's language and region preference in BCP 47 format.",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
|
|
||||||
21
src/generated/schema.ts
generated
21
src/generated/schema.ts
generated
|
|
@ -601,27 +601,6 @@ export const McpUiHostContextSchema = z
|
||||||
.describe(
|
.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.",
|
"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 Window viewport width in pixels. */
|
|
||||||
width: z
|
|
||||||
.union([z.number(), z.undefined()])
|
|
||||||
.optional()
|
|
||||||
.describe("Window viewport width in pixels."),
|
|
||||||
/** @description Window viewport height in pixels. */
|
|
||||||
height: z
|
|
||||||
.union([z.number(), z.undefined()])
|
|
||||||
.optional()
|
|
||||||
.describe("Window viewport height in pixels."),
|
|
||||||
})
|
|
||||||
.optional()
|
|
||||||
.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. */
|
/** @description User's language and region preference in BCP 47 format. */
|
||||||
locale: z
|
locale: z
|
||||||
.string()
|
.string()
|
||||||
|
|
|
||||||
|
|
@ -349,16 +349,6 @@ export interface McpUiHostContext {
|
||||||
maxWidth?: number | undefined;
|
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 Window viewport width in pixels. */
|
|
||||||
width?: number | undefined;
|
|
||||||
/** @description Window viewport height in pixels. */
|
|
||||||
height?: number | undefined;
|
|
||||||
};
|
|
||||||
/** @description User's language and region preference in BCP 47 format. */
|
/** @description User's language and region preference in BCP 47 format. */
|
||||||
locale?: string;
|
locale?: string;
|
||||||
/** @description User's timezone in IANA format. */
|
/** @description User's timezone in IANA format. */
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue