wix-cli-dashboard-modal
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseOverview
概述
Dashboard modals are popup dialogs triggered from dashboard pages or plugins. They consist of three files and use the Dashboard SDK for lifecycle control via and .
openModal()closeModal()仪表盘模态框是从仪表盘页面或插件触发的弹出式对话框。它们由三个文件组成,并通过和方法使用Dashboard SDK进行生命周期控制。
openModal()closeModal()Quick Reference
快速参考
| Task | Method | Example |
|---|---|---|
| Create modal | Create 3 files in | See File Structure below |
| Open modal | | |
| Pass data to modal | | |
| Read data in modal | | |
| Close modal | | |
| Return data to parent | Pass data to | |
| Wait for modal close | | |
| 任务 | 方法 | 示例 |
|---|---|---|
| 创建模态框 | 在 | 见下方文件结构 |
| 打开模态框 | | |
| 向模态框传递数据 | | |
| 在模态框中读取数据 | | |
| 关闭模态框 | | |
| 向父组件返回数据 | 向 | |
| 等待模态框关闭 | | |
File Structure
文件结构
Create three files in :
src/dashboard/modals/<folder-name>/- - Builder configuration with modal ID, title, dimensions, component path
extensions.ts - - React component rendering modal content
<modal-name>.tsx - - Configurable modal properties (title, width, height)
<modal-name>.config.ts
在目录下创建三个文件:
src/dashboard/modals/<folder-name>/- - 包含模态框ID、标题、尺寸、组件路径的构建器配置文件
extensions.ts - - 渲染模态框内容的React组件
<modal-name>.tsx - - 模态框的可配置属性(标题、宽度、高度)
<modal-name>.config.ts
Implementation
实现步骤
Creating a Modal
创建模态框
Create the three required files:
1. - Modal builder configuration:
extensions.tstypescript
import { extensions } from '@wix/astro/builders';
import config from './<modal-name>.config.ts';
export default extensions.dashboardModal({
id: "{{GENERATE_UUID}}",
title: config.title,
width: config.width,
height: config.height,
component: './extensions/dashboard/modals/<modal-name>/<modal-name>.tsx',
});
CRITICAL: UUID Generation
The must be a unique, static UUID v4 string. Generate a fresh UUID for each extension - do NOT use or copy UUIDs from examples. Replace with a freshly generated UUID like .
idrandomUUID(){{GENERATE_UUID}}"a1b2c3d4-e5f6-7890-abcd-ef1234567890"Builder fields:
| Field | Type | Description |
|---|---|---|
| id | string | Unique modal ID (GUID). Used with |
| title | string | Modal title shown in project dashboard |
| width | number | Initial width while loading |
| height | number | Initial height while loading |
| component | string | Path to the modal content |
2. - Modal content component:
<modal-name>.tsxtypescript
import type { FC } from 'react';
import { dashboard } from '@wix/dashboard';
import {
WixDesignSystemProvider,
Text,
Box,
CustomModalLayout,
} from '@wix/design-system';
import '@wix/design-system/styles.global.css';
import config from './<modal-name>.config.ts';
const { width, height, title } = config;
// To open your modal, call `openModal` with your modal id.
// e.g.
// import { dashboard } from '@wix/dashboard';
// function MyComponent() {
// return <button onClick={() => dashboard.openModal({ modalId: '8ef4d434-9c80-44f5-a3f5-6f15f3a34be7' })}>Open Modal</button>;
// }
const Modal: FC = () => {
return (
<WixDesignSystemProvider features={{ newColorsBranding: true }}>
<CustomModalLayout
width={width}
maxHeight={height}
primaryButtonText="Save"
secondaryButtonText="Cancel"
primaryButtonOnClick={() => dashboard.closeModal()}
secondaryButtonOnClick={() => dashboard.closeModal()}
title={title}
subtitle="Edit this file to customize your modal"
content={
<Box direction="vertical" align="center">
<Text>Wix CLI Modal</Text>
</Box>
}
/>
</WixDesignSystemProvider>
);
};
export default Modal;3. - Configurable properties:
<modal-name>.config.tstypescript
export default {
title: "My Modal",
width: 600,
height: 400,
};Then register in :
src/extensions.tstypescript
import { dashboardmodalYourModal } from './dashboard/modals/<modal-name>/extensions.ts';
export default app()
.use(dashboardmodalYourModal)
// ... other extensions创建所需的三个文件:
1. - 模态框构建器配置:
extensions.tstypescript
import { extensions } from '@wix/astro/builders';
import config from './<modal-name>.config.ts';
export default extensions.dashboardModal({
id: "{{GENERATE_UUID}}",
title: config.title,
width: config.width,
height: config.height,
component: './extensions/dashboard/modals/<modal-name>/<modal-name>.tsx',
});
重要提示:UUID生成
idrandomUUID(){{GENERATE_UUID}}"a1b2c3d4-e5f6-7890-abcd-ef1234567890"构建器字段:
| 字段 | 类型 | 描述 |
|---|---|---|
| id | string | 唯一的模态框ID(GUID)。与 |
| title | string | 在项目仪表盘中显示的模态框标题 |
| width | number | 加载时的初始宽度 |
| height | number | 加载时的初始高度 |
| component | string | 模态框内容 |
2. - 模态框内容组件:
<modal-name>.tsxtypescript
import type { FC } from 'react';
import { dashboard } from '@wix/dashboard';
import {
WixDesignSystemProvider,
Text,
Box,
CustomModalLayout,
} from '@wix/design-system';
import '@wix/design-system/styles.global.css';
import config from './<modal-name>.config.ts';
const { width, height, title } = config;
// 要打开模态框,请调用`openModal`并传入你的模态框id。
// 例如
// import { dashboard } from '@wix/dashboard';
// function MyComponent() {
// return <button onClick={() => dashboard.openModal({ modalId: '8ef4d434-9c80-44f5-a3f5-6f15f3a34be7' })}>打开模态框</button>;
// }
const Modal: FC = () => {
return (
<WixDesignSystemProvider features={{ newColorsBranding: true }}>
<CustomModalLayout
width={width}
maxHeight={height}
primaryButtonText="保存"
secondaryButtonText="取消"
primaryButtonOnClick={() => dashboard.closeModal()}
secondaryButtonOnClick={() => dashboard.closeModal()}
title={title}
subtitle="编辑此文件来自定义你的模态框"
content={
<Box direction="vertical" align="center">
<Text>Wix CLI Modal</Text>
</Box>
}
/>
</WixDesignSystemProvider>
);
};
export default Modal;3. - 可配置属性:
<modal-name>.config.tstypescript
export default {
title: "我的模态框",
width: 600,
height: 400,
};然后在中注册:
src/extensions.tstypescript
import { dashboardmodalYourModal } from './dashboard/modals/<modal-name>/extensions.ts';
export default app()
.use(dashboardmodalYourModal)
// ... 其他扩展Opening a Modal
打开模态框
typescript
import { dashboard } from "@wix/dashboard";
// Simple open
const result = await dashboard.openModal({
modalId: "your-modal-id", // From .extension.ts id field
});
// Pass data to modal via params
const result = await dashboard.openModal({
modalId: "your-modal-id",
params: {
userId: user.id,
itemData: complexObject, // Objects are passed directly, no encoding needed
},
});
// Get notified when the modal is closed
const { modalClosed } = dashboard.openModal({
modalId: "your-modal-id",
});
const result = await modalClosed; // Resolves with data from closeModal()typescript
import { dashboard } from "@wix/dashboard";
// 简单打开
const result = await dashboard.openModal({
modalId: "your-modal-id", // 来自.extension.ts文件的id字段
});
// 通过params向模态框传递数据
const result = await dashboard.openModal({
modalId: "your-modal-id",
params: {
userId: user.id,
itemData: complexObject, // 对象直接传递,无需编码
},
});
// 监听模态框关闭事件
const { modalClosed } = dashboard.openModal({
modalId: "your-modal-id",
});
const result = await modalClosed; // 会在closeModal()调用时接收返回的数据Receiving Data in Modal
在模态框中接收数据
Use to access data passed via in :
observeState()paramsopenModal()typescript
import { dashboard } from "@wix/dashboard";
import { useEffect, useState } from "react";
function MyModal() {
const [modalData, setModalData] = useState<{ userId?: string; itemData?: any }>({});
useEffect(() => {
dashboard.observeState((state) => {
// Access custom data passed through openModal params
if (state.userId) {
setModalData({
userId: state.userId,
itemData: state.itemData,
});
}
});
}, []);
return <div>User ID: {modalData.userId}</div>;
}使用访问通过中传递的数据:
observeState()openModal()paramstypescript
import { dashboard } from "@wix/dashboard";
import { useEffect, useState } from "react";
function MyModal() {
const [modalData, setModalData] = useState<{ userId?: string; itemData?: any }>({});
useEffect(() => {
dashboard.observeState((state) => {
// 访问通过openModal params传递的自定义数据
if (state.userId) {
setModalData({
userId: state.userId,
itemData: state.itemData,
});
}
});
}, []);
return <div>用户ID: {modalData.userId}</div>;
}Closing Modal
关闭模态框
Call from within the modal extension to close it. Optionally pass data back to the opener.
closeModal()typescript
import { dashboard } from "@wix/dashboard";
// Close without returning data
dashboard.closeModal();
// Close with custom return data
dashboard.closeModal({ saved: true, itemId: "123" });| Parameter | Type | Description |
|---|---|---|
| closeData | Serializable (optional) | Data to pass back to the modal opener. Must be cloneable via structured clone algorithm - no function callbacks. |
Returns:
void在模态框扩展中调用来关闭它。可选择向打开者返回数据。
closeModal()typescript
import { dashboard } from "@wix/dashboard";
// 不返回数据直接关闭
dashboard.closeModal();
// 携带自定义返回数据关闭
dashboard.closeModal({ saved: true, itemId: "123" });| 参数 | 类型 | 描述 |
|---|---|---|
| closeData | 可序列化类型(可选) | 要传递给模态框打开者的数据。必须可通过结构化克隆算法克隆 - 不支持函数回调。 |
返回值:
voidCustomizing Modal
自定义模态框
Edit for organized settings:
.config.tstypescript
export default {
title: 'User Settings',
width: 600,
height: 500,
}Import in :
.tsxtypescript
import config from './modal.config.ts';
export default function MyModal() {
return (
<CustomModalLayout
title={config.title}
// ... rest of component
/>
);
}编辑文件来管理设置:
.config.tstypescript
export default {
title: '用户设置',
width: 600,
height: 500,
}在中导入:
.tsxtypescript
import config from './modal.config.ts';
export default function MyModal() {
return (
<CustomModalLayout
title={config.title}
// ... 组件其他部分
/>
);
}Common Mistakes
常见错误
| Mistake | Fix |
|---|---|
| Can't find modal ID | Check |
Forgetting to register in | Import and |
Using | Use |
| Can't access params in modal | Use |
| Modal won't close | Use |
| 错误 | 修复方案 |
|---|---|
| 找不到模态框ID | 检查 |
忘记在 | 导入模态框并通过 |
使用 | 在 |
| 无法在模态框中访问params | 使用 |
| 模态框无法关闭 | 使用 |
Real-World Example
实际示例
typescript
// Dashboard Page: Opening edit modal
const handleEdit = async (item: Item) => {
dashboard.openModal({
modalId: "edit-item-modal-guid",
params: {
itemId: item._id,
item: item, // Objects passed directly via params
},
});
};
// Modal: Receiving and saving data
export default function ItemEditModal() {
const [formData, setFormData] = useState<Item | null>(null);
useEffect(() => {
dashboard.observeState((state) => {
if (state.item) {
setFormData(state.item);
}
});
}, []);
const handleSave = async () => {
// Save logic
dashboard.showToast({ message: "Saved!", type: "success" });
dashboard.closeModal();
};
return (
<CustomModalLayout
title="Edit Item"
primaryButtonText="Save"
onCloseButtonClick={() => dashboard.closeModal()}
primaryButtonOnClick={handleSave}
content={/* form fields */}
/>
);
}typescript
// 仪表盘页面:打开编辑模态框
const handleEdit = async (item: Item) => {
dashboard.openModal({
modalId: "edit-item-modal-guid",
params: {
itemId: item._id,
item: item, // 对象直接通过params传递
},
});
};
// 模态框:接收并保存数据
export default function ItemEditModal() {
const [formData, setFormData] = useState<Item | null>(null);
useEffect(() => {
dashboard.observeState((state) => {
if (state.item) {
setFormData(state.item);
}
});
}, []);
const handleSave = async () => {
// 保存逻辑
dashboard.showToast({ message: "已保存!", type: "success" });
dashboard.closeModal();
};
return (
<CustomModalLayout
title="编辑条目"
primaryButtonText="保存"
onCloseButtonClick={() => dashboard.closeModal()}
primaryButtonOnClick={handleSave}
content={/* 表单字段 */}
/>
);
}Verification
验证
After implementation, use wix-cli-app-validation to validate TypeScript compilation, build, preview, and runtime behavior.
实现完成后,使用wix-cli-app-validation来验证TypeScript编译、构建、预览和运行时行为。