该技能旨在确保界面基于 Shopify 的 Polaris 设计系统构建,从而为 Shopify 商家提供原生、可访问且专业的观感与体验。
核心原则
面向商家:为效率与清晰而设计,商家使用这些工具来经营业务。
原生观感:应用应感觉像 Shopify Admin 的自然延伸。除非绝对必要,不要引入外来设计模式(例如 Material Design 阴影、明显 Bootstrap 风格的按钮)。
可访问性:Polaris 在设计时考虑了可访问性。请通过使用语义组件(如 Button、Link、TextField)而非自定义 div 实现来保持这一点。
可预测性:遵循标准 Shopify 模式。保存按钮放在上下文保存栏(Contextual Save Bar)中。页面操作位于右上角。主内容居中。
技术实现
依赖项
@shopify/polaris
@shopify/polaris-icons
@shopify/app-bridge-react(用于导航、标题栏、toast、保存栏)
基础组件
AppProvider:所有 Polaris 应用都必须包裹在 <AppProvider i18n={enTranslations}> 中。
Page:路由的顶层容器。始终设置 title 和 primaryAction(如适用)。
<Page title="Products" primaryAction={{content: 'Add product', onAction: handleAdd}}>
Layout:使用 Layout 和 Layout.Section 来组织内容结构。
Layout.AnnotatedSection:用于设置页面(标题/描述在左侧,Card 在右侧)。
Layout.Section:标准全宽(默认)、1/2(variant="oneHalf")或 1/3(variant="oneThird")宽度列。
Card:内容块的主要容器。将相关信息分组放入 Card。
在 Card 内部使用 BlockStack(垂直)或 InlineStack(水平)进行布局。
不要使用 Card.Section,因为它在较新版本中已弃用;请使用带 gap 的 BlockStack。
数据展示
IndexTable:用于带有批量操作和筛选的对象列表(Products、Orders)。在复杂表格场景中它取代了较早的 ResourceList。
LegacyCard + ResourceList:在不需要表头的简单列表中仍然有效。
DataTable:用于简单、非交互式的数据网格(例如分析数据)。
Text:使用 <Text as="h2" variant="headingMd"> 而不是 <h2>。严格的排版控制是关键。
表单设计
使用 FormLayout 自动处理表单字段的间距与对齐。
使用 TextField、Select、Checkbox、RadioButton。
校验:向表单字段传入 error 属性(字符串或布尔值)以内联显示校验消息。
ContextualSaveBar:对于编辑已有数据的表单,使用 App Bridge 的 useSaveBar 或 <ContextualSaveBar> 组件来显示用于保存/放弃更改的专用顶部栏。
设计令牌与 CSS
避免自定义 CSS:95% 的样式应由 Polaris 属性(gap、padding、align、justify)处理。
设计令牌:如果必须使用自定义 CSS,请使用 Polaris CSS 自定义属性(令牌)。
背景:var(--p-color-bg-surface)
文本:var(--p-color-text-default)
间距:var(--p-space-400)(16px)
边框:var(--p-border-radius-200)
代码风格示例
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>
); }
应避免的反模式
不要手动使用阴影或边框。Card 会处理这些。
不要使用 style={{ margin: 10 }}。请使用 <Box padding="400"> 或 <BlockStack gap="400">。
不要在表单底部创建“保存”按钮。请使用视口顶部的 ContextualSaveBar。
不要使用通用加载旋转器。加载状态请使用 <SkeletonPage> 或 <SkeletonBodyText>。