@astryxdesign/cli 0.1.1 → 0.1.2-canary.2149fa3

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.
Files changed (113) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/docs/theme.doc.mjs +2 -2
  3. package/docs/working-with-ai.doc.mjs +6 -6
  4. package/package.json +19 -8
  5. package/src/api/discover.mjs +78 -26
  6. package/src/api/index.mjs +1 -0
  7. package/src/api/layout.mjs +301 -0
  8. package/src/api/layout.test.mjs +238 -0
  9. package/src/api/template.mjs +191 -50
  10. package/src/api/template.test.mjs +2 -0
  11. package/src/api/theme-add.mjs +182 -0
  12. package/src/codemods/__tests__/registry.test.mjs +1 -0
  13. package/src/codemods/registry.mjs +1 -0
  14. package/src/codemods/transforms/v0.1.2/__tests__/rename-text-color-active-to-accent.test.mjs +120 -0
  15. package/src/codemods/transforms/v0.1.2/index.mjs +19 -0
  16. package/src/codemods/transforms/v0.1.2/rename-text-color-active-to-accent.mjs +136 -0
  17. package/src/commands/build-theme.import-path.test.mjs +22 -2
  18. package/src/commands/build-theme.mjs +185 -16
  19. package/src/commands/gap-report.mjs +17 -9
  20. package/src/commands/gap-report.test.mjs +21 -16
  21. package/src/commands/init.mjs +34 -8
  22. package/src/commands/init.next-steps.test.mjs +46 -0
  23. package/src/commands/layout.mjs +139 -0
  24. package/src/commands/swizzle.mjs +51 -23
  25. package/src/commands/upgrade.mjs +2 -71
  26. package/src/config.mjs +31 -0
  27. package/src/config.test.mjs +24 -0
  28. package/src/index.mjs +6 -0
  29. package/src/lib/config-schema.mjs +119 -0
  30. package/src/lib/config.mjs +34 -7
  31. package/src/lib/config.test.mjs +51 -2
  32. package/src/lib/error-codes.mjs +11 -0
  33. package/src/lib/integrations.mjs +155 -0
  34. package/src/lib/integrations.test.mjs +154 -0
  35. package/src/lib/levenshtein.mjs +29 -0
  36. package/src/lib/manifest.mjs +10 -0
  37. package/src/lib/package-scanner.mjs +31 -7
  38. package/src/lib/string-utils.mjs +5 -14
  39. package/src/lib/xle/browser.d.ts +100 -0
  40. package/src/lib/xle/browser.mjs +120 -0
  41. package/src/lib/xle/expand.mjs +622 -0
  42. package/src/lib/xle/parse.mjs +581 -0
  43. package/src/lib/xle/print.mjs +174 -0
  44. package/src/lib/xle/registry-core.mjs +170 -0
  45. package/src/lib/xle/registry.mjs +237 -0
  46. package/src/lib/xle/splice.mjs +137 -0
  47. package/src/lib/xle/validate.mjs +356 -0
  48. package/src/lib/xle/xle.test.mjs +333 -0
  49. package/src/types/config.d.ts +99 -0
  50. package/src/utils/github.mjs +12 -27
  51. package/templates/blocks/components/Card/ClickableCardWithNestedButton.doc.mjs +1 -1
  52. package/templates/blocks/components/Card/SelectableCardMulti.doc.mjs +1 -1
  53. package/templates/blocks/components/ChatComposerDrawer/ChatComposerDrawerWithProgress.tsx +1 -1
  54. package/templates/blocks/components/ChatDictationButton/ChatDictationButtonShowcase.tsx +3 -3
  55. package/templates/blocks/components/CommandPaletteEmpty/CommandPaletteEmptyShowcase.doc.mjs +15 -0
  56. package/templates/blocks/components/CommandPaletteEmpty/CommandPaletteEmptyShowcase.tsx +26 -0
  57. package/templates/blocks/components/DateInput/DateInputDateRange.doc.mjs +2 -2
  58. package/templates/blocks/components/FileInput/FileInputShowcase.tsx +4 -2
  59. package/templates/blocks/components/LinkProvider/LinkProviderCustomLink.doc.mjs +14 -0
  60. package/templates/blocks/components/LinkProvider/LinkProviderCustomLink.tsx +43 -0
  61. package/templates/blocks/components/MultiSelector/MultiSelectorShowcase.tsx +6 -2
  62. package/templates/blocks/components/NumberInput/NumberInputShowcase.tsx +6 -2
  63. package/templates/blocks/components/Outline/OutlineShowcase.doc.mjs +15 -0
  64. package/templates/blocks/components/Outline/OutlineShowcase.tsx +22 -0
  65. package/templates/blocks/components/RadioList/RadioListShowcase.tsx +8 -1
  66. package/templates/blocks/components/SegmentedControl/SegmentedControlShowcase.tsx +3 -1
  67. package/templates/blocks/components/Selector/SelectorShowcase.tsx +4 -1
  68. package/templates/blocks/components/Slider/SliderShowcase.tsx +10 -1
  69. package/templates/blocks/components/Tab/TabShowcase.tsx +3 -1
  70. package/templates/blocks/components/TabList/TabListShowcase.tsx +3 -1
  71. package/templates/blocks/components/TabMenu/TabMenuShowcase.tsx +3 -1
  72. package/templates/blocks/components/Table/ColumnResizeHookUsage.doc.mjs +14 -0
  73. package/templates/blocks/components/Table/ColumnResizeHookUsage.tsx +59 -0
  74. package/templates/blocks/components/Table/StickyColumnsHookUsage.doc.mjs +14 -0
  75. package/templates/blocks/components/Table/StickyColumnsHookUsage.tsx +104 -0
  76. package/templates/blocks/components/Text/TextColors.tsx +20 -5
  77. package/templates/blocks/components/TextArea/TextAreaShowcase.tsx +4 -2
  78. package/templates/blocks/components/TextInput/TextInputShowcase.tsx +4 -2
  79. package/templates/blocks/components/Thumbnail/ThumbnailDisabled.tsx +11 -6
  80. package/templates/blocks/components/Thumbnail/ThumbnailGallery.tsx +43 -7
  81. package/templates/blocks/components/Thumbnail/ThumbnailRemovable.tsx +40 -3
  82. package/templates/blocks/components/Thumbnail/ThumbnailShowcase.tsx +6 -5
  83. package/templates/blocks/components/Thumbnail/ThumbnailStates.tsx +11 -6
  84. package/templates/blocks/components/Timestamp/TimestampColors.tsx +2 -2
  85. package/templates/blocks/components/ToggleButton/ToggleButtonGroup.doc.mjs +1 -1
  86. package/templates/blocks/components/Tokenizer/TokenizerShowcase.tsx +8 -6
  87. package/templates/blocks/components/Toolbar/ToolbarTableFilter.doc.mjs +2 -2
  88. package/templates/blocks/components/Toolbar/ToolbarTableFilter.tsx +23 -14
  89. package/templates/blocks/components/Typeahead/TypeaheadShowcase.tsx +6 -2
  90. package/templates/pages/shell-nav/page.tsx +321 -0
  91. package/templates/pages/shell-nav/template.doc.mjs +12 -0
  92. package/templates/pages/shell-side-nav/page.tsx +242 -0
  93. package/templates/pages/shell-side-nav/template.doc.mjs +12 -0
  94. package/templates/pages/shell-top-nav/page.tsx +224 -0
  95. package/templates/pages/shell-top-nav/template.doc.mjs +12 -0
  96. package/templates/pages/theme-showcase/page.tsx +8 -19
  97. package/templates/themes/butter/butterTheme.ts +916 -0
  98. package/templates/themes/butter/icons.tsx +77 -0
  99. package/templates/themes/chocolate/chocolateTheme.ts +230 -0
  100. package/templates/themes/chocolate/icons.tsx +77 -0
  101. package/templates/themes/gothic/gothicTheme.ts +657 -0
  102. package/templates/themes/gothic/icons.tsx +77 -0
  103. package/templates/themes/manifest.json +90 -0
  104. package/templates/themes/matcha/icons.tsx +67 -0
  105. package/templates/themes/matcha/matchaTheme.ts +247 -0
  106. package/templates/themes/neutral/icons.tsx +77 -0
  107. package/templates/themes/neutral/neutralTheme.ts +603 -0
  108. package/templates/themes/stone/icons.tsx +77 -0
  109. package/templates/themes/stone/stoneTheme.ts +652 -0
  110. package/templates/themes/y2k/icons.tsx +67 -0
  111. package/templates/themes/y2k/y2kTheme.ts +617 -0
  112. package/templates/blocks/components/MoreMenu/MoreMenuInToolbar.doc.mjs +0 -14
  113. package/templates/blocks/components/MoreMenu/MoreMenuInToolbar.tsx +0 -57
