@astryxdesign/cli 0.1.0 → 0.1.1

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 (140) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/README.md +117 -75
  3. package/bin/astryx.mjs +22 -7
  4. package/docs/getting-started.doc.mjs +11 -11
  5. package/docs/icons.doc.mjs +1 -1
  6. package/docs/migration.doc.mjs +2 -2
  7. package/docs/shape.doc.mjs +1 -1
  8. package/docs/styling.doc.mjs +3 -4
  9. package/docs/theme.doc.dense.mjs +2 -2
  10. package/docs/theme.doc.mjs +14 -0
  11. package/docs/theme.doc.zh.mjs +2 -2
  12. package/docs/working-with-ai.doc.mjs +4 -4
  13. package/package.json +2 -2
  14. package/src/api/doctor.mjs +3 -3
  15. package/src/api/search.mjs +207 -13
  16. package/src/api/template.mjs +2 -1
  17. package/src/codemods/__tests__/registry.test.mjs +1 -0
  18. package/src/codemods/registry.mjs +1 -0
  19. package/src/codemods/runner.mjs +105 -51
  20. package/src/codemods/transforms/v0.1.0/__tests__/migrate-xds-config-surfaces.test.mjs +116 -0
  21. package/src/codemods/transforms/v0.1.0/__tests__/migrate-xds-module-specifiers.test.mjs +51 -0
  22. package/src/codemods/transforms/v0.1.0/index.mjs +28 -0
  23. package/src/codemods/transforms/v0.1.0/migrate-xds-config-surfaces.mjs +230 -0
  24. package/src/codemods/transforms/v0.1.0/migrate-xds-module-specifiers.mjs +84 -0
  25. package/src/commands/agent-docs.mjs +119 -66
  26. package/src/commands/agent-docs.path-safety.test.mjs +1 -1
  27. package/src/commands/agent-docs.test.mjs +87 -31
  28. package/src/commands/build-theme.import-path.test.mjs +1 -1
  29. package/src/commands/build-theme.path-safety.test.mjs +1 -1
  30. package/src/commands/build-theme.prose.test.mjs +1 -1
  31. package/src/commands/build.mjs +196 -0
  32. package/src/commands/component-package.test.mjs +1 -1
  33. package/src/commands/component.test.mjs +1 -1
  34. package/src/commands/docs.test.mjs +1 -1
  35. package/src/commands/doctor.test.mjs +1 -1
  36. package/src/commands/external-showcase.test.mjs +1 -1
  37. package/src/commands/init.mjs +10 -2
  38. package/src/commands/interactive-guard.test.mjs +1 -1
  39. package/src/commands/json-contract.test.mjs +10 -3
  40. package/src/commands/swizzle-gap-safety.test.mjs +1 -1
  41. package/src/commands/swizzle.path-safety.test.mjs +1 -1
  42. package/src/commands/template.path-safety.test.mjs +1 -1
  43. package/src/commands/template.test.mjs +1 -1
  44. package/src/commands/upgrade.mjs +353 -169
  45. package/src/commands/upgrade.test.mjs +41 -27
  46. package/src/index.mjs +1 -0
  47. package/src/lib/config.mjs +12 -0
  48. package/src/lib/config.test.mjs +42 -0
  49. package/src/lib/error-codes.mjs +3 -0
  50. package/src/types/error-codes.d.ts +1 -0
  51. package/src/utils/interactive.mjs +1 -1
  52. package/src/utils/interactive.test.mjs +2 -0
  53. package/src/utils/package-manager.mjs +1 -1
  54. package/src/utils/package-manager.test.mjs +1 -1
  55. package/src/utils/path-safety.test.mjs +1 -1
  56. package/src/utils/paths.test.mjs +8 -8
  57. package/src/utils/update-check.mjs +4 -26
  58. package/src/utils/update-check.test.mjs +2 -64
  59. package/templates/blocks/components/AppShell/AppShellContentOnly.tsx +1 -9
  60. package/templates/blocks/components/AppShell/AppShellShowcase.tsx +1 -10
  61. package/templates/blocks/components/AppShell/AppShellSideNavOnly.tsx +1 -9
  62. package/templates/blocks/components/AppShell/AppShellTopNavOnly.tsx +1 -9
  63. package/templates/blocks/components/AppShell/AppShellTopNavWithSideNav.tsx +1 -9
  64. package/templates/blocks/components/AppShell/AppShellWithBanner.tsx +1 -9
  65. package/templates/blocks/components/AspectRatio/AspectRatioShowcase.tsx +12 -19
  66. package/templates/blocks/components/Banner/BannerShowcase.tsx +1 -8
  67. package/templates/blocks/components/Blockquote/BlockquoteShowcase.tsx +1 -8
  68. package/templates/blocks/components/Carousel/CarouselShowcase.tsx +2 -12
  69. package/templates/blocks/components/ChatComposerDrawer/ChatComposerDrawerShowcase.tsx +6 -9
  70. package/templates/blocks/components/ChatLayout/ChatLayoutPanelChat.tsx +10 -12
  71. package/templates/blocks/components/ChatMessageList/ChatMessageListDensity.tsx +1 -9
  72. package/templates/blocks/components/ChatMessageList/ChatMessageListFullFeatured.tsx +1 -9
  73. package/templates/blocks/components/ChatMessageList/ChatMessageListShowcase.tsx +1 -9
  74. package/templates/blocks/components/ChatMessageMetadata/ChatMessageMetadataShowcase.tsx +1 -8
  75. package/templates/blocks/components/ChatSendButton/ChatSendButtonInComposer.tsx +1 -8
  76. package/templates/blocks/components/Citation/CitationInlineText.tsx +4 -4
  77. package/templates/blocks/components/Code/CodeInlineInParagraph.tsx +1 -8
  78. package/templates/blocks/components/CodeBlock/CodeBlockBashCommand.tsx +1 -1
  79. package/templates/blocks/components/CodeBlock/CodeBlockJSONConfig.tsx +1 -1
  80. package/templates/blocks/components/CommandPaletteItem/CommandPaletteItemShowcase.tsx +9 -12
  81. package/templates/blocks/components/ContextMenu/ContextMenuShowcase.tsx +13 -15
  82. package/templates/blocks/components/Divider/DividerShowcase.tsx +1 -8
  83. package/templates/blocks/components/Divider/DividerVertical.tsx +7 -9
  84. package/templates/blocks/components/Field/FieldShowcase.tsx +1 -8
  85. package/templates/blocks/components/FormLayout/FormLayoutHorizontal.tsx +1 -6
  86. package/templates/blocks/components/Grid/GridResponsiveAutoFit.tsx +1 -9
  87. package/templates/blocks/components/HoverCard/HoverCardInlineTextHoverCard.tsx +4 -6
  88. package/templates/blocks/components/HoverCard/HoverCardInteractiveContent.tsx +1 -6
  89. package/templates/blocks/components/HoverCard/HoverCardProfileHoverCard.tsx +2 -8
  90. package/templates/blocks/components/HoverCard/HoverCardShowcase.tsx +1 -8
  91. package/templates/blocks/components/MoreMenu/MoreMenuInToolbar.tsx +2 -12
  92. package/templates/blocks/components/OverflowList/OverflowListOverflowBadges.tsx +8 -11
  93. package/templates/blocks/components/OverflowList/OverflowListOverflowDropdownActions.tsx +9 -12
  94. package/templates/blocks/components/Overlay/OverlayBottomStrip.tsx +4 -17
  95. package/templates/blocks/components/Overlay/OverlayHoverReveal.tsx +15 -16
  96. package/templates/blocks/components/Overlay/OverlayShowcase.tsx +5 -21
  97. package/templates/blocks/components/Pagination/PaginationDotsCarousel.tsx +2 -14
  98. package/templates/blocks/components/Pagination/PaginationPageSize.tsx +12 -14
  99. package/templates/blocks/components/Pagination/PaginationVariants.tsx +1 -8
  100. package/templates/blocks/components/Pagination/PaginationWithTable.tsx +2 -14
  101. package/templates/blocks/components/Tokenizer/TokenizerClear.tsx +1 -6
  102. package/templates/blocks/components/Tokenizer/TokenizerCreatable.tsx +2 -7
  103. package/templates/blocks/components/Tokenizer/TokenizerEndContent.tsx +1 -6
  104. package/templates/blocks/components/Tokenizer/TokenizerIcon.tsx +1 -6
  105. package/templates/blocks/components/Tokenizer/TokenizerMaxEntries.tsx +1 -6
  106. package/templates/blocks/components/Tokenizer/TokenizerOverflow.tsx +2 -7
  107. package/templates/blocks/components/Tokenizer/TokenizerShowcase.tsx +1 -6
  108. package/templates/blocks/components/Tokenizer/TokenizerStates.tsx +4 -9
  109. package/templates/blocks/components/Toolbar/ToolbarCardHeader.tsx +1 -10
  110. package/templates/blocks/components/Toolbar/ToolbarSizes.tsx +1 -8
  111. package/templates/blocks/components/Toolbar/ToolbarTableFilter.tsx +1 -8
  112. package/templates/blocks/components/Toolbar/ToolbarThreeSlot.tsx +1 -10
  113. package/templates/blocks/components/Toolbar/ToolbarWithTabs.tsx +8 -11
  114. package/templates/pages/ai-chat/page.tsx +71 -64
  115. package/templates/pages/ai-chat-landing/page.tsx +8 -12
  116. package/templates/pages/centered-hero/page.tsx +13 -15
  117. package/templates/pages/classic-gallery/page.tsx +27 -34
  118. package/templates/pages/detail-page/page.tsx +18 -18
  119. package/templates/pages/documentation/page.tsx +42 -58
  120. package/templates/pages/documentation-design/page.tsx +82 -60
  121. package/templates/pages/documentation-technical/page.tsx +101 -60
  122. package/templates/pages/editor/page.tsx +42 -54
  123. package/templates/pages/file-explorer/page.tsx +13 -16
  124. package/templates/pages/form-two-column/page.tsx +13 -17
  125. package/templates/pages/gallery-hero/page.tsx +13 -15
  126. package/templates/pages/ide/page.tsx +188 -264
  127. package/templates/pages/library/page.tsx +16 -23
  128. package/templates/pages/login/page.tsx +14 -18
  129. package/templates/pages/login-card/page.tsx +14 -18
  130. package/templates/pages/login-split/page.tsx +50 -48
  131. package/templates/pages/login-sso/page.tsx +9 -13
  132. package/templates/pages/mixed-gallery/page.tsx +51 -45
  133. package/templates/pages/payment-form/page.tsx +56 -70
  134. package/templates/pages/product-detail/page.tsx +27 -33
  135. package/templates/pages/product-gallery/page.tsx +7 -13
  136. package/templates/pages/settings-dialog/page.tsx +35 -43
  137. package/templates/pages/settings-sidebar/page.tsx +39 -47
  138. package/templates/pages/side-gallery/page.tsx +6 -9
  139. package/templates/pages/table-grouped/page.tsx +11 -15
  140. package/templates/pages/theme-showcase/page.tsx +33 -37
