shopify-polaris-design
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseThis skill ensures that interfaces are built using Shopify's Polaris Design System, guaranteeing a native, accessible, and professional look and feel for Shopify Merchants.
本技能确保界面采用Shopify的Polaris设计系统构建,为Shopify商家提供原生、可访问且专业的视觉与使用体验。
Core Principles
核心原则
- Merchant-Focused: Design for efficiency and clarity. Merchants use these tools to run their business.
- Native Feel: The app should feel like a natural extension of the Shopify Admin. Do not introduce foreign design patterns (e.g. Material Design shadows, distinct bootstappy buttons) unless absolutely necessary.
- Accessibility: Polaris is built with accessibility in mind. Maintain this by using semantic components (e.g., ,
Button,Link) rather than customTextFieldimplementations.div - Predictability: Follow standard Shopify patterns. Save buttons go in the Contextual Save Bar. Page actions go in the top right. Primary content is centered.
- 以商家为中心:设计注重效率与清晰性。商家使用这些工具来运营业务。
- 原生体验:应用应作为Shopify Admin的自然延伸。除非绝对必要,请勿引入外来设计模式(如Material Design阴影、独特的Bootstrap风格按钮)。
- 可访问性:Polaris在设计时就考虑了可访问性。通过使用语义化组件(如、
Button、Link)而非自定义TextField实现来维持这一特性。div - 可预测性:遵循Shopify标准模式。保存按钮应放在Contextual Save Bar中。页面操作位于右上角。主要内容居中显示。
Technical Implementation
技术实现
Dependencies
依赖项
@shopify/polaris@shopify/polaris-icons- (for navigation, title bar, toasts, save bar)
@shopify/app-bridge-react
@shopify/polaris@shopify/polaris-icons- (用于导航、标题栏、提示框、保存栏)
@shopify/app-bridge-react
Fundamental Components
基础组件
- AppProvider: All Polaris apps must be wrapped in .
<AppProvider i18n={enTranslations}> - Page: The top-level container for a route. Always set and
title(if applicable).primaryActionjsx<Page title="Products" primaryAction={{content: 'Add product', onAction: handleAdd}}> - Layout: Use and
Layoutto structure content.Layout.Section- : For settings pages (Title/Description on left, Card on right).
Layout.AnnotatedSection - : Standard Full (default), 1/2 (
Layout.Section), or 1/3 (variant="oneHalf") width columns.variant="oneThird"
- Card: The primary container for content pieces. Group related information in a Card.
- Use (vertical) or
BlockStack(horizontal) for internal layout within a Card.InlineStack - Do not use as it is deprecated in newer versions; use
Card.SectionwithBlockStack.gap
- Use
- AppProvider:所有Polaris应用必须包裹在中。
<AppProvider i18n={enTranslations}> - Page:路由的顶级容器。务必设置和
title(如有需要)。primaryActionjsx<Page title="Products" primaryAction={{content: 'Add product', onAction: handleAdd}}> - Layout:使用和
Layout来组织内容结构。Layout.Section- :用于设置页面(左侧为标题/描述,右侧为卡片)。
Layout.AnnotatedSection - :标准全宽(默认)、半宽(
Layout.Section)或三分之一宽(variant="oneHalf")列。variant="oneThird"
- Card:内容块的主要容器。将相关信息分组到Card中。
- 使用(垂直)或
BlockStack(水平)来实现Card内部的布局。InlineStack - 请勿使用,因为它在新版本中已被弃用;请使用带
Card.Section属性的gap。BlockStack
- 使用
Data Display
数据展示
- IndexTable: For lists of objects (Products, Orders) with bulk actions and filtering. It replaces the older for complex table cases.
ResourceList - LegacyCard + ResourceList: Still valid for simple lists where table headers aren't needed.
- DataTable: For simple, non-interactive data grids (e.g., analytics data).
- Text: Use instead of
<Text as="h2" variant="headingMd">. Strict typography control is key.<h2>
- IndexTable:用于展示带批量操作和筛选功能的对象列表(如产品、订单)。在复杂表格场景中,它替代了旧版的。
ResourceList - LegacyCard + ResourceList:在不需要表头的简单列表场景中仍然适用。
- DataTable:用于简单的非交互式数据网格(如分析数据)。
- Text:使用而非
<Text as="h2" variant="headingMd">。严格的排版控制是关键。<h2>
Form Design
表单设计
- Use to automatically handle spacing and alignment of form fields.
FormLayout - Use ,
TextField,Select,Checkbox.RadioButton - Validation: Pass prop (string or boolean) to form fields to show validation messages inline.
error - ContextualSaveBar: For forms that edit existing data, use the App Bridge or
useSaveBarcomponent to show the specialized top bar for saving/discarding changes.<ContextualSaveBar>
- 使用自动处理表单字段的间距与对齐。
FormLayout - 使用、
TextField、Select、Checkbox。RadioButton - 验证:为表单字段传递属性(字符串或布尔值),以在字段内联显示验证消息。
error - ContextualSaveBar:对于编辑现有数据的表单,使用App Bridge的或
useSaveBar组件,在视口顶部显示用于保存/放弃更改的专用栏。<ContextualSaveBar>
Design Tokens & CSS
设计令牌与CSS
- Avoid Custom CSS: 95% of styling should be handled by Polaris props (,
gap,padding,align).justify - Design Tokens: If you MUST use custom CSS, use Polaris CSS Custom Properties (Tokens).
- Backgrounds:
var(--p-color-bg-surface) - Text:
var(--p-color-text-default) - Spacing: (16px)
var(--p-space-400) - Borders:
var(--p-border-radius-200)
- Backgrounds:
- 避免自定义CSS:95%的样式应通过Polaris的props(如、
gap、padding、align)来处理。justify - 设计令牌:如果必须使用自定义CSS,请使用Polaris CSS自定义属性(令牌)。
- 背景:
var(--p-color-bg-surface) - 文本:
var(--p-color-text-default) - 间距:(16px)
var(--p-space-400) - 边框:
var(--p-border-radius-200)
- 背景:
Code Style Example
代码风格示例
jsx
import { Page, Layout, Card, BlockStack, Text, Button, InlineStack, Badge } from '@shopify/polaris';
export default function Dashboard() {
return (
<Page
title="Dashboard"
primaryAction={{content: 'Create Campaign', onAction: () => {}}}
secondaryActions={[{content: 'View Logs', onAction: () => {}}]}
>
<Layout>
<Layout.Section>
<Card>
<BlockStack gap="400">
<InlineStack align="space-between">
<Text as="h2" variant="headingMd">Recent Activity</Text>
<Badge tone="success">Active</Badge>
</InlineStack>
<Text as="p" tone="subdued">Everything is running smoothly.</Text>
</BlockStack>
</Card>
</Layout.Section>
<Layout.Section variant="oneThird">
<Card>
<BlockStack gap="200">
<Text as="h3" variant="headingSm">Quick Helper</Text>
<Button variant="plain">Read Documentation</Button>
</BlockStack>
</Card>
</Layout.Section>
</Layout>
</Page>
);
}jsx
import { Page, Layout, Card, BlockStack, Text, Button, InlineStack, Badge } from '@shopify/polaris';
export default function Dashboard() {
return (
<Page
title="Dashboard"
primaryAction={{content: 'Create Campaign', onAction: () => {}}}
secondaryActions={[{content: 'View Logs', onAction: () => {}}]}
>
<Layout>
<Layout.Section>
<Card>
<BlockStack gap="400">
<InlineStack align="space-between">
<Text as="h2" variant="headingMd">Recent Activity</Text>
<Badge tone="success">Active</Badge>
</InlineStack>
<Text as="p" tone="subdued">Everything is running smoothly.</Text>
</BlockStack>
</Card>
</Layout.Section>
<Layout.Section variant="oneThird">
<Card>
<BlockStack gap="200">
<Text as="h3" variant="headingSm">Quick Helper</Text>
<Button variant="plain">Read Documentation</Button>
</BlockStack>
</Card>
</Layout.Section>
</Layout>
</Page>
);
}Anti-Patterns to AVOID
需避免的反模式
- DO NOT use Shadows or Borders manually. Cards handle this.
- DO NOT use . Use
style={{ margin: 10 }}or<Box padding="400">.<BlockStack gap="400"> - DO NOT create a "Save" button at the bottom of a form. Use the at the top of the viewport.
ContextualSaveBar - DO NOT use generic loading spinners. Use or
<SkeletonPage>for loading states.<SkeletonBodyText>
- 请勿手动使用阴影或边框。Card组件会处理这些样式。
- 请勿使用。请使用
style={{ margin: 10 }}或<Box padding="400">。<BlockStack gap="400"> - 请勿在表单底部创建“保存”按钮。请使用视口顶部的。
ContextualSaveBar - 请勿使用通用加载动画。请使用或
<SkeletonPage>来实现加载状态。<SkeletonBodyText>