Metabase Embedding SDK 的 StaticQuestion 组件 Props 完全指南:静态嵌入问答组件的 17 个配置项详解
【免费下载链接】metabaseThe easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart:项目地址: https://gitcode.com/GitHub_Trending/me/metabase
导读
StaticQuestion是 Metabase Embedding SDK 中用于**静态嵌入(Static Embedding / Guest Embed)**场景的核心 React 组件,它允许你在宿主应用中渲染一个只读、可交互的问答(Question)视图,支持传入问题 ID、JWT Token、反序列化卡片或查询对象四种数据源,并可精细控制标题、尺寸、SQL 参数与下载/告警等能力。本文以官方 API 文档的 Props 表格为骨架,结合仓库内StaticQuestion组件的真实实现与类型定义,逐一拆解全部 17 个配置项的语义、类型约束、取值规则与源码级行为,帮助你写出可运行、可维护的静态嵌入代码。
一、组件定位:静态模式下的问答渲染器
StaticQuestion位于frontend/src/embedding-sdk-bundle/components/public/StaticQuestion/StaticQuestion.tsx,其 Props 类型StaticQuestionProps由两部分组成:
export type StaticQuestionProps = StaticQuestionBaseProps & SdkQuestionEntityPublicProps;StaticQuestionBaseProps从SdkQuestionProps中挑选了withChartTypeSelector、height、width、className、style、initialSqlParameters、sqlParameters、onSqlParametersChange、hiddenParameters、withDownloads、withAlerts、title等 UI 与行为配置;SdkQuestionEntityPublicProps则定义了下文要讲的四选一数据来源(questionId/token/card/query)。
从实现上看,StaticQuestion内部把questionId、token、card、query归一化为deserializedCard,并渲染在SdkQuestion之上,同时通过getEmbeddingMode({ queryMode: EmbeddingSdkStaticMode })将交互模式锁定为静态模式(navigateToNewCard={null},即点击下钻不再跳转新卡片)。组件同时导出了一整套子组件(StaticQuestion.Filter、StaticQuestion.ChartTypeDropdown、StaticQuestion.SqlParametersList等)用于自定义布局,且通过withPublicComponentWrapper包装,supportsGuestEmbed: true,意味着它原生支持 JWT 访客嵌入。
需要特别注意的是:StaticQuestion是只读呈现组件,主要用于展示而非编辑。若要创建新问题,可通过questionId="new"(笔记本编辑器)或questionId="new-native"(SQL 编辑器)进入创建流程。
二、数据来源 Props:四种渲染内容的入口(四选一)
StaticQuestion必须且只能提供以下四种数据源之一,这是类型系统强制保证的(见SdkQuestionEntityPublicProps的联合类型定义)。运行时也会通过StaticQuestion.schema.ts中的 Yup 校验兜底:questionId, token, card, or query is required,且.noUnknown()拒绝未声明属性。
| Prop | 类型 | 说明 |
|---|---|---|
questionId? | SdkQuestionId|null | 要渲染的问题 ID |
token? | string|null | 访客嵌入(Guest Embed)的合法 JWT Token |
card? | string|MetabaseCard | 不保存即可渲染的临时问题(ad-hoc question) |
query? | MetabaseQueryObject|null | 通过useMetabaseQueryObject创建的基于表的临时查询 |
1. questionId:三种取值形态
SdkQuestionId的类型定义位于frontend/src/embedding-sdk-bundle/types/question.ts:
export type SdkQuestionId = | number // 数值型问题 ID(例如 123) | "new" // 显示新建问题的笔记本编辑器 | "new-native" // 显示新建原生(SQL)问题的编辑器 | SdkEntityId; // 实体 ID 字符串(例如 "abc123def456")具体来说:
- 数值 ID:访问问题链接
http://localhost:3000/question/1-my-question时,URL 中1即为数值 ID; - 字符串 entity_id:通过 API 直接返回的问题对象中的
entity_id字段,或通过 SDK 的 Collection Browser(集合浏览器)返回数据时携带的字符串 ID; "new"/"new-native":分别打开笔记本编辑器与 SQL 编辑器用于新建问题,StaticQuestion.tsx中通过isNewQuestion判断并在埋点事件中区分id_new与id_new_native。
2. card:临时卡片的两种传递形式
card用于渲染无需提前保存的临时问题,支持两种形式:
- 一个完整的
MetabaseCard对象; - 一段序列化卡片字符串,即从问题 URL hash 中复制的内容(
/question#<base64>,或直接裸的 base64)。
3. query:与 useMetabaseQueryObject 配合
query是useMetabaseQueryObject钩子的返回值,定义见MetabaseQueryObject结构类型。与card的区别在于:query是"仅查询"的临时结构,而card还可以携带visualization与visualizationSettings(详见下文"可视化与展示细节")。
内部还有一种仅供
useMetabot钩子使用的字符串形态query(StaticQuestionInternalProps),它不会从公共 SDK 包入口导出,普通用户无需关心。
三、尺寸与样式 Props:精确控制组件外观
StaticQuestion的根元素尺寸与样式由FlexibleSizeComponent承载(见StaticQuestion.tsx中children ?? <FlexibleSizeComponent ...>的默认布局分支):
| Prop | 类型 | 说明 |
|---|---|---|
width? | Width<string \| number> | 组件宽度,接受数字或 CSS 尺寸字符串 |
height? | Height<string \| number> | 组件高度,接受数字或 CSS 尺寸字符串 |
className? | string | 追加到根元素的自定义 class 名 |
style? | CSSProperties | 追加到根元素的自定义样式对象 |
width/height直接透传给FlexibleSizeComponent,同时也会作为参数传入内部的可视化渲染SdkQuestion.QuestionVisualization,保证图表区域与容器一致;className/style与尺寸一样会"双路透传":既作用于外层容器,也传给可视化区域,因此可用于整体调色、圆角、边框等定制;- 需要自定义完整布局时,可以通过
children传入自定义内容并配合StaticQuestion.*子组件组合(此时默认的尺寸容器不再渲染)。
四、标题 Props:默认标题与自定义标题
| Prop | 类型 | 说明 |
|---|---|---|
title? | SdkQuestionTitleProps | 决定是否显示问题标题,也允许传入自定义标题替代默认标题 |
SdkQuestionTitleProps的定义为boolean | undefined | ReactNode | (() => ReactNode):
true/ 不传:显示问题默认标题(文档表格中的 "Shown by default");false:隐藏标题;ReactNode:显示自定义标题内容;() => ReactNode:以函数形式返回自定义标题。
需要注意一个源码细节:StaticQuestion.tsx中title的解构默认值是title = false,注释为 "Hidden by default for backwards-compatibility"(为向后兼容默认隐藏)。也就是说,当前仓库实现中title未传入时标题默认隐藏,这与官方 API 文档中 "Shown by default" 的描述存在差异。从源码结构推断,这是组件演进过程中默认值发生过调整;为获得确定行为,建议显式传title={true}或自定义标题节点。这是文档与实现不一致的典型场景,编写代码时应以实际版本行为为准。
五、SQL 参数 Props:受控与非受控的参数管理
这一组 Props 是StaticQuestion最复杂也最强大的能力,专门用于原生(SQL)问题的参数注入,核心类型为SqlParameterValues(Record<string, string | number | boolean | Array<...> | null | undefined>,以参数 slug 为键)。
| Prop | 类型 | 说明 |
|---|---|---|
initialSqlParameters? | SqlParameterValues | SQL 参数的初始值(按 slug 键控),仅在挂载时应用一次 |
sqlParameters? | SqlParameterValues | 受控的 SQL 参数值(按 slug 键控),每次渲染都会替换问题参数值 |
onSqlParametersChange? | (payload:SqlParameterChangePayload) =>void | SQL 参数变化时的回调 |
hiddenParameters? | string[] | 需要隐藏的参数 slug 列表 |
initialSqlParameters:一次性的初始注入
initialSqlParameters只在组件挂载时应用一次,此后用户在 UI 中修改参数控件,不会回写宿主应用。它的三态语义非常关键:
- 设为某个值:应用该值;
- 设为
null:严格清除该参数,忽略参数自身的默认值; - 省略(或设为
undefined):回退到参数的默认值(若参数无默认值则为null)。
sqlParameters:受控的"全量替换"语义
sqlParameters是**受控(controlled)**参数:在每一次渲染时,该对象会整体替换问题的参数值。规则与initialSqlParameters相似但发生在渲染期:
- 设为某值 → 使用该值;
- 设为
null→ 清除,即使参数有默认值; - 从对象中省略(或
undefined)→ 使用默认值(无默认值则为null)。
正因如此,官方推荐将sqlParameters与onSqlParametersChange配对使用,以便把用户的编辑同步回宿主的受控状态,避免渲染时把用户输入"冲掉"。
onSqlParametersChange:事件来源三态
回调 payload 为SqlParameterChangePayload,包含source、parameters、defaultParameters三个字段。其中source用来区分事件来源(类型定义见frontend/src/embedding-sdk-bundle/types/question.ts):
'initial-state':组件加载时的初始状态(每次加载只触发一次);'manual-change':用户在 UI 中手动编辑参数;'auto-change':自动更新场景,例如把归一化后的值回传给父组件。
典型用法是在source === 'manual-change'时更新受控的sqlParameters状态,形成闭环。
hiddenParameters:隐藏指定参数
hiddenParameters接收一组参数 slug,用于隐藏问题中不需要用户看到的参数控件。在默认布局中,SQL 参数列表通过SdkQuestion.SqlParametersList渲染,并且仅在isGuestEmbed(访客嵌入)时展示(见StaticQuestion.tsx第 219 行{isGuestEmbed && <SdkQuestion.SqlParametersList />}),非访客嵌入场景不会显示参数列表控件。
六、功能开关 Props:下载、告警与图表类型选择
| Prop | 类型 | 说明 |
|---|---|---|
withDownloads? | boolean | 是否允许在问题中下载结果 |
withAlerts? | boolean | 是否允许针对该问题创建告警(Alert) |
withChartTypeSelector? | boolean | 是否显示图表类型选择器及对应设置按钮,仅默认布局下生效 |
withDownloads控制结果下载按钮(DownloadWidgetDropdown),默认布局中它始终渲染在工具栏右侧;withAlerts控制告警入口(QuestionAlertsButton),实现中在移动端布局(isMobile)下会被隐藏;withChartTypeSelector只影响默认布局;当通过children自定义布局时,你需要自行决定是否渲染StaticQuestion.ChartTypeDropdown/ChartTypeSelector子组件。
此外,StaticQuestion.tsx在挂载时还会通过useTrackSdkComponentMount("StaticQuestion", ...)进行组件使用埋点,payload 中记录了with_title、with_downloads、with_alerts等开关状态(以及新建场景下的id_new/id_new_native),这有助于在宿主侧了解静态问答的使用情况。
七、可视化与展示细节:MetabaseCard 的进阶能力
虽然MetabaseCard不是本文表格中的直接 Prop,但card是它的承载类型,理解它可以显著提升StaticQuestion的表现力。MetabaseCard(定义于frontend/src/metabase/embedding-sdk/types/question.ts)由三部分组成:
query:MetabaseQueryObject \| null,基础查询;visualization?:显式指定图表类型,可选table、pivot、object、list、bar、line、area、combo、row、scatter、waterfall、pie、scalar、smartscalar、gauge、progress、funnel、map、sankey、boxplot或自定义custom:...;visualizationSettings?:与visualization类型配对的展示细节设置,例如隐藏坐标轴标签、显示数值标签、堆叠柱状图、添加目标线、调整表格列顺序等。
该类型通过Pick<VisualizationSettings, ...>对每种图表只暴露精炼的子集(如CartesianVisualizationSettings、PieVisualizationSettings),保证自动补全与类型检查的精确性;自定义可视化(custom:...)则接受任意Record<string, unknown>设置。实践建议是:省略visualization让 Metabase 依据查询结果自动推断图表类型;仅在需要特定图表时显式设置visualization;只有在需要具体展示细节时才设置visualizationSettings。
八、运行时校验与组合规则速查
StaticQuestion通过StaticQuestion.schema.ts中的 Yup Schema 做运行时校验,核心约束如下:
- 必须有且仅有四个实体 Prop(
questionId/token/card/query)之一,否则报错questionId, token, card, or query is required; .noUnknown():传入未声明的属性会被拒绝,这有助于尽早发现拼写错误;children及全部 Props 均为可选(optional()),因此最小可用用法是只传一个questionId(或token)。
组合使用时的常见场景:
| 场景 | 推荐组合 |
|---|---|
| 渲染已保存问题(登录态) | questionId={123}或questionId="entityId字符串" |
| 访客嵌入渲染已保存问题 | token={jwt}+questionId={...} |
| 渲染未保存的临时问题 | card={card对象或序列化字符串} |
| 基于临时查询对象渲染 | query={useMetabaseQueryObject(...) 的返回值} |
| 原生问题带初始参数 | questionId+initialSqlParameters={{ slug: value }} |
| 原生问题受控参数 | questionId+sqlParameters+onSqlParametersChange |
九、默认布局与自定义布局
不传children时,StaticQuestion渲染默认布局(见StaticQuestion.tsx的默认分支):
- 顶部栏(TopBar):标题(受
title控制)→ 工具栏(图表类型下拉、下载按钮、告警按钮)→ 访客嵌入下的 SQL 参数列表; - 主区域:
SdkQuestion.QuestionVisualization渲染图表结果。
传入children时,你可以完全掌控布局,自由组合以下子组件(StaticQuestionComponents):Filter、FilterDropdown、ResetButton、Title、Summarize、SummarizeDropdown、QuestionVisualization、ChartTypeSelector、ChartTypeDropdown、QuestionSettings、QuestionSettingsDropdown、Breakout、BreakoutDropdown、DownloadWidget、DownloadWidgetDropdown、AlertsButton、SqlParametersList。这也解释了为什么withChartTypeSelector的文档注明"仅在使用默认布局时生效"——自定义布局下该开关不再自动注入图表类型选择器。
结语
StaticQuestion的 17 个 Props 共同构成了 Metabase 静态嵌入问答能力的完整控制面:四选一的数据来源、可双向透传的尺寸样式、带默认值演进历史的标题控制、受控/非受控双模式的 SQL 参数体系,以及三个功能开关。理解并组合它们,即可在不暴露 Metabase 界面的前提下,把"只读 + 受控交互"的问答能力无缝嵌入任何 React 宿主应用。若需进一步深入,可直接阅读 StaticQuestion.tsx 的实现、类型定义 与 运行时校验 Schema,并结合 SDK 入口导出 sdk-bundle-exports.ts 确认公共 API 边界。
【免费下载链接】metabaseThe easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart:项目地址: https://gitcode.com/GitHub_Trending/me/metabase
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考