@@ -2,8 +2,7 @@
2
2
 
3
3
  'use client';
4
4
 
5
- import {useState} from 'react';
6
- import * as stylex from '@stylexjs/stylex';
5
+ import {useState, type CSSProperties} from 'react';
7
6
  import {
8
7
  VStack,
9
8
  HStack,
@@ -36,12 +35,6 @@ import {ShieldCheckIcon} from '@heroicons/react/24/outline';
36
35
  import {LockClosedIcon} from '@heroicons/react/24/outline';
37
36
  import {CheckCircleIcon} from '@heroicons/react/24/outline';
38
37
  import {TruckIcon} from '@heroicons/react/24/outline';
39
- import {
40
- colorVars,
41
- spacingVars,
42
- radiusVars,
43
- borderVars,
44
- } from '@astryxdesign/core/theme/tokens.stylex';
45
38
 
46
39
  // ── Constants ─────────────────────────────────────────────────────────────────
47
40
 
@@ -156,51 +149,48 @@ const TAX = 18.4;
156
149
  const fmt = (n: number) => `$${n.toFixed(2)}`;
157
150
 
158
151
  // ── Styles ────────────────────────────────────────────────────────────────────
152
+ // Plain inline styles using Astryx design-token CSS variables (declared at
153
+ // :root by `@astryxdesign/core/astryx.css`). No StyleX compiler required.
159
154
 
160
- const styles = stylex.create({
161
- fullWidth: {width: '100%'},
162
- // LayoutContent clips overflow by default, which traps position:sticky
163
- // children (the sticky order summary). With height="auto" the page scrolls
164
- // at the window, so let overflow be visible here so sticky can pin.
165
- visibleOverflow: {overflow: 'visible'},
166
- // Form column flex-basis so the two checkout columns share width evenly.
167
- formColBasis: {flexBasis: 0},
168
- // Space the Order Summary content below its collapsible trigger title.
169
- summaryContent: {paddingBlockStart: spacingVars['--spacing-2']},
170
- // Order-summary column: sticky beside the form on desktop.
171
- summarySticky: {
172
- flexBasis: 0,
173
- position: 'sticky',
174
- top: spacingVars['--spacing-4'],
175
- alignSelf: 'flex-start',
176
- },
177
- // On mobile the summary moves above the form.
178
- summaryMobileOrder: {order: -1},
179
- // Express-checkout brand buttons (fixed brand colors).
180
- paypalButton: {backgroundColor: '#FFC439', borderColor: '#FFC439'},
181
- // Official Google Pay dark button: black background with the unaltered
182
- // dark-variant mark (white "Google Pay" text + full-color G), per the
183
- // Google Pay brand guidelines.
184
- gpayButton: {backgroundColor: '#000', borderColor: '#000'},
185
- // Brand logos inside the express-checkout buttons.
186
- paypalLogo: {height: spacingVars['--spacing-5'], width: 'auto'},
187
- // Unaltered Google Pay mark (no filter/recolor — brand requirement),
188
- // sized so it keeps comfortable clear space inside the lg button.
189
- gpayLogo: {
190
- height: spacingVars['--spacing-5'],
191
- width: 'auto',
192
- },
193
- // Accepted card-network marks (Visa/Mastercard/Amex), shared style.
194
- cardLogo: {
195
- height: spacingVars['--spacing-7'],
196
- width: 'auto',
197
- borderRadius: radiusVars['--radius-element'],
198
- borderWidth: borderVars['--border-width'],
199
- borderStyle: 'solid',
200
- borderColor: colorVars['--color-border'],
201
- backgroundColor: colorVars['--color-background-surface'],
202
- },
203
- });
155
+ const fullWidth: CSSProperties = {width: '100%'};
156
+ // LayoutContent clips overflow by default, which traps position:sticky
157
+ // children (the sticky order summary). With height="auto" the page scrolls
158
+ // at the window, so let overflow be visible here so sticky can pin.
159
+ const visibleOverflow: CSSProperties = {overflow: 'visible'};
160
+ // Form column flex-basis so the two checkout columns share width evenly.
161
+ const formColBasis: CSSProperties = {flexBasis: 0};
162
+ // Space the Order Summary content below its collapsible trigger title.
163
+ const summaryContent: CSSProperties = {paddingBlockStart: 'var(--spacing-2)'};
164
+ // Order-summary column: sticky beside the form on desktop.
165
+ const summarySticky: CSSProperties = {
166
+ flexBasis: 0,
167
+ position: 'sticky',
168
+ top: 'var(--spacing-4)',
169
+ alignSelf: 'flex-start',
170
+ };
171
+ // On mobile the summary moves above the form.
172
+ const summaryMobileOrder: CSSProperties = {order: -1};
173
+ // Express-checkout brand buttons (fixed brand colors).
174
+ const paypalButton: CSSProperties = {
175
+ backgroundColor: '#FFC439',
176
+ borderColor: '#FFC439',
177
+ };
178
+ // Official Google Pay dark button: black background with the unaltered
179
+ // dark-variant mark (white "Google Pay" text + full-color G), per the
180
+ // Google Pay brand guidelines.
181
+ const gpayButton: CSSProperties = {backgroundColor: '#000', borderColor: '#000'};
182
+ // Brand logos inside the express-checkout buttons.
183
+ const brandLogo: CSSProperties = {height: 'var(--spacing-5)', width: 'auto'};
184
+ // Accepted card-network marks (Visa/Mastercard/Amex), shared style.
185
+ const cardLogo: CSSProperties = {
186
+ height: 'var(--spacing-7)',
187
+ width: 'auto',
188
+ borderRadius: 'var(--radius-element)',
189
+ borderWidth: 'var(--border-width)',
190
+ borderStyle: 'solid',
191
+ borderColor: 'var(--color-border)',
192
+ backgroundColor: 'var(--color-background-surface)',
193
+ };
204
194
 
205
195
  export default function PaymentFormPage() {
206
196
  const isMobile = useMediaQuery('(max-width: 767px)');
@@ -278,7 +268,7 @@ export default function PaymentFormPage() {
278
268
  <Layout
279
269
  height="auto"
280
270
  content={
281
- <LayoutContent padding={0} xstyle={styles.visibleOverflow}>
271
+ <LayoutContent padding={0} style={visibleOverflow}>
282
272
  <Center axis="horizontal">
283
273
  <Section
284
274
  variant="transparent"
@@ -306,7 +296,7 @@ export default function PaymentFormPage() {
306
296
  vAlign="start">
307
297
  <StackItem
308
298
  size="fill"
309
- xstyle={isMobile ? undefined : styles.formColBasis}>
299
+ style={isMobile ? undefined : formColBasis}>
310
300
  <VStack gap={8}>
311
301
  {/* Sign in */}
312
302
  <VStack gap={1}>
@@ -509,11 +499,11 @@ export default function PaymentFormPage() {
509
499
  variant="primary"
510
500
  size="lg"
511
501
  onClick={() => {}}
512
- xstyle={styles.paypalButton}>
502
+ style={paypalButton}>
513
503
  <img
514
504
  src="https://www.paypalobjects.com/webstatic/mktg/Logo/pp-logo-100px.png"
515
505
  alt="PayPal"
516
- {...stylex.props(styles.paypalLogo)}
506
+ style={brandLogo}
517
507
  />
518
508
  </Button>
519
509
  {/* Google Pay */}
@@ -522,11 +512,11 @@ export default function PaymentFormPage() {
522
512
  variant="primary"
523
513
  size="lg"
524
514
  onClick={() => {}}
525
- xstyle={styles.gpayButton}>
515
+ style={gpayButton}>
526
516
  <img
527
517
  src="https://pay.google.com/about/static_kcs/images/logos/google-pay-logo.svg"
528
518
  alt="Google Pay"
529
- {...stylex.props(styles.gpayLogo)}
519
+ style={brandLogo}
530
520
  />
531
521
  </Button>
532
522
  </Grid>
@@ -552,17 +542,17 @@ export default function PaymentFormPage() {
552
542
  <img
553
543
  src="https://raw.githubusercontent.com/aaronfagan/svg-credit-card-payment-icons/main/flat/visa.svg"
554
544
  alt="Visa"
555
- {...stylex.props(styles.cardLogo)}
545
+ style={cardLogo}
556
546
  />
557
547
  <img
558
548
  src="https://raw.githubusercontent.com/aaronfagan/svg-credit-card-payment-icons/main/flat/mastercard.svg"
559
549
  alt="Mastercard"
560
- {...stylex.props(styles.cardLogo)}
550
+ style={cardLogo}
561
551
  />
562
552
  <img
563
553
  src="https://raw.githubusercontent.com/aaronfagan/svg-credit-card-payment-icons/main/flat/amex.svg"
564
554
  alt="Amex"
565
- {...stylex.props(styles.cardLogo)}
555
+ style={cardLogo}
566
556
  />
567
557
  </HStack>
568
558
  <TextInput
@@ -719,7 +709,7 @@ export default function PaymentFormPage() {
719
709
  placeholder="Enter promo code"
720
710
  value={promo}
721
711
  onChange={setPromo}
722
- xstyle={styles.fullWidth}
712
+ style={fullWidth}
723
713
  />
724
714
  </StackItem>
725
715
  <Button
@@ -811,14 +801,14 @@ export default function PaymentFormPage() {
811
801
  label="Place Order"
812
802
  variant="primary"
813
803
  size="lg"
814
- xstyle={styles.fullWidth}
804
+ style={fullWidth}
815
805
  onClick={() => setSubmitted(true)}
816
806
  />
817
807
  <Button
818
808
  label="Continue Shopping"
819
809
  variant="secondary"
820
810
  size="lg"
821
- xstyle={styles.fullWidth}
811
+ style={fullWidth}
822
812
  onClick={() => {}}
823
813
  />
824
814
  </VStack>
@@ -843,18 +833,14 @@ export default function PaymentFormPage() {
843
833
 
844
834
  <StackItem
845
835
  size="fill"
846
- xstyle={
847
- isMobile
848
- ? styles.summaryMobileOrder
849
- : styles.summarySticky
850
- }>
836
+ style={isMobile ? summaryMobileOrder : summarySticky}>
851
837
  <Card padding={5}>
852
838
  <VStack gap={4}>
853
839
  {/* Accordion header — clickable on mobile only */}
854
840
  <Collapsible
855
841
  trigger="Order Summary"
856
842
  defaultIsOpen={true}>
857
- <VStack gap={4} xstyle={styles.summaryContent}>
843
+ <VStack gap={4} style={summaryContent}>
858
844
  {/* Line items */}
859
845
  {ORDER_ITEMS.map(item => (
860
846
  <VStack key={item.id} gap={3}>
@@ -24,36 +24,34 @@ import {Divider} from '@astryxdesign/core/Divider';
24
24
  import {Collapsible, CollapsibleGroup} from '@astryxdesign/core/Collapsible';
25
25
  import {AspectRatio} from '@astryxdesign/core/AspectRatio';
26
26
  import {SelectableCard} from '@astryxdesign/core/SelectableCard';
27
- import * as stylex from '@stylexjs/stylex';
27
+ import type {CSSProperties} from 'react';
28
28
 
29
29
  // Custom CSS here is limited to what Astryx components can't express today:
30
30
  // - image fill + corner radius (no Image primitive — #2582)
31
31
  // - the sticky info column (no sticky prop on Astryx layout primitives — #2613)
32
- const pageStyles = stylex.create({
33
- // Keeps the info column in view while the gallery scrolls. No sticky prop on
34
- // Astryx layout primitives.
35
- stickyInfo: {
36
- position: 'sticky',
37
- top: 'var(--spacing-8)',
38
- alignSelf: 'start',
39
- },
40
- // Fills the AspectRatio box + rounds corners. No objectFit/radius props on
41
- // AspectRatio (#2582).
42
- heroImage: {
43
- width: '100%',
44
- height: '100%',
45
- objectFit: 'cover',
46
- borderRadius: 'var(--radius-container)',
47
- },
48
- // Fills the thumbnail card. Corner radius + selection ring come from
49
- // SelectableCard; the image only needs to fill and cover (#2582).
50
- thumbImage: {
51
- width: '100%',
52
- height: '100%',
53
- objectFit: 'cover',
54
- display: 'block',
55
- },
56
- });
32
+ // Keeps the info column in view while the gallery scrolls. No sticky prop on
33
+ // Astryx layout primitives.
34
+ const stickyInfo: CSSProperties = {
35
+ position: 'sticky',
36
+ top: 'var(--spacing-8)',
37
+ alignSelf: 'start',
38
+ };
39
+ // Fills the AspectRatio box + rounds corners. No objectFit/radius props on
40
+ // AspectRatio (#2582).
41
+ const heroImage: CSSProperties = {
42
+ width: '100%',
43
+ height: '100%',
44
+ objectFit: 'cover',
45
+ borderRadius: 'var(--radius-container)',
46
+ };
47
+ // Fills the thumbnail card. Corner radius + selection ring come from
48
+ // SelectableCard; the image only needs to fill and cover (#2582).
49
+ const thumbImage: CSSProperties = {
50
+ width: '100%',
51
+ height: '100%',
52
+ objectFit: 'cover',
53
+ display: 'block',
54
+ };
57
55
 
58
56
  import {MinusIcon, PlusIcon, StarIcon} from '@heroicons/react/24/outline';
59
57
  import {StarIcon as StarIconSolid} from '@heroicons/react/24/solid';
@@ -133,11 +131,7 @@ function ImageGallery({
133
131
  return (
134
132
  <VStack gap={3}>
135
133
  <AspectRatio ratio={4 / 5}>
136
- <img
137
- {...stylex.props(pageStyles.heroImage)}
138
- src={heroSrc}
139
- alt={PRODUCT.name}
140
- />
134
+ <img style={heroImage} src={heroSrc} alt={PRODUCT.name} />
141
135
  </AspectRatio>
142
136
  <Grid columns={3} gap={2}>
143
137
  {thumbnails.map((src, i) => (
@@ -151,7 +145,7 @@ function ImageGallery({
151
145
  width="100%"
152
146
  height="100%">
153
147
  <img
154
- {...stylex.props(pageStyles.thumbImage)}
148
+ style={thumbImage}
155
149
  src={src}
156
150
  alt={`Product image ${i + 1}`}
157
151
  />
@@ -301,7 +295,7 @@ export default function ProductDetailTemplate() {
301
295
  selected={selectedThumb}
302
296
  onSelect={setSelectedThumb}
303
297
  />
304
- <VStack gap={0} xstyle={pageStyles.stickyInfo}>
298
+ <VStack gap={0} style={stickyInfo}>
305
299
  <ProductInfo />
306
300
  </VStack>
307
301
  </Grid>
@@ -10,19 +10,17 @@ import {AspectRatio} from '@astryxdesign/core/AspectRatio';
10
10
  import {Card} from '@astryxdesign/core/Card';
11
11
  import {Icon} from '@astryxdesign/core/Icon';
12
12
  import {ArrowRightIcon} from '@heroicons/react/24/outline';
13
- import * as stylex from '@stylexjs/stylex';
13
+ import type {CSSProperties} from 'react';
14
14
 
15
15
  // ─── Styles ─────────────────────────────────────────────────────────────────
16
16
  // The only custom CSS is the image fill — there is no Image primitive to
17
17
  // fill the AspectRatio box with `object-fit` (#2582).
18
18
 
19
- const styles = stylex.create({
20
- image: {
21
- width: '100%',
22
- height: '100%',
23
- objectFit: 'cover',
24
- },
25
- });
19
+ const image: CSSProperties = {
20
+ width: '100%',
21
+ height: '100%',
22
+ objectFit: 'cover',
23
+ };
26
24
 
27
25
  // ─── Product Data ───────────────────────────────────────────────────────────
28
26
 
@@ -100,11 +98,7 @@ function ProductCard({product}: {product: Product}) {
100
98
  <VStack gap={3}>
101
99
  <Card padding={0}>
102
100
  <AspectRatio ratio={1}>
103
- <img
104
- src={product.image}
105
- alt={product.name}
106
- {...stylex.props(styles.image)}
107
- />
101
+ <img src={product.image} alt={product.name} style={image} />
108
102
  </AspectRatio>
109
103
  </Card>
110
104
  <VStack gap={1}>
@@ -2,8 +2,7 @@
2
2
 
3
3
  'use client';
4
4
 
5
- import React, {useState} from 'react';
6
- import * as stylex from '@stylexjs/stylex';
5
+ import React, {useState, type CSSProperties} from 'react';
7
6
  import {
8
7
  VStack,
9
8
  HStack,
@@ -26,11 +25,6 @@ import {TabList, Tab} from '@astryxdesign/core/TabList';
26
25
  import {Badge} from '@astryxdesign/core/Badge';
27
26
  import {Icon} from '@astryxdesign/core/Icon';
28
27
  import {Center} from '@astryxdesign/core/Center';
29
- import {
30
- colorVars,
31
- radiusVars,
32
- spacingVars,
33
- } from '@astryxdesign/core/theme/tokens.stylex';
34
28
  import {
35
29
  UserIcon,
36
30
  LockClosedIcon,
@@ -46,33 +40,31 @@ import {
46
40
  ShareIcon,
47
41
  } from '@heroicons/react/24/outline';
48
42
 
49
- const styles = stylex.create({
50
- iconBox: {
51
- borderRadius: radiusVars['--radius-container'],
52
- backgroundColor: colorVars['--color-background-surface'],
53
- flexShrink: 0,
54
- },
55
- // Sticky dialog header bar no Astryx prop for sticky/background/z-index.
56
- // Inline + block padding comes from the parent LayoutContent `padding`.
57
- headerSticky: {
58
- position: 'sticky',
59
- top: 0,
60
- backgroundColor: colorVars['--color-background-surface'],
61
- zIndex: 1,
62
- },
63
- // No `maxWidth` prop on VStack — width only. Inline padding comes from
64
- // the parent LayoutContent `padding`.
65
- contentMaxWidth: {
66
- maxWidth: 680,
67
- },
68
- // Aligns the sidebar heading with list-item label text. No heading margin prop.
69
- sideNavHeading: {
70
- marginInline: spacingVars['--spacing-4'],
71
- },
72
- dialogHeight: {
73
- height: '85vh',
74
- },
75
- });
43
+ const iconBox: CSSProperties = {
44
+ borderRadius: 'var(--radius-container)',
45
+ backgroundColor: 'var(--color-background-surface)',
46
+ flexShrink: 0,
47
+ };
48
+ // Sticky dialog header bar — no Astryx prop for sticky/background/z-index.
49
+ // Inline + block padding comes from the parent LayoutContent `padding`.
50
+ const headerSticky: CSSProperties = {
51
+ position: 'sticky',
52
+ top: 0,
53
+ backgroundColor: 'var(--color-background-surface)',
54
+ zIndex: 1,
55
+ };
56
+ // No `maxWidth` prop on VStack — width only. Inline padding comes from
57
+ // the parent LayoutContent `padding`.
58
+ const contentMaxWidth: CSSProperties = {
59
+ maxWidth: 680,
60
+ };
61
+ // Aligns the sidebar heading with list-item label text. No heading margin prop.
62
+ const sideNavHeading: CSSProperties = {
63
+ marginInline: 'var(--spacing-4)',
64
+ };
65
+ const dialogHeight: CSSProperties = {
66
+ height: '85vh',
67
+ };
76
68
 
77
69
  const NAV_ITEMS = [
78
70
  {label: 'Personal information', icon: UserIcon},
@@ -274,7 +266,7 @@ export default function SettingsDialogTemplate() {
274
266
  maxHeight="85vh"
275
267
  padding={0}
276
268
  purpose="form"
277
- xstyle={styles.dialogHeight}>
269
+ style={dialogHeight}>
278
270
  <Layout
279
271
  height="fill"
280
272
  start={
@@ -284,7 +276,7 @@ export default function SettingsDialogTemplate() {
284
276
  role="navigation"
285
277
  padding={3}>
286
278
  <VStack gap={4}>
287
- <Heading level={2} xstyle={styles.sideNavHeading}>
279
+ <Heading level={2} style={sideNavHeading}>
288
280
  Account settings
289
281
  </Heading>
290
282
  <List density="spacious">
@@ -315,7 +307,7 @@ export default function SettingsDialogTemplate() {
315
307
  content={
316
308
  <LayoutContent isScrollable padding={6}>
317
309
  <VStack gap={6}>
318
- <VStack xstyle={styles.headerSticky}>
310
+ <VStack style={headerSticky}>
319
311
  <DialogHeader
320
312
  title={
321
313
  activeNav === 'Personal information'
@@ -326,7 +318,7 @@ export default function SettingsDialogTemplate() {
326
318
  hasDivider={false}
327
319
  />
328
320
  </VStack>
329
- <VStack gap={0} xstyle={styles.contentMaxWidth}>
321
+ <VStack gap={0} style={contentMaxWidth}>
330
322
  {activeNav === 'Personal information' && (
331
323
  <VStack gap={6}>
332
324
  <VStack gap={4}>
@@ -441,7 +433,7 @@ export default function SettingsDialogTemplate() {
441
433
  <Center
442
434
  width={48}
443
435
  height={48}
444
- xstyle={styles.iconBox}>
436
+ style={iconBox}>
445
437
  <Icon icon={LockClosedIcon} />
446
438
  </Center>
447
439
  <VStack gap={0}>
@@ -465,7 +457,7 @@ export default function SettingsDialogTemplate() {
465
457
  <Center
466
458
  width={48}
467
459
  height={48}
468
- xstyle={styles.iconBox}>
460
+ style={iconBox}>
469
461
  <Icon icon={PencilSquareIcon} />
470
462
  </Center>
471
463
  <VStack gap={0}>
@@ -491,7 +483,7 @@ export default function SettingsDialogTemplate() {
491
483
  <Center
492
484
  width={48}
493
485
  height={48}
494
- xstyle={styles.iconBox}>
486
+ style={iconBox}>
495
487
  <Icon icon={ShareIcon} />
496
488
  </Center>
497
489
  <VStack gap={0}>
@@ -620,7 +612,7 @@ export default function SettingsDialogTemplate() {
620
612
  <Center
621
613
  width={48}
622
614
  height={48}
623
- xstyle={styles.iconBox}>
615
+ style={iconBox}>
624
616
  <Icon icon={LockClosedIcon} />
625
617
  </Center>
626
618
  <VStack gap={1}>
@@ -813,7 +805,7 @@ export default function SettingsDialogTemplate() {
813
805
  <Center
814
806
  width={48}
815
807
  height={48}
816
- xstyle={styles.iconBox}>
808
+ style={iconBox}>
817
809
  <Icon icon={ShieldCheckIcon} />
818
810
  </Center>
819
811
  <VStack gap={1}>