@astryxdesign/cli 0.0.15 → 0.1.0-canary.0b5b49f

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.
@@ -2,22 +2,21 @@
2
2
 
3
3
  'use client';
4
4
 
5
- import {
6
- SideNav,
7
- SideNavHeading,
8
- SideNavItem,
9
- SideNavSection,
10
- } from '@astryxdesign/core/SideNav';
5
+ import {useCallback, useState} from 'react';
6
+ import * as stylex from '@stylexjs/stylex';
11
7
  import {Heading, Text} from '@astryxdesign/core/Text';
12
8
  import {Button} from '@astryxdesign/core/Button';
13
9
  import {Card} from '@astryxdesign/core/Card';
14
10
  import {DropdownMenu} from '@astryxdesign/core/DropdownMenu';
15
11
  import {List, ListItem} from '@astryxdesign/core/List';
16
12
  import {CodeBlock} from '@astryxdesign/core/CodeBlock';
13
+ import {Selector} from '@astryxdesign/core/Selector';
17
14
  import {HStack, VStack, StackItem} from '@astryxdesign/core/Stack';
18
15
  import {Layout, LayoutContent, LayoutPanel} from '@astryxdesign/core/Layout';
19
16
  import {Divider} from '@astryxdesign/core/Divider';
20
17
  import {Icon} from '@astryxdesign/core/Icon';