@@ -0,0 +1,242 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ import {useState} from 'react';
6
+ import {AppShell} from '@astryxdesign/core/AppShell';
7
+ import {Divider} from '@astryxdesign/core/Divider';
8
+ import {Layout, LayoutContent, LayoutFooter} from '@astryxdesign/core/Layout';
9
+ import {
10
+ SideNav,
11
+ SideNavHeading,
12
+ SideNavItem,
13
+ SideNavSection,
14
+ } from '@astryxdesign/core/SideNav';
15
+ import {NavIcon} from '@astryxdesign/core/NavIcon';
16
+ import {Icon} from '@astryxdesign/core/Icon';
17
+ import type {IconType} from '@astryxdesign/core/Icon';
18
+ import {MoreMenu} from '@astryxdesign/core/MoreMenu';
19
+ import {StatusDot} from '@astryxdesign/core/StatusDot';
20
+ import type {StatusDotVariant} from '@astryxdesign/core/StatusDot';
21
+ import {Card} from '@astryxdesign/core/Card';
22
+ import {Stack, VStack, HStack} from '@astryxdesign/core/Stack';
23
+ import {
24
+ SparklesIcon,
25
+ PlusIcon,
26
+ MagnifyingGlassIcon,
27
+ BookOpenIcon,
28
+ Cog6ToothIcon,
29
+ UserCircleIcon,
30
+ UserIcon,
31
+ BuildingOffice2Icon,
32
+ CodeBracketIcon,
33
+ } from '@heroicons/react/24/outline';
34
+
35
+ type Conversation = {
36
+ label: string;
37
+ status: StatusDotVariant;
38
+ statusLabel: string;
39
+ };
40
+
41
+ type Workspace = {
42
+ name: string;
43
+ icon: IconType;
44
+ chats: Conversation[];
45
+ };
46
+
47
+ const WORKSPACES: Workspace[] = [
48
+ {
49
+ name: 'Personal',
50
+ icon: UserIcon,
51
+ chats: [
52
+ {
53
+ label: 'Weekend trip planning',
54
+ status: 'success',
55
+ statusLabel: 'Active',
56
+ },
57
+ {
58
+ label: 'Recipe ideas for the week',
59
+ status: 'neutral',
60
+ statusLabel: 'Idle',
61
+ },
62
+ {
63
+ label: 'Book recommendations',
64
+ status: 'warning',
65
+ statusLabel: 'Needs review',
66
+ },
67
+ {label: 'Home workout plan', status: 'neutral', statusLabel: 'Idle'},
68
+ ],
69
+ },
70
+ {
71
+ name: 'Acme Corp',
72
+ icon: BuildingOffice2Icon,
73
+ chats: [
74
+ {label: 'Q3 roadmap draft', status: 'accent', statusLabel: 'In progress'},
75
+ {
76
+ label: 'Customer onboarding flow',
77
+ status: 'success',
78
+ statusLabel: 'Active',
79
+ },
80
+ {
81
+ label: 'Pricing strategy review',
82
+ status: 'warning',
83
+ statusLabel: 'Needs review',
84
+ },
85
+ {label: 'Standup summary', status: 'neutral', statusLabel: 'Idle'},
86
+ ],
87
+ },
88
+ {
89
+ name: 'Open Source',
90
+ icon: CodeBracketIcon,
91
+ chats: [
92
+ {
93
+ label: 'StyleX migration notes',
94
+ status: 'accent',
95
+ statusLabel: 'In progress',
96
+ },
97
+ {
98
+ label: 'Skeleton loading states',
99
+ status: 'success',
100
+ statusLabel: 'Active',
101
+ },
102
+ {label: 'Accessibility audit', status: 'error', statusLabel: 'Blocked'},
103
+ {label: 'Release notes v4.0', status: 'neutral', statusLabel: 'Idle'},
104
+ ],
105
+ },
106
+ ];
107
+
108
+ const SELECTED_CHAT = 'StyleX migration notes';
109
+
110
+ const MESSAGES = [
111
+ {role: 'assistant', width: '78%', height: 104},
112
+ {role: 'user', width: '48%', height: 48},
113
+ {role: 'assistant', width: '64%', height: 132},
114
+ {role: 'user', width: '38%', height: 40},
115
+ ];
116
+
117
+ function ConversationItem({
118
+ label,
119
+ status,
120
+ statusLabel,
121
+ isSelected,
122
+ }: {
123
+ label: string;
124
+ status: StatusDotVariant;
125
+ statusLabel: string;
126
+ isSelected?: boolean;
127
+ }) {
128
+ const [isHovered, setIsHovered] = useState(false);
129
+ const [isMenuOpen, setIsMenuOpen] = useState(false);
130
+ const showMenu = isHovered || isMenuOpen;
131
+
132
+ return (
133
+ <Stack
134
+ onMouseEnter={() => setIsHovered(true)}
135
+ onMouseLeave={() => setIsHovered(false)}>
136
+ <SideNavItem
137
+ label={label}
138
+ href="#"
139
+ isSelected={isSelected}
140
+ endContent={
141
+ showMenu ? (
142
+ <MoreMenu
143
+ size="sm"
144
+ label="Conversation options"
145
+ hasAutoFocus={false}
146
+ onOpenChange={setIsMenuOpen}
147
+ items={[
148
+ {label: 'Pin', onClick: () => {}},
149
+ {label: 'Rename', onClick: () => {}},
150
+ {label: 'Archive', onClick: () => {}},
151
+ {label: 'Delete', onClick: () => {}},
152
+ ]}
153
+ />
154
+ ) : (
155
+ <StatusDot variant={status} label={statusLabel} />
156
+ )
157
+ }
158
+ />
159
+ </Stack>
160
+ );
161
+ }
162
+
163
+ export default function ShellSideNav() {
164
+ return (
165
+ <AppShell
166
+ contentPadding={0}
167
+ sideNav={
168
+ <SideNav
169
+ collapsible
170
+ resizable={{defaultWidth: 300, minWidth: 220, maxWidth: 420}}
171
+ header={
172
+ <SideNavHeading
173
+ heading="AI Assistant"
174
+ icon={<NavIcon icon={<Icon icon={SparklesIcon} size="sm" />} />}
175
+ headingHref="#"
176
+ />
177
+ }
178
+ footer={
179
+ <SideNavSection title="Account" isHeaderHidden>
180
+ <SideNavItem label="Settings" icon={Cog6ToothIcon} href="#" />
181
+ <SideNavItem label="Sarah Chen" icon={UserCircleIcon} href="#" />
182
+ </SideNavSection>
183
+ }>
184
+ <SideNavSection title="Menu" isHeaderHidden>
185
+ <SideNavItem label="New chat" icon={PlusIcon} href="#" />
186
+ <SideNavItem label="Search" icon={MagnifyingGlassIcon} href="#" />
187
+ <SideNavItem label="Library" icon={BookOpenIcon} href="#" />
188
+ </SideNavSection>
189
+ <Divider />
190
+ <SideNavSection title="Workspaces" isHeaderHidden>
191
+ {WORKSPACES.map(workspace => (
192
+ <SideNavItem
193
+ key={workspace.name}
194
+ label={workspace.name}
195
+ icon={workspace.icon}
196
+ collapsible={{defaultIsCollapsed: false}}>
197
+ <VStack gap={0.5}>
198
+ {workspace.chats.map(chat => (
199
+ <ConversationItem
200
+ key={chat.label}
201
+ label={chat.label}
202
+ status={chat.status}
203
+ statusLabel={chat.statusLabel}
204
+ isSelected={chat.label === SELECTED_CHAT}
205
+ />
206
+ ))}
207
+ </VStack>
208
+ </SideNavItem>
209
+ ))}
210
+ </SideNavSection>
211
+ </SideNav>
212
+ }>
213
+ <Layout
214
+ height="fill"
215
+ contentWidth={768}
216
+ content={
217
+ <LayoutContent padding={6}>
218
+ <VStack gap={5}>
219
+ {MESSAGES.map((message, mi) => (
220
+ <HStack
221
+ key={mi}
222
+ hAlign={message.role === 'assistant' ? 'start' : 'end'}>
223
+ <Card
224
+ variant="muted"
225
+ padding={0}
226
+ width={message.width}
227
+ height={message.height}
228
+ />
229
+ </HStack>
230
+ ))}
231
+ </VStack>
232
+ </LayoutContent>
233
+ }
234
+ footer={
235
+ <LayoutFooter>
236
+ <Card variant="muted" padding={0} width="100%" height={56} />
237
+ </LayoutFooter>
238
+ }
239
+ />
240
+ </AppShell>
241
+ );
242
+ }
@@ -0,0 +1,12 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /** @type {import('../../../../core/src/docs-types').TemplateDoc} */
4
+ export const doc = {
5
+ type: 'page',
6
+ name: 'Side Nav',
7
+ displayName: 'Side Nav',
8
+ description:
9
+ 'A side-nav app shell with a collapsible, resizable SideNav (new chat, search, library, and workspace-grouped conversations with status dots) over static grey-card conversation and composer placeholders.',
10
+ isReady: true,
11
+ category: 'Shell - Left Sidebar',
12
+ };
@@ -0,0 +1,224 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ import * as stylex from '@stylexjs/stylex';
6
+ import {AppShell} from '@astryxdesign/core/AppShell';
7
+ import {
8
+ TopNav,
9
+ TopNavHeading,
10
+ TopNavItem,
11
+ TopNavMegaMenu,
12
+ TopNavMegaMenuItem,
13
+ TopNavMegaMenuFeaturedCard,
14
+ } from '@astryxdesign/core/TopNav';
15
+ import {NavIcon} from '@astryxdesign/core/NavIcon';
16
+ import {Icon} from '@astryxdesign/core/Icon';
17
+ import type {IconType} from '@astryxdesign/core/Icon';
18
+ import {IconButton} from '@astryxdesign/core/IconButton';
19
+ import {Button} from '@astryxdesign/core/Button';
20
+ import {Badge} from '@astryxdesign/core/Badge';
21
+ import {Card} from '@astryxdesign/core/Card';
22
+ import {Grid} from '@astryxdesign/core/Grid';
23
+ import {Stack, VStack} from '@astryxdesign/core/Stack';
24
+ import {
25
+ ShoppingBagIcon,
26
+ ShoppingCartIcon,
27
+ MagnifyingGlassIcon,
28
+ SparklesIcon,
29
+ SwatchIcon,
30
+ TagIcon,
31
+ HomeModernIcon,
32
+ FaceSmileIcon,
33
+ ReceiptPercentIcon,
34
+ GiftIcon,
35
+ CloudIcon,
36
+ BoltIcon,
37
+ SunIcon,
38
+ StarIcon,
39
+ FireIcon,
40
+ GlobeAltIcon,
41
+ MoonIcon,
42
+ } from '@heroicons/react/24/outline';
43
+
44
+ const styles = stylex.create({
45
+ // Cap + center the page body so wide screens show whitespace gutters.
46
+ contentMax: {maxWidth: 1100, marginInline: 'auto'},
47
+ // Lock both mega-menu panels to an identical size. Without this, Shop and
48
+ // Brands size to their own content (different widths); since both anchor to
49
+ // the centered nav, switching between them resizes the panel — which reads
50
+ // as flashing/jumping. Fixed item + featured widths make the panels
51
+ // pixel-identical so the transition is seamless.
52
+ megaItems: {gridColumn: '1 / -1', width: 520},
53
+ megaFeatured: {width: 240},
54
+ });
55
+
56
+ type MegaItem = {name: string; tagline: string; icon: IconType};
57
+
58
+ // Shop and Brands each render 8 items — the mega menu's built-in 2-column grid
59
+ // lays them out as 2 columns × 4 rows, alongside a featured card.
60
+ const SHOP_ITEMS: MegaItem[] = [
61
+ {name: 'New Arrivals', tagline: 'The latest drops', icon: SparklesIcon},
62
+ {name: 'Womenswear', tagline: 'Dresses, knitwear & more', icon: SwatchIcon},
63
+ {name: 'Menswear', tagline: 'Shirts, tailoring & more', icon: TagIcon},
64
+ {name: 'Home', tagline: 'Bedding, lighting & décor', icon: HomeModernIcon},
65
+ {
66
+ name: 'Beauty',
67
+ tagline: 'Skincare, fragrance & makeup',
68
+ icon: FaceSmileIcon,
69
+ },
70
+ {
71
+ name: 'Accessories',
72
+ tagline: 'Bags, hats & sunglasses',
73
+ icon: ShoppingBagIcon,
74
+ },
75
+ {name: 'Sale', tagline: 'Up to 50% off', icon: ReceiptPercentIcon},
76
+ {name: 'Gift Cards', tagline: 'The perfect present', icon: GiftIcon},
77
+ ];
78
+
79
+ const BRAND_ITEMS: MegaItem[] = [
80
+ {name: 'Aether', tagline: 'Performance essentials', icon: SparklesIcon},
81
+ {name: 'Northwind', tagline: 'Outdoor & technical', icon: CloudIcon},
82
+ {name: 'Loomwell', tagline: 'Everyday knitwear', icon: BoltIcon},
83
+ {name: 'Verdant', tagline: 'Sustainable basics', icon: SunIcon},
84
+ {name: 'Studio Mara', tagline: 'Modern tailoring', icon: StarIcon},
85
+ {name: 'Atelier Kos', tagline: 'Limited ateliers', icon: FireIcon},
86
+ {name: 'Rue & Co', tagline: 'City streetwear', icon: GlobeAltIcon},
87
+ {name: 'Halden', tagline: 'Minimal staples', icon: MoonIcon},
88
+ ];
89
+
90
+ const CATEGORY_TILES = [
91
+ 'New Arrivals',
92
+ 'Womenswear',
93
+ 'Menswear',
94
+ 'Home & Living',
95
+ 'Beauty',
96
+ 'Accessories',
97
+ ];
98
+
99
+ // Wraps the 8 items in a fixed-width 2-column grid so every mega menu's item
100
+ // area is exactly the same width regardless of its content.
101
+ function MegaItems({items}: {items: MegaItem[]}) {
102
+ return (
103
+ <Stack xstyle={styles.megaItems}>
104
+ <Grid columns={2} gap={2}>
105
+ {items.map(item => (
106
+ <TopNavMegaMenuItem
107
+ key={item.name}
108
+ title={item.name}
109
+ description={item.tagline}
110
+ icon={<Icon icon={item.icon} size="md" color="secondary" />}
111
+ href="#"
112
+ />
113
+ ))}
114
+ </Grid>
115
+ </Stack>
116
+ );
117
+ }
118
+
119
+ // Pins the featured card to a fixed width so both panels match exactly.
120
+ function MegaFeatured(props: {
121
+ title: string;
122
+ description: string;
123
+ image: string;
124
+ imageAlt: string;
125
+ linkLabel: string;
126
+ linkHref: string;
127
+ }) {
128
+ return (
129
+ <Stack xstyle={styles.megaFeatured}>
130
+ <TopNavMegaMenuFeaturedCard {...props} />
131
+ </Stack>
132
+ );
133
+ }
134
+
135
+ export default function ShellTopNav() {
136
+ return (
137
+ <AppShell
138
+ variant="surface"
139
+ contentPadding={6}
140
+ topNav={
141
+ <TopNav
142
+ label="Lumen storefront navigation"
143
+ heading={
144
+ <TopNavHeading
145
+ heading="Lumen"
146
+ logo={
147
+ <NavIcon icon={<Icon icon={ShoppingBagIcon} size="sm" />} />
148
+ }
149
+ href="#"
150
+ />
151
+ }
152
+ centerContent={
153
+ <>
154
+ <TopNavMegaMenu
155
+ label="Shop"
156
+ items={<MegaItems items={SHOP_ITEMS} />}
157
+ featured={
158
+ <MegaFeatured
159
+ title="The Autumn Edit"
160
+ description="Layering staples in warm, earthy tones."
161
+ image="https://lookaside.facebook.com/assets/astryx/texture-beige-horizontal-1.png"
162
+ imageAlt="Autumn collection lookbook"
163
+ linkLabel="Shop the edit"
164
+ linkHref="#autumn-edit"
165
+ />
166
+ }
167
+ />
168
+ <TopNavMegaMenu
169
+ label="Brands"
170
+ items={<MegaItems items={BRAND_ITEMS} />}
171
+ featured={
172
+ <MegaFeatured
173
+ title="Meet Studio Mara"
174
+ description="Modern tailoring, made to last."
175
+ image="https://lookaside.facebook.com/assets/astryx/texture-beige-horizontal-2.png"
176
+ imageAlt="Studio Mara lookbook"
177
+ linkLabel="Discover the label"
178
+ linkHref="#studio-mara"
179
+ />
180
+ }
181
+ />
182
+ <TopNavItem label="Sale" href="#" />
183
+ <TopNavItem label="Service" href="#" />
184
+ </>
185
+ }
186
+ endContent={
187
+ <>
188
+ <IconButton
189
+ label="Search products"
190
+ tooltip="Search"
191
+ variant="ghost"
192
+ icon={<Icon icon={MagnifyingGlassIcon} size="sm" />}
193
+ />
194
+ <Button label="Sign in" variant="ghost" />
195
+ <Button
196
+ label="Checkout"
197
+ variant="primary"
198
+ icon={<Icon icon={ShoppingCartIcon} size="sm" />}
199
+ endContent={<Badge label={3} />}
200
+ />
201
+ </>
202
+ }
203
+ />
204
+ }>
205
+ <VStack gap={10} xstyle={styles.contentMax}>
206
+ <Card variant="muted" padding={0} width="100%" height={360} />
207
+
208
+ {[0, 1, 2].map(section => (
209
+ <VStack key={section} gap={4}>
210
+ <Card variant="muted" padding={0} width={200} height={24} />
211
+ <Grid minChildWidth={160} gap={4}>
212
+ {CATEGORY_TILES.map(tile => (
213
+ <VStack key={tile} gap={2}>
214
+ <Card variant="muted" padding={0} width="100%" height={120} />
215
+ <Card variant="muted" padding={0} width="60%" height={14} />
216
+ </VStack>
217
+ ))}
218
+ </Grid>
219
+ </VStack>
220
+ ))}
221
+ </VStack>
222
+ </AppShell>
223
+ );
224
+ }
@@ -0,0 +1,12 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /** @type {import('../../../../core/src/docs-types').TemplateDoc} */
4
+ export const doc = {
5
+ type: 'page',
6
+ name: 'Top Nav',
7
+ displayName: 'Top Nav',
8
+ description:
9
+ 'A top-nav app shell with a centered TopNav (Shop and Brands mega menus with a 2x4 item grid plus a featured card each, Sale/Service links, and a Checkout button) over static grey-card hero and category sections.',
10
+ isReady: true,
11
+ category: 'Shell - Top Nav',
12
+ };
@@ -143,12 +143,6 @@ const styles: Record<string, CSSProperties> = {
143
143
  textAlign: 'center' as const,
144
144
  maxWidth: 560,
145
145
  },
