app-shopify-polaris-web-components
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseShopify Polaris Web Components
Shopify Polaris Web Components
Use this skill when building UI for Shopify App Home surfaces using Polaris Web Components.
当使用Polaris Web Components为Shopify App Home页面构建界面时,可使用本技能。
When to Use
适用场景
- Building App Home pages (the app surface outside of Shopify Admin iframe)
- Creating UI with custom elements
s-* - Designing layouts with s-section, s-stack, s-box
- Building forms, modals, or lists for App Home
Important: App Home uses Polaris Web Components ( elements), NOT Polaris React (). These are different technologies.
s-*@shopify/polaris- 开发App Home页面(Shopify Admin iframe之外的应用页面)
- 使用自定义元素创建界面
s-* - 使用s-section、s-stack、s-box设计布局
- 为App Home构建表单、模态框或列表
重要提示:App Home使用Polaris Web Components(元素),而非Polaris React()。这是两种不同的技术。
s-*@shopify/polarisPolaris React vs Web Components
Polaris React 与 Web Components 对比
| Feature | Polaris React | Polaris Web Components |
|---|---|---|
| Use for | Embedded admin apps | App Home surfaces |
| Import | | No import (native elements) |
| Syntax | | |
| Framework | React components | Custom HTML elements |
| 特性 | Polaris React | Polaris Web Components |
|---|---|---|
| 适用场景 | 嵌入式管理后台应用 | App Home页面 |
| 引入方式 | | 无需引入(原生元素) |
| 语法 | | |
| 技术框架 | React组件 | 自定义HTML元素 |
Core Components
核心组件
Page Structure
页面结构
html
<s-page heading="Dashboard">
<s-section heading="Overview">
<!-- Content -->
</s-section>
<s-section heading="Settings">
<!-- More content -->
</s-section>
</s-page>html
<s-page heading="Dashboard">
<s-section heading="Overview">
<!-- Content -->
</s-section>
<s-section heading="Settings">
<!-- More content -->
</s-section>
</s-page>Layout with Stack
堆叠布局
html
<!-- Vertical stack (default) -->
<s-stack direction="block" gap="large">
<s-text>Item 1</s-text>
<s-text>Item 2</s-text>
</s-stack>
<!-- Horizontal stack -->
<s-stack direction="inline" gap="medium" alignItems="center">
<s-button>Cancel</s-button>
<s-button variant="primary">Save</s-button>
</s-stack>
<!-- Stack with justification -->
<s-stack
direction="inline"
justifyContent="space-between"
alignItems="center"
>
<s-text variant="headingMd">Title</s-text>
<s-button>Action</s-button>
</s-stack>html
<!-- 垂直堆叠(默认) -->
<s-stack direction="block" gap="large">
<s-text>Item 1</s-text>
<s-text>Item 2</s-text>
</s-stack>
<!-- 水平堆叠 -->
<s-stack direction="inline" gap="medium" alignItems="center">
<s-button>Cancel</s-button>
<s-button variant="primary">Save</s-button>
</s-stack>
<!-- 带对齐方式的堆叠 -->
<s-stack
direction="inline"
justifyContent="space-between"
alignItems="center"
>
<s-text variant="headingMd">Title</s-text>
<s-button>Action</s-button>
</s-stack>Section (Card-like Container)
区块(类卡片容器)
Use for grouped content with optional heading:
s-sectionhtml
<!-- Section with heading -->
<s-section heading="Chat Widget Settings">
<s-stack direction="block" gap="medium">
<s-text>Configure your widget appearance.</s-text>
<!-- Form fields -->
</s-stack>
</s-section>
<!-- Section without heading -->
<s-section>
<s-text>Simple content block</s-text>
</s-section>使用来分组内容,可选择添加标题:
s-sectionhtml
<!-- 带标题的区块 -->
<s-section heading="Chat Widget Settings">
<s-stack direction="block" gap="medium">
<s-text>Configure your widget appearance.</s-text>
<!-- Form fields -->
</s-stack>
</s-section>
<!-- 无标题的区块 -->
<s-section>
<s-text>Simple content block</s-text>
</s-section>Box (Generic Layout Container)
容器(通用布局容器)
Use for padding, borders, and spacing - NOT for cards:
s-boxhtml
<!-- Box with padding -->
<s-box padding="large">
<s-text>Padded content</s-text>
</s-box>
<!-- Box with border -->
<s-box
padding="medium"
borderWidth="base"
borderRadius="base"
>
<s-text>Bordered content</s-text>
</s-box>
<!-- Box for spacing -->
<s-box paddingBlockStart="large">
<s-text>Content with top margin</s-text>
</s-box>Rule: Use for card-like containers, for layout/spacing only.
s-sections-box使用来设置内边距、边框和间距——请勿用于卡片:
s-boxhtml
<!-- 带内边距的容器 -->
<s-box padding="large">
<s-text>Padded content</s-text>
</s-box>
<!-- 带边框的容器 -->
<s-box
padding="medium"
borderWidth="base"
borderRadius="base"
>
<s-text>Bordered content</s-text>
</s-box>
<!-- 用于间距的容器 -->
<s-box paddingBlockStart="large">
<s-text>Content with top margin</s-text>
</s-box>规则:使用作为类卡片容器,仅用于布局/间距设置。
s-sections-boxButtons
按钮
html
<!-- Primary action -->
<s-button variant="primary" type="submit">
Save Settings
</s-button>
<!-- Default button -->
<s-button>Cancel</s-button>
<!-- Destructive -->
<s-button variant="primary" tone="critical">
Delete
</s-button>
<!-- Disabled -->
<s-button disabled>Unavailable</s-button>
<!-- With click handler (in JS) -->
<s-button id="save-btn">Save</s-button>
<script>
document.getElementById('save-btn').addEventListener('click', handleSave);
</script>html
<!-- 主要操作按钮 -->
<s-button variant="primary" type="submit">
Save Settings
</s-button>
<!-- 默认按钮 -->
<s-button>Cancel</s-button>
<!-- 危险操作按钮 -->
<s-button variant="primary" tone="critical">
Delete
</s-button>
<!-- 禁用状态按钮 -->
<s-button disabled>Unavailable</s-button>
<!-- 带点击事件的按钮(JS中) -->
<s-button id="save-btn">Save</s-button>
<script>
document.getElementById('save-btn').addEventListener('click', handleSave);
</script>Text
文本
html
<!-- Headings -->
<s-text variant="headingLg">Large Heading</s-text>
<s-text variant="headingMd">Medium Heading</s-text>
<s-text variant="headingSm">Small Heading</s-text>
<!-- Body text -->
<s-text>Default body text</s-text>
<s-text variant="bodySm">Small body text</s-text>
<!-- Tones -->
<s-text tone="subdued">Muted text</s-text>
<s-text tone="critical">Error text</s-text>
<s-text tone="success">Success text</s-text>html
<!-- 标题 -->
<s-text variant="headingLg">Large Heading</s-text>
<s-text variant="headingMd">Medium Heading</s-text>
<s-text variant="headingSm">Small Heading</s-text>
<!-- 正文 -->
<s-text>Default body text</s-text>
<s-text variant="bodySm">Small body text</s-text>
<!-- 文本色调 -->
<s-text tone="subdued">Muted text</s-text>
<s-text tone="critical">Error text</s-text>
<s-text tone="success">Success text</s-text>Banner
横幅
html
<!-- Info banner -->
<s-banner>
<p>This is an informational message.</p>
</s-banner>
<!-- Critical banner -->
<s-banner tone="critical">
<p>Something went wrong. Please try again.</p>
</s-banner>
<!-- Success banner -->
<s-banner tone="success">
<p>Settings saved successfully!</p>
</s-banner>
<!-- Dismissible banner -->
<s-banner tone="warning" onDismiss="handleDismiss">
<p>Your trial ends in 3 days.</p>
</s-banner>html
<!-- 信息横幅 -->
<s-banner>
<p>This is an informational message.</p>
</s-banner>
<!-- 错误横幅 -->
<s-banner tone="critical">
<p>Something went wrong. Please try again.</p>
</s-banner>
<!-- 成功横幅 -->
<s-banner tone="success">
<p>Settings saved successfully!</p>
</s-banner>
<!-- 可关闭的横幅 -->
<s-banner tone="warning" onDismiss="handleDismiss">
<p>Your trial ends in 3 days.</p>
</s-banner>Link
链接
html
<s-link href="/settings">Go to Settings</s-link>
<s-link href="https://shopify.dev" external>
Documentation
</s-link>html
<s-link href="/settings">Go to Settings</s-link>
<s-link href="https://shopify.dev" external>
Documentation
</s-link>Form Elements
表单元素
html
<!-- Text field -->
<s-text-field
label="Store name"
value="My Store"
helpText="This appears in your widget"
></s-text-field>
<!-- Select -->
<s-select label="Language">
<option value="en">English</option>
<option value="es">Spanish</option>
</s-select>
<!-- Checkbox -->
<s-checkbox label="Enable notifications" checked></s-checkbox>html
<!-- 文本输入框 -->
<s-text-field
label="Store name"
value="My Store"
helpText="This appears in your widget"
></s-text-field>
<!-- 下拉选择框 -->
<s-select label="Language">
<option value="en">English</option>
<option value="es">Spanish</option>
</s-select>
<!-- 复选框 -->
<s-checkbox label="Enable notifications" checked></s-checkbox>Common Patterns
常见模式
Settings Page
设置页面
html
<s-page heading="Settings">
<s-stack direction="block" gap="large">
<s-section heading="General">
<s-stack direction="block" gap="medium">
<s-text-field
label="Welcome message"
value="Hello! How can we help?"
></s-text-field>
<s-checkbox label="Enable auto-reply"></s-checkbox>
</s-stack>
</s-section>
<s-section heading="Appearance">
<s-stack direction="block" gap="medium">
<s-select label="Theme">
<option value="light">Light</option>
<option value="dark">Dark</option>
</s-select>
</s-stack>
</s-section>
<s-box paddingBlockStart="large">
<s-stack direction="inline" gap="medium" justifyContent="flex-end">
<s-button>Cancel</s-button>
<s-button variant="primary">Save</s-button>
</s-stack>
</s-box>
</s-stack>
</s-page>html
<s-page heading="Settings">
<s-stack direction="block" gap="large">
<s-section heading="General">
<s-stack direction="block" gap="medium">
<s-text-field
label="Welcome message"
value="Hello! How can we help?"
></s-text-field>
<s-checkbox label="Enable auto-reply"></s-checkbox>
</s-stack>
</s-section>
<s-section heading="Appearance">
<s-stack direction="block" gap="medium">
<s-select label="Theme">
<option value="light">Light</option>
<option value="dark">Dark</option>
</s-select>
</s-stack>
</s-section>
<s-box paddingBlockStart="large">
<s-stack direction="inline" gap="medium" justifyContent="flex-end">
<s-button>Cancel</s-button>
<s-button variant="primary">Save</s-button>
</s-stack>
</s-box>
</s-stack>
</s-page>Empty State
空状态页面
html
<s-section>
<s-stack direction="block" gap="medium" alignItems="center">
<s-text variant="headingMd">No campaigns yet</s-text>
<s-text tone="subdued">
Create your first campaign to get started.
</s-text>
<s-button variant="primary">Create Campaign</s-button>
</s-stack>
</s-section>html
<s-section>
<s-stack direction="block" gap="medium" alignItems="center">
<s-text variant="headingMd">No campaigns yet</s-text>
<s-text tone="subdued">
Create your first campaign to get started.
</s-text>
<s-button variant="primary">Create Campaign</s-button>
</s-stack>
</s-section>List with Actions
带操作的列表
html
<s-section heading="Campaigns">
<s-stack direction="block" gap="none">
<s-box padding="medium" borderBlockEnd="base">
<s-stack direction="inline" justifyContent="space-between" alignItems="center">
<s-stack direction="block" gap="extraSmall">
<s-text variant="headingSm">Welcome Series</s-text>
<s-text tone="subdued">Active • 1,234 sent</s-text>
</s-stack>
<s-button>Edit</s-button>
</s-stack>
</s-box>
<s-box padding="medium" borderBlockEnd="base">
<s-stack direction="inline" justifyContent="space-between" alignItems="center">
<s-stack direction="block" gap="extraSmall">
<s-text variant="headingSm">Abandoned Cart</s-text>
<s-text tone="subdued">Paused • 567 sent</s-text>
</s-stack>
<s-button>Edit</s-button>
</s-stack>
</s-box>
</s-stack>
</s-section>html
<s-section heading="Campaigns">
<s-stack direction="block" gap="none">
<s-box padding="medium" borderBlockEnd="base">
<s-stack direction="inline" justifyContent="space-between" alignItems="center">
<s-stack direction="block" gap="extraSmall">
<s-text variant="headingSm">Welcome Series</s-text>
<s-text tone="subdued">Active • 1,234 sent</s-text>
</s-stack>
<s-button>Edit</s-button>
</s-stack>
</s-box>
<s-box padding="medium" borderBlockEnd="base">
<s-stack direction="inline" justifyContent="space-between" alignItems="center">
<s-stack direction="block" gap="extraSmall">
<s-text variant="headingSm">Abandoned Cart</s-text>
<s-text tone="subdued">Paused • 567 sent</s-text>
</s-stack>
<s-button>Edit</s-button>
</s-stack>
</s-box>
</s-stack>
</s-section>TypeScript Support
TypeScript 支持
Add types for s-* components in your :
tsconfig.jsonjson
{
"compilerOptions": {
"types": ["@shopify/polaris-types"]
}
}在中添加s-*组件的类型声明:
tsconfig.jsonjson
{
"compilerOptions": {
"types": ["@shopify/polaris-types"]
}
}Best Practices
最佳实践
- Use s-section for cards - Not s-box
- Use s-box for layout only - Padding, borders, spacing
- Prefer s- over custom divs* - Only use div when s-* can't achieve the layout
- Use semantic structure - s-page > s-section > content
- Consistent spacing - Use gap props, not manual margins
- Check the docs - Components have many props not shown here
- 使用s-section作为卡片容器——而非s-box
- 仅将s-box用于布局——设置内边距、边框、间距
- *优先使用s-组件而非自定义div——仅当s-*组件无法实现所需布局时才使用div
- 使用语义化结构——遵循s-page > s-section > 内容的层级
- 保持间距一致——使用gap属性,而非手动设置外边距
- 查阅官方文档——组件还有许多未在此展示的属性
When to Use Custom Styles
自定义样式的适用场景
Only use plain and inline styles when:
div- The user explicitly requests it
- After trying s-* components and they can't achieve the required layout
- For very specific visual effects not supported by Polaris
仅在以下情况使用普通和内联样式:
div- 用户明确要求时
- 尝试使用s-*组件后仍无法实现所需布局时
- 用于Polaris不支持的特殊视觉效果时