astryx-dracula 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/BRAND.md +30 -18
- package/README.md +17 -12
- package/USAGE.md +29 -10
- package/astryx-dracula.js +19 -13
- package/astryx-dracula.variants.d.ts +15 -0
- package/package.json +59 -17
- package/shared/auth-chrome-config.ts +18 -0
- package/shared/auth-chrome.tsx +25 -0
- package/shared/auth-copy.ts +22 -0
- package/shared/chaptered-doc-config.ts +92 -0
- package/shared/chaptered-doc.tsx +332 -0
- package/shared/chart-hues.ts +27 -0
- package/shared/chart-labels.tsx +44 -0
- package/shared/chart-legend.tsx +100 -0
- package/shared/chart-panel-style.ts +13 -0
- package/shared/data-bar.tsx +160 -0
- package/shared/gallery-image.ts +20 -0
- package/shared/login-demo.ts +7 -0
- package/shared/metric-delta.tsx +36 -0
- package/shared/order-desk.tsx +273 -0
- package/shared/revenue-chart.tsx +174 -0
- package/shared/scene-castle.tsx +322 -0
- package/shared/scene-frame.tsx +88 -0
- package/shared/scene-hues.ts +49 -0
- package/shared/scene-tile.tsx +128 -0
- package/shared/settings-data.ts +125 -0
- package/shared/settings-rows.tsx +179 -0
- package/shared/sparkline.tsx +94 -0
- package/shared/sso-icons.tsx +30 -0
- package/templates/ai-chat-landing.tsx +66 -33
- package/templates/ai-chat.tsx +36 -19
- package/templates/blank.tsx +4 -3
- package/templates/centered-hero.tsx +14 -125
- package/templates/classic-gallery.tsx +20 -66
- package/templates/contact-form.tsx +59 -39
- package/templates/dashboard-portfolio.tsx +143 -226
- package/templates/dashboard.tsx +122 -122
- package/templates/detail-page.tsx +95 -91
- package/templates/documentation-design.template.mjs +1 -1
- package/templates/documentation-design.tsx +83 -96
- package/templates/documentation-technical.template.mjs +1 -1
- package/templates/documentation-technical.tsx +29 -19
- package/templates/documentation.template.mjs +1 -1
- package/templates/documentation.tsx +52 -74
- package/templates/editor.tsx +112 -84
- package/templates/file-explorer.tsx +131 -84
- package/templates/form-two-column.tsx +61 -125
- package/templates/gallery-hero.tsx +15 -171
- package/templates/ide.tsx +22 -20
- package/templates/incident-console.tsx +104 -70
- package/templates/kanban-board.tsx +99 -42
- package/templates/library.template.mjs +2 -2
- package/templates/library.tsx +37 -42
- package/templates/login-card.tsx +58 -87
- package/templates/login-split.tsx +88 -126
- package/templates/login-sso.tsx +105 -64
- package/templates/login.tsx +107 -53
- package/templates/messaging-shell.tsx +171 -144
- package/templates/mixed-gallery.tsx +29 -130
- package/templates/payment-form.tsx +368 -290
- package/templates/product-detail.tsx +39 -58
- package/templates/product-gallery.tsx +30 -41
- package/templates/product-tour.template.mjs +6 -0
- package/templates/product-tour.tsx +916 -0
- package/templates/settings-dialog.tsx +135 -282
- package/templates/settings-sidebar.tsx +178 -268
- package/templates/settings.tsx +41 -14
- package/templates/shell-nav.tsx +31 -24
- package/templates/shell-side-nav.tsx +29 -20
- package/templates/shell-top-nav.tsx +80 -44
- package/templates/side-gallery.tsx +38 -94
- package/templates/table-grouped.tsx +62 -34
- package/templates/table-page-chart.tsx +23 -302
- package/templates/table-page-heatmap-status.tsx +156 -92
- package/templates/table-page-shoe-store-heatmap.tsx +18 -293
- package/templates/table-page.tsx +23 -7
- package/templates/table.tsx +23 -8
- package/templates/tech-report.template.mjs +6 -0
- package/templates/tech-report.tsx +1486 -0
- package/templates/theme-showcase.template.mjs +1 -1
- package/templates/theme-showcase.tsx +299 -237
- package/theme.css +76 -14
- package/tokens.css +425 -30
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
// XLE (canonical structure, validated with `bunx astryx layout check`):
|
|
3
|
-
// L > (LC > V[g=8] > (V[g=2] >
|
|
3
|
+
// L > (LC > V[g=8] > (V[g=2] > Hd"Getting started with Astryx Dracula"[level=1] + Tx"Last updated March 30, 2026"[t=supporting]) + (C > V[g=3] > (H[j=between] > (H[g=2] > Ic + Tx"AI Assistance"[t=body]) + (H > B"Copy prompt" + DM)) + Tx"Prompt description"[t=body]) + (V[g=4] > Hd"Prerequisites"[level=2] + UL) + D + (V[g=4] > Hd"Install the package"[level=2] + Tx"Description"[t=body] + (V[g=2] > Tx"Step"[t=body] + Cd)*3) + D + (V[g=4] > Hd"Configure theming"[level=2] + Tx"Description"[t=body] + Cd + Tx"Note"[t=body]) + D + (V[g=4] > Hd"Next steps"[level=2] + UL)) + (LP > Outline)
|
|
4
4
|
|
|
5
|
-
import {useCallback, useState
|
|
5
|
+
import {useCallback, useState} from 'react';
|
|
6
6
|
import {Heading, Text} from '@astryxdesign/core/Text';
|
|
7
7
|
import {Button} from '@astryxdesign/core/Button';
|
|
8
8
|
import {Card} from '@astryxdesign/core/Card';
|
|
@@ -17,11 +17,31 @@ import {Icon} from '@astryxdesign/core/Icon';
|
|
|
17
17
|
import {Outline, type OutlineItem} from '@astryxdesign/core/Outline';
|
|
18
18
|
import {useMediaQuery} from '@astryxdesign/core/hooks';
|
|
19
19
|
import {Sparkles, ClipboardCopy, ChevronDown} from 'lucide-react';
|
|
20
|
+
import {outlinePanel} from 'astryx-dracula/shared/chaptered-doc-config';
|
|
20
21
|
|
|
21
22
|
// ---------------------------------------------------------------------------
|
|
22
23
|
// Main component
|
|
23
24
|
// ---------------------------------------------------------------------------
|
|
24
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Documentation technical — the getting-started guide: prerequisites, install steps, theming, and next steps. (Frame/responsive/container: see XLE header above.)
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
// Same prompt in the copy action and the visible body: one string, so the
|
|
31
|
+
// two can never drift.
|
|
32
|
+
const SETUP_PROMPT =
|
|
33
|
+
'Help me get set up with Astryx Dracula. Based on my project, do the following: 1. Install @astryxdesign/core and the StyleX compiler. 2. Wrap my app in ThemeProvider. 3. Replace one existing component with an Astryx equivalent. After setup, suggest relevant next steps based on my project.';
|
|
34
|
+
|
|
35
|
+
// Copies the setup prompt in the shape each tool wants to receive it. The
|
|
36
|
+
// menu cannot navigate anywhere from a static template, so the action says
|
|
37
|
+
// what it does.
|
|
38
|
+
const PROMPT_TARGETS = ['v0', 'Claude', 'ChatGPT', 'Cursor'].map(target => ({
|
|
39
|
+
label: `Copy for ${target}`,
|
|
40
|
+
onClick: () => {
|
|
41
|
+
void navigator.clipboard.writeText(SETUP_PROMPT);
|
|
42
|
+
},
|
|
43
|
+
}));
|
|
44
|
+
|
|
25
45
|
const OUTLINE_ITEMS: OutlineItem[] = [
|
|
26
46
|
{id: 'prerequisites', label: 'Prerequisites', level: 2},
|
|
27
47
|
{id: 'install-package', label: 'Install the package', level: 2},
|
|
@@ -34,13 +54,6 @@ const OUTLINE_OPTIONS = OUTLINE_ITEMS.map(item => ({
|
|
|
34
54
|
label: item.label,
|
|
35
55
|
}));
|
|
36
56
|
|
|
37
|
-
const outlinePanel: CSSProperties = {
|
|
38
|
-
position: 'sticky',
|
|
39
|
-
top: 24,
|
|
40
|
-
alignSelf: 'start',
|
|
41
|
-
paddingBlockStart: 120,
|
|
42
|
-
};
|
|
43
|
-
|
|
44
57
|
export default function DocumentationTechnical() {
|
|
45
58
|
const [activeId, setActiveId] = useState<string | undefined>(
|
|
46
59
|
OUTLINE_ITEMS[0]?.id,
|
|
@@ -75,7 +88,7 @@ export default function DocumentationTechnical() {
|
|
|
75
88
|
<LayoutContent isScrollable={false} padding={8}>
|
|
76
89
|
<VStack gap={8}>
|
|
77
90
|
<VStack gap={2}>
|
|
78
|
-
<
|
|
91
|
+
<Heading level={1}>Getting started with Astryx Dracula</Heading>
|
|
79
92
|
<Text type="supporting" color="secondary" hasTabularNumbers>
|
|
80
93
|
Last updated March 30, 2026
|
|
81
94
|
</Text>
|
|
@@ -108,9 +121,7 @@ export default function DocumentationTechnical() {
|
|
|
108
121
|
size="sm"
|
|
109
122
|
icon={<Icon icon={ClipboardCopy} />}
|
|
110
123
|
onClick={() => {
|
|
111
|
-
void navigator.clipboard.writeText(
|
|
112
|
-
'Help me get set up with Astryx Dracula. Based on my project, do the following: 1. Install @astryxdesign/core and the StyleX compiler. 2. Wrap my app in ThemeProvider. 3. Replace one existing component with an Astryx equivalent. After setup, suggest relevant next steps based on my project.',
|
|
113
|
-
);
|
|
124
|
+
void navigator.clipboard.writeText(SETUP_PROMPT);
|
|
114
125
|
}}
|
|
115
126
|
/>
|
|
116
127
|
<DropdownMenu
|
|
@@ -121,12 +132,7 @@ export default function DocumentationTechnical() {
|
|
|
121
132
|
isIconOnly: true,
|
|
122
133
|
icon: <Icon icon={ChevronDown} />,
|
|
123
134
|
}}
|
|
124
|
-
items={
|
|
125
|
-
{label: 'Open in v0', onClick: () => {}},
|
|
126
|
-
{label: 'Open in Claude', onClick: () => {}},
|
|
127
|
-
{label: 'Open in ChatGPT', onClick: () => {}},
|
|
128
|
-
{label: 'Open in Cursor', onClick: () => {}},
|
|
129
|
-
]}
|
|
135
|
+
items={PROMPT_TARGETS}
|
|
130
136
|
/>
|
|
131
137
|
</HStack>
|
|
132
138
|
<Text type="body" color="secondary">
|
|
@@ -174,6 +180,7 @@ export default function DocumentationTechnical() {
|
|
|
174
180
|
code="npm install @astryxdesign/core"
|
|
175
181
|
language="bash"
|
|
176
182
|
width="100%"
|
|
183
|
+
hasCopyButton
|
|
177
184
|
/>
|
|
178
185
|
</VStack>
|
|
179
186
|
<VStack gap={2}>
|
|
@@ -190,6 +197,7 @@ export default function DocumentationTechnical() {
|
|
|
190
197
|
import '@astryxdesign/core/astryx.css';`}
|
|
191
198
|
language="tsx"
|
|
192
199
|
width="100%"
|
|
200
|
+
hasCopyButton
|
|
193
201
|
/>
|
|
194
202
|
</VStack>
|
|
195
203
|
<VStack gap={2}>
|
|
@@ -204,6 +212,7 @@ export default function App() {
|
|
|
204
212
|
}`}
|
|
205
213
|
language="tsx"
|
|
206
214
|
width="100%"
|
|
215
|
+
hasCopyButton
|
|
207
216
|
/>
|
|
208
217
|
</VStack>
|
|
209
218
|
</VStack>
|
|
@@ -231,6 +240,7 @@ export default function App({ children }) {
|
|
|
231
240
|
}`}
|
|
232
241
|
language="tsx"
|
|
233
242
|
width="100%"
|
|
243
|
+
hasCopyButton
|
|
234
244
|
/>
|
|
235
245
|
<Text type="body" color="secondary">
|
|
236
246
|
See the theming guide for the full list of customizable tokens.
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
// XLE (canonical structure, validated with `bunx astryx layout check`):
|
|
3
|
-
//
|
|
3
|
+
// Counts: 31 total, Core 18 / Layout 4 / Navigation 4 / Form 5. Derived at
|
|
4
|
+
// render from COMPONENT_CATEGORIES, so these numerals must move together with
|
|
5
|
+
// the array -- the gate in scripts/check.ts reads the rendered count, not this
|
|
6
|
+
// comment.
|
|
7
|
+
// L > LC > V[g=10] > (C[p=10] > (H[g=8 a=center] > (V[g=4] > Hd"The coven grimoire"[level=1 t=display-1] + Tx.lg"Every incantation in the Astryx spellbook"[t=large] + (H > B.primary"Enter the grimoire")))) + (V[g=4] > (H[j=between a=center] > Hd"Core"[level=2] + Tx"18 spells"[t=body]) + (H[j=between a=center] > Hd"Layout"[level=2] + Tx"4 spells"[t=body]) + (H[j=between a=center] > Hd"Navigation"[level=2] + Tx"4 spells"[t=body]) + (H[j=between a=center] > Hd"Form"[level=2] + Tx"5 spells"[t=body]) + (G[c={min:260} g=4] > (CC[p=4] > V[g=3] > C[p=0] + (V[g=1] > Tx"Avatar"[t=body] + Tx"Avatars represent"[t=body]))*4))
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Documentation catalog — every component shelf in the grimoire. Frame-first layout (see `bunx astryx docs layout`): (Frame/responsive/container: see XLE header above.)
|
|
11
|
+
*/
|
|
4
12
|
|
|
5
13
|
import type {CSSProperties} from 'react';
|
|
6
14
|
import {Heading, Text} from '@astryxdesign/core/Text';
|
|
@@ -10,25 +18,25 @@ import {ClickableCard} from '@astryxdesign/core/ClickableCard';
|
|
|
10
18
|
import {HStack, VStack, StackItem} from '@astryxdesign/core/Stack';
|
|
11
19
|
import {Layout, LayoutContent} from '@astryxdesign/core/Layout';
|
|
12
20
|
import {Grid} from '@astryxdesign/core/Grid';
|
|
21
|
+
import {SceneTile} from 'astryx-dracula/shared/scene-tile';
|
|
22
|
+
import {galleryImageClip} from 'astryx-dracula/shared/gallery-image';
|
|
23
|
+
import type {SceneHue} from 'astryx-dracula/shared/scene-hues';
|
|
13
24
|
|
|
14
|
-
const previewArt: CSSProperties = {
|
|
15
|
-
width: '100%',
|
|
16
|
-
height: '100%',
|
|
17
|
-
display: 'block',
|
|
18
|
-
};
|
|
19
|
-
const previewClip: CSSProperties = {
|
|
20
|
-
borderRadius: 'var(--radius-element)',
|
|
21
|
-
overflow: 'clip',
|
|
22
|
-
};
|
|
23
25
|
// Negative margin offsets each card's 8px padding so the grid content stays
|
|
24
26
|
// visually aligned while giving every card a padded hover/click target.
|
|
25
27
|
const cardGrid: CSSProperties = {
|
|
26
|
-
margin: -
|
|
28
|
+
margin: 'calc(var(--spacing-2) * -1)',
|
|
27
29
|
};
|
|
28
30
|
|
|
29
|
-
//
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
// Same-route hash: demo links stay focusable anchors without escaping the
|
|
32
|
+
// template through the hash router (bare "#" would drop back to the home page).
|
|
33
|
+
const SELF_HASH = '#/templates/documentation';
|
|
34
|
+
|
|
35
|
+
// Decorative accent per grimoire shelf. None of them is purple: the sigils
|
|
36
|
+
// are not interactive, and purple belongs to the things that are. Art lives
|
|
37
|
+
// in shared/scene-tile (lg fork: centered glyph on a flat field).
|
|
38
|
+
const SHELF_HUES: Record<string, SceneHue> = {
|
|
39
|
+
Core: 'var(--dracula-pink)',
|
|
32
40
|
Layout: 'var(--dracula-cyan)',
|
|
33
41
|
Navigation: 'var(--dracula-green)',
|
|
34
42
|
Form: 'var(--dracula-yellow)',
|
|
@@ -216,50 +224,16 @@ const COMPONENT_CATEGORIES = [
|
|
|
216
224
|
},
|
|
217
225
|
];
|
|
218
226
|
|
|
219
|
-
//
|
|
220
|
-
//
|
|
221
|
-
//
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
style={previewArt}
|
|
230
|
-
role="img"
|
|
231
|
-
aria-label={`${name} sigil`}>
|
|
232
|
-
<rect width="400" height="300" fill="var(--dracula-bg-light)" />
|
|
233
|
-
<circle cx="316" cy="66" r="26" fill={hue} opacity={0.85} />
|
|
234
|
-
<circle
|
|
235
|
-
cx="306"
|
|
236
|
-
cy="60"
|
|
237
|
-
r="21"
|
|
238
|
-
fill="var(--dracula-bg-light)"
|
|
239
|
-
opacity={0.5}
|
|
240
|
-
/>
|
|
241
|
-
<path
|
|
242
|
-
d="M0 208 Q110 168 210 198 T400 184 V300 H0 Z"
|
|
243
|
-
fill="var(--dracula-current-line)"
|
|
244
|
-
/>
|
|
245
|
-
<path
|
|
246
|
-
d="M0 236 Q130 206 260 230 T400 222 V300 H0 Z"
|
|
247
|
-
fill="var(--dracula-bg)"
|
|
248
|
-
/>
|
|
249
|
-
<g
|
|
250
|
-
transform="translate(140 150)"
|
|
251
|
-
fill="none"
|
|
252
|
-
stroke="var(--dracula-comment)"
|
|
253
|
-
strokeWidth="5"
|
|
254
|
-
strokeLinecap="round"
|
|
255
|
-
strokeLinejoin="round">
|
|
256
|
-
<rect x="-44" y="-44" width="88" height="88" rx="5" />
|
|
257
|
-
<circle cx="18" cy="-18" r="2.5" fill={hue} stroke="none" />
|
|
258
|
-
<path d="M-34 30 L-8 0 L10 18 L20 8 L34 24" />
|
|
259
|
-
</g>
|
|
260
|
-
</svg>
|
|
261
|
-
);
|
|
262
|
-
}
|
|
227
|
+
// Every count in this template is DERIVED from the array above, never written as
|
|
228
|
+
// a numeral. The hero copy and the per-category "N spells" line both read this
|
|
229
|
+
// and `items.length`, so adding a component can no longer make the page lie
|
|
230
|
+
// about its own size -- which is what happened while the hero copy said
|
|
231
|
+
// "twenty-eight" against 31 entries and the XLE header said 15 for a category
|
|
232
|
+
// of 18.
|
|
233
|
+
const COMPONENT_TOTAL = COMPONENT_CATEGORIES.reduce(
|
|
234
|
+
(sum, category) => sum + category.items.length,
|
|
235
|
+
0,
|
|
236
|
+
);
|
|
263
237
|
|
|
264
238
|
// ---------------------------------------------------------------------------
|
|
265
239
|
// Main component
|
|
@@ -273,26 +247,26 @@ export default function DocumentationCatalog() {
|
|
|
273
247
|
content={
|
|
274
248
|
<LayoutContent padding={8}>
|
|
275
249
|
<VStack gap={10}>
|
|
276
|
-
<Card variant="
|
|
250
|
+
<Card variant="transparent" padding={10}>
|
|
277
251
|
<HStack gap={8} vAlign="center">
|
|
278
252
|
<StackItem size="fill">
|
|
279
253
|
<VStack gap={4}>
|
|
280
|
-
<
|
|
254
|
+
<Heading level={1} type="display-1">
|
|
255
|
+
The coven grimoire
|
|
256
|
+
</Heading>
|
|
281
257
|
<Text type="large" weight="normal" color="secondary">
|
|
282
|
-
Every incantation in the Astryx spellbook
|
|
283
|
-
components for building beautiful,
|
|
284
|
-
after dark.
|
|
258
|
+
Every incantation in the Astryx spellbook, with{' '}
|
|
259
|
+
{COMPONENT_TOTAL} components for building beautiful,
|
|
260
|
+
accessible products after dark.
|
|
285
261
|
</Text>
|
|
286
262
|
<HStack>
|
|
287
263
|
<Button
|
|
288
264
|
label="Enter the grimoire"
|
|
289
265
|
variant="primary"
|
|
290
|
-
size="lg"
|
|
291
266
|
/>
|
|
292
267
|
</HStack>
|
|
293
268
|
</VStack>
|
|
294
269
|
</StackItem>
|
|
295
|
-
<StackItem size="fill" />
|
|
296
270
|
</HStack>
|
|
297
271
|
</Card>
|
|
298
272
|
|
|
@@ -301,33 +275,37 @@ export default function DocumentationCatalog() {
|
|
|
301
275
|
<HStack justify="between" vAlign="center">
|
|
302
276
|
<Heading level={2}>{category.label}</Heading>
|
|
303
277
|
<Text
|
|
304
|
-
type="
|
|
278
|
+
type="body"
|
|
305
279
|
color="secondary"
|
|
306
280
|
hasTabularNumbers>
|
|
307
281
|
{category.items.length}{' '}
|
|
308
282
|
{category.items.length === 1 ? 'spell' : 'spells'}
|
|
309
283
|
</Text>
|
|
310
284
|
</HStack>
|
|
311
|
-
<Grid columns={{minWidth: 260}} gap={
|
|
285
|
+
<Grid columns={{minWidth: 260}} gap={4} style={cardGrid}>
|
|
312
286
|
{category.items.map(item => (
|
|
313
287
|
<ClickableCard
|
|
314
288
|
key={item.key}
|
|
315
289
|
label={`Open ${item.name}`}
|
|
316
|
-
|
|
290
|
+
href={SELF_HASH}
|
|
317
291
|
variant="transparent"
|
|
318
|
-
padding={
|
|
292
|
+
padding={4}>
|
|
319
293
|
<VStack gap={3}>
|
|
320
294
|
<Card
|
|
321
295
|
variant="muted"
|
|
322
296
|
padding={0}
|
|
323
297
|
minHeight={160}
|
|
324
|
-
style={
|
|
325
|
-
<
|
|
326
|
-
|
|
327
|
-
|
|
298
|
+
style={galleryImageClip}>
|
|
299
|
+
<SceneTile
|
|
300
|
+
label={`${item.name} sigil`}
|
|
301
|
+
hue={
|
|
302
|
+
SHELF_HUES[category.label] ??
|
|
303
|
+
'var(--dracula-comment)'
|
|
304
|
+
}
|
|
305
|
+
size="lg"
|
|
328
306
|
/>
|
|
329
307
|
</Card>
|
|
330
|
-
<VStack gap={
|
|
308
|
+
<VStack gap={1}>
|
|
331
309
|
<Text type="body" weight="semibold">
|
|
332
310
|
{item.name}
|
|
333
311
|
</Text>
|