@astryxdesign/cli 0.1.2 → 0.1.3

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 (238) hide show
  1. package/CHANGELOG.md +64 -1
  2. package/README.md +49 -55
  3. package/docs/layout.doc.dense.mjs +90 -0
  4. package/docs/layout.doc.mjs +160 -0
  5. package/docs/principles.doc.dense.mjs +2 -2
  6. package/docs/principles.doc.mjs +4 -0
  7. package/docs/principles.doc.zh.mjs +2 -2
  8. package/docs/theme.doc.mjs +2 -2
  9. package/package.json +13 -1
  10. package/src/api/blog.mjs +192 -0
  11. package/src/api/blog.test.mjs +144 -0
  12. package/src/api/component.mjs +253 -12
  13. package/src/api/discover.mjs +14 -7
  14. package/src/api/doctor.mjs +10 -25
  15. package/src/api/index.mjs +1 -0
  16. package/src/api/layout.mjs +11 -10
  17. package/src/api/layout.test.mjs +4 -1
  18. package/src/api/template-integration.test.mjs +225 -0
  19. package/src/api/template.mjs +242 -84
  20. package/src/api/validate-integration.mjs +370 -0
  21. package/src/api/validate-integration.test.mjs +222 -0
  22. package/src/codemod.mjs +93 -0
  23. package/src/codemod.test.mjs +134 -0
  24. package/src/codemods/__tests__/registry.test.mjs +1 -0
  25. package/src/codemods/__tests__/runner.test.mjs +103 -0
  26. package/src/codemods/integration-discovery.mjs +168 -0
  27. package/src/codemods/integration-discovery.test.mjs +234 -0
  28. package/src/codemods/integration-runner.mjs +109 -0
  29. package/src/codemods/registry.mjs +1 -0
  30. package/src/codemods/run-codemod.mjs +207 -0
  31. package/src/codemods/runner.mjs +73 -96
  32. package/src/codemods/transforms/v0.0.15/index.mjs +0 -13
  33. package/src/codemods/transforms/v0.1.0/__tests__/migrate-xds-css-surfaces.test.mjs +67 -0
  34. package/src/codemods/transforms/v0.1.0/__tests__/migrate-xds-declare-module.test.mjs +61 -0
  35. package/src/codemods/transforms/v0.1.0/__tests__/v0.1.0-ordering.test.mjs +104 -0
  36. package/src/codemods/transforms/{v0.0.15 → v0.1.0}/drop-xds-prefix-imports.mjs +15 -4
  37. package/src/codemods/transforms/v0.1.0/index.mjs +43 -6
  38. package/src/codemods/transforms/v0.1.0/migrate-xds-css-surfaces.mjs +77 -0
  39. package/src/codemods/transforms/v0.1.0/migrate-xds-declare-module.mjs +78 -0
  40. package/src/codemods/transforms/v0.1.3/__tests__/migrate-layout-components-to-experimental.test.mjs +360 -0
  41. package/src/codemods/transforms/v0.1.3/index.mjs +19 -0
  42. package/src/codemods/transforms/v0.1.3/migrate-layout-components-to-experimental.mjs +260 -0
  43. package/src/commands/agent-docs.mjs +4 -1
  44. package/src/commands/blog.mjs +60 -0
  45. package/src/commands/build-theme.import-path.test.mjs +2 -12
  46. package/src/commands/build-theme.mjs +117 -0
  47. package/src/commands/build-theme.prose.test.mjs +5 -15
  48. package/src/commands/build-theme.watch.test.mjs +149 -0
  49. package/src/commands/component/index.mjs +44 -10
  50. package/src/commands/component-ownership.test.mjs +227 -0
  51. package/src/commands/discover.mjs +5 -16
  52. package/src/commands/doctor.test.mjs +3 -3
  53. package/src/commands/ensure-core-built.mjs +120 -0
  54. package/src/commands/json-contract.test.mjs +0 -32
  55. package/src/commands/swizzle.mjs +224 -235
  56. package/src/commands/swizzle.path-safety.test.mjs +3 -3
  57. package/src/commands/swizzle.routing.test.mjs +279 -0
  58. package/src/commands/template.mjs +33 -37
  59. package/src/commands/upgrade.config-ordering.test.mjs +273 -0
  60. package/src/commands/upgrade.integration-policy.test.mjs +204 -0
  61. package/src/commands/upgrade.mjs +349 -170
  62. package/src/commands/validate-integration.mjs +110 -0
  63. package/src/commands/validate-integration.test.mjs +124 -0
  64. package/src/config.mjs +7 -20
  65. package/src/config.test.mjs +89 -13
  66. package/src/index.mjs +8 -3
  67. package/src/integration.mjs +19 -0
  68. package/src/lib/component-discovery.mjs +177 -0
  69. package/src/lib/config-cache.mjs +91 -0
  70. package/src/lib/config-cache.test.mjs +83 -0
  71. package/src/lib/config-schema.mjs +41 -55
  72. package/src/lib/error-codes.mjs +15 -12
  73. package/src/lib/integration-warnings.mjs +62 -0
  74. package/src/lib/integration-warnings.test.mjs +102 -0
  75. package/src/lib/integrations.mjs +92 -115
  76. package/src/lib/integrations.test.mjs +88 -107
  77. package/src/lib/manifest.mjs +5 -2
  78. package/src/lib/module-loader.mjs +80 -0
  79. package/src/lib/module-loader.test.mjs +106 -0
  80. package/src/lib/project.mjs +502 -0
  81. package/src/lib/project.test.mjs +308 -0
  82. package/src/lib/site.mjs +20 -0
  83. package/src/template.mjs +73 -0
  84. package/src/template.test.mjs +127 -0
  85. package/src/types/api.d.ts +2 -6
  86. package/src/types/base.d.ts +3 -9
  87. package/src/types/codemod.d.ts +81 -0
  88. package/src/types/component.d.ts +27 -2
  89. package/src/types/config.d.ts +56 -85
  90. package/src/types/error-codes.d.ts +5 -3
  91. package/src/types/index.d.ts +0 -1
  92. package/src/types/integration.d.ts +29 -0
  93. package/src/types/swizzle.d.ts +9 -2
  94. package/src/types/template-api.d.ts +54 -0
  95. package/src/types/template.d.ts +10 -7
  96. package/src/types/upgrade.d.ts +29 -0
  97. package/src/types/validate-integration.d.ts +24 -0
  98. package/src/utils/github.mjs +0 -237
  99. package/src/utils/interactive.mjs +2 -2
  100. package/templates/blocks/components/AvatarStatusDot/AvatarStatusDotVariants.doc.mjs +14 -0
  101. package/templates/blocks/components/AvatarStatusDot/AvatarStatusDotVariants.tsx +28 -0
  102. package/templates/blocks/components/Blockquote/BlockquoteTestimonials.doc.mjs +14 -0
  103. package/templates/blocks/components/Blockquote/BlockquoteTestimonials.tsx +34 -0
  104. package/templates/blocks/components/Blockquote/BlockquoteWithCite.doc.mjs +14 -0
  105. package/templates/blocks/components/Blockquote/BlockquoteWithCite.tsx +21 -0
  106. package/templates/blocks/components/BreadcrumbItem/BreadcrumbItemBasic.doc.mjs +14 -0
  107. package/templates/blocks/components/BreadcrumbItem/BreadcrumbItemBasic.tsx +15 -0
  108. package/templates/blocks/components/ButtonGroup/ButtonGroupBasic.doc.mjs +14 -0
  109. package/templates/blocks/components/ButtonGroup/ButtonGroupBasic.tsx +16 -0
  110. package/templates/blocks/components/ChatDictationButton/ChatDictationButtonBasic.doc.mjs +19 -0
  111. package/templates/blocks/components/ChatDictationButton/ChatDictationButtonBasic.tsx +34 -0
  112. package/templates/blocks/components/CheckboxListItem/CheckboxListItemBasic.doc.mjs +14 -0
  113. package/templates/blocks/components/CheckboxListItem/CheckboxListItemBasic.tsx +30 -0
  114. package/templates/blocks/components/CollapsibleGroup/CollapsibleGroupAccordion.doc.mjs +14 -0
  115. package/templates/blocks/components/CollapsibleGroup/CollapsibleGroupAccordion.tsx +31 -0
  116. package/templates/blocks/components/CommandPaletteEmpty/CommandPaletteEmptyBasic.doc.mjs +14 -0
  117. package/templates/blocks/components/CommandPaletteEmpty/CommandPaletteEmptyBasic.tsx +26 -0
  118. package/templates/blocks/components/CommandPaletteFooter/CommandPaletteFooterBasic.doc.mjs +14 -0
  119. package/templates/blocks/components/CommandPaletteFooter/CommandPaletteFooterBasic.tsx +32 -0
  120. package/templates/blocks/components/CommandPaletteGroup/CommandPaletteGroupBasic.doc.mjs +18 -0
  121. package/templates/blocks/components/CommandPaletteGroup/CommandPaletteGroupBasic.tsx +32 -0
  122. package/templates/blocks/components/CommandPaletteItem/CommandPaletteItemBasic.doc.mjs +14 -0
  123. package/templates/blocks/components/CommandPaletteItem/CommandPaletteItemBasic.tsx +27 -0
  124. package/templates/blocks/components/ContextMenu/ContextMenuBasic.doc.mjs +14 -0
  125. package/templates/blocks/components/ContextMenu/ContextMenuBasic.tsx +32 -0
  126. package/templates/blocks/components/DateRangeInput/DateRangeInputWithPresets.doc.mjs +14 -0
  127. package/templates/blocks/components/DateRangeInput/DateRangeInputWithPresets.tsx +46 -0
  128. package/templates/blocks/components/DateRangeInput/DateRangeInputWithValidation.doc.mjs +14 -0
  129. package/templates/blocks/components/DateRangeInput/DateRangeInputWithValidation.tsx +52 -0
  130. package/templates/blocks/components/DateTimeInput/DateTimeInputWithValidation.doc.mjs +14 -0
  131. package/templates/blocks/components/DateTimeInput/DateTimeInputWithValidation.tsx +43 -0
  132. package/templates/blocks/components/DialogHeader/DialogHeaderBasic.doc.mjs +14 -0
  133. package/templates/blocks/components/DialogHeader/DialogHeaderBasic.tsx +30 -0
  134. package/templates/blocks/components/DropdownMenu/DropdownMenuShowcase.tsx +0 -6
  135. package/templates/blocks/components/DropdownMenuItem/DropdownMenuItemBasic.doc.mjs +14 -0
  136. package/templates/blocks/components/DropdownMenuItem/DropdownMenuItemBasic.tsx +27 -0
  137. package/templates/blocks/components/DropdownMenuItem/DropdownMenuItemShowcase.tsx +1 -5
  138. package/templates/blocks/components/FieldLabel/FieldLabelBasic.doc.mjs +14 -0
  139. package/templates/blocks/components/FieldLabel/FieldLabelBasic.tsx +20 -0
  140. package/templates/blocks/components/FieldStatus/FieldStatusBasic.doc.mjs +14 -0
  141. package/templates/blocks/components/FieldStatus/FieldStatusBasic.tsx +23 -0
  142. package/templates/blocks/components/FileInput/FileInputBasic.doc.mjs +14 -0
  143. package/templates/blocks/components/FileInput/FileInputBasic.tsx +22 -0
  144. package/templates/blocks/components/GridSpan/GridSpanColumns.doc.mjs +14 -0
  145. package/templates/blocks/components/GridSpan/GridSpanColumns.tsx +38 -0
  146. package/templates/blocks/components/HStack/HStackBasic.doc.mjs +14 -0
  147. package/templates/blocks/components/HStack/HStackBasic.tsx +16 -0
  148. package/templates/blocks/components/Hooks/useKeyboardHintHookUsage.doc.mjs +14 -0
  149. package/templates/blocks/components/Hooks/useKeyboardHintHookUsage.tsx +57 -0
  150. package/templates/blocks/components/HoverCard/HoverCardInteractiveContent.doc.mjs +1 -1
  151. package/templates/blocks/components/HoverCard/HoverCardInteractiveContent.tsx +9 -4
  152. package/templates/blocks/components/InputGroup/InputGroupBasic.doc.mjs +14 -0
  153. package/templates/blocks/components/InputGroup/InputGroupBasic.tsx +27 -0
  154. package/templates/blocks/components/LayoutContent/LayoutContentBasic.doc.mjs +23 -0
  155. package/templates/blocks/components/LayoutContent/LayoutContentBasic.tsx +40 -0
  156. package/templates/blocks/components/LayoutFooter/LayoutFooterActions.doc.mjs +22 -0
  157. package/templates/blocks/components/LayoutFooter/LayoutFooterActions.tsx +41 -0
  158. package/templates/blocks/components/LayoutHeader/LayoutHeaderWithActions.doc.mjs +23 -0
  159. package/templates/blocks/components/LayoutHeader/LayoutHeaderWithActions.tsx +40 -0
  160. package/templates/blocks/components/LayoutPanel/LayoutPanelNavigation.doc.mjs +22 -0
  161. package/templates/blocks/components/LayoutPanel/LayoutPanelNavigation.tsx +37 -0
  162. package/templates/blocks/components/Lightbox/LightboxGallery.doc.mjs +14 -0
  163. package/templates/blocks/components/Lightbox/LightboxGallery.tsx +53 -0
  164. package/templates/blocks/components/Lightbox/LightboxShowcase.tsx +4 -3
  165. package/templates/blocks/components/Lightbox/LightboxVideo.doc.mjs +14 -0
  166. package/templates/blocks/components/Lightbox/LightboxVideo.tsx +27 -0
  167. package/templates/blocks/components/Lightbox/LightboxZoom.doc.mjs +14 -0
  168. package/templates/blocks/components/Lightbox/LightboxZoom.tsx +33 -0
  169. package/templates/blocks/components/LinkProvider/LinkProviderCustomLink.doc.mjs +1 -1
  170. package/templates/blocks/components/MetadataListItem/MetadataListItemBasic.doc.mjs +14 -0
  171. package/templates/blocks/components/MetadataListItem/MetadataListItemBasic.tsx +19 -0
  172. package/templates/blocks/components/MobileNavToggle/MobileNavToggleBasic.doc.mjs +23 -0
  173. package/templates/blocks/components/MobileNavToggle/MobileNavToggleBasic.tsx +42 -0
  174. package/templates/blocks/components/MoreMenu/MoreMenuShowcase.tsx +0 -6
  175. package/templates/blocks/components/NavIcon/NavIconBasic.doc.mjs +14 -0
  176. package/templates/blocks/components/NavIcon/NavIconBasic.tsx +16 -0
  177. package/templates/blocks/components/RadioListItem/RadioListItemBasic.doc.mjs +14 -0
  178. package/templates/blocks/components/RadioListItem/RadioListItemBasic.tsx +30 -0
  179. package/templates/blocks/components/Resizable/ResizableSidebar.doc.mjs +25 -0
  180. package/templates/blocks/components/Resizable/ResizableSidebar.tsx +67 -0
  181. package/templates/blocks/components/SegmentedControlItem/SegmentedControlItemBasic.doc.mjs +14 -0
  182. package/templates/blocks/components/SegmentedControlItem/SegmentedControlItemBasic.tsx +21 -0
  183. package/templates/blocks/components/SelectorOption/SelectorOptionBasic.doc.mjs +14 -0
  184. package/templates/blocks/components/SelectorOption/SelectorOptionBasic.tsx +39 -0
  185. package/templates/blocks/components/SideNavCollapseButton/SideNavCollapseButtonBasic.doc.mjs +14 -0
  186. package/templates/blocks/components/SideNavCollapseButton/SideNavCollapseButtonBasic.tsx +55 -0
  187. package/templates/blocks/components/SideNavHeading/SideNavHeadingBasic.doc.mjs +14 -0
  188. package/templates/blocks/components/SideNavHeading/SideNavHeadingBasic.tsx +38 -0
  189. package/templates/blocks/components/SideNavItem/SideNavItemBasic.doc.mjs +14 -0
  190. package/templates/blocks/components/SideNavItem/SideNavItemBasic.tsx +49 -0
  191. package/templates/blocks/components/SideNavSection/SideNavSectionBasic.doc.mjs +14 -0
  192. package/templates/blocks/components/SideNavSection/SideNavSectionBasic.tsx +71 -0
  193. package/templates/blocks/components/StackItem/StackItemFill.doc.mjs +14 -0
  194. package/templates/blocks/components/StackItem/StackItemFill.tsx +28 -0
  195. package/templates/blocks/components/Tab/TabWithSelectedIcon.doc.mjs +13 -0
  196. package/templates/blocks/components/Tab/TabWithSelectedIcon.tsx +39 -0
  197. package/templates/blocks/components/TabMenu/TabMenuBasic.doc.mjs +14 -0
  198. package/templates/blocks/components/TabMenu/TabMenuBasic.tsx +23 -0
  199. package/templates/blocks/components/Table/StickyColumnsHookUsage.doc.mjs +1 -1
  200. package/templates/blocks/components/ToggleButtonGroup/ToggleButtonGroupVertical.doc.mjs +14 -0
  201. package/templates/blocks/components/ToggleButtonGroup/ToggleButtonGroupVertical.tsx +47 -0
  202. package/templates/blocks/components/TopNavHeading/TopNavHeadingBasic.doc.mjs +14 -0
  203. package/templates/blocks/components/TopNavHeading/TopNavHeadingBasic.tsx +22 -0
  204. package/templates/blocks/components/TopNavItem/TopNavItemBasic.doc.mjs +14 -0
  205. package/templates/blocks/components/TopNavItem/TopNavItemBasic.tsx +21 -0
  206. package/templates/blocks/components/TopNavMegaMenu/TopNavMegaMenuBasic.doc.mjs +20 -0
  207. package/templates/blocks/components/TopNavMegaMenu/TopNavMegaMenuBasic.tsx +46 -0
  208. package/templates/blocks/components/TopNavMegaMenuFeaturedCard/TopNavMegaMenuFeaturedCardBasic.doc.mjs +14 -0
  209. package/templates/blocks/components/TopNavMegaMenuFeaturedCard/TopNavMegaMenuFeaturedCardBasic.tsx +16 -0
  210. package/templates/blocks/components/TopNavMegaMenuItem/TopNavMegaMenuItemBasic.doc.mjs +14 -0
  211. package/templates/blocks/components/TopNavMegaMenuItem/TopNavMegaMenuItemBasic.tsx +26 -0
  212. package/templates/blocks/components/TopNavMenu/TopNavMenuBasic.doc.mjs +14 -0
  213. package/templates/blocks/components/TopNavMenu/TopNavMenuBasic.tsx +43 -0
  214. package/templates/blocks/components/TypeaheadItem/TypeaheadItemBasic.doc.mjs +14 -0
  215. package/templates/blocks/components/TypeaheadItem/TypeaheadItemBasic.tsx +43 -0
  216. package/templates/blocks/components/VStack/VStackBasic.doc.mjs +14 -0
  217. package/templates/blocks/components/VStack/VStackBasic.tsx +20 -0
  218. package/templates/pages/kanban-board/page.tsx +729 -0
  219. package/templates/pages/kanban-board/template.doc.mjs +12 -0
  220. package/templates/pages/shell-nav/page.tsx +321 -0
  221. package/templates/pages/shell-nav/template.doc.mjs +12 -0
  222. package/templates/pages/shell-side-nav/page.tsx +241 -0
  223. package/templates/pages/shell-side-nav/template.doc.mjs +12 -0
  224. package/templates/pages/shell-top-nav/page.tsx +224 -0
  225. package/templates/pages/shell-top-nav/template.doc.mjs +12 -0
  226. package/src/codemods/transforms/v0.1.0/__tests__/migrate-xds-config-surfaces.test.mjs +0 -116
  227. package/src/codemods/transforms/v0.1.0/migrate-xds-config-surfaces.mjs +0 -230
  228. package/src/commands/gap-report.mjs +0 -464
  229. package/src/commands/gap-report.test.mjs +0 -168
  230. package/src/commands/swizzle-gap-safety.test.mjs +0 -273
  231. package/src/lib/config.mjs +0 -113
  232. package/src/lib/config.test.mjs +0 -91
  233. package/src/types/gap-report.d.ts +0 -29
  234. package/templates/blocks/components/TreeListBranches/TreeListBranchesShowcase.doc.mjs +0 -14
  235. package/templates/blocks/components/TreeListBranches/TreeListBranchesShowcase.tsx +0 -64
  236. package/templates/blocks/components/TreeListItem/TreeListItemShowcase.doc.mjs +0 -14
  237. package/templates/blocks/components/TreeListItem/TreeListItemShowcase.tsx +0 -60
  238. /package/src/codemods/transforms/{v0.0.15 → v0.1.0}/__tests__/drop-xds-prefix-imports.test.mjs +0 -0