146
- // Hero headline painted with the theme's accent-text ink. Text has no
147
- // 'accent' color value, so we set the dedicated --color-text-accent token
148
- // directly (distinct from --color-accent / the 'active' color).
149
- heroHeadline: {
150
- color: 'var(--color-text-accent)',
151
- },
152
146
  centerText: {
153
147
  textAlign: 'center',
154
148
  },
@@ -438,7 +432,7 @@ function StorePreview({
438
432
  <VStack gap={10} style={{...styles.content, ...styles.contentFluid}}>
439
433
  <Center>
440
434
  <VStack gap={4} hAlign="center" style={styles.heroText}>
441
- <Text type="display-2" style={styles.heroHeadline}>
435
+ <Text type="display-2" color="accent">
442
436
  Little joys,
443
437
  <br />
444
438
  everywhere you go
@@ -462,10 +456,7 @@ function StorePreview({
462
456
  />
463
457
  </AspectRatio>
464
458
  <div style={inlineStyles.cardBody}>
465
- <VStack
466
- gap={2}
467
- hAlign="center"
468
- style={styles.cardStack}>
459
+ <VStack gap={2} hAlign="center" style={styles.cardStack}>
469
460
  <HStack>
470
461
  <Badge label={p.badge} variant={p.badgeVariant} />
471
462
  </HStack>
@@ -475,7 +466,10 @@ function StorePreview({
475
466
  <Text
476
467
  type="supporting"
477
468
  color="secondary"
478
- style={{...styles.cardDescription, ...styles.centerText}}>
469
+ style={{
470
+ ...styles.cardDescription,
471
+ ...styles.centerText,
472
+ }}>
479
473
  {p.description}
480
474
  </Text>
481
475
  <HStack gap={2} vAlign="center" hAlign="center">
@@ -746,9 +740,7 @@ function ChatCard() {
746
740
 
747
741
  <ChatMessage sender="assistant">
748
742
  <VStack gap={3}>
749
- <Text type="body">
750
- Here’s everything I have on order #1043:
751
- </Text>
743
+ <Text type="body">Here’s everything I have on order #1043:</Text>
752
744
  <Card padding={3}>
753
745
  <VStack gap={1}>
754
746
  <Item
@@ -1107,10 +1099,7 @@ function InventoryCard({
1107
1099
  ).length;
1108
1100
  return (
1109
1101
  <Card padding={0} style={styles.inventoryCard}>
1110
- <HStack
1111
- hAlign="between"
1112
- vAlign="center"
1113
- style={styles.inventoryHeader}>
1102
+ <HStack hAlign="between" vAlign="center" style={styles.inventoryHeader}>
1114
1103
  <Heading level={2}>Inventory</Heading>
1115
1104
  <Button
1116
1105
  label="Add item"