astryx-dracula 0.5.0 → 0.6.2
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/BRAND.md +3 -3
- package/README.md +7 -4
- package/USAGE.md +49 -49
- package/astryx-dracula.d.ts +2 -2
- package/astryx-dracula.js +25 -9
- package/astryx-dracula.variants.d.ts +2 -2
- package/astryx.integration.mjs +1 -1
- package/icons.mjs +21 -17
- package/icons.tsx +69 -62
- package/package.json +125 -120
- package/shared/auth-chrome-config.ts +6 -6
- package/shared/auth-chrome.tsx +143 -144
- package/shared/auth-copy.ts +14 -14
- package/shared/chaptered-doc-config.ts +48 -51
- package/shared/chaptered-doc.tsx +267 -289
- package/shared/chart-hues.ts +25 -10
- package/shared/chart-labels.tsx +31 -30
- package/shared/chart-legend.tsx +55 -56
- package/shared/chart-panel-style.ts +3 -3
- package/shared/data-bar.tsx +97 -102
- package/shared/format-money.ts +1 -1
- package/shared/gallery-image.ts +6 -6
- package/shared/login-demo.ts +1 -1
- package/shared/metric-card.tsx +101 -105
- package/shared/metric-delta.tsx +28 -27
- package/shared/order-desk.tsx +205 -216
- package/shared/revenue-chart.tsx +145 -165
- package/shared/scene-castle.tsx +206 -291
- package/shared/scene-frame.tsx +33 -32
- package/shared/scene-hues.ts +17 -17
- package/shared/scene-tile.tsx +88 -92
- package/shared/settings-data.ts +119 -125
- package/shared/settings-rows.tsx +122 -159
- package/shared/sparkline.tsx +75 -88
- package/shared/sso-icons.tsx +10 -22
- package/shared/stars.tsx +16 -25
- package/templates/ai-chat-landing.template.mjs +5 -4
- package/templates/ai-chat-landing.tsx +473 -460
- package/templates/ai-chat.template.mjs +5 -4
- package/templates/ai-chat.tsx +543 -612
- package/templates/blank.template.mjs +5 -4
- package/templates/blank.tsx +18 -14
- package/templates/centered-hero.template.mjs +5 -4
- package/templates/centered-hero.tsx +55 -68
- package/templates/classic-gallery.template.mjs +5 -4
- package/templates/classic-gallery.tsx +97 -104
- package/templates/contact-form.template.mjs +5 -4
- package/templates/contact-form.tsx +247 -282
- package/templates/dashboard-portfolio.template.mjs +5 -4
- package/templates/dashboard-portfolio.tsx +717 -548
- package/templates/dashboard.template.mjs +5 -4
- package/templates/dashboard.tsx +596 -567
- package/templates/detail-page.template.mjs +5 -4
- package/templates/detail-page.tsx +546 -603
- package/templates/documentation-design.template.mjs +5 -4
- package/templates/documentation-design.tsx +231 -243
- package/templates/documentation-technical.template.mjs +5 -4
- package/templates/documentation-technical.tsx +236 -239
- package/templates/documentation.template.mjs +5 -4
- package/templates/documentation.tsx +267 -279
- package/templates/editor.template.mjs +5 -4
- package/templates/editor.tsx +844 -877
- package/templates/file-explorer.template.mjs +5 -4
- package/templates/file-explorer.tsx +566 -590
- package/templates/form-two-column.template.mjs +5 -4
- package/templates/form-two-column.tsx +195 -210
- package/templates/gallery-hero.template.mjs +5 -4
- package/templates/gallery-hero.tsx +93 -114
- package/templates/ide.template.mjs +5 -4
- package/templates/ide.tsx +407 -453
- package/templates/incident-console.template.mjs +5 -4
- package/templates/incident-console.tsx +593 -575
- package/templates/kanban-board.template.mjs +5 -4
- package/templates/kanban-board.tsx +665 -683
- package/templates/library.template.mjs +5 -4
- package/templates/library.tsx +409 -430
- package/templates/login-card.template.mjs +5 -4
- package/templates/login-card.tsx +63 -72
- package/templates/login-split.template.mjs +5 -4
- package/templates/login-split.tsx +192 -193
- package/templates/login-sso.template.mjs +5 -4
- package/templates/login-sso.tsx +257 -258
- package/templates/login.template.mjs +5 -4
- package/templates/login.tsx +53 -49
- package/templates/messaging-shell.template.mjs +5 -4
- package/templates/messaging-shell.tsx +556 -574
- package/templates/mixed-gallery.template.mjs +5 -4
- package/templates/mixed-gallery.tsx +60 -58
- package/templates/payment-form.template.mjs +5 -4
- package/templates/payment-form.tsx +882 -991
- package/templates/product-detail.template.mjs +5 -4
- package/templates/product-detail.tsx +261 -272
- package/templates/product-gallery.template.mjs +5 -4
- package/templates/product-gallery.tsx +126 -137
- package/templates/product-tour.template.mjs +5 -4
- package/templates/product-tour.tsx +741 -773
- package/templates/settings-dialog.template.mjs +5 -4
- package/templates/settings-dialog.tsx +688 -717
- package/templates/settings-sidebar.template.mjs +5 -4
- package/templates/settings-sidebar.tsx +762 -807
- package/templates/settings.template.mjs +5 -4
- package/templates/settings.tsx +289 -304
- package/templates/shell-nav.template.mjs +5 -4
- package/templates/shell-nav.tsx +212 -219
- package/templates/shell-side-nav.template.mjs +5 -4
- package/templates/shell-side-nav.tsx +135 -157
- package/templates/shell-top-nav.template.mjs +5 -4
- package/templates/shell-top-nav.tsx +182 -203
- package/templates/side-gallery.template.mjs +5 -4
- package/templates/side-gallery.tsx +85 -90
- package/templates/table-grouped.template.mjs +5 -4
- package/templates/table-grouped.tsx +1000 -1053
- package/templates/table-page-chart.template.mjs +5 -4
- package/templates/table-page-chart.tsx +400 -398
- package/templates/table-page-heatmap-status.template.mjs +5 -4
- package/templates/table-page-heatmap-status.tsx +483 -512
- package/templates/table-page-shoe-store-heatmap.template.mjs +5 -4
- package/templates/table-page-shoe-store-heatmap.tsx +748 -746
- package/templates/table-page.template.mjs +5 -4
- package/templates/table-page.tsx +396 -405
- package/templates/table.template.mjs +5 -4
- package/templates/table.tsx +92 -93
- package/templates/tech-report.template.mjs +5 -4
- package/templates/tech-report.tsx +1316 -1304
- package/templates/theme-showcase.template.mjs +5 -4
- package/templates/theme-showcase.tsx +871 -951
- package/theme.css +35 -77
- package/theme.css.d.ts +9 -0
- package/tokens.css +373 -380
|
@@ -1,46 +1,40 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
// XLE (canonical structure
|
|
3
|
-
//
|
|
2
|
+
// XLE (canonical structure of the tree below; the CLI had no XLE validator
|
|
3
|
+
// after `astryx layout` was removed in 0.7.0, so this is a reading aid and a
|
|
4
|
+
// human drift check — update it with the file, never alone):
|
|
5
|
+
// A.surface[cp=6 @topNav=(TN > (Hd{TopNavHeading}"Nocturne") + (TNI{TopNavMegaMenu}"Shop" > (TNI{TopNavMegaMenuItem}*4 + C{TopNavMegaMenuFeaturedCard}"The Midnight Edit") + TNI{TopNavMegaMenu}"Brands" > (TNI{TopNavMegaMenuItem}*4 + C{TopNavMegaMenuFeaturedCard}"Meet Studio Mara") + TNI"Sale" + TNI"Service") + (IB"Search products" + B.ghost"Sign in" + B.primary"Checkout"))] > Ctr[axis=horizontal] > S.transparent[mw=1100 w=100% p=0] > V[g=10] > C.muted[p=0 w=100% h=360] + (V[g=4] > C.muted[p=0 w=200 h=24] + (G[c={min:160} g=4] > (V[g=2] > C.muted[p=0 w=100% h=120] + C.muted[p=0 w=60% h=14])*4))*3
|
|
4
6
|
// Note: skeleton placeholders carry no Hd by design (skill skeleton-shell
|
|
5
7
|
// exemption) — routed pages supply the h1.
|
|
6
8
|
|
|
7
|
-
import {AppShell} from
|
|
8
|
-
import {
|
|
9
|
+
import { AppShell } from "@astryxdesign/core/AppShell";
|
|
10
|
+
import { Badge } from "@astryxdesign/core/Badge";
|
|
11
|
+
import { Button } from "@astryxdesign/core/Button";
|
|
12
|
+
import { Card } from "@astryxdesign/core/Card";
|
|
13
|
+
import { Center } from "@astryxdesign/core/Center";
|
|
14
|
+
import { Grid } from "@astryxdesign/core/Grid";
|
|
15
|
+
import { useMediaQuery } from "@astryxdesign/core/hooks";
|
|
16
|
+
import type { IconType } from "@astryxdesign/core/Icon";
|
|
17
|
+
import { Icon } from "@astryxdesign/core/Icon";
|
|
18
|
+
import { IconButton } from "@astryxdesign/core/IconButton";
|
|
19
|
+
import { NavIcon } from "@astryxdesign/core/NavIcon";
|
|
20
|
+
import { Section } from "@astryxdesign/core/Section";
|
|
21
|
+
import { Stack, VStack } from "@astryxdesign/core/Stack";
|
|
9
22
|
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
} from
|
|
18
|
-
import {
|
|
19
|
-
import {Icon} from '@astryxdesign/core/Icon';
|
|
20
|
-
import type {IconType} from '@astryxdesign/core/Icon';
|
|
21
|
-
import {IconButton} from '@astryxdesign/core/IconButton';
|
|
22
|
-
import {Button} from '@astryxdesign/core/Button';
|
|
23
|
-
import {Badge} from '@astryxdesign/core/Badge';
|
|
24
|
-
import {Card} from '@astryxdesign/core/Card';
|
|
25
|
-
import {Center} from '@astryxdesign/core/Center';
|
|
26
|
-
import {Grid} from '@astryxdesign/core/Grid';
|
|
27
|
-
import {Section} from '@astryxdesign/core/Section';
|
|
28
|
-
import {Stack, VStack} from '@astryxdesign/core/Stack';
|
|
29
|
-
import {
|
|
30
|
-
ShoppingBag,
|
|
31
|
-
ShoppingCart,
|
|
32
|
-
Search,
|
|
33
|
-
Sparkles,
|
|
34
|
-
SwatchBook,
|
|
35
|
-
Tag,
|
|
36
|
-
House,
|
|
37
|
-
} from 'lucide-react';
|
|
23
|
+
TopNav,
|
|
24
|
+
TopNavHeading,
|
|
25
|
+
TopNavItem,
|
|
26
|
+
TopNavMegaMenu,
|
|
27
|
+
TopNavMegaMenuFeaturedCard,
|
|
28
|
+
TopNavMegaMenuItem,
|
|
29
|
+
useTopNavRenderMode,
|
|
30
|
+
} from "@astryxdesign/core/TopNav";
|
|
31
|
+
import { House, Search, ShoppingBag, ShoppingCart, Sparkles, SwatchBook, Tag } from "lucide-react";
|
|
38
32
|
|
|
39
33
|
// Cap + center the page body so wide screens show whitespace gutters.
|
|
40
34
|
const CONTENT_MAX_WIDTH = 1100;
|
|
41
35
|
// Same-route hash: demo links stay focusable anchors without escaping the
|
|
42
36
|
// template through the hash router (bare "#" would drop back to the home page).
|
|
43
|
-
const SELF_HASH =
|
|
37
|
+
const SELF_HASH = "#/templates/shell-top-nav";
|
|
44
38
|
// Lock both mega-menu panels to an identical size. Without fixed widths Shop
|
|
45
39
|
// and Brands size to their own content (different widths); since both anchor
|
|
46
40
|
// to the centered nav, switching between them resizes the panel — which reads
|
|
@@ -49,200 +43,185 @@ const SELF_HASH = '#/templates/shell-top-nav';
|
|
|
49
43
|
// MegaItems) instead of painting past the edge.
|
|
50
44
|
|
|
51
45
|
// Three identical shelves; the ids keep React keys stable if they reorder.
|
|
52
|
-
const SHELVES = [
|
|
46
|
+
const SHELVES = ["new-in", "featured", "sale"];
|
|
53
47
|
|
|
54
|
-
type MegaItem = {name: string; tagline: string; icon: IconType};
|
|
48
|
+
type MegaItem = { name: string; tagline: string; icon: IconType };
|
|
55
49
|
|
|
56
50
|
// Shop and Brands each render 4 items — the mega menu's built-in 2-column
|
|
57
51
|
// grid lays them out as 2 columns × 2 rows, alongside a featured card.
|
|
58
52
|
const SHOP_ITEMS: MegaItem[] = [
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
53
|
+
{ name: "New Moon Arrivals", tagline: "Fresh from the kiln", icon: Sparkles },
|
|
54
|
+
{
|
|
55
|
+
name: "Gowns & Cloaks",
|
|
56
|
+
tagline: "Dresses, knitwear & moonlit layers",
|
|
57
|
+
icon: SwatchBook,
|
|
58
|
+
},
|
|
59
|
+
{ name: "Doublets & Tailoring", tagline: "Shirts, cloaks & more", icon: Tag },
|
|
60
|
+
{ name: "Keep & Crypt", tagline: "Bedding, candlelight & décor", icon: House },
|
|
67
61
|
];
|
|
68
62
|
|
|
69
63
|
const BRAND_ITEMS: MegaItem[] = [
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
64
|
+
{ name: "Aether", tagline: "Moonlit essentials", icon: Sparkles },
|
|
65
|
+
{ name: "Loomwell", tagline: "Everyday knitwear, coven-stitched", icon: Tag },
|
|
66
|
+
{ name: "Verdant", tagline: "Earth-kept basics", icon: House },
|
|
67
|
+
{ name: "Studio Mara", tagline: "Modern tailoring for the night", icon: SwatchBook },
|
|
74
68
|
];
|
|
75
69
|
|
|
76
70
|
// Shelf tiles mirror the Shop menu so the page previews what the menu links.
|
|
77
|
-
const CATEGORY_TILES = SHOP_ITEMS.map(item => item.name);
|
|
71
|
+
const CATEGORY_TILES = SHOP_ITEMS.map((item) => item.name);
|
|
78
72
|
|
|
79
73
|
// Both panels share one item renderer so the drawer's single column and the
|
|
80
74
|
// desktop popover's fixed-width grid stay in lockstep. Fixed widths keep the
|
|
81
75
|
// two panels pixel-identical (no resize flash when switching menus); the
|
|
82
76
|
// drawer and narrow viewports fall back to a natural-width column so the
|
|
83
77
|
// locked 520px panel never paints past the edge.
|
|
84
|
-
function MegaItems({items}: {items: MegaItem[]}) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
78
|
+
function MegaItems({ items }: { items: MegaItem[] }) {
|
|
79
|
+
// In the mobile drawer the fixed 520px panel would overflow the ~350px
|
|
80
|
+
// drawer, and the 2-column grid overlaps item text there — so the drawer
|
|
81
|
+
// gets a natural-width single column. The same goes for viewports too
|
|
82
|
+
// narrow to seat the locked desktop panel, which would otherwise paint
|
|
83
|
+
// past the edge: below 1024px the popover keeps the natural-width column.
|
|
84
|
+
const isDrawer = useTopNavRenderMode() === "drawer";
|
|
85
|
+
const isCompact = useMediaQuery("(max-width: 1024px)");
|
|
86
|
+
if (isDrawer || isCompact) {
|
|
87
|
+
return (
|
|
88
|
+
<VStack gap={1}>
|
|
89
|
+
{items.map((item) => (
|
|
90
|
+
<TopNavMegaMenuItem
|
|
91
|
+
key={item.name}
|
|
92
|
+
title={item.name}
|
|
93
|
+
description={item.tagline}
|
|
94
|
+
icon={<Icon icon={item.icon} size="md" color="secondary" />}
|
|
95
|
+
href={SELF_HASH}
|
|
96
|
+
/>
|
|
97
|
+
))}
|
|
98
|
+
</VStack>
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
return (
|
|
102
|
+
<Stack style={{ gridColumn: "1 / -1", width: 520 }}>
|
|
103
|
+
<Grid columns={2} gap={2}>
|
|
104
|
+
{items.map((item) => (
|
|
105
|
+
<TopNavMegaMenuItem
|
|
106
|
+
key={item.name}
|
|
107
|
+
title={item.name}
|
|
108
|
+
description={item.tagline}
|
|
109
|
+
icon={<Icon icon={item.icon} size="md" color="secondary" />}
|
|
110
|
+
href={SELF_HASH}
|
|
111
|
+
/>
|
|
112
|
+
))}
|
|
113
|
+
</Grid>
|
|
114
|
+
</Stack>
|
|
115
|
+
);
|
|
122
116
|
}
|
|
123
117
|
|
|
124
118
|
// Pins the featured card to a fixed width so both panels match exactly.
|
|
125
119
|
function MegaFeatured(props: {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
120
|
+
title: string;
|
|
121
|
+
description: string;
|
|
122
|
+
linkLabel: string;
|
|
123
|
+
linkHref: string;
|
|
130
124
|
}) {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
125
|
+
const isDrawer = useTopNavRenderMode() === "drawer";
|
|
126
|
+
const isCompact = useMediaQuery("(max-width: 1024px)");
|
|
127
|
+
return (
|
|
128
|
+
<Stack style={isDrawer || isCompact ? undefined : { width: 240 }}>
|
|
129
|
+
<TopNavMegaMenuFeaturedCard {...props} />
|
|
130
|
+
</Stack>
|
|
131
|
+
);
|
|
138
132
|
}
|
|
139
133
|
|
|
140
134
|
export default function ShellTopNav() {
|
|
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
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
width="100%"
|
|
215
|
-
padding={0}>
|
|
216
|
-
<VStack gap={10}>
|
|
217
|
-
{/* Skeleton shelves only — the routed collection supplies the h1. */}
|
|
218
|
-
<Card variant="muted" padding={0} width="100%" height={360} />
|
|
135
|
+
// Below ~640px the mobile bar (heading + actions + toggle) overflows 390px
|
|
136
|
+
// viewports, pushing the nav toggle off-screen. Dropping the text Sign in
|
|
137
|
+
// button there restores room for search, checkout, and the toggle.
|
|
138
|
+
const isCompact = useMediaQuery("(max-width: 640px)");
|
|
139
|
+
return (
|
|
140
|
+
<AppShell
|
|
141
|
+
variant="surface"
|
|
142
|
+
contentPadding={6}
|
|
143
|
+
topNav={
|
|
144
|
+
<TopNav
|
|
145
|
+
label="Nocturne storefront navigation"
|
|
146
|
+
heading={
|
|
147
|
+
<TopNavHeading
|
|
148
|
+
heading="Nocturne"
|
|
149
|
+
logo={<NavIcon icon={<Icon icon={ShoppingBag} size="sm" />} />}
|
|
150
|
+
/>
|
|
151
|
+
}
|
|
152
|
+
centerContent={
|
|
153
|
+
<>
|
|
154
|
+
<TopNavMegaMenu
|
|
155
|
+
label="Shop"
|
|
156
|
+
items={<MegaItems items={SHOP_ITEMS} />}
|
|
157
|
+
featured={
|
|
158
|
+
<MegaFeatured
|
|
159
|
+
title="The Midnight Edit"
|
|
160
|
+
description="Layered staples in moonlit purples."
|
|
161
|
+
linkLabel="Shop the edit"
|
|
162
|
+
linkHref={SELF_HASH}
|
|
163
|
+
/>
|
|
164
|
+
}
|
|
165
|
+
/>
|
|
166
|
+
<TopNavMegaMenu
|
|
167
|
+
label="Brands"
|
|
168
|
+
items={<MegaItems items={BRAND_ITEMS} />}
|
|
169
|
+
featured={
|
|
170
|
+
<MegaFeatured
|
|
171
|
+
title="Meet Studio Mara"
|
|
172
|
+
description="Modern tailoring, made to last."
|
|
173
|
+
linkLabel="Discover the label"
|
|
174
|
+
linkHref={SELF_HASH}
|
|
175
|
+
/>
|
|
176
|
+
}
|
|
177
|
+
/>
|
|
178
|
+
<TopNavItem label="Sale" href={SELF_HASH} />
|
|
179
|
+
<TopNavItem label="Service" href={SELF_HASH} />
|
|
180
|
+
</>
|
|
181
|
+
}
|
|
182
|
+
endContent={
|
|
183
|
+
<>
|
|
184
|
+
<IconButton
|
|
185
|
+
label="Search products"
|
|
186
|
+
tooltip="Search"
|
|
187
|
+
variant="ghost"
|
|
188
|
+
icon={<Icon icon={Search} size="sm" />}
|
|
189
|
+
/>
|
|
190
|
+
{!isCompact && <Button label="Sign in" variant="ghost" />}
|
|
191
|
+
<Button
|
|
192
|
+
label="Checkout"
|
|
193
|
+
variant="primary"
|
|
194
|
+
tooltip="Cart, 3 items"
|
|
195
|
+
icon={<Icon icon={ShoppingCart} size="sm" />}
|
|
196
|
+
endContent={<Badge label={3} />}
|
|
197
|
+
/>
|
|
198
|
+
</>
|
|
199
|
+
}
|
|
200
|
+
/>
|
|
201
|
+
}
|
|
202
|
+
>
|
|
203
|
+
<Center axis="horizontal">
|
|
204
|
+
<Section variant="transparent" maxWidth={CONTENT_MAX_WIDTH} width="100%" padding={0}>
|
|
205
|
+
<VStack gap={10}>
|
|
206
|
+
{/* Skeleton shelves only — the routed collection supplies the h1. */}
|
|
207
|
+
<Card variant="muted" padding={0} width="100%" height={360} />
|
|
219
208
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
</VStack>
|
|
239
|
-
))}
|
|
240
|
-
</Grid>
|
|
241
|
-
</VStack>
|
|
242
|
-
))}
|
|
243
|
-
</VStack>
|
|
244
|
-
</Section>
|
|
245
|
-
</Center>
|
|
246
|
-
</AppShell>
|
|
247
|
-
);
|
|
209
|
+
{SHELVES.map((shelf) => (
|
|
210
|
+
<VStack key={shelf} gap={4}>
|
|
211
|
+
<Card variant="muted" padding={0} width={200} height={24} />
|
|
212
|
+
<Grid columns={{ minWidth: 160, repeat: "fit" }} gap={4}>
|
|
213
|
+
{CATEGORY_TILES.map((tile) => (
|
|
214
|
+
<VStack key={tile} gap={2}>
|
|
215
|
+
<Card variant="muted" padding={0} width="100%" height={120} />
|
|
216
|
+
<Card variant="muted" padding={0} width="60%" height={14} />
|
|
217
|
+
</VStack>
|
|
218
|
+
))}
|
|
219
|
+
</Grid>
|
|
220
|
+
</VStack>
|
|
221
|
+
))}
|
|
222
|
+
</VStack>
|
|
223
|
+
</Section>
|
|
224
|
+
</Center>
|
|
225
|
+
</AppShell>
|
|
226
|
+
);
|
|
248
227
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export default {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
type: "page",
|
|
3
|
+
name: "Side Gallery",
|
|
4
|
+
description: "Headline, CTA, and image collage side by side",
|
|
5
|
+
keywords: ["gallery", "sidebar", "collection", "grid", "art", "images"],
|
|
6
|
+
category: "marketing",
|
|
6
7
|
};
|