18
+ import {Outline, type OutlineItem} from '@astryxdesign/core/Outline';
19
+ import {useMediaQuery} from '@astryxdesign/core/hooks';
21
20
  import {
22
21
  SparklesIcon,
23
22
  ClipboardDocumentIcon,
@@ -28,35 +27,75 @@ import {
28
27
  // Main component
29
28
  // ---------------------------------------------------------------------------
30
29
 
30
+ const OUTLINE_ITEMS: OutlineItem[] = [
31
+ {id: 'prerequisites', label: 'Prerequisites', level: 2},
32
+ {id: 'install-package', label: 'Install the package', level: 2},
33
+ {id: 'configure-theming', label: 'Configure theming', level: 2},
34
+ {id: 'next-steps', label: 'Next steps', level: 2},
35
+ ];
36
+
37
+ const OUTLINE_OPTIONS = OUTLINE_ITEMS.map(item => ({
38
+ value: item.id,
39
+ label: item.label,
40
+ }));
41
+
42
+ const styles = stylex.create({
43
+ outlinePanel: {
44
+ position: 'sticky',
45
+ top: 24,
46
+ alignSelf: 'start',
47
+ paddingBlockStart: 120,
48
+ },
49
+ });
50
+
31
51
  export default function TechnicalDocumentationPage() {
52
+ const [activeId, setActiveId] = useState<string | undefined>(
53
+ OUTLINE_ITEMS[0]?.id,
54
+ );
55
+ const isMobile = useMediaQuery('(max-width: 768px)');
56
+
57
+ const scrollToId = useCallback((id: string) => {
58
+ setActiveId(id);
59
+ const target = document.getElementById(id);
60
+ if (target != null) {
61
+ target.scrollIntoView({behavior: 'smooth', block: 'start'});
62
+ window.history.pushState(null, '', `#${id}`);
63
+ }
64
+ }, []);
65
+
32
66
  return (
33
67
  <Layout
34
- height="fill"
68
+ height="auto"
35
69
  contentWidth={960}
36
- start={
37
- <LayoutPanel hasDivider padding={0}>
38
- <SideNav header={<SideNavHeading heading="Product Name" />}>
39
- <SideNavSection title="Navigation" isHeaderHidden>
40
- <SideNavItem label="Home" />
41
- <SideNavItem label="Getting started" isSelected />
42
- </SideNavSection>
43
- </SideNav>
44
- </LayoutPanel>
70
+ end={
71
+ isMobile ? undefined : (
72
+ <LayoutPanel
73
+ isScrollable={false}
74
+ label="On this page"
75
+ role="complementary"
76
+ xstyle={styles.outlinePanel}>
77
+ <Outline items={OUTLINE_ITEMS} onActiveIdChange={setActiveId} />
78
+ </LayoutPanel>
79
+ )
45
80
  }
46
81
  content={
47
- <LayoutContent padding={8}>
82
+ <LayoutContent isScrollable={false} padding={8}>
48
83
  <VStack gap={8}>
49
84
  <VStack gap={2}>
50
- <Text type="display-1">
51
- Getting started with Product Name
52
- </Text>
85
+ <Text type="display-1">Getting started with Product Name</Text>
53
86
  <Text type="supporting" color="secondary">
54
87
  Last updated March 30, 2026
55
88
  </Text>
56
- <Text type="body">
57
- Install the package, configure your theme, and build your first
58
- component in three steps.
59
- </Text>
89
+ {isMobile && (
90
+ <Selector
91
+ label="On this page"
92
+ isLabelHidden
93
+ options={OUTLINE_OPTIONS}
94
+ value={activeId}
95
+ onChange={scrollToId}
96
+ width="100%"
97
+ />
98
+ )}
60
99
  </VStack>
61
100
 
62
101
  <Card>
@@ -64,11 +103,7 @@ export default function TechnicalDocumentationPage() {
64
103
  <HStack gap={2} vAlign="center">
65
104
  <StackItem size="fill">
66
105
  <HStack gap={2} vAlign="center">
67
- <Icon
68
- icon={SparklesIcon}
69
- size="sm"
70
- color="secondary"
71
- />
106
+ <Icon icon={SparklesIcon} size="sm" color="secondary" />
72
107
  <Text type="body" weight="semibold">
73
108
  AI Assistance
74
109
  </Text>
@@ -111,7 +146,9 @@ export default function TechnicalDocumentationPage() {
111
146
  </Card>
112
147
 
113
148
  <VStack gap={4}>
114
- <Heading level={2}>Prerequisites</Heading>
149
+ <Heading id="prerequisites" level={2}>
150
+ Prerequisites
151
+ </Heading>
115
152
  <List density="compact" listStyle="disc">
116
153
  <ListItem label="Node.js 18+" />
117
154
  <ListItem label="React 18 or 19" />
@@ -122,7 +159,9 @@ export default function TechnicalDocumentationPage() {
122
159
  <Divider />
123
160
 
124
161
  <VStack gap={4}>
125
- <Heading level={2}>Install the package</Heading>
162
+ <Heading id="install-package" level={2}>
163
+ Install the package
164
+ </Heading>
126
165
  <Text type="body">
127
166
  Every project starts with installing the core package. This
128
167
  gives you access to all components, tokens, and utilities.
@@ -131,9 +170,11 @@ export default function TechnicalDocumentationPage() {
131
170
  <Text type="body" weight="bold">
132
171
  Step 1: Install the core package
133
172
  </Text>
134
- <Card padding={0}>
135
- <CodeBlock code="npm install @astryxdesign/core" language="bash" />
136
- </Card>
173
+ <CodeBlock
174
+ code="npm install @astryxdesign/core"
175
+ language="bash"
176
+ width="100%"
177
+ />
137
178
  </VStack>
138
179
  <VStack gap={2}>
139
180
  <Text type="body" weight="bold">
@@ -143,42 +184,41 @@ export default function TechnicalDocumentationPage() {
143
184
  Astryx uses StyleX for styling. Add the compiler plugin to your
144
185
  build configuration.
145
186
  </Text>
146
- <Card padding={0}>
147
- <CodeBlock
148
- code="npm install @stylexjs/babel-plugin"
149
- language="bash"
150
- />
151
- </Card>
187
+ <CodeBlock
188
+ code="npm install @stylexjs/babel-plugin"
189
+ language="bash"
190
+ width="100%"
191
+ />
152
192
  </VStack>
153
193
  <VStack gap={2}>
154
194
  <Text type="body" weight="bold">
155
195
  Step 3: Import your first component
156
196
  </Text>
157
- <Card padding={0}>
158
- <CodeBlock
159
- code={`import { Button } from '@astryxdesign/core/Button';
197
+ <CodeBlock
198
+ code={`import { Button } from '@astryxdesign/core/Button';
160
199
 
161
200
  export default function App() {
162
201
  return <Button label="Hello Astryx" variant="primary" />;
163
202
  }`}
164
- language="tsx"
165
- />
166
- </Card>
203
+ language="tsx"
204
+ width="100%"
205
+ />
167
206
  </VStack>
168
207
  </VStack>
169
208
 
170
209
  <Divider />
171
210
 
172
211
  <VStack gap={4}>
173
- <Heading level={2}>Configure theming</Heading>
212
+ <Heading id="configure-theming" level={2}>
213
+ Configure theming
214
+ </Heading>
174
215
  <Text type="body">
175
216
  Astryx ships with a default theme that works out of the box. To
176
217
  customize colors, typography, and spacing, wrap your app in a
177
218
  theme provider.
178
219
  </Text>
179
- <Card padding={0}>
180
- <CodeBlock
181
- code={`import { ThemeProvider } from '@astryxdesign/core/Theme';
220
+ <CodeBlock
221
+ code={`import { ThemeProvider } from '@astryxdesign/core/Theme';
182
222
 
183
223
  export default function App({ children }) {
184
224
  return (
@@ -187,9 +227,9 @@ export default function App({ children }) {
187
227
  </ThemeProvider>
188
228
  );
189
229
  }`}
190
- language="tsx"
191
- />
192
- </Card>
230
+ language="tsx"
231
+ width="100%"
232
+ />
193
233
  <Text type="body" color="secondary">
194
234
  See the theming guide for the full list of customizable tokens.
195
235
  </Text>
@@ -198,7 +238,9 @@ export default function App({ children }) {
198
238
  <Divider />
199
239
 
200
240
  <VStack gap={4}>
201
- <Heading level={2}>Next steps</Heading>
241
+ <Heading id="next-steps" level={2}>
242
+ Next steps
243
+ </Heading>
202
244
  <List density="compact" listStyle="disc">
203
245
  <ListItem label="Fundamental concepts — How theming, layout, and composition work" />
204
246
  <ListItem label="Component API reference — Props, variants, and examples for every component" />
@@ -18,13 +18,10 @@ import {Link} from '@astryxdesign/core/Link';
18
18
  import {Divider} from '@astryxdesign/core/Divider';
19
19
  import {Card} from '@astryxdesign/core/Card';
20
20
  import {Selector} from '@astryxdesign/core/Selector';
21
+ import {radiusVars} from '@astryxdesign/core/theme/tokens.stylex';
21
22
 
22
23
  const ILLUSTRATION_URL =
23
- 'https://lookaside.facebook.com/assets/astryx/illustration-horizontal-1.png';
24
-
25
- // ─────────────────────────────────────────────────────────────
26
- // Constants
27
- // ─────────────────────────────────────────────────────────────
24
+ 'https://lookaside.facebook.com/assets/astryx/light-working-vertical-2.png';
28
25
 
29
26
  const INQUIRY_REASONS = [
30
27
  'New business',
@@ -51,13 +48,9 @@ const CONTACT_COLUMNS = [
51
48
  {label: 'Press & partnerships', email: 'press@company.com'},
52
49
  ];
53
50
 
54
- // ─────────────────────────────────────────────────────────────
55
- // Styles
56
- // ─────────────────────────────────────────────────────────────
57
-
58
- // The only custom styling is fitting the illustration inside its AspectRatio
59
- // box without distortion (contain, not cover — it's line art, don't crop it).
60
- // No objectFit prop on AspectRatio, and there's no Image primitive (#2582).
51
+ // AspectRatio has no objectFit/radius prop and there's no Image primitive
52
+ // (#2582), so the cover photo is styled directly. overflow:hidden masks the
53
+ // cover crop to the rounded corners.
61
54
  const styles = stylex.create({
62
55
  page: {
63
56
  minHeight: '100%',
@@ -65,14 +58,12 @@ const styles = stylex.create({
65
58
  illustrationImg: {
66
59
  width: '100%',
67
60
  height: '100%',
68
- objectFit: 'contain',
61
+ objectFit: 'cover',
62
+ borderRadius: radiusVars['--radius-container'],
63
+ overflow: 'hidden',
69
64
  },
70
65
  });
71
66
 
72
- // ─────────────────────────────────────────────────────────────
73
- // Page
74
- // ─────────────────────────────────────────────────────────────
75
-
76
67
  /**
77
68
  * Form (Two-column) — marketing contact form template.
78
69
  *
@@ -105,15 +96,10 @@ export default function FormTwoColumnPage() {
105
96
 
106
97
  return (
107
98
  <Center xstyle={styles.page}>
108
- <Section
109
- maxWidth={1100}
110
- width="100%"
111
- padding={10}
112
- variant="transparent">
99
+ <Section maxWidth={1100} width="100%" padding={10} variant="transparent">
113
100
  <VStack gap={10}>
114
- {/* ── Top: two-column, stacks to one column below ~520px ── */}
101
+ {/* Two-column; stacks to one column below ~520px. */}
115
102
  <Grid columns={{minWidth: 320}} align="center" gap={10}>
116
- {/* Left: headline + description + illustration */}
117
103
  <VStack gap={6}>
118
104
  <VStack gap={3}>
119
105
  <Text type="display-1" as="h1">
@@ -127,13 +113,12 @@ export default function FormTwoColumnPage() {
127
113
  <AspectRatio ratio={4 / 3}>
128
114
  <img
129
115
  src={ILLUSTRATION_URL}
130
- alt="Person with a laptop and a lightbulb idea"
116
+ alt="Two people working at a desk"
131
117
  {...stylex.props(styles.illustrationImg)}
132
118
  />
133
119
  </AspectRatio>
134
120
  </VStack>
135
121
 
136
- {/* Right: form on a card */}
137
122
  <Card padding={8}>
138
123
  <VStack gap={4}>
139
124
  <Text type="label">Your details</Text>
@@ -188,9 +173,7 @@ export default function FormTwoColumnPage() {
188
173
  </Grid>
189
174
 
190
175
  <VStack gap={2}>
191
- <Text type="label">
192
- What are you reaching out about?
193
- </Text>
176
+ <Text type="label">What are you reaching out about?</Text>
194
177
  <HStack gap={2} wrap="wrap">
195
178
  {INQUIRY_REASONS.map(reason => (
196
179
  <Token
@@ -238,7 +221,7 @@ export default function FormTwoColumnPage() {
238
221
  </Card>
239
222
  </Grid>
240
223
 
241
- {/* ── Bottom: contact strip (stacks below ~440px) ── */}
224
+ {/* Contact strip; stacks below ~440px. */}
242
225
  <VStack gap={6}>
243
226
  <Divider />
244
227
  <Grid columns={{minWidth: 200}} gap={6}>