@@ -0,0 +1,19 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ import {MetadataList, MetadataListItem} from '@astryxdesign/core/MetadataList';
6
+ import {Badge} from '@astryxdesign/core/Badge';
7
+
8
+ export default function MetadataListItemBasic() {
9
+ return (
10
+ <MetadataList title="Deployment">
11
+ <MetadataListItem label="Environment">Production</MetadataListItem>
12
+ <MetadataListItem label="Status">
13
+ <Badge label="Healthy" variant="green" />
14
+ </MetadataListItem>
15
+ <MetadataListItem label="Version">v2.14.0</MetadataListItem>
16
+ <MetadataListItem label="Last deployed">June 12, 2026</MetadataListItem>
17
+ </MetadataList>
18
+ );
19
+ }
@@ -0,0 +1,23 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /** @type {import('../../../../../core/src/docs-types').TemplateDoc} */
4
+ export const doc = {
5
+ type: 'block',
6
+ exampleFor: 'MobileNavToggle',
7
+ name: 'MobileNavToggle — Basic',
8
+ displayName: 'MobileNavToggle — Basic',
9
+ description:
10
+ 'A nav toggle with a custom icon and accessible label instead of the default hamburger. It opens a MobileNav drawer via the AppShell mobile context, which AppShell provides automatically.',
11
+ isReady: true,
12
+ aspectRatio: 16 / 9,
13
+ componentsUsed: [
14
+ 'MobileNav',
15
+ 'MobileNavToggle',
16
+ 'AppShell',
17
+ 'SideNavItem',
18
+ 'SideNavSection',
19
+ 'Icon',
20
+ 'HStack',
21
+ 'Text',
22
+ ],
23
+ };
@@ -0,0 +1,42 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ import {useState} from 'react';
6
+ import {MobileNav, MobileNavToggle} from '@astryxdesign/core/MobileNav';
7
+ import {AppShellMobileContext} from '@astryxdesign/core/AppShell';
8
+ import {SideNavItem, SideNavSection} from '@astryxdesign/core/SideNav';
9
+ import {Icon} from '@astryxdesign/core/Icon';
10
+ import {HStack} from '@astryxdesign/core/Layout';
11
+ import {Text} from '@astryxdesign/core/Text';
12
+
13
+ export default function MobileNavToggleBasic() {
14
+ const [isOpen, setIsOpen] = useState(false);
15
+ return (
16
+ <AppShellMobileContext.Provider
17
+ value={{
18
+ isMobile: true,
19
+ isMobileNavOpen: isOpen,
20
+ toggleMobileNav: () => setIsOpen(v => !v),
21
+ openMobileNav: () => setIsOpen(true),
22
+ closeMobileNav: () => setIsOpen(false),
23
+ isMobileNavEnabled: true,
24
+ hasAutoToggle: false,
25
+ }}>
26
+ <HStack gap={3} vAlign="center">
27
+ <MobileNavToggle label="Open menu">
28
+ <Icon icon="viewColumns" />
29
+ </MobileNavToggle>
30
+ <Text type="body" weight="bold">
31
+ Page title
32
+ </Text>
33
+ </HStack>
34
+ <MobileNav isOpen={isOpen} onOpenChange={setIsOpen} header="Navigation">
35
+ <SideNavSection title="Pages">
36
+ <SideNavItem label="Home" isSelected href="#" />
37
+ <SideNavItem label="Settings" href="#" />
38
+ </SideNavSection>
39
+ </MobileNav>
40
+ </AppShellMobileContext.Provider>
41
+ );
42
+ }
@@ -2,17 +2,11 @@
2
2
 
