create-shopify-firebase-app 2.0.5 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +122 -74
- package/lib/index.js +540 -244
- package/lib/preflight.js +358 -0
- package/lib/provision.js +187 -5
- package/package.json +1 -1
- package/templates/js/functions/package.json +6 -6
- package/templates/js/functions/src/admin-api.js +1 -1
- package/templates/js/functions/src/auth.js +45 -13
- package/templates/js/functions/src/firebase.js +6 -4
- package/templates/js/functions/src/index.js +14 -0
- package/templates/shared/extensions/theme-block/blocks/app-block.liquid +1 -1
- package/templates/shared/extensions/theme-block/shopify.extension.toml +1 -1
- package/templates/shared/firebase.json +1 -1
- package/templates/shared/firestore.rules +10 -2
- package/templates/shopify.app.toml +1 -1
- package/templates/ts/functions/package.json +10 -10
- package/templates/ts/functions/src/admin-api.ts +5 -2
- package/templates/ts/functions/src/auth.ts +69 -15
- package/templates/ts/functions/src/firebase.ts +8 -4
- package/templates/ts/functions/tsconfig.json +2 -1
- package/templates/web/css/app.css +78 -1138
- package/templates/web/index.html +79 -68
- package/templates/web/js/app.js +60 -33
- package/templates/web/js/pages/home.js +33 -22
- package/templates/web/js/pages/polaris-demo.js +25 -83
- package/templates/web/js/pages/products.js +100 -114
- package/templates/web/js/pages/settings.js +68 -166
- package/templates/web/polaris.html +1221 -950
- package/templates/web/products.html +35 -40
- package/templates/web/settings.html +69 -17
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>Components - {{APP_NAME}}</title>
|
|
7
7
|
<link rel="stylesheet" href="/css/app.css">
|
|
8
|
+
<meta name="shopify-api-key" content="{{API_KEY}}">
|
|
8
9
|
<script src="https://cdn.shopify.com/shopifycloud/app-bridge.js"></script>
|
|
10
|
+
<script src="https://cdn.shopify.com/shopifycloud/polaris.js"></script>
|
|
9
11
|
</head>
|
|
10
12
|
<body>
|
|
11
13
|
<ui-nav-menu>
|
|
@@ -15,785 +17,1034 @@
|
|
|
15
17
|
<a href="/polaris">Components</a>
|
|
16
18
|
</ui-nav-menu>
|
|
17
19
|
|
|
18
|
-
<
|
|
20
|
+
<s-page heading="Polaris Web Components Reference">
|
|
21
|
+
<s-link slot="breadcrumb-actions" href="/">Dashboard</s-link>
|
|
19
22
|
|
|
20
|
-
<div class="page page-wide">
|
|
21
23
|
<!-- Intro banner -->
|
|
22
|
-
<
|
|
23
|
-
<
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
<s-section>
|
|
25
|
+
<s-banner tone="info">
|
|
26
|
+
<s-text>A comprehensive catalog of <s-text fontWeight="semibold">Shopify Polaris Web Components</s-text> (<code><s-*></code> elements). These are the official Shopify admin UI components loaded from <code>polaris.js</code> CDN. Copy code snippets directly into your pages — no build step required.</s-text>
|
|
27
|
+
</s-banner>
|
|
28
|
+
</s-section>
|
|
26
29
|
|
|
27
30
|
<!-- Table of contents -->
|
|
28
|
-
<
|
|
29
|
-
<
|
|
30
|
-
|
|
31
|
-
<
|
|
32
|
-
<
|
|
33
|
-
<
|
|
34
|
-
<
|
|
35
|
-
<
|
|
36
|
-
<
|
|
37
|
-
<
|
|
38
|
-
<
|
|
39
|
-
<
|
|
40
|
-
<
|
|
41
|
-
<
|
|
42
|
-
<
|
|
43
|
-
|
|
44
|
-
|
|
31
|
+
<s-section heading="Quick Navigation">
|
|
32
|
+
<s-stack direction="inline" gap="small-200" wrap>
|
|
33
|
+
<s-button href="#section-page" variant="tertiary">Page</s-button>
|
|
34
|
+
<s-button href="#section-box" variant="tertiary">Box</s-button>
|
|
35
|
+
<s-button href="#section-stack" variant="tertiary">Stack</s-button>
|
|
36
|
+
<s-button href="#section-grid" variant="tertiary">Grid</s-button>
|
|
37
|
+
<s-button href="#section-text" variant="tertiary">Text & Heading</s-button>
|
|
38
|
+
<s-button href="#section-buttons" variant="tertiary">Buttons</s-button>
|
|
39
|
+
<s-button href="#section-badges" variant="tertiary">Badges</s-button>
|
|
40
|
+
<s-button href="#section-banners" variant="tertiary">Banners</s-button>
|
|
41
|
+
<s-button href="#section-forms" variant="tertiary">Forms</s-button>
|
|
42
|
+
<s-button href="#section-switch" variant="tertiary">Switch</s-button>
|
|
43
|
+
<s-button href="#section-select" variant="tertiary">Select</s-button>
|
|
44
|
+
<s-button href="#section-links" variant="tertiary">Links & Clickable</s-button>
|
|
45
|
+
<s-button href="#section-spinner" variant="tertiary">Spinner</s-button>
|
|
46
|
+
<s-button href="#section-section" variant="tertiary">Section</s-button>
|
|
47
|
+
<s-button href="#section-modals" variant="tertiary">Modals</s-button>
|
|
48
|
+
<s-button href="#section-savebar" variant="tertiary">Save Bar</s-button>
|
|
49
|
+
<s-button href="#section-toasts" variant="tertiary">Toasts</s-button>
|
|
50
|
+
<s-button href="#section-navigation" variant="tertiary">Navigation</s-button>
|
|
51
|
+
<s-button href="#section-resource-picker" variant="tertiary">Resource Picker</s-button>
|
|
52
|
+
<s-button href="#section-patterns" variant="tertiary">Patterns</s-button>
|
|
53
|
+
</s-stack>
|
|
54
|
+
</s-section>
|
|
45
55
|
|
|
46
56
|
|
|
47
57
|
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
48
|
-
<!-- SECTION
|
|
58
|
+
<!-- SECTION: PAGE -->
|
|
49
59
|
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
50
|
-
<div
|
|
51
|
-
<
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
</
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
60
|
+
<div id="section-page">
|
|
61
|
+
<s-section heading="Page">
|
|
62
|
+
<s-text color="subdued">The top-level container for any admin page. Provides heading, breadcrumbs, and primary actions.</s-text>
|
|
63
|
+
|
|
64
|
+
<s-box paddingBlockStart="base">
|
|
65
|
+
<!-- Basic page -->
|
|
66
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
67
|
+
<s-stack gap="base">
|
|
68
|
+
<s-text variant="headingSm">Basic Page</s-text>
|
|
69
|
+
<s-text color="subdued">Every page starts with <code><s-page></code>. Set the <code>heading</code> attribute for the title.</s-text>
|
|
70
|
+
<div class="demo-code">
|
|
71
|
+
<div class="code-block-header">
|
|
72
|
+
<span>HTML</span>
|
|
73
|
+
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
74
|
+
</div>
|
|
75
|
+
<pre><code><s-page heading="My Page Title">
|
|
76
|
+
<!-- Page content here -->
|
|
77
|
+
</s-page></code></pre>
|
|
78
|
+
</div>
|
|
79
|
+
</s-stack>
|
|
80
|
+
</s-box>
|
|
81
|
+
</s-box>
|
|
82
|
+
|
|
83
|
+
<s-box paddingBlockStart="base">
|
|
84
|
+
<!-- Page with breadcrumbs + primary action -->
|
|
85
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
86
|
+
<s-stack gap="base">
|
|
87
|
+
<s-text variant="headingSm">Page with Breadcrumbs & Actions</s-text>
|
|
88
|
+
<s-text color="subdued">Use <code>slot="breadcrumb-actions"</code> for back navigation and <code>slot="primary-action"</code> for the main CTA.</s-text>
|
|
89
|
+
<div class="demo-code">
|
|
90
|
+
<div class="code-block-header">
|
|
91
|
+
<span>HTML</span>
|
|
92
|
+
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
93
|
+
</div>
|
|
94
|
+
<pre><code><s-page heading="Product Details">
|
|
95
|
+
<s-link slot="breadcrumb-actions" href="/">Dashboard</s-link>
|
|
96
|
+
<s-button slot="primary-action" variant="primary">Save</s-button>
|
|
97
|
+
|
|
98
|
+
<s-section heading="Details">
|
|
99
|
+
<s-text>Page content here.</s-text>
|
|
100
|
+
</s-section>
|
|
101
|
+
</s-page></code></pre>
|
|
102
|
+
</div>
|
|
103
|
+
</s-stack>
|
|
104
|
+
</s-box>
|
|
105
|
+
</s-box>
|
|
106
|
+
|
|
107
|
+
<s-box paddingBlockStart="base">
|
|
108
|
+
<!-- Page sizes -->
|
|
109
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
110
|
+
<s-stack gap="base">
|
|
111
|
+
<s-text variant="headingSm">Page Width</s-text>
|
|
112
|
+
<s-text color="subdued">Control page width with the <code>inlineSize</code> attribute.</s-text>
|
|
113
|
+
<div class="demo-code">
|
|
114
|
+
<div class="code-block-header">
|
|
115
|
+
<span>HTML</span>
|
|
116
|
+
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
117
|
+
</div>
|
|
118
|
+
<pre><code><!-- Default width -->
|
|
119
|
+
<s-page heading="Default">...</s-page>
|
|
120
|
+
|
|
121
|
+
<!-- Narrow width (for settings/forms) -->
|
|
122
|
+
<s-page heading="Settings" inlineSize="small">...</s-page></code></pre>
|
|
123
|
+
</div>
|
|
124
|
+
</s-stack>
|
|
125
|
+
</s-box>
|
|
126
|
+
</s-box>
|
|
127
|
+
</s-section>
|
|
128
|
+
</div>
|
|
78
129
|
|
|
79
|
-
<!-- Sizes -->
|
|
80
|
-
<div class="demo-block">
|
|
81
|
-
<div class="demo-block-title">Button Sizes</div>
|
|
82
|
-
<div class="demo-preview">
|
|
83
|
-
<div class="btn-group items-center">
|
|
84
|
-
<button class="btn btn-primary btn-sm">Small</button>
|
|
85
|
-
<button class="btn btn-primary">Default</button>
|
|
86
|
-
<button class="btn btn-primary btn-lg">Large</button>
|
|
87
|
-
</div>
|
|
88
|
-
</div>
|
|
89
|
-
<div class="demo-code">
|
|
90
|
-
<div class="code-block-header">
|
|
91
|
-
<span>HTML</span>
|
|
92
|
-
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
93
|
-
</div>
|
|
94
|
-
<pre><code><button class="btn btn-primary btn-sm">Small</button>
|
|
95
|
-
<button class="btn btn-primary">Default</button>
|
|
96
|
-
<button class="btn btn-primary btn-lg">Large</button></code></pre>
|
|
97
|
-
</div>
|
|
98
|
-
</div>
|
|
99
130
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
131
|
+
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
132
|
+
<!-- SECTION: BOX -->
|
|
133
|
+
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
134
|
+
<div id="section-box">
|
|
135
|
+
<s-section heading="Box">
|
|
136
|
+
<s-text color="subdued">A flexible container with padding, borders, and background. The building block for cards and custom layouts.</s-text>
|
|
137
|
+
|
|
138
|
+
<s-box paddingBlockStart="base">
|
|
139
|
+
<!-- Live demos -->
|
|
140
|
+
<s-stack gap="base">
|
|
141
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
142
|
+
<s-text>Basic box with border, radius, and padding.</s-text>
|
|
143
|
+
</s-box>
|
|
144
|
+
|
|
145
|
+
<s-box border="base" borderRadius="base" padding="large-400" background="bg-surface-secondary">
|
|
146
|
+
<s-text>Box with secondary background and large padding.</s-text>
|
|
147
|
+
</s-box>
|
|
148
|
+
|
|
149
|
+
<s-grid gridTemplateColumns="1fr 1fr 1fr" gap="base">
|
|
150
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
151
|
+
<s-text color="subdued">Column 1</s-text>
|
|
152
|
+
</s-box>
|
|
153
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
154
|
+
<s-text color="subdued">Column 2</s-text>
|
|
155
|
+
</s-box>
|
|
156
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
157
|
+
<s-text color="subdued">Column 3</s-text>
|
|
158
|
+
</s-box>
|
|
159
|
+
</s-grid>
|
|
160
|
+
</s-stack>
|
|
161
|
+
</s-box>
|
|
162
|
+
|
|
163
|
+
<s-box paddingBlockStart="base">
|
|
164
|
+
<div class="demo-code">
|
|
165
|
+
<div class="code-block-header">
|
|
166
|
+
<span>HTML</span>
|
|
167
|
+
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
168
|
+
</div>
|
|
169
|
+
<pre><code><!-- Basic box -->
|
|
170
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
171
|
+
<s-text>Content here.</s-text>
|
|
172
|
+
</s-box>
|
|
173
|
+
|
|
174
|
+
<!-- Box with background -->
|
|
175
|
+
<s-box border="base" borderRadius="base" padding="large-400"
|
|
176
|
+
background="bg-surface-secondary">
|
|
177
|
+
<s-text>Secondary background.</s-text>
|
|
178
|
+
</s-box>
|
|
179
|
+
|
|
180
|
+
<!-- Padding options: small-200, base, large-400, large-1200 -->
|
|
181
|
+
<!-- Border: base, none -->
|
|
182
|
+
<!-- borderRadius: base, large, full --></code></pre>
|
|
114
183
|
</div>
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
<button class="btn btn-loading">Loading</button></code></pre>
|
|
118
|
-
</div>
|
|
119
|
-
</div>
|
|
184
|
+
</s-box>
|
|
185
|
+
</s-section>
|
|
120
186
|
</div>
|
|
121
187
|
|
|
122
188
|
|
|
123
189
|
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
124
|
-
<!-- SECTION
|
|
190
|
+
<!-- SECTION: STACK -->
|
|
125
191
|
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
126
|
-
<div
|
|
127
|
-
<
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
<
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
<
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
</
|
|
142
|
-
</
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
<
|
|
160
|
-
|
|
161
|
-
<
|
|
162
|
-
<
|
|
163
|
-
|
|
164
|
-
<
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
192
|
+
<div id="section-stack">
|
|
193
|
+
<s-section heading="Stack">
|
|
194
|
+
<s-text color="subdued">Flexbox-based layout component. Vertical by default, horizontal with <code>direction="inline"</code>.</s-text>
|
|
195
|
+
|
|
196
|
+
<s-box paddingBlockStart="base">
|
|
197
|
+
<!-- Vertical stack -->
|
|
198
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
199
|
+
<s-text variant="headingSm">Vertical Stack (default)</s-text>
|
|
200
|
+
<s-box paddingBlockStart="small-200">
|
|
201
|
+
<s-stack gap="base">
|
|
202
|
+
<s-box border="base" borderRadius="base" padding="small-200"><s-text>Item 1</s-text></s-box>
|
|
203
|
+
<s-box border="base" borderRadius="base" padding="small-200"><s-text>Item 2</s-text></s-box>
|
|
204
|
+
<s-box border="base" borderRadius="base" padding="small-200"><s-text>Item 3</s-text></s-box>
|
|
205
|
+
</s-stack>
|
|
206
|
+
</s-box>
|
|
207
|
+
</s-box>
|
|
208
|
+
</s-box>
|
|
209
|
+
|
|
210
|
+
<s-box paddingBlockStart="base">
|
|
211
|
+
<!-- Horizontal stack -->
|
|
212
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
213
|
+
<s-text variant="headingSm">Inline Stack (horizontal)</s-text>
|
|
214
|
+
<s-box paddingBlockStart="small-200">
|
|
215
|
+
<s-stack direction="inline" gap="base" alignItems="center">
|
|
216
|
+
<s-badge tone="info">Tag 1</s-badge>
|
|
217
|
+
<s-badge tone="success">Tag 2</s-badge>
|
|
218
|
+
<s-badge tone="warning">Tag 3</s-badge>
|
|
219
|
+
<s-button>Action</s-button>
|
|
220
|
+
</s-stack>
|
|
221
|
+
</s-box>
|
|
222
|
+
</s-box>
|
|
223
|
+
</s-box>
|
|
224
|
+
|
|
225
|
+
<s-box paddingBlockStart="base">
|
|
226
|
+
<!-- Wrapping stack -->
|
|
227
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
228
|
+
<s-text variant="headingSm">Wrapping Stack</s-text>
|
|
229
|
+
<s-box paddingBlockStart="small-200">
|
|
230
|
+
<s-stack direction="inline" gap="small-200" wrap>
|
|
231
|
+
<s-badge>One</s-badge>
|
|
232
|
+
<s-badge>Two</s-badge>
|
|
233
|
+
<s-badge>Three</s-badge>
|
|
234
|
+
<s-badge>Four</s-badge>
|
|
235
|
+
<s-badge>Five</s-badge>
|
|
236
|
+
<s-badge>Six</s-badge>
|
|
237
|
+
<s-badge>Seven</s-badge>
|
|
238
|
+
<s-badge>Eight</s-badge>
|
|
239
|
+
</s-stack>
|
|
240
|
+
</s-box>
|
|
241
|
+
</s-box>
|
|
242
|
+
</s-box>
|
|
243
|
+
|
|
244
|
+
<s-box paddingBlockStart="base">
|
|
245
|
+
<div class="demo-code">
|
|
246
|
+
<div class="code-block-header">
|
|
247
|
+
<span>HTML</span>
|
|
248
|
+
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
249
|
+
</div>
|
|
250
|
+
<pre><code><!-- Vertical (default) -->
|
|
251
|
+
<s-stack gap="base">
|
|
252
|
+
<s-text>Item 1</s-text>
|
|
253
|
+
<s-text>Item 2</s-text>
|
|
254
|
+
</s-stack>
|
|
255
|
+
|
|
256
|
+
<!-- Horizontal -->
|
|
257
|
+
<s-stack direction="inline" gap="base" alignItems="center">
|
|
258
|
+
<s-badge>Tag</s-badge>
|
|
259
|
+
<s-button>Action</s-button>
|
|
260
|
+
</s-stack>
|
|
261
|
+
|
|
262
|
+
<!-- Wrapping -->
|
|
263
|
+
<s-stack direction="inline" gap="small-200" wrap>
|
|
264
|
+
<s-badge>Wraps on overflow</s-badge>
|
|
265
|
+
</s-stack>
|
|
266
|
+
|
|
267
|
+
<!-- gap: small-200, base, large-400 -->
|
|
268
|
+
<!-- alignItems: center, start, end --></code></pre>
|
|
180
269
|
</div>
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
<span class="info-list-label">Order #1001</span>
|
|
184
|
-
<span class="badge badge-success">Fulfilled</span>
|
|
185
|
-
</li>
|
|
186
|
-
<li>
|
|
187
|
-
<span class="info-list-label">Order #1002</span>
|
|
188
|
-
<span class="badge badge-warning">Pending</span>
|
|
189
|
-
</li>
|
|
190
|
-
</ul></code></pre>
|
|
191
|
-
</div>
|
|
192
|
-
</div>
|
|
270
|
+
</s-box>
|
|
271
|
+
</s-section>
|
|
193
272
|
</div>
|
|
194
273
|
|
|
195
274
|
|
|
196
275
|
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
197
|
-
<!-- SECTION
|
|
276
|
+
<!-- SECTION: GRID -->
|
|
198
277
|
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
199
|
-
<div
|
|
200
|
-
<
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
</
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
278
|
+
<div id="section-grid">
|
|
279
|
+
<s-section heading="Grid">
|
|
280
|
+
<s-text color="subdued">CSS Grid container with responsive column support using container queries.</s-text>
|
|
281
|
+
|
|
282
|
+
<s-box paddingBlockStart="base">
|
|
283
|
+
<!-- 3-column grid -->
|
|
284
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
285
|
+
<s-text variant="headingSm">Responsive Grid</s-text>
|
|
286
|
+
<s-box paddingBlockStart="small-200">
|
|
287
|
+
<s-grid gridTemplateColumns="@container (inline-size <= 400px) 1fr, 1fr 1fr 1fr" gap="base">
|
|
288
|
+
<s-box border="base" borderRadius="base" padding="base" background="bg-surface-secondary">
|
|
289
|
+
<s-text>Column A</s-text>
|
|
290
|
+
</s-box>
|
|
291
|
+
<s-box border="base" borderRadius="base" padding="base" background="bg-surface-secondary">
|
|
292
|
+
<s-text>Column B</s-text>
|
|
293
|
+
</s-box>
|
|
294
|
+
<s-box border="base" borderRadius="base" padding="base" background="bg-surface-secondary">
|
|
295
|
+
<s-text>Column C</s-text>
|
|
296
|
+
</s-box>
|
|
297
|
+
</s-grid>
|
|
298
|
+
</s-box>
|
|
299
|
+
</s-box>
|
|
300
|
+
</s-box>
|
|
301
|
+
|
|
302
|
+
<s-box paddingBlockStart="base">
|
|
303
|
+
<!-- 2-column with sidebar -->
|
|
304
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
305
|
+
<s-text variant="headingSm">Sidebar Layout</s-text>
|
|
306
|
+
<s-box paddingBlockStart="small-200">
|
|
307
|
+
<s-grid gridTemplateColumns="@container (inline-size <= 500px) 1fr, 2fr 1fr" gap="base">
|
|
308
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
309
|
+
<s-text variant="headingSm">Main Content</s-text>
|
|
310
|
+
<s-text color="subdued">Takes up 2/3 of the width.</s-text>
|
|
311
|
+
</s-box>
|
|
312
|
+
<s-box border="base" borderRadius="base" padding="base" background="bg-surface-secondary">
|
|
313
|
+
<s-text variant="headingSm">Sidebar</s-text>
|
|
314
|
+
<s-text color="subdued">Takes up 1/3.</s-text>
|
|
315
|
+
</s-box>
|
|
316
|
+
</s-grid>
|
|
317
|
+
</s-box>
|
|
318
|
+
</s-box>
|
|
319
|
+
</s-box>
|
|
320
|
+
|
|
321
|
+
<s-box paddingBlockStart="base">
|
|
322
|
+
<div class="demo-code">
|
|
323
|
+
<div class="code-block-header">
|
|
324
|
+
<span>HTML</span>
|
|
325
|
+
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
232
326
|
</div>
|
|
233
|
-
<
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
327
|
+
<pre><code><!-- Responsive 3-column grid (stacks on small) -->
|
|
328
|
+
<s-grid gridTemplateColumns="@container (inline-size <= 400px) 1fr, 1fr 1fr 1fr" gap="base">
|
|
329
|
+
<s-box>Col 1</s-box>
|
|
330
|
+
<s-box>Col 2</s-box>
|
|
331
|
+
<s-box>Col 3</s-box>
|
|
332
|
+
</s-grid>
|
|
333
|
+
|
|
334
|
+
<!-- Sidebar layout -->
|
|
335
|
+
<s-grid gridTemplateColumns="@container (inline-size <= 500px) 1fr, 2fr 1fr" gap="base">
|
|
336
|
+
<s-box>Main content</s-box>
|
|
337
|
+
<s-box>Sidebar</s-box>
|
|
338
|
+
</s-grid>
|
|
339
|
+
|
|
340
|
+
<!-- Static columns -->
|
|
341
|
+
<s-grid gridTemplateColumns="1fr 1fr" gap="base">
|
|
342
|
+
<s-box>Left</s-box>
|
|
343
|
+
<s-box>Right</s-box>
|
|
344
|
+
</s-grid></code></pre>
|
|
247
345
|
</div>
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
</div>
|
|
253
|
-
<div class="card-section">
|
|
254
|
-
<h3>Section Two</h3>
|
|
255
|
-
<p>Second section content.</p>
|
|
256
|
-
</div>
|
|
257
|
-
</div></code></pre>
|
|
258
|
-
</div>
|
|
259
|
-
</div>
|
|
346
|
+
</s-box>
|
|
347
|
+
</s-section>
|
|
348
|
+
</div>
|
|
349
|
+
|
|
260
350
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
351
|
+
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
352
|
+
<!-- SECTION: TEXT & HEADING -->
|
|
353
|
+
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
354
|
+
<div id="section-text">
|
|
355
|
+
<s-section heading="Text & Heading">
|
|
356
|
+
<s-text color="subdued">Typography components for headings, body text, and paragraphs.</s-text>
|
|
357
|
+
|
|
358
|
+
<s-box paddingBlockStart="base">
|
|
359
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
360
|
+
<s-stack gap="base">
|
|
361
|
+
<s-text variant="heading2xl">Heading 2XL</s-text>
|
|
362
|
+
<s-text variant="headingXl">Heading XL</s-text>
|
|
363
|
+
<s-text variant="headingLg">Heading Lg</s-text>
|
|
364
|
+
<s-text variant="headingMd">Heading Md</s-text>
|
|
365
|
+
<s-text variant="headingSm">Heading Sm</s-text>
|
|
366
|
+
<s-text variant="headingXs">Heading Xs</s-text>
|
|
367
|
+
<s-text variant="bodyLg">Body Large text</s-text>
|
|
368
|
+
<s-text variant="bodyMd">Body Medium text (default)</s-text>
|
|
369
|
+
<s-text variant="bodySm">Body Small text</s-text>
|
|
370
|
+
</s-stack>
|
|
371
|
+
</s-box>
|
|
372
|
+
</s-box>
|
|
373
|
+
|
|
374
|
+
<s-box paddingBlockStart="base">
|
|
375
|
+
<!-- Text colors & weights -->
|
|
376
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
377
|
+
<s-text variant="headingSm">Colors & Weights</s-text>
|
|
378
|
+
<s-box paddingBlockStart="small-200">
|
|
379
|
+
<s-stack gap="small-200">
|
|
380
|
+
<s-text>Default color</s-text>
|
|
381
|
+
<s-text color="subdued">Subdued color</s-text>
|
|
382
|
+
<s-text color="success">Success color</s-text>
|
|
383
|
+
<s-text color="critical">Critical color</s-text>
|
|
384
|
+
<s-text color="warning">Warning color</s-text>
|
|
385
|
+
<s-text fontWeight="bold">Bold weight</s-text>
|
|
386
|
+
<s-text fontWeight="semibold">Semibold weight</s-text>
|
|
387
|
+
<s-text fontWeight="medium">Medium weight</s-text>
|
|
388
|
+
</s-stack>
|
|
389
|
+
</s-box>
|
|
390
|
+
</s-box>
|
|
391
|
+
</s-box>
|
|
392
|
+
|
|
393
|
+
<s-box paddingBlockStart="base">
|
|
394
|
+
<!-- Heading & Paragraph -->
|
|
395
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
396
|
+
<s-text variant="headingSm">Heading & Paragraph Elements</s-text>
|
|
397
|
+
<s-box paddingBlockStart="small-200">
|
|
398
|
+
<s-stack gap="base">
|
|
399
|
+
<s-heading>This is an <s-heading></s-heading>
|
|
400
|
+
<s-paragraph>This is an <s-paragraph>. Use it for longer blocks of body text. Paragraphs automatically apply proper spacing and line height for readability.</s-paragraph>
|
|
401
|
+
<s-paragraph color="subdued">A subdued paragraph for secondary information.</s-paragraph>
|
|
402
|
+
</s-stack>
|
|
403
|
+
</s-box>
|
|
404
|
+
</s-box>
|
|
405
|
+
</s-box>
|
|
406
|
+
|
|
407
|
+
<s-box paddingBlockStart="base">
|
|
408
|
+
<div class="demo-code">
|
|
409
|
+
<div class="code-block-header">
|
|
410
|
+
<span>HTML</span>
|
|
411
|
+
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
269
412
|
</div>
|
|
270
|
-
<
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
413
|
+
<pre><code><!-- Heading variants -->
|
|
414
|
+
<s-text variant="headingLg">Large Heading</s-text>
|
|
415
|
+
<s-text variant="headingMd">Medium Heading</s-text>
|
|
416
|
+
<s-text variant="headingSm">Small Heading</s-text>
|
|
417
|
+
|
|
418
|
+
<!-- Body text -->
|
|
419
|
+
<s-text>Default body text</s-text>
|
|
420
|
+
<s-text variant="bodySm">Small body text</s-text>
|
|
421
|
+
|
|
422
|
+
<!-- Colors -->
|
|
423
|
+
<s-text color="subdued">Muted text</s-text>
|
|
424
|
+
<s-text color="success">Success</s-text>
|
|
425
|
+
<s-text color="critical">Error</s-text>
|
|
426
|
+
|
|
427
|
+
<!-- Font weight -->
|
|
428
|
+
<s-text fontWeight="bold">Bold text</s-text>
|
|
429
|
+
<s-text fontWeight="semibold">Semibold text</s-text>
|
|
430
|
+
|
|
431
|
+
<!-- Block elements -->
|
|
432
|
+
<s-heading>Section heading</s-heading>
|
|
433
|
+
<s-paragraph>A paragraph of text.</s-paragraph>
|
|
434
|
+
<s-paragraph color="subdued">Muted paragraph.</s-paragraph></code></pre>
|
|
286
435
|
</div>
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
<button class="btn btn-sm btn-plain">View all</button>
|
|
291
|
-
</div>
|
|
292
|
-
<ul class="info-list">
|
|
293
|
-
<li>
|
|
294
|
-
<span class="info-list-label">Order #1234</span>
|
|
295
|
-
<span class="info-list-value">$149.00</span>
|
|
296
|
-
</li>
|
|
297
|
-
</ul>
|
|
298
|
-
</div></code></pre>
|
|
299
|
-
</div>
|
|
300
|
-
</div>
|
|
436
|
+
</s-box>
|
|
437
|
+
</s-section>
|
|
438
|
+
</div>
|
|
301
439
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
440
|
+
|
|
441
|
+
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
442
|
+
<!-- SECTION: BUTTONS -->
|
|
443
|
+
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
444
|
+
<div id="section-buttons">
|
|
445
|
+
<s-section heading="Buttons">
|
|
446
|
+
<s-text color="subdued">Interactive buttons with variants, tones, loading, and disabled states.</s-text>
|
|
447
|
+
|
|
448
|
+
<s-box paddingBlockStart="base">
|
|
449
|
+
<!-- Button variants -->
|
|
450
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
451
|
+
<s-text variant="headingSm">Button Variants</s-text>
|
|
452
|
+
<s-box paddingBlockStart="small-200">
|
|
453
|
+
<s-stack direction="inline" gap="small-200" wrap>
|
|
454
|
+
<s-button variant="primary">Primary</s-button>
|
|
455
|
+
<s-button>Secondary (default)</s-button>
|
|
456
|
+
<s-button variant="tertiary">Tertiary</s-button>
|
|
457
|
+
<s-button variant="primary" tone="critical">Critical Primary</s-button>
|
|
458
|
+
<s-button tone="critical">Critical</s-button>
|
|
459
|
+
</s-stack>
|
|
460
|
+
</s-box>
|
|
461
|
+
</s-box>
|
|
462
|
+
</s-box>
|
|
463
|
+
|
|
464
|
+
<s-box paddingBlockStart="base">
|
|
465
|
+
<!-- States -->
|
|
466
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
467
|
+
<s-text variant="headingSm">States</s-text>
|
|
468
|
+
<s-box paddingBlockStart="small-200">
|
|
469
|
+
<s-stack direction="inline" gap="small-200" wrap>
|
|
470
|
+
<s-button variant="primary" disabled>Disabled Primary</s-button>
|
|
471
|
+
<s-button disabled>Disabled</s-button>
|
|
472
|
+
<s-button variant="primary" loading>Loading</s-button>
|
|
473
|
+
<s-button loading>Loading</s-button>
|
|
474
|
+
</s-stack>
|
|
475
|
+
</s-box>
|
|
476
|
+
</s-box>
|
|
477
|
+
</s-box>
|
|
478
|
+
|
|
479
|
+
<s-box paddingBlockStart="base">
|
|
480
|
+
<!-- Button as link -->
|
|
481
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
482
|
+
<s-text variant="headingSm">Button as Link</s-text>
|
|
483
|
+
<s-box paddingBlockStart="small-200">
|
|
484
|
+
<s-stack direction="inline" gap="small-200">
|
|
485
|
+
<s-button variant="primary" href="/products">Navigate to Products</s-button>
|
|
486
|
+
<s-button href="https://polaris.shopify.com" target="_blank">Polaris Docs (external)</s-button>
|
|
487
|
+
</s-stack>
|
|
488
|
+
</s-box>
|
|
489
|
+
</s-box>
|
|
490
|
+
</s-box>
|
|
491
|
+
|
|
492
|
+
<s-box paddingBlockStart="base">
|
|
493
|
+
<div class="demo-code">
|
|
494
|
+
<div class="code-block-header">
|
|
495
|
+
<span>HTML</span>
|
|
496
|
+
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
318
497
|
</div>
|
|
498
|
+
<pre><code><!-- Variants -->
|
|
499
|
+
<s-button variant="primary">Primary</s-button>
|
|
500
|
+
<s-button>Secondary</s-button>
|
|
501
|
+
<s-button variant="tertiary">Tertiary</s-button>
|
|
502
|
+
|
|
503
|
+
<!-- Destructive -->
|
|
504
|
+
<s-button variant="primary" tone="critical">Delete</s-button>
|
|
505
|
+
<s-button tone="critical">Remove</s-button>
|
|
506
|
+
|
|
507
|
+
<!-- States -->
|
|
508
|
+
<s-button disabled>Disabled</s-button>
|
|
509
|
+
<s-button loading>Loading</s-button>
|
|
510
|
+
|
|
511
|
+
<!-- As link -->
|
|
512
|
+
<s-button href="/page">Navigate</s-button>
|
|
513
|
+
<s-button href="https://example.com" target="_blank">External</s-button></code></pre>
|
|
319
514
|
</div>
|
|
320
|
-
</
|
|
321
|
-
|
|
322
|
-
<div class="code-block-header">
|
|
323
|
-
<span>HTML</span>
|
|
324
|
-
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
325
|
-
</div>
|
|
326
|
-
<pre><code><div class="card-grid">
|
|
327
|
-
<div class="card">
|
|
328
|
-
<h3>Card A</h3>
|
|
329
|
-
<p>Content here.</p>
|
|
330
|
-
</div>
|
|
331
|
-
<div class="card">
|
|
332
|
-
<h3>Card B</h3>
|
|
333
|
-
<p>Content here.</p>
|
|
334
|
-
</div>
|
|
335
|
-
</div></code></pre>
|
|
336
|
-
</div>
|
|
337
|
-
</div>
|
|
515
|
+
</s-box>
|
|
516
|
+
</s-section>
|
|
338
517
|
</div>
|
|
339
518
|
|
|
340
519
|
|
|
341
520
|
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
342
|
-
<!-- SECTION
|
|
521
|
+
<!-- SECTION: BADGES -->
|
|
343
522
|
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
344
|
-
<div
|
|
345
|
-
<
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
523
|
+
<div id="section-badges">
|
|
524
|
+
<s-section heading="Badges">
|
|
525
|
+
<s-text color="subdued">Compact status indicators and labels.</s-text>
|
|
526
|
+
|
|
527
|
+
<s-box paddingBlockStart="base">
|
|
528
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
529
|
+
<s-text variant="headingSm">Badge Tones</s-text>
|
|
530
|
+
<s-box paddingBlockStart="small-200">
|
|
531
|
+
<s-stack direction="inline" gap="small-200" wrap>
|
|
532
|
+
<s-badge>Default</s-badge>
|
|
533
|
+
<s-badge tone="info">Info</s-badge>
|
|
534
|
+
<s-badge tone="success">Success</s-badge>
|
|
535
|
+
<s-badge tone="warning">Warning</s-badge>
|
|
536
|
+
<s-badge tone="critical">Critical</s-badge>
|
|
537
|
+
<s-badge tone="attention">Attention</s-badge>
|
|
538
|
+
<s-badge tone="new">New</s-badge>
|
|
539
|
+
<s-badge tone="read-only">Read Only</s-badge>
|
|
540
|
+
<s-badge tone="enabled">Enabled</s-badge>
|
|
541
|
+
</s-stack>
|
|
542
|
+
</s-box>
|
|
543
|
+
</s-box>
|
|
544
|
+
</s-box>
|
|
545
|
+
|
|
546
|
+
<s-box paddingBlockStart="base">
|
|
547
|
+
<!-- Badges in context -->
|
|
548
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
549
|
+
<s-text variant="headingSm">Badges in Context</s-text>
|
|
550
|
+
<s-box paddingBlockStart="small-200">
|
|
551
|
+
<s-stack gap="small-200">
|
|
552
|
+
<s-stack direction="inline" gap="base" alignItems="center">
|
|
553
|
+
<s-text>Order #1001</s-text>
|
|
554
|
+
<s-badge tone="success">Fulfilled</s-badge>
|
|
555
|
+
</s-stack>
|
|
556
|
+
<s-stack direction="inline" gap="base" alignItems="center">
|
|
557
|
+
<s-text>Order #1002</s-text>
|
|
558
|
+
<s-badge tone="warning">Pending</s-badge>
|
|
559
|
+
</s-stack>
|
|
560
|
+
<s-stack direction="inline" gap="base" alignItems="center">
|
|
561
|
+
<s-text>Order #1003</s-text>
|
|
562
|
+
<s-badge tone="critical">Cancelled</s-badge>
|
|
563
|
+
</s-stack>
|
|
564
|
+
</s-stack>
|
|
565
|
+
</s-box>
|
|
566
|
+
</s-box>
|
|
567
|
+
</s-box>
|
|
568
|
+
|
|
569
|
+
<s-box paddingBlockStart="base">
|
|
570
|
+
<div class="demo-code">
|
|
571
|
+
<div class="code-block-header">
|
|
572
|
+
<span>HTML</span>
|
|
573
|
+
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
574
|
+
</div>
|
|
575
|
+
<pre><code><s-badge>Default</s-badge>
|
|
576
|
+
<s-badge tone="info">Info</s-badge>
|
|
577
|
+
<s-badge tone="success">Success</s-badge>
|
|
578
|
+
<s-badge tone="warning">Warning</s-badge>
|
|
579
|
+
<s-badge tone="critical">Critical</s-badge>
|
|
580
|
+
<s-badge tone="attention">Attention</s-badge>
|
|
581
|
+
<s-badge tone="new">New</s-badge>
|
|
582
|
+
<s-badge tone="read-only">Read Only</s-badge>
|
|
583
|
+
<s-badge tone="enabled">Enabled</s-badge></code></pre>
|
|
367
584
|
</div>
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
placeholder="My Awesome Store">
|
|
372
|
-
<p class="form-hint">Help text here.</p>
|
|
373
|
-
</div>
|
|
585
|
+
</s-box>
|
|
586
|
+
</s-section>
|
|
587
|
+
</div>
|
|
374
588
|
|
|
375
|
-
<!-- Error state -->
|
|
376
|
-
<div class="form-group">
|
|
377
|
-
<label for="email">Email</label>
|
|
378
|
-
<input type="email" class="form-input form-input-error"
|
|
379
|
-
id="email" value="not-valid">
|
|
380
|
-
<p class="form-error">Please enter a valid email.</p>
|
|
381
|
-
</div></code></pre>
|
|
382
|
-
</div>
|
|
383
|
-
</div>
|
|
384
589
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
<
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
<
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
590
|
+
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
591
|
+
<!-- SECTION: BANNERS -->
|
|
592
|
+
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
593
|
+
<div id="section-banners">
|
|
594
|
+
<s-section heading="Banners">
|
|
595
|
+
<s-text color="subdued">Alert banners for status messages, errors, and announcements.</s-text>
|
|
596
|
+
|
|
597
|
+
<s-box paddingBlockStart="base">
|
|
598
|
+
<s-stack gap="base">
|
|
599
|
+
<s-banner tone="info">
|
|
600
|
+
<s-text><s-text fontWeight="semibold">Information:</s-text> This is an informational banner. Use for tips and neutral messages.</s-text>
|
|
601
|
+
</s-banner>
|
|
602
|
+
|
|
603
|
+
<s-banner tone="success">
|
|
604
|
+
<s-text><s-text fontWeight="semibold">Success:</s-text> The operation completed successfully. Your changes have been saved.</s-text>
|
|
605
|
+
</s-banner>
|
|
606
|
+
|
|
607
|
+
<s-banner tone="warning">
|
|
608
|
+
<s-text><s-text fontWeight="semibold">Warning:</s-text> This action may have unintended consequences. Please review before proceeding.</s-text>
|
|
609
|
+
</s-banner>
|
|
610
|
+
|
|
611
|
+
<s-banner tone="critical">
|
|
612
|
+
<s-text><s-text fontWeight="semibold">Error:</s-text> Something went wrong. Please try again or contact support.</s-text>
|
|
613
|
+
</s-banner>
|
|
614
|
+
</s-stack>
|
|
615
|
+
</s-box>
|
|
616
|
+
|
|
617
|
+
<s-box paddingBlockStart="base">
|
|
618
|
+
<div class="demo-code">
|
|
619
|
+
<div class="code-block-header">
|
|
620
|
+
<span>HTML</span>
|
|
621
|
+
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
622
|
+
</div>
|
|
623
|
+
<pre><code><s-banner tone="info">
|
|
624
|
+
<s-text>Informational message.</s-text>
|
|
625
|
+
</s-banner>
|
|
415
626
|
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
<div class="demo-preview">
|
|
420
|
-
<div class="form-group">
|
|
421
|
-
<label class="form-checkbox">
|
|
422
|
-
<input type="checkbox" checked>
|
|
423
|
-
<span>Enable email notifications</span>
|
|
424
|
-
</label>
|
|
425
|
-
</div>
|
|
426
|
-
<div class="form-group">
|
|
427
|
-
<label class="form-checkbox">
|
|
428
|
-
<input type="checkbox">
|
|
429
|
-
<span>Subscribe to newsletter</span>
|
|
430
|
-
</label>
|
|
431
|
-
</div>
|
|
432
|
-
<hr class="divider">
|
|
433
|
-
<div class="form-group">
|
|
434
|
-
<label class="form-checkbox">
|
|
435
|
-
<input type="radio" name="demo-radio" value="option1" checked>
|
|
436
|
-
<span>Option A</span>
|
|
437
|
-
</label>
|
|
438
|
-
</div>
|
|
439
|
-
<div class="form-group">
|
|
440
|
-
<label class="form-checkbox">
|
|
441
|
-
<input type="radio" name="demo-radio" value="option2">
|
|
442
|
-
<span>Option B</span>
|
|
443
|
-
</label>
|
|
444
|
-
</div>
|
|
445
|
-
</div>
|
|
446
|
-
<div class="demo-code">
|
|
447
|
-
<div class="code-block-header">
|
|
448
|
-
<span>HTML</span>
|
|
449
|
-
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
450
|
-
</div>
|
|
451
|
-
<pre><code><label class="form-checkbox">
|
|
452
|
-
<input type="checkbox" checked>
|
|
453
|
-
<span>Enable notifications</span>
|
|
454
|
-
</label>
|
|
455
|
-
|
|
456
|
-
<label class="form-checkbox">
|
|
457
|
-
<input type="radio" name="group" value="a" checked>
|
|
458
|
-
<span>Option A</span>
|
|
459
|
-
</label></code></pre>
|
|
460
|
-
</div>
|
|
461
|
-
</div>
|
|
627
|
+
<s-banner tone="success">
|
|
628
|
+
<s-text>Success message.</s-text>
|
|
629
|
+
</s-banner>
|
|
462
630
|
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
</div>
|
|
471
|
-
</div>
|
|
472
|
-
<div class="demo-code">
|
|
473
|
-
<div class="code-block-header">
|
|
474
|
-
<span>HTML</span>
|
|
475
|
-
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
631
|
+
<s-banner tone="warning">
|
|
632
|
+
<s-text>Warning message.</s-text>
|
|
633
|
+
</s-banner>
|
|
634
|
+
|
|
635
|
+
<s-banner tone="critical">
|
|
636
|
+
<s-text>Error message.</s-text>
|
|
637
|
+
</s-banner></code></pre>
|
|
476
638
|
</div>
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
<textarea class="form-textarea" id="notes"
|
|
480
|
-
rows="4" placeholder="Add notes..."></textarea>
|
|
481
|
-
</div></code></pre>
|
|
482
|
-
</div>
|
|
483
|
-
</div>
|
|
639
|
+
</s-box>
|
|
640
|
+
</s-section>
|
|
484
641
|
</div>
|
|
485
642
|
|
|
486
643
|
|
|
487
644
|
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
488
|
-
<!-- SECTION
|
|
645
|
+
<!-- SECTION: FORMS -->
|
|
489
646
|
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
490
|
-
<div
|
|
491
|
-
<
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
<
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
</
|
|
566
|
-
|
|
647
|
+
<div id="section-forms">
|
|
648
|
+
<s-section heading="Form Fields">
|
|
649
|
+
<s-text color="subdued">Text fields with labels, placeholders, help text, error states, and multiline support.</s-text>
|
|
650
|
+
|
|
651
|
+
<s-box paddingBlockStart="base">
|
|
652
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
653
|
+
<s-stack gap="base">
|
|
654
|
+
<s-text-field
|
|
655
|
+
label="Store name"
|
|
656
|
+
placeholder="My Awesome Store"
|
|
657
|
+
helpText="The public-facing name of your store."
|
|
658
|
+
></s-text-field>
|
|
659
|
+
|
|
660
|
+
<s-text-field
|
|
661
|
+
label="Email address"
|
|
662
|
+
type="email"
|
|
663
|
+
placeholder="merchant@example.com"
|
|
664
|
+
></s-text-field>
|
|
665
|
+
|
|
666
|
+
<s-text-field
|
|
667
|
+
label="Password"
|
|
668
|
+
type="password"
|
|
669
|
+
placeholder="Enter password"
|
|
670
|
+
></s-text-field>
|
|
671
|
+
|
|
672
|
+
<s-text-field
|
|
673
|
+
label="Product count"
|
|
674
|
+
type="number"
|
|
675
|
+
placeholder="0"
|
|
676
|
+
min="0"
|
|
677
|
+
max="10000"
|
|
678
|
+
></s-text-field>
|
|
679
|
+
|
|
680
|
+
<s-text-field
|
|
681
|
+
label="Description"
|
|
682
|
+
multiline="4"
|
|
683
|
+
placeholder="Enter a detailed description..."
|
|
684
|
+
helpText="Supports multiline input."
|
|
685
|
+
></s-text-field>
|
|
686
|
+
|
|
687
|
+
<s-text-field
|
|
688
|
+
label="Invalid field"
|
|
689
|
+
value="bad-value"
|
|
690
|
+
error="This value is not valid. Please correct it."
|
|
691
|
+
></s-text-field>
|
|
692
|
+
</s-stack>
|
|
693
|
+
</s-box>
|
|
694
|
+
</s-box>
|
|
695
|
+
|
|
696
|
+
<s-box paddingBlockStart="base">
|
|
697
|
+
<!-- URL field -->
|
|
698
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
699
|
+
<s-text variant="headingSm">URL Field</s-text>
|
|
700
|
+
<s-box paddingBlockStart="small-200">
|
|
701
|
+
<s-url-field
|
|
702
|
+
label="Website URL"
|
|
703
|
+
placeholder="https://example.com"
|
|
704
|
+
helpText="Enter a valid URL."
|
|
705
|
+
></s-url-field>
|
|
706
|
+
</s-box>
|
|
707
|
+
</s-box>
|
|
708
|
+
</s-box>
|
|
709
|
+
|
|
710
|
+
<s-box paddingBlockStart="base">
|
|
711
|
+
<!-- Color field -->
|
|
712
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
713
|
+
<s-text variant="headingSm">Color Field</s-text>
|
|
714
|
+
<s-box paddingBlockStart="small-200">
|
|
715
|
+
<s-color-field
|
|
716
|
+
label="Brand color"
|
|
717
|
+
value="#008060"
|
|
718
|
+
helpText="Pick your brand's primary color."
|
|
719
|
+
></s-color-field>
|
|
720
|
+
</s-box>
|
|
721
|
+
</s-box>
|
|
722
|
+
</s-box>
|
|
723
|
+
|
|
724
|
+
<s-box paddingBlockStart="base">
|
|
725
|
+
<div class="demo-code">
|
|
726
|
+
<div class="code-block-header">
|
|
727
|
+
<span>HTML</span>
|
|
728
|
+
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
729
|
+
</div>
|
|
730
|
+
<pre><code><!-- Text field -->
|
|
731
|
+
<s-text-field
|
|
732
|
+
label="Store name"
|
|
733
|
+
placeholder="My Store"
|
|
734
|
+
helpText="Help text below."
|
|
735
|
+
></s-text-field>
|
|
567
736
|
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
737
|
+
<!-- Email / Password / Number -->
|
|
738
|
+
<s-text-field label="Email" type="email"></s-text-field>
|
|
739
|
+
<s-text-field label="Password" type="password"></s-text-field>
|
|
740
|
+
<s-text-field label="Count" type="number" min="0"></s-text-field>
|
|
741
|
+
|
|
742
|
+
<!-- Multiline (textarea) -->
|
|
743
|
+
<s-text-field label="Notes" multiline="4"></s-text-field>
|
|
744
|
+
|
|
745
|
+
<!-- Error state -->
|
|
746
|
+
<s-text-field label="Field"
|
|
747
|
+
error="Validation error message."
|
|
748
|
+
></s-text-field>
|
|
749
|
+
|
|
750
|
+
<!-- URL field (with validation) -->
|
|
751
|
+
<s-url-field label="Website" placeholder="https://..."></s-url-field>
|
|
752
|
+
|
|
753
|
+
<!-- Color picker -->
|
|
754
|
+
<s-color-field label="Color" value="#008060"></s-color-field>
|
|
755
|
+
|
|
756
|
+
<!-- Hidden label -->
|
|
757
|
+
<s-text-field label="Search" labelHidden
|
|
758
|
+
placeholder="Search..."></s-text-field>
|
|
759
|
+
|
|
760
|
+
<!-- Clear button -->
|
|
761
|
+
<s-text-field label="Search" clearButton></s-text-field></code></pre>
|
|
593
762
|
</div>
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
<th class="sortable">Amount</th></code></pre>
|
|
597
|
-
</div>
|
|
598
|
-
</div>
|
|
763
|
+
</s-box>
|
|
764
|
+
</s-section>
|
|
599
765
|
</div>
|
|
600
766
|
|
|
601
767
|
|
|
602
768
|
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
603
|
-
<!-- SECTION
|
|
769
|
+
<!-- SECTION: SWITCH -->
|
|
604
770
|
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
605
|
-
<div
|
|
606
|
-
<
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
<
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
<
|
|
616
|
-
|
|
771
|
+
<div id="section-switch">
|
|
772
|
+
<s-section heading="Switch (Toggle)">
|
|
773
|
+
<s-text color="subdued">Toggle switches for boolean settings. Replaces checkboxes in Polaris.</s-text>
|
|
774
|
+
|
|
775
|
+
<s-box paddingBlockStart="base">
|
|
776
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
777
|
+
<s-stack gap="base">
|
|
778
|
+
<s-switch label="Enable feature" checked></s-switch>
|
|
779
|
+
<s-switch label="Disabled feature (off)"></s-switch>
|
|
780
|
+
<s-switch label="Disabled toggle" disabled></s-switch>
|
|
781
|
+
<s-switch label="With help text" helpText="This setting controls notification preferences." checked></s-switch>
|
|
782
|
+
</s-stack>
|
|
783
|
+
</s-box>
|
|
784
|
+
</s-box>
|
|
785
|
+
|
|
786
|
+
<s-box paddingBlockStart="base">
|
|
787
|
+
<div class="demo-code">
|
|
788
|
+
<div class="code-block-header">
|
|
789
|
+
<span>HTML</span>
|
|
790
|
+
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
617
791
|
</div>
|
|
618
|
-
<
|
|
792
|
+
<pre><code><s-switch label="Enable feature" checked></s-switch>
|
|
793
|
+
<s-switch label="Feature off"></s-switch>
|
|
794
|
+
<s-switch label="Cannot change" disabled></s-switch>
|
|
795
|
+
<s-switch label="With help"
|
|
796
|
+
helpText="Description text."
|
|
797
|
+
checked></s-switch></code></pre>
|
|
619
798
|
</div>
|
|
799
|
+
</s-box>
|
|
800
|
+
</s-section>
|
|
801
|
+
</div>
|
|
620
802
|
|
|
621
|
-
<div class="banner banner-success">
|
|
622
|
-
<div class="banner-icon">✓</div>
|
|
623
|
-
<div class="banner-content">
|
|
624
|
-
<p><strong>Success</strong></p>
|
|
625
|
-
<p>The operation completed successfully. Your changes have been saved.</p>
|
|
626
|
-
</div>
|
|
627
|
-
<button class="banner-dismiss" onclick="this.closest('.banner').remove()">×</button>
|
|
628
|
-
</div>
|
|
629
803
|
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
804
|
+
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
805
|
+
<!-- SECTION: SELECT -->
|
|
806
|
+
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
807
|
+
<div id="section-select">
|
|
808
|
+
<s-section heading="Select (Dropdown)">
|
|
809
|
+
<s-text color="subdued">Dropdown selection with <code><s-select></code> and <code><s-option></code> elements.</s-text>
|
|
810
|
+
|
|
811
|
+
<s-box paddingBlockStart="base">
|
|
812
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
813
|
+
<s-stack gap="base">
|
|
814
|
+
<s-select label="Country" helpText="Select your country.">
|
|
815
|
+
<s-option value="">Select a country</s-option>
|
|
816
|
+
<s-option value="us">United States</s-option>
|
|
817
|
+
<s-option value="ca">Canada</s-option>
|
|
818
|
+
<s-option value="gb">United Kingdom</s-option>
|
|
819
|
+
<s-option value="au">Australia</s-option>
|
|
820
|
+
<s-option value="in">India</s-option>
|
|
821
|
+
</s-select>
|
|
822
|
+
|
|
823
|
+
<s-select label="Sort by">
|
|
824
|
+
<s-option value="newest" selected>Newest first</s-option>
|
|
825
|
+
<s-option value="oldest">Oldest first</s-option>
|
|
826
|
+
<s-option value="price-asc">Price: Low to High</s-option>
|
|
827
|
+
<s-option value="price-desc">Price: High to Low</s-option>
|
|
828
|
+
</s-select>
|
|
829
|
+
</s-stack>
|
|
830
|
+
</s-box>
|
|
831
|
+
</s-box>
|
|
832
|
+
|
|
833
|
+
<s-box paddingBlockStart="base">
|
|
834
|
+
<div class="demo-code">
|
|
835
|
+
<div class="code-block-header">
|
|
836
|
+
<span>HTML</span>
|
|
837
|
+
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
635
838
|
</div>
|
|
636
|
-
<
|
|
839
|
+
<pre><code><s-select label="Country" helpText="Select country.">
|
|
840
|
+
<s-option value="">Select a country</s-option>
|
|
841
|
+
<s-option value="us">United States</s-option>
|
|
842
|
+
<s-option value="ca">Canada</s-option>
|
|
843
|
+
<s-option value="gb">United Kingdom</s-option>
|
|
844
|
+
</s-select></code></pre>
|
|
637
845
|
</div>
|
|
846
|
+
</s-box>
|
|
847
|
+
</s-section>
|
|
848
|
+
</div>
|
|
638
849
|
|
|
639
|
-
<div class="banner banner-critical">
|
|
640
|
-
<div class="banner-icon">✖</div>
|
|
641
|
-
<div class="banner-content">
|
|
642
|
-
<p><strong>Error</strong></p>
|
|
643
|
-
<p>Something went wrong. Please try again or contact support.</p>
|
|
644
|
-
</div>
|
|
645
|
-
<button class="banner-dismiss" onclick="this.closest('.banner').remove()">×</button>
|
|
646
|
-
</div>
|
|
647
850
|
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
851
|
+
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
852
|
+
<!-- SECTION: LINKS & CLICKABLE -->
|
|
853
|
+
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
854
|
+
<div id="section-links">
|
|
855
|
+
<s-section heading="Links & Clickable">
|
|
856
|
+
<s-text color="subdued">Navigation links and clickable wrappers for making containers interactive.</s-text>
|
|
857
|
+
|
|
858
|
+
<s-box paddingBlockStart="base">
|
|
859
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
860
|
+
<s-stack gap="base">
|
|
861
|
+
<s-text variant="headingSm">Links</s-text>
|
|
862
|
+
<s-stack direction="inline" gap="base">
|
|
863
|
+
<s-link href="/">Internal link</s-link>
|
|
864
|
+
<s-link href="https://polaris.shopify.com" target="_blank">External link</s-link>
|
|
865
|
+
</s-stack>
|
|
866
|
+
</s-stack>
|
|
867
|
+
</s-box>
|
|
868
|
+
</s-box>
|
|
869
|
+
|
|
870
|
+
<s-box paddingBlockStart="base">
|
|
871
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
872
|
+
<s-text variant="headingSm">Clickable Card</s-text>
|
|
873
|
+
<s-text color="subdued">Wrap any content in <code><s-clickable></code> to make the entire area interactive.</s-text>
|
|
874
|
+
<s-box paddingBlockStart="small-200">
|
|
875
|
+
<s-grid gridTemplateColumns="1fr 1fr" gap="base">
|
|
876
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
877
|
+
<s-clickable href="/products">
|
|
878
|
+
<s-stack gap="small-200">
|
|
879
|
+
<s-text variant="headingSm">Products</s-text>
|
|
880
|
+
<s-text color="subdued">Click anywhere in this card</s-text>
|
|
881
|
+
</s-stack>
|
|
882
|
+
</s-clickable>
|
|
883
|
+
</s-box>
|
|
884
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
885
|
+
<s-clickable href="/settings">
|
|
886
|
+
<s-stack gap="small-200">
|
|
887
|
+
<s-text variant="headingSm">Settings</s-text>
|
|
888
|
+
<s-text color="subdued">Entire box is clickable</s-text>
|
|
889
|
+
</s-stack>
|
|
890
|
+
</s-clickable>
|
|
891
|
+
</s-box>
|
|
892
|
+
</s-grid>
|
|
893
|
+
</s-box>
|
|
894
|
+
</s-box>
|
|
895
|
+
</s-box>
|
|
896
|
+
|
|
897
|
+
<s-box paddingBlockStart="base">
|
|
898
|
+
<div class="demo-code">
|
|
899
|
+
<div class="code-block-header">
|
|
900
|
+
<span>HTML</span>
|
|
901
|
+
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
902
|
+
</div>
|
|
903
|
+
<pre><code><!-- Standard link -->
|
|
904
|
+
<s-link href="/">Internal link</s-link>
|
|
905
|
+
<s-link href="https://..." target="_blank">External</s-link>
|
|
906
|
+
|
|
907
|
+
<!-- Clickable wrapper (makes entire area tappable) -->
|
|
908
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
909
|
+
<s-clickable href="/page">
|
|
910
|
+
<s-text variant="headingSm">Card Title</s-text>
|
|
911
|
+
<s-text color="subdued">Click anywhere</s-text>
|
|
912
|
+
</s-clickable>
|
|
913
|
+
</s-box></code></pre>
|
|
654
914
|
</div>
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
<div class="banner-content">
|
|
658
|
-
<p><strong>Information</strong></p>
|
|
659
|
-
<p>Your message here.</p>
|
|
660
|
-
</div>
|
|
661
|
-
<button class="banner-dismiss"
|
|
662
|
-
onclick="this.closest('.banner').remove()">&times;</button>
|
|
663
|
-
</div>
|
|
664
|
-
|
|
665
|
-
<!-- Variants: banner-info, banner-success,
|
|
666
|
-
banner-warning, banner-critical --></code></pre>
|
|
667
|
-
</div>
|
|
668
|
-
</div>
|
|
915
|
+
</s-box>
|
|
916
|
+
</s-section>
|
|
669
917
|
</div>
|
|
670
918
|
|
|
671
919
|
|
|
672
920
|
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
673
|
-
<!-- SECTION
|
|
921
|
+
<!-- SECTION: SPINNER -->
|
|
674
922
|
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
675
|
-
<div
|
|
676
|
-
<
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
<
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
923
|
+
<div id="section-spinner">
|
|
924
|
+
<s-section heading="Spinner">
|
|
925
|
+
<s-text color="subdued">Loading indicator for async operations.</s-text>
|
|
926
|
+
|
|
927
|
+
<s-box paddingBlockStart="base">
|
|
928
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
929
|
+
<s-stack direction="inline" gap="large-400" alignItems="center">
|
|
930
|
+
<s-stack alignItems="center" gap="small-200">
|
|
931
|
+
<s-spinner></s-spinner>
|
|
932
|
+
<s-text color="subdued" variant="bodySm">Default</s-text>
|
|
933
|
+
</s-stack>
|
|
934
|
+
<s-stack alignItems="center" gap="small-200">
|
|
935
|
+
<s-spinner size="large"></s-spinner>
|
|
936
|
+
<s-text color="subdued" variant="bodySm">Large</s-text>
|
|
937
|
+
</s-stack>
|
|
938
|
+
</s-stack>
|
|
939
|
+
</s-box>
|
|
940
|
+
</s-box>
|
|
941
|
+
|
|
942
|
+
<s-box paddingBlockStart="base">
|
|
943
|
+
<!-- Full loading pattern -->
|
|
944
|
+
<s-box border="base" borderRadius="base" padding="large-400">
|
|
945
|
+
<s-stack alignItems="center" gap="base">
|
|
946
|
+
<s-spinner></s-spinner>
|
|
947
|
+
<s-text color="subdued">Loading content...</s-text>
|
|
948
|
+
</s-stack>
|
|
949
|
+
</s-box>
|
|
950
|
+
</s-box>
|
|
951
|
+
|
|
952
|
+
<s-box paddingBlockStart="base">
|
|
953
|
+
<div class="demo-code">
|
|
954
|
+
<div class="code-block-header">
|
|
955
|
+
<span>HTML</span>
|
|
956
|
+
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
957
|
+
</div>
|
|
958
|
+
<pre><code><!-- Default spinner -->
|
|
959
|
+
<s-spinner></s-spinner>
|
|
960
|
+
|
|
961
|
+
<!-- Large spinner -->
|
|
962
|
+
<s-spinner size="large"></s-spinner>
|
|
963
|
+
|
|
964
|
+
<!-- Full loading state pattern -->
|
|
965
|
+
<s-box padding="large-400">
|
|
966
|
+
<s-stack alignItems="center" gap="base">
|
|
967
|
+
<s-spinner></s-spinner>
|
|
968
|
+
<s-text color="subdued">Loading...</s-text>
|
|
969
|
+
</s-stack>
|
|
970
|
+
</s-box></code></pre>
|
|
693
971
|
</div>
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
<h3>No orders yet</h3>
|
|
697
|
-
<p>Your description text here.</p>
|
|
698
|
-
<button class="btn btn-primary">Add product</button>
|
|
699
|
-
</div></code></pre>
|
|
700
|
-
</div>
|
|
701
|
-
</div>
|
|
972
|
+
</s-box>
|
|
973
|
+
</s-section>
|
|
702
974
|
</div>
|
|
703
975
|
|
|
704
976
|
|
|
705
977
|
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
706
|
-
<!-- SECTION
|
|
978
|
+
<!-- SECTION: SECTION -->
|
|
707
979
|
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
708
|
-
<div
|
|
709
|
-
<
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
<div>
|
|
718
|
-
<div class="spinner"></div>
|
|
719
|
-
<p class="text-sm text-secondary mt-2">Default</p>
|
|
720
|
-
</div>
|
|
721
|
-
<div>
|
|
722
|
-
<div class="spinner spinner-lg"></div>
|
|
723
|
-
<p class="text-sm text-secondary mt-2">Large</p>
|
|
724
|
-
</div>
|
|
725
|
-
<div class="loading-state" style="padding: 20px;">
|
|
726
|
-
<div class="spinner"></div>
|
|
727
|
-
<p>Loading content...</p>
|
|
980
|
+
<div id="section-section">
|
|
981
|
+
<s-section heading="Section">
|
|
982
|
+
<s-text color="subdued">Content sections within a page, with optional headings and padding.</s-text>
|
|
983
|
+
|
|
984
|
+
<s-box paddingBlockStart="base">
|
|
985
|
+
<div class="demo-code">
|
|
986
|
+
<div class="code-block-header">
|
|
987
|
+
<span>HTML</span>
|
|
988
|
+
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
728
989
|
</div>
|
|
990
|
+
<pre><code><s-page heading="My Page">
|
|
991
|
+
<!-- Section with heading -->
|
|
992
|
+
<s-section heading="General Settings">
|
|
993
|
+
<s-text>Content here...</s-text>
|
|
994
|
+
</s-section>
|
|
995
|
+
|
|
996
|
+
<!-- Section without heading -->
|
|
997
|
+
<s-section>
|
|
998
|
+
<s-text>More content...</s-text>
|
|
999
|
+
</s-section>
|
|
1000
|
+
|
|
1001
|
+
<!-- Section with padding -->
|
|
1002
|
+
<s-section padding="base">
|
|
1003
|
+
<s-text>Padded content.</s-text>
|
|
1004
|
+
</s-section>
|
|
1005
|
+
</s-page></code></pre>
|
|
729
1006
|
</div>
|
|
730
|
-
</
|
|
731
|
-
|
|
732
|
-
<div class="code-block-header">
|
|
733
|
-
<span>HTML</span>
|
|
734
|
-
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
735
|
-
</div>
|
|
736
|
-
<pre><code><div class="spinner"></div>
|
|
737
|
-
<div class="spinner spinner-lg"></div>
|
|
738
|
-
|
|
739
|
-
<!-- Full loading state -->
|
|
740
|
-
<div class="loading-state">
|
|
741
|
-
<div class="spinner"></div>
|
|
742
|
-
<p>Loading content...</p>
|
|
743
|
-
</div></code></pre>
|
|
744
|
-
</div>
|
|
745
|
-
</div>
|
|
746
|
-
|
|
747
|
-
<!-- Skeleton -->
|
|
748
|
-
<div class="demo-block">
|
|
749
|
-
<div class="demo-block-title">Skeleton Loaders</div>
|
|
750
|
-
<p class="demo-description mt-3">Skeleton loaders provide a placeholder preview of content while it loads.</p>
|
|
751
|
-
<div class="demo-preview">
|
|
752
|
-
<div class="card" style="margin-bottom:0;">
|
|
753
|
-
<div class="skeleton skeleton-heading"></div>
|
|
754
|
-
<div class="skeleton skeleton-text"></div>
|
|
755
|
-
<div class="skeleton skeleton-text"></div>
|
|
756
|
-
<div class="skeleton skeleton-text" style="width: 40%;"></div>
|
|
757
|
-
</div>
|
|
758
|
-
</div>
|
|
759
|
-
<div class="demo-code">
|
|
760
|
-
<div class="code-block-header">
|
|
761
|
-
<span>HTML</span>
|
|
762
|
-
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
763
|
-
</div>
|
|
764
|
-
<pre><code><div class="skeleton skeleton-heading"></div>
|
|
765
|
-
<div class="skeleton skeleton-text"></div>
|
|
766
|
-
<div class="skeleton skeleton-text"></div>
|
|
767
|
-
<div class="skeleton skeleton-text"
|
|
768
|
-
style="width: 40%;"></div>
|
|
769
|
-
|
|
770
|
-
<!-- Image skeleton -->
|
|
771
|
-
<div class="skeleton skeleton-image"></div></code></pre>
|
|
772
|
-
</div>
|
|
773
|
-
</div>
|
|
1007
|
+
</s-box>
|
|
1008
|
+
</s-section>
|
|
774
1009
|
</div>
|
|
775
1010
|
|
|
776
1011
|
|
|
777
1012
|
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
778
|
-
<!-- SECTION
|
|
1013
|
+
<!-- SECTION: MODALS -->
|
|
779
1014
|
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
780
|
-
<div
|
|
781
|
-
<
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
<
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
<
|
|
1015
|
+
<div id="section-modals">
|
|
1016
|
+
<s-section heading="Modals">
|
|
1017
|
+
<s-text color="subdued">App Bridge modals rendered by Shopify outside your iframe for a native feel. Uses <code><ui-modal></code>.</s-text>
|
|
1018
|
+
|
|
1019
|
+
<s-box paddingBlockStart="base">
|
|
1020
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
1021
|
+
<s-text variant="headingSm">Basic Modal</s-text>
|
|
1022
|
+
<s-box paddingBlockStart="small-200">
|
|
1023
|
+
<s-button variant="primary" onclick="document.getElementById('demo-modal-basic').show()">Open Modal</s-button>
|
|
1024
|
+
</s-box>
|
|
1025
|
+
</s-box>
|
|
1026
|
+
</s-box>
|
|
1027
|
+
|
|
1028
|
+
<s-box paddingBlockStart="base">
|
|
1029
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
1030
|
+
<s-text variant="headingSm">Confirmation Dialog</s-text>
|
|
1031
|
+
<s-text color="subdued">Use before destructive actions like deleting records.</s-text>
|
|
1032
|
+
<s-box paddingBlockStart="small-200">
|
|
1033
|
+
<s-button tone="critical" onclick="document.getElementById('demo-modal-confirm').show()">Delete Item</s-button>
|
|
1034
|
+
</s-box>
|
|
1035
|
+
</s-box>
|
|
1036
|
+
</s-box>
|
|
1037
|
+
|
|
1038
|
+
<s-box paddingBlockStart="base">
|
|
1039
|
+
<div class="demo-code">
|
|
1040
|
+
<div class="code-block-header">
|
|
1041
|
+
<span>HTML</span>
|
|
1042
|
+
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
1043
|
+
</div>
|
|
1044
|
+
<pre><code><!-- Basic modal -->
|
|
1045
|
+
<ui-modal id="my-modal">
|
|
795
1046
|
<div style="padding: 16px;">
|
|
796
|
-
<
|
|
1047
|
+
<s-text>Modal content here.</s-text>
|
|
797
1048
|
</div>
|
|
798
1049
|
<ui-title-bar title="Modal Title">
|
|
799
1050
|
<button variant="primary"
|
|
@@ -804,28 +1055,14 @@
|
|
|
804
1055
|
</ui-modal>
|
|
805
1056
|
|
|
806
1057
|
<!-- Trigger -->
|
|
807
|
-
<button onclick="document.getElementById('my-modal').show()">
|
|
1058
|
+
<s-button onclick="document.getElementById('my-modal').show()">
|
|
808
1059
|
Open Modal
|
|
809
|
-
</button>
|
|
810
|
-
</div>
|
|
811
|
-
</div>
|
|
1060
|
+
</s-button>
|
|
812
1061
|
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
<div class="demo-block-title">Confirmation Dialog</div>
|
|
816
|
-
<p class="demo-description mt-3">Use a confirmation modal before destructive actions like deleting records.</p>
|
|
817
|
-
<div class="demo-preview">
|
|
818
|
-
<button class="btn btn-destructive" onclick="document.getElementById('demo-modal-confirm').show()">Delete Item</button>
|
|
819
|
-
</div>
|
|
820
|
-
<div class="demo-code">
|
|
821
|
-
<div class="code-block-header">
|
|
822
|
-
<span>HTML</span>
|
|
823
|
-
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
824
|
-
</div>
|
|
825
|
-
<pre><code><ui-modal id="confirm-delete">
|
|
1062
|
+
<!-- Confirmation dialog -->
|
|
1063
|
+
<ui-modal id="confirm-delete">
|
|
826
1064
|
<div style="padding: 16px;">
|
|
827
|
-
<
|
|
828
|
-
This action cannot be undone.</p>
|
|
1065
|
+
<s-text>Are you sure? This cannot be undone.</s-text>
|
|
829
1066
|
</div>
|
|
830
1067
|
<ui-title-bar title="Confirm Deletion">
|
|
831
1068
|
<button onclick="document.getElementById('confirm-delete').hide()">
|
|
@@ -836,17 +1073,23 @@
|
|
|
836
1073
|
Delete
|
|
837
1074
|
</button>
|
|
838
1075
|
</ui-title-bar>
|
|
839
|
-
</ui-modal>
|
|
840
|
-
|
|
841
|
-
|
|
1076
|
+
</ui-modal>
|
|
1077
|
+
|
|
1078
|
+
<!-- Large variant -->
|
|
1079
|
+
<ui-modal id="my-modal" variant="large">...</ui-modal></code></pre>
|
|
1080
|
+
</div>
|
|
1081
|
+
</s-box>
|
|
1082
|
+
</s-section>
|
|
842
1083
|
</div>
|
|
843
1084
|
|
|
844
|
-
<!-- Demo modals
|
|
1085
|
+
<!-- Demo modals -->
|
|
845
1086
|
<ui-modal id="demo-modal-basic">
|
|
846
1087
|
<div style="padding: 16px;">
|
|
847
|
-
<
|
|
848
|
-
|
|
849
|
-
|
|
1088
|
+
<s-stack gap="base">
|
|
1089
|
+
<s-text variant="headingMd">Hello from a modal!</s-text>
|
|
1090
|
+
<s-text>This is an App Bridge modal rendered by Shopify. It appears outside your app's iframe for a seamless, native experience.</s-text>
|
|
1091
|
+
<s-text color="subdued">Modals are great for forms, confirmations, and displaying details without navigating away.</s-text>
|
|
1092
|
+
</s-stack>
|
|
850
1093
|
</div>
|
|
851
1094
|
<ui-title-bar title="Basic Modal">
|
|
852
1095
|
<button variant="primary" onclick="document.getElementById('demo-modal-basic').hide()">Done</button>
|
|
@@ -855,7 +1098,7 @@
|
|
|
855
1098
|
|
|
856
1099
|
<ui-modal id="demo-modal-confirm">
|
|
857
1100
|
<div style="padding: 16px;">
|
|
858
|
-
<
|
|
1101
|
+
<s-text>Are you sure you want to delete this item? This action cannot be undone.</s-text>
|
|
859
1102
|
</div>
|
|
860
1103
|
<ui-title-bar title="Confirm Deletion">
|
|
861
1104
|
<button onclick="document.getElementById('demo-modal-confirm').hide()">Cancel</button>
|
|
@@ -865,259 +1108,268 @@
|
|
|
865
1108
|
|
|
866
1109
|
|
|
867
1110
|
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
868
|
-
<!-- SECTION
|
|
1111
|
+
<!-- SECTION: SAVE BAR -->
|
|
869
1112
|
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
870
|
-
<div
|
|
871
|
-
<
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
<
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
1113
|
+
<div id="section-savebar">
|
|
1114
|
+
<s-section heading="Save Bar (data-save-bar)">
|
|
1115
|
+
<s-text color="subdued">Shopify's native save/discard bar appears automatically when a <code><form data-save-bar></code> detects changes.</s-text>
|
|
1116
|
+
|
|
1117
|
+
<s-box paddingBlockStart="base">
|
|
1118
|
+
<s-banner tone="info">
|
|
1119
|
+
<s-text>The save bar is demonstrated on the <s-link href="/settings">Settings page</s-link>. Change any field and the save/discard bar appears automatically.</s-text>
|
|
1120
|
+
</s-banner>
|
|
1121
|
+
</s-box>
|
|
1122
|
+
|
|
1123
|
+
<s-box paddingBlockStart="base">
|
|
1124
|
+
<div class="demo-code">
|
|
1125
|
+
<div class="code-block-header">
|
|
1126
|
+
<span>HTML</span>
|
|
1127
|
+
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
1128
|
+
</div>
|
|
1129
|
+
<pre><code><!-- Wrap your page in a form with data-save-bar -->
|
|
1130
|
+
<form data-save-bar id="settings-form">
|
|
1131
|
+
<s-page heading="Settings">
|
|
1132
|
+
<s-section heading="General">
|
|
1133
|
+
<s-text-field id="name" label="Name"></s-text-field>
|
|
1134
|
+
<s-switch id="enabled" label="Enabled"></s-switch>
|
|
1135
|
+
</s-section>
|
|
1136
|
+
</s-page>
|
|
1137
|
+
</form>
|
|
1138
|
+
|
|
1139
|
+
<script>
|
|
1140
|
+
// Handle form submit (save)
|
|
1141
|
+
document.getElementById("settings-form")
|
|
1142
|
+
.addEventListener("submit", async (e) => {
|
|
1143
|
+
e.preventDefault();
|
|
1144
|
+
// Save logic here...
|
|
1145
|
+
shopify.toast.show("Saved!");
|
|
1146
|
+
});
|
|
1147
|
+
|
|
1148
|
+
// Handle form reset (discard)
|
|
1149
|
+
document.getElementById("settings-form")
|
|
1150
|
+
.addEventListener("reset", () => {
|
|
1151
|
+
// Reload original values
|
|
1152
|
+
});
|
|
1153
|
+
</script></code></pre>
|
|
886
1154
|
</div>
|
|
887
|
-
|
|
1155
|
+
</s-box>
|
|
1156
|
+
</s-section>
|
|
1157
|
+
</div>
|
|
1158
|
+
|
|
1159
|
+
|
|
1160
|
+
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
1161
|
+
<!-- SECTION: TOASTS -->
|
|
1162
|
+
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
1163
|
+
<div id="section-toasts">
|
|
1164
|
+
<s-section heading="Toasts">
|
|
1165
|
+
<s-text color="subdued">Brief, non-blocking feedback notifications using App Bridge.</s-text>
|
|
1166
|
+
|
|
1167
|
+
<s-box paddingBlockStart="base">
|
|
1168
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
1169
|
+
<s-stack direction="inline" gap="small-200">
|
|
1170
|
+
<s-button variant="primary" onclick="showToast('Product saved successfully')">Success Toast</s-button>
|
|
1171
|
+
<s-button tone="critical" onclick="showToast('Failed to save product', true)">Error Toast</s-button>
|
|
1172
|
+
</s-stack>
|
|
1173
|
+
</s-box>
|
|
1174
|
+
</s-box>
|
|
1175
|
+
|
|
1176
|
+
<s-box paddingBlockStart="base">
|
|
1177
|
+
<div class="demo-code">
|
|
1178
|
+
<div class="code-block-header">
|
|
1179
|
+
<span>JavaScript</span>
|
|
1180
|
+
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
1181
|
+
</div>
|
|
1182
|
+
<pre><code>// Success toast (uses App Bridge in embedded admin)
|
|
888
1183
|
showToast("Product saved successfully");
|
|
889
1184
|
|
|
890
1185
|
// Error toast
|
|
891
1186
|
showToast("Failed to save product", true);
|
|
892
1187
|
|
|
893
|
-
// App Bridge
|
|
894
|
-
shopify.toast.show("Message", { duration: 5000 })
|
|
895
|
-
|
|
896
|
-
|
|
1188
|
+
// Direct App Bridge API
|
|
1189
|
+
shopify.toast.show("Message", { duration: 5000 });
|
|
1190
|
+
shopify.toast.show("Error!", { isError: true });</code></pre>
|
|
1191
|
+
</div>
|
|
1192
|
+
</s-box>
|
|
1193
|
+
</s-section>
|
|
897
1194
|
</div>
|
|
898
1195
|
|
|
899
1196
|
|
|
900
1197
|
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
901
|
-
<!-- SECTION
|
|
1198
|
+
<!-- SECTION: NAVIGATION -->
|
|
902
1199
|
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
903
|
-
<div
|
|
904
|
-
<
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
<div style="background: var(--p-color-bg-info); padding: 8px 12px; border-radius: 6px; max-width: 720px; margin: 0 auto; width: 100%; text-align: center;">
|
|
913
|
-
<code>.page-narrow</code> - 720px max
|
|
1200
|
+
<div id="section-navigation">
|
|
1201
|
+
<s-section heading="Navigation">
|
|
1202
|
+
<s-text color="subdued">App navigation in the Shopify admin sidebar. Uses <code><ui-nav-menu></code> (App Bridge) or <code><s-app-nav></code> (Polaris).</s-text>
|
|
1203
|
+
|
|
1204
|
+
<s-box paddingBlockStart="base">
|
|
1205
|
+
<div class="demo-code">
|
|
1206
|
+
<div class="code-block-header">
|
|
1207
|
+
<span>HTML</span>
|
|
1208
|
+
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
914
1209
|
</div>
|
|
915
|
-
<
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
<pre><code><div class="page">Default width (960px)</div>
|
|
929
|
-
<div class="page-narrow">Narrow (720px)</div>
|
|
930
|
-
<div class="page-wide">Wide (1200px)</div></code></pre>
|
|
931
|
-
</div>
|
|
932
|
-
</div>
|
|
933
|
-
|
|
934
|
-
<!-- Stats grid -->
|
|
935
|
-
<div class="demo-block">
|
|
936
|
-
<div class="demo-block-title">Stats Grid</div>
|
|
937
|
-
<div class="demo-preview">
|
|
938
|
-
<div class="stats-grid" style="margin-bottom: 0;">
|
|
939
|
-
<div class="stat-card" style="margin-bottom:0;">
|
|
940
|
-
<div class="stat-label">Total Sales</div>
|
|
941
|
-
<div class="stat-value">$12,450</div>
|
|
942
|
-
<div class="stat-change stat-change-positive">+12.5%</div>
|
|
943
|
-
</div>
|
|
944
|
-
<div class="stat-card" style="margin-bottom:0;">
|
|
945
|
-
<div class="stat-label">Orders</div>
|
|
946
|
-
<div class="stat-value">156</div>
|
|
947
|
-
<div class="stat-change stat-change-positive">+8.2%</div>
|
|
948
|
-
</div>
|
|
949
|
-
<div class="stat-card" style="margin-bottom:0;">
|
|
950
|
-
<div class="stat-label">Visitors</div>
|
|
951
|
-
<div class="stat-value">3,842</div>
|
|
952
|
-
<div class="stat-change stat-change-negative">-2.1%</div>
|
|
953
|
-
</div>
|
|
954
|
-
<div class="stat-card" style="margin-bottom:0;">
|
|
955
|
-
<div class="stat-label">Conversion</div>
|
|
956
|
-
<div class="stat-value">4.1%</div>
|
|
957
|
-
<div class="stat-change stat-change-positive">+0.3%</div>
|
|
958
|
-
</div>
|
|
959
|
-
</div>
|
|
960
|
-
</div>
|
|
961
|
-
<div class="demo-code">
|
|
962
|
-
<div class="code-block-header">
|
|
963
|
-
<span>HTML</span>
|
|
964
|
-
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
1210
|
+
<pre><code><!-- Option 1: App Bridge nav (used in this template) -->
|
|
1211
|
+
<ui-nav-menu>
|
|
1212
|
+
<a href="/" rel="home">Dashboard</a>
|
|
1213
|
+
<a href="/products">Products</a>
|
|
1214
|
+
<a href="/settings">Settings</a>
|
|
1215
|
+
</ui-nav-menu>
|
|
1216
|
+
|
|
1217
|
+
<!-- Option 2: Polaris nav -->
|
|
1218
|
+
<s-app-nav>
|
|
1219
|
+
<s-link href="/" rel="home">Dashboard</s-link>
|
|
1220
|
+
<s-link href="/products">Products</s-link>
|
|
1221
|
+
<s-link href="/settings">Settings</s-link>
|
|
1222
|
+
</s-app-nav></code></pre>
|
|
965
1223
|
</div>
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
<div class="stat-label">Total Sales</div>
|
|
969
|
-
<div class="stat-value">$12,450</div>
|
|
970
|
-
<div class="stat-change stat-change-positive">
|
|
971
|
-
+12.5%
|
|
972
|
-
</div>
|
|
973
|
-
</div>
|
|
974
|
-
<!-- More stat cards... -->
|
|
975
|
-
</div></code></pre>
|
|
976
|
-
</div>
|
|
977
|
-
</div>
|
|
978
|
-
|
|
979
|
-
<!-- Flex utilities -->
|
|
980
|
-
<div class="demo-block">
|
|
981
|
-
<div class="demo-block-title">Flex Utilities</div>
|
|
982
|
-
<div class="demo-preview">
|
|
983
|
-
<div class="flex items-center justify-between p-3" style="background: var(--p-color-bg-surface-hover); border-radius: 8px; margin-bottom: 8px;">
|
|
984
|
-
<span>justify-between</span>
|
|
985
|
-
<button class="btn btn-sm">Action</button>
|
|
986
|
-
</div>
|
|
987
|
-
<div class="flex items-center justify-center gap-3 p-3" style="background: var(--p-color-bg-surface-hover); border-radius: 8px; margin-bottom: 8px;">
|
|
988
|
-
<span>justify-center + gap-3</span>
|
|
989
|
-
<span class="badge badge-info">Centered</span>
|
|
990
|
-
</div>
|
|
991
|
-
<div class="flex flex-wrap gap-2 p-3" style="background: var(--p-color-bg-surface-hover); border-radius: 8px;">
|
|
992
|
-
<span class="badge badge-default">flex-wrap</span>
|
|
993
|
-
<span class="badge badge-default">gap-2</span>
|
|
994
|
-
<span class="badge badge-default">wraps</span>
|
|
995
|
-
<span class="badge badge-default">on</span>
|
|
996
|
-
<span class="badge badge-default">smaller</span>
|
|
997
|
-
<span class="badge badge-default">screens</span>
|
|
998
|
-
</div>
|
|
999
|
-
</div>
|
|
1000
|
-
<div class="demo-code">
|
|
1001
|
-
<div class="code-block-header">
|
|
1002
|
-
<span>HTML</span>
|
|
1003
|
-
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
1004
|
-
</div>
|
|
1005
|
-
<pre><code><div class="flex items-center justify-between">
|
|
1006
|
-
<span>Label</span>
|
|
1007
|
-
<button class="btn btn-sm">Action</button>
|
|
1008
|
-
</div>
|
|
1009
|
-
|
|
1010
|
-
<!-- Available: flex, flex-col, flex-wrap,
|
|
1011
|
-
items-center, items-start,
|
|
1012
|
-
justify-between, justify-center, justify-end,
|
|
1013
|
-
gap-1 through gap-5 --></code></pre>
|
|
1014
|
-
</div>
|
|
1015
|
-
</div>
|
|
1016
|
-
|
|
1017
|
-
<!-- Quick Links -->
|
|
1018
|
-
<div class="demo-block">
|
|
1019
|
-
<div class="demo-block-title">Quick Links</div>
|
|
1020
|
-
<div class="demo-preview">
|
|
1021
|
-
<div class="quick-links">
|
|
1022
|
-
<a class="quick-link" href="#">
|
|
1023
|
-
<div class="quick-link-icon">🛒</div>
|
|
1024
|
-
<div class="quick-link-text">
|
|
1025
|
-
<h4>Products</h4>
|
|
1026
|
-
<p>Manage inventory</p>
|
|
1027
|
-
</div>
|
|
1028
|
-
</a>
|
|
1029
|
-
<a class="quick-link" href="#">
|
|
1030
|
-
<div class="quick-link-icon">💰</div>
|
|
1031
|
-
<div class="quick-link-text">
|
|
1032
|
-
<h4>Orders</h4>
|
|
1033
|
-
<p>View recent orders</p>
|
|
1034
|
-
</div>
|
|
1035
|
-
</a>
|
|
1036
|
-
<a class="quick-link" href="#">
|
|
1037
|
-
<div class="quick-link-icon">⚙</div>
|
|
1038
|
-
<div class="quick-link-text">
|
|
1039
|
-
<h4>Settings</h4>
|
|
1040
|
-
<p>Configure your app</p>
|
|
1041
|
-
</div>
|
|
1042
|
-
</a>
|
|
1043
|
-
</div>
|
|
1044
|
-
</div>
|
|
1045
|
-
<div class="demo-code">
|
|
1046
|
-
<div class="code-block-header">
|
|
1047
|
-
<span>HTML</span>
|
|
1048
|
-
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
1049
|
-
</div>
|
|
1050
|
-
<pre><code><div class="quick-links">
|
|
1051
|
-
<a class="quick-link" href="/products">
|
|
1052
|
-
<div class="quick-link-icon">&#128722;</div>
|
|
1053
|
-
<div class="quick-link-text">
|
|
1054
|
-
<h4>Products</h4>
|
|
1055
|
-
<p>Manage inventory</p>
|
|
1056
|
-
</div>
|
|
1057
|
-
</a>
|
|
1058
|
-
</div></code></pre>
|
|
1059
|
-
</div>
|
|
1060
|
-
</div>
|
|
1224
|
+
</s-box>
|
|
1225
|
+
</s-section>
|
|
1061
1226
|
</div>
|
|
1062
1227
|
|
|
1063
1228
|
|
|
1064
1229
|
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
1065
|
-
<!-- SECTION
|
|
1230
|
+
<!-- SECTION: RESOURCE PICKER -->
|
|
1066
1231
|
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
1067
|
-
<div
|
|
1068
|
-
<
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
<
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1232
|
+
<div id="section-resource-picker">
|
|
1233
|
+
<s-section heading="Resource Picker">
|
|
1234
|
+
<s-text color="subdued">App Bridge provides a native product/collection picker. Only available inside the Shopify admin.</s-text>
|
|
1235
|
+
|
|
1236
|
+
<s-box paddingBlockStart="base">
|
|
1237
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
1238
|
+
<s-stack gap="base">
|
|
1239
|
+
<s-button variant="primary" onclick="demoResourcePicker()">Open Product Picker</s-button>
|
|
1240
|
+
<div id="picker-demo-result"></div>
|
|
1241
|
+
</s-stack>
|
|
1242
|
+
</s-box>
|
|
1243
|
+
</s-box>
|
|
1244
|
+
|
|
1245
|
+
<s-box paddingBlockStart="base">
|
|
1246
|
+
<div class="demo-code">
|
|
1247
|
+
<div class="code-block-header">
|
|
1248
|
+
<span>JavaScript</span>
|
|
1249
|
+
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
1250
|
+
</div>
|
|
1251
|
+
<pre><code>// Open the product resource picker
|
|
1083
1252
|
const selected = await shopify.resourcePicker({
|
|
1084
1253
|
type: "product",
|
|
1085
|
-
// Optional: allow multiple selection
|
|
1086
1254
|
// multiple: true,
|
|
1087
|
-
// Optional: filter
|
|
1088
1255
|
// filter: { query: "shirt" },
|
|
1089
1256
|
});
|
|
1090
1257
|
|
|
1091
1258
|
if (selected && selected.length > 0) {
|
|
1092
|
-
console.log("Selected:", selected);
|
|
1093
1259
|
selected.forEach(product => {
|
|
1094
1260
|
console.log(product.title, product.id);
|
|
1095
1261
|
});
|
|
1096
1262
|
}</code></pre>
|
|
1097
|
-
</div>
|
|
1098
|
-
</div>
|
|
1099
|
-
|
|
1100
|
-
<!-- API fetch pattern -->
|
|
1101
|
-
<div class="demo-block">
|
|
1102
|
-
<div class="demo-block-title">API Fetch Pattern</div>
|
|
1103
|
-
<p class="demo-description mt-3">Use the <code>apiFetch()</code> helper for all API calls. It handles session tokens automatically.</p>
|
|
1104
|
-
<div class="demo-preview">
|
|
1105
|
-
<button class="btn" onclick="demoApiFetch()">Test API Call</button>
|
|
1106
|
-
</div>
|
|
1107
|
-
<div class="demo-code">
|
|
1108
|
-
<div class="code-block-header">
|
|
1109
|
-
<span>JavaScript</span>
|
|
1110
|
-
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
1111
1263
|
</div>
|
|
1112
|
-
|
|
1113
|
-
|
|
1264
|
+
</s-box>
|
|
1265
|
+
</s-section>
|
|
1266
|
+
</div>
|
|
1114
1267
|
|
|
1115
|
-
|
|
1268
|
+
|
|
1269
|
+
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
1270
|
+
<!-- SECTION: COMMON PATTERNS -->
|
|
1271
|
+
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
1272
|
+
<div id="section-patterns">
|
|
1273
|
+
<s-section heading="Common Patterns">
|
|
1274
|
+
<s-text color="subdued">Reusable UI patterns combining multiple Polaris components.</s-text>
|
|
1275
|
+
|
|
1276
|
+
<!-- Pattern: Stat cards -->
|
|
1277
|
+
<s-box paddingBlockStart="base">
|
|
1278
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
1279
|
+
<s-text variant="headingSm">Metric Cards</s-text>
|
|
1280
|
+
<s-box paddingBlockStart="small-200">
|
|
1281
|
+
<s-grid gridTemplateColumns="@container (inline-size <= 400px) 1fr 1fr, 1fr 1fr 1fr 1fr" gap="base">
|
|
1282
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
1283
|
+
<s-stack gap="small-200">
|
|
1284
|
+
<s-text color="subdued">Total Sales</s-text>
|
|
1285
|
+
<s-text variant="headingLg">$12,450</s-text>
|
|
1286
|
+
<s-text color="success" variant="bodySm">+12.5%</s-text>
|
|
1287
|
+
</s-stack>
|
|
1288
|
+
</s-box>
|
|
1289
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
1290
|
+
<s-stack gap="small-200">
|
|
1291
|
+
<s-text color="subdued">Orders</s-text>
|
|
1292
|
+
<s-text variant="headingLg">156</s-text>
|
|
1293
|
+
<s-text color="success" variant="bodySm">+8.2%</s-text>
|
|
1294
|
+
</s-stack>
|
|
1295
|
+
</s-box>
|
|
1296
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
1297
|
+
<s-stack gap="small-200">
|
|
1298
|
+
<s-text color="subdued">Visitors</s-text>
|
|
1299
|
+
<s-text variant="headingLg">3,842</s-text>
|
|
1300
|
+
<s-text color="critical" variant="bodySm">-2.1%</s-text>
|
|
1301
|
+
</s-stack>
|
|
1302
|
+
</s-box>
|
|
1303
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
1304
|
+
<s-stack gap="small-200">
|
|
1305
|
+
<s-text color="subdued">Conversion</s-text>
|
|
1306
|
+
<s-text variant="headingLg">4.1%</s-text>
|
|
1307
|
+
<s-text color="success" variant="bodySm">+0.3%</s-text>
|
|
1308
|
+
</s-stack>
|
|
1309
|
+
</s-box>
|
|
1310
|
+
</s-grid>
|
|
1311
|
+
</s-box>
|
|
1312
|
+
</s-box>
|
|
1313
|
+
</s-box>
|
|
1314
|
+
|
|
1315
|
+
<!-- Pattern: Info list -->
|
|
1316
|
+
<s-box paddingBlockStart="base">
|
|
1317
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
1318
|
+
<s-text variant="headingSm">Info List (Key-Value)</s-text>
|
|
1319
|
+
<s-box paddingBlockStart="small-200">
|
|
1320
|
+
<s-stack gap="small-200">
|
|
1321
|
+
<s-grid gridTemplateColumns="1fr 1fr" gap="small-200">
|
|
1322
|
+
<s-text color="subdued">Store name</s-text>
|
|
1323
|
+
<s-text>My Awesome Store</s-text>
|
|
1324
|
+
</s-grid>
|
|
1325
|
+
<s-grid gridTemplateColumns="1fr 1fr" gap="small-200">
|
|
1326
|
+
<s-text color="subdued">Plan</s-text>
|
|
1327
|
+
<s-text>Shopify Plus</s-text>
|
|
1328
|
+
</s-grid>
|
|
1329
|
+
<s-grid gridTemplateColumns="1fr 1fr" gap="small-200">
|
|
1330
|
+
<s-text color="subdued">Status</s-text>
|
|
1331
|
+
<s-badge tone="success">Active</s-badge>
|
|
1332
|
+
</s-grid>
|
|
1333
|
+
</s-stack>
|
|
1334
|
+
</s-box>
|
|
1335
|
+
</s-box>
|
|
1336
|
+
</s-box>
|
|
1337
|
+
|
|
1338
|
+
<!-- Pattern: Empty state -->
|
|
1339
|
+
<s-box paddingBlockStart="base">
|
|
1340
|
+
<s-box border="base" borderRadius="base" padding="large-1200">
|
|
1341
|
+
<s-stack alignItems="center" gap="base">
|
|
1342
|
+
<s-text variant="headingMd">No orders yet</s-text>
|
|
1343
|
+
<s-text color="subdued">When customers place orders, they will appear here.</s-text>
|
|
1344
|
+
<s-button variant="primary">Add product</s-button>
|
|
1345
|
+
</s-stack>
|
|
1346
|
+
</s-box>
|
|
1347
|
+
</s-box>
|
|
1348
|
+
|
|
1349
|
+
<!-- Pattern: API fetch -->
|
|
1350
|
+
<s-box paddingBlockStart="base">
|
|
1351
|
+
<s-box border="base" borderRadius="base" padding="base">
|
|
1352
|
+
<s-stack gap="base">
|
|
1353
|
+
<s-text variant="headingSm">API Fetch Pattern</s-text>
|
|
1354
|
+
<s-text color="subdued">Use <code>apiFetch()</code> for all API calls. It handles session tokens automatically.</s-text>
|
|
1355
|
+
<s-button onclick="demoApiFetch()">Test API Call</s-button>
|
|
1356
|
+
</s-stack>
|
|
1357
|
+
</s-box>
|
|
1358
|
+
</s-box>
|
|
1359
|
+
|
|
1360
|
+
<s-box paddingBlockStart="base">
|
|
1361
|
+
<div class="demo-code">
|
|
1362
|
+
<div class="code-block-header">
|
|
1363
|
+
<span>JavaScript</span>
|
|
1364
|
+
<button class="btn-copy" onclick="copyCode(this)">Copy</button>
|
|
1365
|
+
</div>
|
|
1366
|
+
<pre><code>// GET request
|
|
1367
|
+
const data = await apiFetch("/api/shop");
|
|
1368
|
+
|
|
1369
|
+
// POST request
|
|
1116
1370
|
await apiFetch("/api/settings", {
|
|
1117
1371
|
method: "POST",
|
|
1118
|
-
body: JSON.stringify({
|
|
1119
|
-
settings: { greeting: "Hello!" }
|
|
1120
|
-
}),
|
|
1372
|
+
body: JSON.stringify({ greeting: "Hello!" }),
|
|
1121
1373
|
});
|
|
1122
1374
|
|
|
1123
1375
|
// Search with query params
|
|
@@ -1131,17 +1383,36 @@ try {
|
|
|
1131
1383
|
showToast("Success!");
|
|
1132
1384
|
} catch (err) {
|
|
1133
1385
|
showToast("Error: " + err.message, true);
|
|
1386
|
+
}
|
|
1387
|
+
|
|
1388
|
+
// Loading pattern
|
|
1389
|
+
const loading = document.getElementById("my-loading");
|
|
1390
|
+
const content = document.getElementById("my-content");
|
|
1391
|
+
loading.style.display = "";
|
|
1392
|
+
content.style.display = "none";
|
|
1393
|
+
try {
|
|
1394
|
+
const data = await apiFetch("/api/data");
|
|
1395
|
+
// Render data...
|
|
1396
|
+
loading.style.display = "none";
|
|
1397
|
+
content.style.display = "";
|
|
1398
|
+
} catch (err) {
|
|
1399
|
+
loading.innerHTML = '<s-banner tone="critical">' +
|
|
1400
|
+
'<s-text>' + err.message + '</s-text></s-banner>';
|
|
1134
1401
|
}</code></pre>
|
|
1135
|
-
|
|
1136
|
-
|
|
1402
|
+
</div>
|
|
1403
|
+
</s-box>
|
|
1404
|
+
</s-section>
|
|
1137
1405
|
</div>
|
|
1138
1406
|
|
|
1139
1407
|
|
|
1140
1408
|
<!-- Footer -->
|
|
1141
|
-
<
|
|
1142
|
-
<
|
|
1143
|
-
|
|
1144
|
-
|
|
1409
|
+
<s-section>
|
|
1410
|
+
<s-stack alignItems="center">
|
|
1411
|
+
<s-text color="subdued">Built with Shopify Polaris Web Components + App Bridge + Firebase Hosting. See <s-link href="https://polaris.shopify.com" target="_blank">polaris.shopify.com</s-link> for full documentation.</s-text>
|
|
1412
|
+
</s-stack>
|
|
1413
|
+
</s-section>
|
|
1414
|
+
|
|
1415
|
+
</s-page>
|
|
1145
1416
|
|
|
1146
1417
|
<script src="/js/app.js"></script>
|
|
1147
1418
|
<script src="/js/pages/polaris-demo.js"></script>
|