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