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,93 +1,30 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
// XLE (canonical structure, validated with `bunx astryx layout check`):
|
|
3
|
-
// L > LC[p=6] > V[g=
|
|
3
|
+
// L > LC[p=6] > V[g=8] > ((V[g=2 a=center] > Hd"Every corner of the castle, caught after dark."[level=1] + Tx"Relics, sketches, and moonlit views from the coven archives, collected over one long Transylvanian night."[t=body]) + (V[g=3] > (V[g=2] > AR[ratio=3/1] + Tx"The castle at moonrise"[t=body]) + (G[c={min:280} g=4] > (V[g=2] > AR[ratio=3/2] + Tx"Coven gathering"[t=body]) + (V[g=2] > AR[ratio=3/2] + Tx"Belfry view"[t=body]) + (V[g=2] > AR[ratio=3/2] + Tx"Crypt archives"[t=body]) + (V[g=2] > AR[ratio=3/2] + Tx"Midnight garden"[t=body]))))
|
|
4
4
|
|
|
5
|
-
import type {CSSProperties} from 'react';
|
|
6
5
|
import {VStack, Layout, LayoutContent} from '@astryxdesign/core/Layout';
|
|
7
6
|
import {Text, Heading} from '@astryxdesign/core/Text';
|
|
8
7
|
import {AspectRatio} from '@astryxdesign/core/AspectRatio';
|
|
8
|
+
import {Grid} from '@astryxdesign/core/Grid';
|
|
9
|
+
import {galleryImageClip} from 'astryx-dracula/shared/gallery-image';
|
|
10
|
+
import {SceneTile} from 'astryx-dracula/shared/scene-tile';
|
|
11
|
+
import type {SceneHue} from 'astryx-dracula/shared/scene-hues';
|
|
9
12
|
|
|
10
13
|
// ─── Styles ────────────────────────────────────────────────────────────────
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
// inline, so a responsive span can't be expressed through its props — this is a
|
|
14
|
-
// @container grid (the sanctioned Astryx pattern for container-responsive layout).
|
|
15
|
-
// The container query lives in a plain <style> tag below so it needs NO CSS
|
|
16
|
-
// compiler. Image fill + radius are custom because Astryx has no image
|
|
17
|
-
// primitive (#2582).
|
|
18
|
-
|
|
19
|
-
// Named inline-size container on the page column so the grid responds to the
|
|
20
|
-
// available content width (works inside the sandbox's resizable preview).
|
|
21
|
-
const containerStyle: CSSProperties = {
|
|
22
|
-
containerType: 'inline-size',
|
|
23
|
-
containerName: 'gallery',
|
|
24
|
-
};
|
|
25
|
-
// Fills the AspectRatio box with a Dracula placeholder scene. No Image
|
|
26
|
-
// primitive in Astryx (#2582), so gallery tiles are inline SVG on brand
|
|
27
|
-
// tokens instead of light-mode data-URI bitmaps.
|
|
28
|
-
const svgStyle: CSSProperties = {
|
|
29
|
-
width: '100%',
|
|
30
|
-
height: '100%',
|
|
31
|
-
display: 'block',
|
|
32
|
-
};
|
|
33
|
-
// Rounds the image corners. No radius prop on AspectRatio (#2582).
|
|
34
|
-
const clipStyle: CSSProperties = {
|
|
35
|
-
borderRadius: 'var(--radius-element)',
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
// 3 columns on desktop, dropping straight to 1 column below 720px (no 2-col
|
|
39
|
-
// middle state). minmax(0, 1fr) (not 1fr) so tracks split evenly and ignore the
|
|
40
|
-
// images' intrinsic min-width. The hero spans 2 columns on desktop, then fills
|
|
41
|
-
// the row once it's single-column.
|
|
42
|
-
const GALLERY_CSS = `
|
|
43
|
-
.mixed-gallery-grid {
|
|
44
|
-
display: grid;
|
|
45
|
-
gap: var(--spacing-3);
|
|
46
|
-
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
47
|
-
}
|
|
48
|
-
.mixed-gallery-hero {
|
|
49
|
-
grid-column: span 2;
|
|
50
|
-
}
|
|
51
|
-
/* The hero image stretches to the row height instead of keeping its own
|
|
52
|
-
ratio: a 3:1 hero spanning 2 columns + 1 gap is taller than the 3:2 sidebar
|
|
53
|
-
by exactly gap/3, so ratio-driven heights can never align. The sidebar keeps
|
|
54
|
-
its ratio (it defines the row height); the hero flex-fills the leftover cell
|
|
55
|
-
height. flex-basis is 0px — not 0%: a percentage basis falls back to content
|
|
56
|
-
size against the indefinite grid-row measurement, which would let the hero's
|
|
57
|
-
own ratio define the row again. 0px contributes nothing, so the row follows
|
|
58
|
-
the sidebar exactly (equal single-line captions keep the math exact), and
|
|
59
|
-
the hero grows into it. AspectRatio's aspect-ratio yields once flex gives it
|
|
60
|
-
a definite height; the svg slice-fills either way. */
|
|
61
|
-
.mixed-gallery-hero > :first-child {
|
|
62
|
-
flex: 1 1 0px;
|
|
63
|
-
min-height: 0;
|
|
64
|
-
}
|
|
65
|
-
@container gallery (max-width: 720px) {
|
|
66
|
-
.mixed-gallery-grid {
|
|
67
|
-
grid-template-columns: minmax(0, 1fr);
|
|
68
|
-
}
|
|
69
|
-
.mixed-gallery-hero {
|
|
70
|
-
grid-column: 1 / -1;
|
|
71
|
-
}
|
|
72
|
-
/* Single column: no sibling defines the row, so the hero falls back to its
|
|
73
|
-
own 3:1 ratio. */
|
|
74
|
-
.mixed-gallery-hero > :first-child {
|
|
75
|
-
flex: none;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
`;
|
|
14
|
+
// Image fill + radius live in shared/gallery-image (no Image primitive in
|
|
15
|
+
// Astryx, #2582). Tile art lives in shared/scene-tile (large fork).
|
|
79
16
|
|
|
80
17
|
// ─── Gallery Data ───────────────────────────────────────────────────────────
|
|
81
18
|
|
|
82
19
|
interface GalleryImage {
|
|
83
20
|
title: string;
|
|
84
|
-
hue:
|
|
21
|
+
hue: SceneHue;
|
|
85
22
|
}
|
|
86
23
|
|
|
87
24
|
// One accent per tile from the fixed badge vocabulary; the SVG scenes below
|
|
88
25
|
// resolve to Dracula tokens so tiles stay on-brand in the dark-only theme.
|
|
89
26
|
const IMAGES: GalleryImage[] = [
|
|
90
|
-
{title: 'The castle at moonrise', hue: 'var(--dracula-
|
|
27
|
+
{title: 'The castle at moonrise', hue: 'var(--dracula-orange)'},
|
|
91
28
|
{title: 'Coven gathering', hue: 'var(--dracula-cyan)'},
|
|
92
29
|
{title: 'Belfry view', hue: 'var(--dracula-pink)'},
|
|
93
30
|
{title: 'Crypt archives', hue: 'var(--dracula-yellow)'},
|
|
@@ -98,42 +35,15 @@ const IMAGES: GalleryImage[] = [
|
|
|
98
35
|
// Each tile is an image plus its caption (titles lived only in aria-labels
|
|
99
36
|
// before, leaving the tiles cryptic). AspectRatio gives every image a
|
|
100
37
|
// definite, self-contained height from its ratio, so images can't overflow
|
|
101
|
-
// their grid cell
|
|
102
|
-
// row height instead via GALLERY_CSS (see above).
|
|
38
|
+
// their grid cell and no tile depends on a neighbour's caption height.
|
|
103
39
|
|
|
104
|
-
function GalleryCard({
|
|
105
|
-
image,
|
|
106
|
-
ratio,
|
|
107
|
-
className,
|
|
108
|
-
}: {
|
|
109
|
-
image: GalleryImage;
|
|
110
|
-
ratio: number;
|
|
111
|
-
className?: string;
|
|
112
|
-
}) {
|
|
40
|
+
function GalleryCard({image, ratio}: {image: GalleryImage; ratio: number}) {
|
|
113
41
|
return (
|
|
114
|
-
<VStack gap={2}
|
|
115
|
-
<AspectRatio ratio={ratio} style={
|
|
116
|
-
<
|
|
117
|
-
viewBox="0 0 400 300"
|
|
118
|
-
preserveAspectRatio="xMidYMid slice"
|
|
119
|
-
style={svgStyle}
|
|
120
|
-
role="img"
|
|
121
|
-
aria-label={image.title}>
|
|
122
|
-
<rect width="400" height="300" fill="var(--dracula-bg-light)" />
|
|
123
|
-
<g
|
|
124
|
-
transform="translate(200 150)"
|
|
125
|
-
fill="none"
|
|
126
|
-
stroke="var(--dracula-comment)"
|
|
127
|
-
strokeWidth="5"
|
|
128
|
-
strokeLinecap="round"
|
|
129
|
-
strokeLinejoin="round">
|
|
130
|
-
<rect x="-44" y="-44" width="88" height="88" rx="5" />
|
|
131
|
-
<circle cx="18" cy="-18" r="2.5" fill={image.hue} stroke="none" />
|
|
132
|
-
<path d="M-34 30 L-8 0 L10 18 L20 8 L34 24" />
|
|
133
|
-
</g>
|
|
134
|
-
</svg>
|
|
42
|
+
<VStack gap={2}>
|
|
43
|
+
<AspectRatio ratio={ratio} style={galleryImageClip}>
|
|
44
|
+
<SceneTile label={image.title} hue={image.hue} size="lg" />
|
|
135
45
|
</AspectRatio>
|
|
136
|
-
<Text type="
|
|
46
|
+
<Text type="body" color="secondary" justify="center">
|
|
137
47
|
{image.title}
|
|
138
48
|
</Text>
|
|
139
49
|
</VStack>
|
|
@@ -149,41 +59,30 @@ export default function MixedGallery() {
|
|
|
149
59
|
contentWidth={1400}
|
|
150
60
|
content={
|
|
151
61
|
<LayoutContent padding={6}>
|
|
152
|
-
<
|
|
153
|
-
<VStack gap={6} style={containerStyle}>
|
|
62
|
+
<VStack gap={8}>
|
|
154
63
|
{/* Header */}
|
|
155
64
|
<VStack gap={2} hAlign="center">
|
|
156
65
|
<Heading level={1} justify="center">
|
|
157
66
|
Every corner of the castle, caught after dark.
|
|
158
67
|
</Heading>
|
|
159
68
|
<Text type="body" color="secondary" justify="center">
|
|
160
|
-
Relics, sketches, and moonlit views from the coven archives
|
|
69
|
+
Relics, sketches, and moonlit views from the coven archives,
|
|
161
70
|
collected over one long Transylvanian night.
|
|
162
71
|
</Text>
|
|
163
72
|
</VStack>
|
|
164
73
|
|
|
165
|
-
{/* Featured layout
|
|
166
|
-
of
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
/>
|
|
178
|
-
|
|
179
|
-
{/* Sidebar — its ratio defines the row height */}
|
|
180
|
-
<GalleryCard image={IMAGES[2]} ratio={3 / 2} />
|
|
181
|
-
|
|
182
|
-
{/* Bottom row — three equal tiles */}
|
|
183
|
-
<GalleryCard image={IMAGES[3]} ratio={3 / 2} />
|
|
184
|
-
<GalleryCard image={IMAGES[4]} ratio={3 / 2} />
|
|
185
|
-
<GalleryCard image={IMAGES[1]} ratio={3 / 2} />
|
|
186
|
-
</div>
|
|
74
|
+
{/* Featured layout: the wide 3:1 hero heads the page, then the rest
|
|
75
|
+
of the set reflows as a grid (4 → 2 → 1 columns). Every tile
|
|
76
|
+
keeps its own ratio, so no tile's height depends on another's
|
|
77
|
+
caption wrapping. */}
|
|
78
|
+
<VStack gap={3}>
|
|
79
|
+
<GalleryCard image={IMAGES[0]} ratio={3 / 1} />
|
|
80
|
+
<Grid columns={{minWidth: 280}} gap={4}>
|
|
81
|
+
{IMAGES.slice(1).map(image => (
|
|
82
|
+
<GalleryCard key={image.title} image={image} ratio={3 / 2} />
|
|
83
|
+
))}
|
|
84
|
+
</Grid>
|
|
85
|
+
</VStack>
|
|
187
86
|
</VStack>
|
|
188
87
|
</LayoutContent>
|
|
189
88
|
}
|