3
3
  'use client';
4
4
 
5
- import {useState} from 'react';
6
5
  import {MoreMenu} from '@astryxdesign/core/MoreMenu';
7
6
 
8
7
  export default function MoreMenuShowcase() {
9
- const [isMenuOpen, setIsMenuOpen] = useState(false);
10
-
11
8
  return (
12
9
  <MoreMenu
13
- isMenuOpen={isMenuOpen}
14
- onOpenChange={setIsMenuOpen}
15
- hasAutoFocus={false}
16
10
  items={[
17
11
  {label: 'Edit', onClick: () => {}},
18
12
  {label: 'Duplicate', onClick: () => {}},
@@ -0,0 +1,14 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /** @type {import('../../../../../core/src/docs-types').TemplateDoc} */
4
+ export const doc = {
5
+ type: 'block',
6
+ exampleFor: 'NavIcon',
7
+ name: 'NavIcon — Basic',
8
+ displayName: 'NavIcon — Basic',
9
+ description:
10
+ 'Circular icon containers wrapping semantic icons. Use as logos or accent icons in navigation headers such as TopNavHeading.',
11
+ isReady: true,
12
+ aspectRatio: 16 / 9,
13
+ componentsUsed: ['NavIcon', 'Icon', 'HStack'],
14
+ };
@@ -0,0 +1,16 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ import {NavIcon} from '@astryxdesign/core/NavIcon';
6
+ import {Icon} from '@astryxdesign/core/Icon';
7
+ import {HStack} from '@astryxdesign/core/Layout';
8
+
9
+ export default function NavIconBasic() {
10
+ return (
11
+ <HStack gap={4} vAlign="center">
12
+ <NavIcon icon={<Icon icon="search" />} />
13
+ <NavIcon icon={<Icon icon="calendar" />} />
14
+ </HStack>
15
+ );
16
+ }
@@ -0,0 +1,14 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /** @type {import('../../../../../core/src/docs-types').TemplateDoc} */
4
+ export const doc = {
5
+ type: 'block',
6
+ exampleFor: 'RadioListItem',
7
+ name: 'RadioListItem — Basic',
8
+ displayName: 'RadioListItem — Basic',
9
+ description:
10
+ 'Radio items with labels and descriptions inside a controlled RadioList. Use for single-choice option groups like shipping methods.',
11
+ isReady: true,
12
+ aspectRatio: 16 / 9,
13
+ componentsUsed: ['RadioList', 'RadioListItem'],
14
+ };
@@ -0,0 +1,30 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ import {useState} from 'react';
6
+ import {RadioList, RadioListItem} from '@astryxdesign/core/RadioList';
7
+
8
+ export default function RadioListItemBasic() {
9
+ const [value, setValue] = useState('standard');
10
+
11
+ return (
12
+ <RadioList label="Shipping method" value={value} onChange={setValue}>
13
+ <RadioListItem
14
+ label="Standard"
15
+ value="standard"
16
+ description="5–7 business days"
17
+ />
18
+ <RadioListItem
19
+ label="Express"
20
+ value="express"
21
+ description="2–3 business days"
22
+ />
23
+ <RadioListItem
24
+ label="Overnight"
25
+ value="overnight"
26
+ description="Next business day"
27
+ />
28
+ </RadioList>
29
+ );
30
+ }
@@ -0,0 +1,25 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /** @type {import('../../../../../core/src/docs-types').TemplateDoc} */
4
+ export const doc = {
5
+ type: 'block',
6
+ exampleFor: 'ResizeHandle',
7
+ alsoExampleFor: ['useResizable'],
8
+ name: 'Resizable — Collapsible with snap points',
9
+ displayName: 'Resizable — Collapsible with snap points',
10
+ description:
11
+ 'A collapsible sidebar with snap points, driven by useResizable. Dragging snaps to preset widths, dragging past the minimum collapses the panel, and the expand method restores it programmatically.',
12
+ isReady: true,
13
+ aspectRatio: 16 / 9,
14
+ componentsUsed: [
15
+ 'Resizable',
16
+ 'ResizeHandle',
17
+ 'Layout',
18
+ 'LayoutPanel',
19
+ 'LayoutContent',
20
+ 'Card',
21
+ 'VStack',
22
+ 'Button',
23
+ 'Text',
24
+ ],
25
+ };
@@ -0,0 +1,67 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ import {useResizable, ResizeHandle} from '@astryxdesign/core/Resizable';
6
+ import {
7
+ Card,
8
+ Layout,
9
+ LayoutContent,
10
+ LayoutPanel,
11
+ VStack,
12
+ } from '@astryxdesign/core/Layout';
13
+ import {Button} from '@astryxdesign/core/Button';
14
+ import {Text} from '@astryxdesign/core/Text';
15
+
16
+ export default function ResizableSidebar() {
17
+ const sidebar = useResizable({
18
+ defaultSize: 240,
19
+ minSizePx: 160,
20
+ maxSizePx: 360,
21
+ collapsible: true,
22
+ snaps: [200, 280],
23
+ });
24
+
25
+ return (
26
+ <Card variant="muted" height={240} width={500}>
27
+ <Layout
28
+ height="fill"
29
+ start={
30
+ <>
31
+ <LayoutPanel width={sidebar.size} hasDivider={false}>
32
+ <Text color="secondary">
33
+ {sidebar.isCollapsed
34
+ ? ''
35
+ : `${Math.round(sidebar.size)}px wide`}
36
+ </Text>
37
+ </LayoutPanel>
38
+ <ResizeHandle
39
+ direction="horizontal"
40
+ hasDivider
41
+ resizable={sidebar.props}
42
+ label="Resize sidebar"
43
+ />
44
+ </>
45
+ }
46
+ content={
47
+ <LayoutContent>
48
+ <VStack gap={2}>
49
+ <Text color="secondary">
50
+ Drag the handle — it snaps at 200px and 280px. Drag all the way
51
+ left to collapse the sidebar.
52
+ </Text>
53
+ {sidebar.isCollapsed && (
54
+ <Button
55
+ label="Expand sidebar"
56
+ variant="secondary"
57
+ size="sm"
58
+ onClick={() => sidebar.expand()}
59
+ />
60
+ )}
61
+ </VStack>
62
+ </LayoutContent>
63
+ }
64
+ />
65
+ </Card>
66
+ );
67
+ }
@@ -0,0 +1,14 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /** @type {import('../../../../../core/src/docs-types').TemplateDoc} */
4
+ export const doc = {
5
+ type: 'block',
6
+ exampleFor: 'SegmentedControlItem',
7
+ name: 'SegmentedControlItem — Basic',
8
+ displayName: 'SegmentedControlItem — Basic',
9
+ description:
10
+ 'Label-only options inside a SegmentedControl. Each item declares a value; the parent control holds the selected value and change handler.',
11
+ isReady: true,
12
+ aspectRatio: 16 / 9,
13
+ componentsUsed: ['SegmentedControl', 'SegmentedControlItem'],
14
+ };
@@ -0,0 +1,21 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ import {useState} from 'react';
6
+ import {
7
+ SegmentedControl,
8
+ SegmentedControlItem,
9
+ } from '@astryxdesign/core/SegmentedControl';
10
+
11
+ export default function SegmentedControlItemBasic() {
12
+ const [view, setView] = useState('board');
13
+
14
+ return (
15
+ <SegmentedControl value={view} onChange={setView} label="View mode">
16
+ <SegmentedControlItem value="board" label="Board" />
17
+ <SegmentedControlItem value="list" label="List" />
18
+ <SegmentedControlItem value="timeline" label="Timeline" />
19
+ </SegmentedControl>
20
+ );
21
+ }
@@ -0,0 +1,14 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /** @type {import('../../../../../core/src/docs-types').TemplateDoc} */
4
+ export const doc = {
5
+ type: 'block',
6
+ exampleFor: 'SelectorOption',
7
+ name: 'SelectorOption — Basic',
8
+ displayName: 'SelectorOption — Basic',
9
+ description:
10
+ 'A selector whose options are rendered with SelectorOption, adding a secondary description below each label. Use inside renderOption for consistent custom option styling.',
11
+ isReady: true,
12
+ aspectRatio: 16 / 9,
13
+ componentsUsed: ['Selector', 'SelectorOption'],
14
+ };
@@ -0,0 +1,39 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ import {useState} from 'react';
6
+ import {Selector, SelectorOption} from '@astryxdesign/core/Selector';
7
+
8
+ const descriptions: Record<string, string> = {
9
+ admin: 'Full access to all resources',
10
+ editor: 'Can edit and publish content',
11
+ viewer: 'Read-only access',
12
+ };
13
+
14
+ const roles = [
15
+ {value: 'admin', label: 'Admin'},
16
+ {value: 'editor', label: 'Editor'},
17
+ {value: 'viewer', label: 'Viewer'},
18
+ ];
19
+
20
+ export default function SelectorOptionBasic() {
21
+ const [value, setValue] = useState<string | undefined>('editor');
22
+
23
+ return (
24
+ <Selector
25
+ style={{width: 300}}
26
+ label="Role"
27
+ options={roles}
28
+ value={value}
29
+ onChange={setValue}
30
+ placeholder="Assign a role..."
31
+ renderOption={option => (
32
+ <SelectorOption
33
+ label={option.label}
34
+ description={descriptions[option.value]}
35
+ />
36
+ )}
37
+ />
38
+ );
39
+ }
@@ -0,0 +1,14 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /** @type {import('../../../../../core/src/docs-types').TemplateDoc} */
4
+ export const doc = {
5
+ type: 'block',
6
+ exampleFor: 'SideNavCollapseButton',
7
+ name: 'SideNavCollapseButton — Basic',
8
+ displayName: 'SideNavCollapseButton — Basic',
9
+ description:
10
+ 'Place a collapse button in the SideNav footer to let users toggle the rail between expanded and collapsed states. Disable the built-in button via collapsible={{hasButton: false}} when positioning it yourself.',
11
+ isReady: true,
12
+ aspectRatio: 16 / 9,
13
+ componentsUsed: ['SideNav', 'SideNavCollapseButton', 'SideNavItem'],
14
+ };
@@ -0,0 +1,55 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ import type {ComponentProps} from 'react';
6
+ import {
7
+ SideNav,
8
+ SideNavCollapseButton,
9
+ SideNavItem,
10
+ } from '@astryxdesign/core/SideNav';
11
+
12
+ function HomeIcon(props: ComponentProps<'svg'>) {
13
+ return (
14
+ <svg
15
+ fill="none"
16
+ viewBox="0 0 24 24"
17
+ strokeWidth={1.5}
18
+ stroke="currentColor"
19
+ {...props}>
20
+ <path
21
+ strokeLinecap="round"
22
+ strokeLinejoin="round"
23
+ d="m2.25 12 8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25"
24
+ />
25
+ </svg>
26
+ );
27
+ }
28
+
29
+ function FolderIcon(props: ComponentProps<'svg'>) {
30
+ return (
31
+ <svg
32
+ fill="none"
33
+ viewBox="0 0 24 24"
34
+ strokeWidth={1.5}
35
+ stroke="currentColor"
36
+ {...props}>
37
+ <path
38
+ strokeLinecap="round"
39
+ strokeLinejoin="round"
40
+ d="M2.25 12.75V12A2.25 2.25 0 0 1 4.5 9.75h15A2.25 2.25 0 0 1 21.75 12v.75m-8.69-6.44-2.12-2.12a1.5 1.5 0 0 0-1.061-.44H4.5A2.25 2.25 0 0 0 2.25 6v12a2.25 2.25 0 0 0 2.25 2.25h15A2.25 2.25 0 0 0 21.75 18V9a2.25 2.25 0 0 0-2.25-2.25h-5.379a1.5 1.5 0 0 1-1.06-.44Z"
41
+ />
42
+ </svg>
43
+ );
44
+ }
45
+
46
+ export default function SideNavCollapseButtonBasic() {
47
+ return (
48
+ <SideNav
49
+ collapsible={{hasButton: false}}
50
+ footerIcons={<SideNavCollapseButton />}>
51
+ <SideNavItem label="Home" icon={HomeIcon} isSelected href="#" />
52
+ <SideNavItem label="Projects" icon={FolderIcon} href="#" />
53
+ </SideNav>
54
+ );
55
+ }
@@ -0,0 +1,14 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /** @type {import('../../../../../core/src/docs-types').TemplateDoc} */
4
+ export const doc = {
5
+ type: 'block',
6
+ exampleFor: 'SideNavHeading',
7
+ name: 'SideNavHeading — Basic',
8
+ displayName: 'SideNavHeading — Basic',
9
+ description:
10
+ 'A SideNav header with an app icon and a linked title. Pass it to the SideNav header prop to identify the product or workspace at the top of the navigation rail.',
11
+ isReady: true,
12
+ aspectRatio: 16 / 9,
13
+ componentsUsed: ['SideNav', 'SideNavHeading'],
14
+ };
@@ -0,0 +1,38 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ import {SideNav, SideNavHeading} from '@astryxdesign/core/SideNav';
6
+
7
+ function AppIcon() {
8
+ return (
9
+ <svg
10
+ width="20"
11
+ height="20"
12
+ viewBox="0 0 24 24"
13
+ fill="none"
14
+ stroke="currentColor"
15
+ strokeWidth="1.5">
16
+ <path
17
+ strokeLinecap="round"
18
+ strokeLinejoin="round"
19
+ d="M3.75 6A2.25 2.25 0 0 1 6 3.75h2.25A2.25 2.25 0 0 1 10.5 6v2.25a2.25 2.25 0 0 1-2.25 2.25H6a2.25 2.25 0 0 1-2.25-2.25V6ZM3.75 15.75A2.25 2.25 0 0 1 6 13.5h2.25a2.25 2.25 0 0 1 2.25 2.25V18a2.25 2.25 0 0 1-2.25 2.25H6A2.25 2.25 0 0 1 3.75 18v-2.25ZM13.5 6a2.25 2.25 0 0 1 2.25-2.25H18A2.25 2.25 0 0 1 20.25 6v2.25A2.25 2.25 0 0 1 18 10.5h-2.25a2.25 2.25 0 0 1-2.25-2.25V6ZM13.5 15.75a2.25 2.25 0 0 1 2.25-2.25H18a2.25 2.25 0 0 1 2.25 2.25V18A2.25 2.25 0 0 1 18 20.25h-2.25a2.25 2.25 0 0 1-2.25-2.25v-2.25Z"
20
+ />
21
+ </svg>
22
+ );
23
+ }
24
+
25
+ export default function SideNavHeadingBasic() {
26
+ return (
27
+ <SideNav
28
+ header={
29
+ <SideNavHeading
30
+ heading="Analytics"
31
+ icon={<AppIcon />}
32
+ headingHref="/"
33
+ />
34
+ }>
35
+ {null}
36
+ </SideNav>
37
+ );
38
+ }
@@ -0,0 +1,14 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /** @type {import('../../../../../core/src/docs-types').TemplateDoc} */
4
+ export const doc = {
5
+ type: 'block',
6
+ exampleFor: 'SideNavItem',
7
+ name: 'SideNavItem — Basic',
8
+ displayName: 'SideNavItem — Basic',
9
+ description:
10
+ 'Navigation links inside a SideNav, each with a label, an icon, and an href. Mark the item for the current page with isSelected.',
11
+ isReady: true,
12
+ aspectRatio: 16 / 9,
13
+ componentsUsed: ['SideNav', 'SideNavItem'],
14
+ };
@@ -0,0 +1,49 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ import type {ComponentProps} from 'react';
6
+ import {SideNav, SideNavItem} from '@astryxdesign/core/SideNav';
7
+
8
+ function InboxIcon(props: ComponentProps<'svg'>) {
9
+ return (
10
+ <svg
11
+ fill="none"
12
+ viewBox="0 0 24 24"
13
+ strokeWidth={1.5}
14
+ stroke="currentColor"
15
+ {...props}>
16
+ <path
17
+ strokeLinecap="round"
18
+ strokeLinejoin="round"
19
+ d="M2.25 13.5h3.86a2.25 2.25 0 0 1 2.012 1.244l.256.512a2.25 2.25 0 0 0 2.013 1.244h3.218a2.25 2.25 0 0 0 2.013-1.244l.256-.512a2.25 2.25 0 0 1 2.013-1.244h3.859m-19.5.338V18a2.25 2.25 0 0 0 2.25 2.25h15A2.25 2.25 0 0 0 21.75 18v-4.162c0-.224-.034-.447-.1-.661L19.24 5.338a2.25 2.25 0 0 0-2.15-1.588H6.911a2.25 2.25 0 0 0-2.15 1.588L2.35 13.177a2.25 2.25 0 0 0-.1.661Z"
20
+ />
21
+ </svg>
22
+ );
23
+ }
24
+
25
+ function DocumentIcon(props: ComponentProps<'svg'>) {
26
+ return (
27
+ <svg
28
+ fill="none"
29
+ viewBox="0 0 24 24"
30
+ strokeWidth={1.5}
31
+ stroke="currentColor"
32
+ {...props}>
33
+ <path
34
+ strokeLinecap="round"
35
+ strokeLinejoin="round"
36
+ d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m2.25 0H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z"
37
+ />
38
+ </svg>
39
+ );
40
+ }
41
+
42
+ export default function SideNavItemBasic() {
43
+ return (
44
+ <SideNav>
45
+ <SideNavItem label="Inbox" icon={InboxIcon} isSelected href="#" />
46
+ <SideNavItem label="Documents" icon={DocumentIcon} href="#" />
47
+ </SideNav>
48
+ );
49
+ }
@@ -0,0 +1,14 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /** @type {import('../../../../../core/src/docs-types').TemplateDoc} */
4
+ export const doc = {
5
+ type: 'block',
6
+ exampleFor: 'SideNavSection',
7
+ name: 'SideNavSection — Basic',
8
+ displayName: 'SideNavSection — Basic',
9
+ description:
10
+ 'Group related SideNavItems under titled sections. Use sections to organize longer navigation lists into scannable clusters like Overview and Account.',
11
+ isReady: true,
12
+ aspectRatio: 16 / 9,
13
+ componentsUsed: ['SideNav', 'SideNavSection', 'SideNavItem'],
14
+ };
@@ -0,0 +1,71 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ import type {ComponentProps} from 'react';
6
+ import {SideNav, SideNavItem, SideNavSection} from '@astryxdesign/core/SideNav';
7
+
8
+ function HomeIcon(props: ComponentProps<'svg'>) {
9
+ return (
10
+ <svg
11
+ fill="none"
12
+ viewBox="0 0 24 24"
13
+ strokeWidth={1.5}
14
+ stroke="currentColor"
15
+ {...props}>
16
+ <path
17
+ strokeLinecap="round"
18
+ strokeLinejoin="round"
19
+ d="m2.25 12 8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25"
20
+ />
21
+ </svg>
22
+ );
23
+ }
24
+
25
+ function ChartIcon(props: ComponentProps<'svg'>) {
26
+ return (
27
+ <svg
28
+ fill="none"
29
+ viewBox="0 0 24 24"
30
+ strokeWidth={1.5}
31
+ stroke="currentColor"
32
+ {...props}>
33
+ <path
34
+ strokeLinecap="round"
35
+ strokeLinejoin="round"
36
+ d="M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 0 1 3 19.875v-6.75ZM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V8.625ZM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V4.125Z"
37
+ />
38
+ </svg>
39
+ );
40
+ }
41
+
42
+ function UserIcon(props: ComponentProps<'svg'>) {
43
+ return (
44
+ <svg
45
+ fill="none"
46
+ viewBox="0 0 24 24"
47
+ strokeWidth={1.5}
48
+ stroke="currentColor"
49
+ {...props}>
50
+ <path
51
+ strokeLinecap="round"
52
+ strokeLinejoin="round"
53
+ d="M15.75 6a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0ZM4.501 20.118a7.5 7.5 0 0 1 14.998 0A17.933 17.933 0 0 1 12 21.75c-2.676 0-5.216-.584-7.499-1.632Z"
54
+ />
55
+ </svg>
56
+ );
57
+ }
58
+
59
+ export default function SideNavSectionBasic() {
60
+ return (
61
+ <SideNav>
62
+ <SideNavSection title="Overview">
63
+ <SideNavItem label="Dashboard" icon={HomeIcon} isSelected href="#" />
64
+ <SideNavItem label="Analytics" icon={ChartIcon} href="#" />
65
+ </SideNavSection>
66
+ <SideNavSection title="Account">
67
+ <SideNavItem label="Profile" icon={UserIcon} href="#" />
68
+ </SideNavSection>
69
+ </SideNav>
70
+ );
71
+ }
@@ -0,0 +1,14 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /** @type {import('../../../../../core/src/docs-types').TemplateDoc} */
4
+ export const doc = {
5
+ type: 'block',
6
+ exampleFor: 'StackItem',
7
+ name: 'StackItem — Fill',
8
+ displayName: 'StackItem — Fill',
9
+ description:
10
+ 'A static-width item next to one that fills the remaining space. Wrap stack children in StackItem when an item needs explicit sizing control.',
11
+ isReady: true,
12
+ aspectRatio: 16 / 9,
13
+ componentsUsed: ['StackItem', 'HStack', 'Card', 'Text'],
14
+ };