home / skills / toilahuongg / google-antigravity-kit / shopify-polaris-design

shopify-polaris-design skill

/.agent/skills/shopify-polaris-design

This is most likely a fork of the shopify-polaris-design skill from toilahuongg
npx playbooks add skill toilahuongg/google-antigravity-kit --skill shopify-polaris-design

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
5.0 KB
---
name: shopify-polaris-design
description: Design and implement Shopify Admin interfaces using the Polaris Design System. Use this skill when building Shopify Apps, Admin extensions, or any interface that needs to feel native to Shopify.
---

This skill ensures that interfaces are built using Shopify's Polaris Design System, guaranteeing a native, accessible, and professional look and feel for Shopify Merchants.

## Core Principles

1.  **Merchant-Focused**: Design for efficiency and clarity. Merchants use these tools to run their business. 
2.  **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.
3.  **Accessibility**: Polaris is built with accessibility in mind. Maintain this by using semantic components (e.g., `Button`, `Link`, `TextField`) rather than custom `div` implementations.
4.  **Predictability**: Follow standard Shopify patterns. Save buttons go in the Contextual Save Bar. Page actions go in the top right. Primary content is centered.

## Technical Implementation

### Dependencies
- `@shopify/polaris`
- `@shopify/polaris-icons`
- `@shopify/app-bridge-react` (for navigation, title bar, toasts, save bar)

### Fundamental Components

- **AppProvider**: All Polaris apps must be wrapped in `<AppProvider i18n={enTranslations}>`.
- **Page**: The top-level container for a route. Always set `title` and `primaryAction` (if applicable).
  ```jsx
  <Page title="Products" primaryAction={{content: 'Add product', onAction: handleAdd}}>
  ```
- **Layout**: Use `Layout` and `Layout.Section` to structure content.
    - `Layout.AnnotatedSection`: For settings pages (Title/Description on left, Card on right).
    - `Layout.Section`: Standard Full (default), 1/2 (`variant="oneHalf"`), or 1/3 (`variant="oneThird"`) width columns.
- **Card**: The primary container for content pieces. Group related information in a Card. 
    - Use `BlockStack` (vertical) or `InlineStack` (horizontal) for internal layout within a Card.
    - **Do not** use `Card.Section` as it is deprecated in newer versions; use `BlockStack` with `gap`.

### Data Display

- **IndexTable**: For lists of objects (Products, Orders) with bulk actions and filtering. It replaces the older `ResourceList` for complex table cases.
- **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 `<Text as="h2" variant="headingMd">` instead of `<h2>`. Strict typography control is key.

### Form Design

- Use `FormLayout` to automatically handle spacing and alignment of form fields.
- Use `TextField`, `Select`, `Checkbox`, `RadioButton`.
- **Validation**: Pass `error` prop (string or boolean) to form fields to show validation messages inline.
- **ContextualSaveBar**: For forms that edit existing data, use the App Bridge `useSaveBar` or `<ContextualSaveBar>` component to show the specialized top bar for saving/discarding changes.

## Design Tokens & 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: `var(--p-space-400)` (16px)
  - Borders: `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>
  );
}
```

## Anti-Patterns to AVOID

- **DO NOT** use Shadows or Borders manually. Cards handle this.
- **DO NOT** use `style={{ margin: 10 }}`. Use `<Box padding="400">` or `<BlockStack gap="400">`.
- **DO NOT** create a "Save" button at the bottom of a form. Use the `ContextualSaveBar` at the top of the viewport.
- **DO NOT** use generic loading spinners. Use `<SkeletonPage>` or `<SkeletonBodyText>` for loading states.