astryx-dracula 0.1.5 → 0.2.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 (90) hide show
  1. package/README.md +8 -0
  2. package/USAGE.md +13 -0
  3. package/astryx.integration.mjs +3 -0
  4. package/package.json +4 -2
  5. package/templates/ai-chat-landing.template.mjs +6 -0
  6. package/templates/ai-chat-landing.tsx +478 -0
  7. package/templates/ai-chat.template.mjs +6 -0
  8. package/templates/ai-chat.tsx +766 -0
  9. package/templates/blank.template.mjs +6 -0
  10. package/templates/blank.tsx +18 -0
  11. package/templates/centered-hero.template.mjs +6 -0
  12. package/templates/centered-hero.tsx +190 -0
  13. package/templates/classic-gallery.template.mjs +6 -0
  14. package/templates/classic-gallery.tsx +183 -0
  15. package/templates/contact-form.template.mjs +6 -0
  16. package/templates/contact-form.tsx +294 -0
  17. package/templates/dashboard-portfolio.template.mjs +6 -0
  18. package/templates/dashboard-portfolio.tsx +802 -0
  19. package/templates/dashboard.template.mjs +6 -0
  20. package/templates/dashboard.tsx +776 -0
  21. package/templates/detail-page.template.mjs +6 -0
  22. package/templates/detail-page.tsx +697 -0
  23. package/templates/documentation-design.template.mjs +6 -0
  24. package/templates/documentation-design.tsx +753 -0
  25. package/templates/documentation-technical.template.mjs +6 -0
  26. package/templates/documentation-technical.tsx +294 -0
  27. package/templates/documentation.template.mjs +6 -0
  28. package/templates/documentation.tsx +349 -0
  29. package/templates/editor.template.mjs +6 -0
  30. package/templates/editor.tsx +961 -0
  31. package/templates/file-explorer.template.mjs +6 -0
  32. package/templates/file-explorer.tsx +579 -0
  33. package/templates/form-two-column.template.mjs +6 -0
  34. package/templates/form-two-column.tsx +316 -0
  35. package/templates/gallery-hero.template.mjs +6 -0
  36. package/templates/gallery-hero.tsx +289 -0
  37. package/templates/ide.template.mjs +6 -0
  38. package/templates/ide.tsx +537 -0
  39. package/templates/incident-console.template.mjs +6 -0
  40. package/templates/incident-console.tsx +586 -0
  41. package/templates/kanban-board.template.mjs +6 -0
  42. package/templates/kanban-board.tsx +748 -0
  43. package/templates/library.template.mjs +6 -0
  44. package/templates/library.tsx +491 -0
  45. package/templates/login-card.template.mjs +6 -0
  46. package/templates/login-card.tsx +202 -0
  47. package/templates/login-split.template.mjs +6 -0
  48. package/templates/login-split.tsx +316 -0
  49. package/templates/login-sso.template.mjs +6 -0
  50. package/templates/login-sso.tsx +275 -0
  51. package/templates/login.template.mjs +6 -0
  52. package/templates/login.tsx +100 -0
  53. package/templates/messaging-shell.template.mjs +6 -0
  54. package/templates/messaging-shell.tsx +677 -0
  55. package/templates/mixed-gallery.template.mjs +6 -0
  56. package/templates/mixed-gallery.tsx +192 -0
  57. package/templates/payment-form.template.mjs +6 -0
  58. package/templates/payment-form.tsx +992 -0
  59. package/templates/product-detail.template.mjs +6 -0
  60. package/templates/product-detail.tsx +368 -0
  61. package/templates/product-gallery.template.mjs +6 -0
  62. package/templates/product-gallery.tsx +175 -0
  63. package/templates/settings-dialog.template.mjs +6 -0
  64. package/templates/settings-dialog.tsx +926 -0
  65. package/templates/settings-sidebar.template.mjs +6 -0
  66. package/templates/settings-sidebar.tsx +954 -0
  67. package/templates/settings.template.mjs +6 -0
  68. package/templates/settings.tsx +237 -0
  69. package/templates/shell-nav.template.mjs +6 -0
  70. package/templates/shell-nav.tsx +308 -0
  71. package/templates/shell-side-nav.template.mjs +6 -0
  72. package/templates/shell-side-nav.tsx +240 -0
  73. package/templates/shell-top-nav.template.mjs +6 -0
  74. package/templates/shell-top-nav.tsx +245 -0
  75. package/templates/side-gallery.template.mjs +6 -0
  76. package/templates/side-gallery.tsx +181 -0
  77. package/templates/table-grouped.template.mjs +6 -0
  78. package/templates/table-grouped.tsx +1176 -0
  79. package/templates/table-page-chart.template.mjs +6 -0
  80. package/templates/table-page-chart.tsx +699 -0
  81. package/templates/table-page-heatmap-status.template.mjs +6 -0
  82. package/templates/table-page-heatmap-status.tsx +549 -0
  83. package/templates/table-page-shoe-store-heatmap.template.mjs +6 -0
  84. package/templates/table-page-shoe-store-heatmap.tsx +1044 -0
  85. package/templates/table-page.template.mjs +6 -0
  86. package/templates/table-page.tsx +447 -0
  87. package/templates/table.template.mjs +6 -0
  88. package/templates/table.tsx +86 -0
  89. package/templates/theme-showcase.template.mjs +6 -0
  90. package/templates/theme-showcase.tsx +1284 -0
@@ -0,0 +1,294 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+ // XLE (canonical structure, validated with `bunx astryx layout check`):
3
+ // Ctr > V[a=center] > S.section[p=6] > V[g=6] > (V[g=2 a=center] > Hd"Let's brew after dark"[level=1] + Tx"Tell us a bit"[t=body]) + (G[c={min:200} g=4] > (C > V[g=3] > Ic + (V[g=1] > Tx"Title"[t=body] + Tx"Desc"[t=supporting]))*3) + (G[c={min:260} g=4] > TI"Full Name" + TI"Email") + (G[c={min:260} g=4] > TI"Company" + TI"Phone") + D + (V[g=5] > (V[g=2] > Tx"Goals"[t=label] + (H[g=2] > Tk"Goal"*3)) + SE"Timeline" + SE"Budget" + (RL"Source" > RLI*5) + TA"Notes" + CB"Decision maker") + (V[g=3] > B.primary"Submit" + (H[j=center g=1] > Tx[t=supporting] > Lk"Privacy Policy"))
4
+
5
+ import {useState} from 'react';
6
+ import {VStack, HStack} from '@astryxdesign/core/Layout';
7
+ import {Center} from '@astryxdesign/core/Center';
8
+ import {Section} from '@astryxdesign/core/Section';
9
+ import {Grid} from '@astryxdesign/core/Grid';
10
+ import {Card} from '@astryxdesign/core/Card';
11
+ import {Button} from '@astryxdesign/core/Button';
12
+ import {Text, Heading} from '@astryxdesign/core/Text';
13
+ import {Icon} from '@astryxdesign/core/Icon';
14
+ import {TextInput} from '@astryxdesign/core/TextInput';
15
+ import {Selector} from '@astryxdesign/core/Selector';
16
+ import {CheckboxInput} from '@astryxdesign/core/CheckboxInput';
17
+ import {Link} from '@astryxdesign/core/Link';
18
+ import {Token} from '@astryxdesign/core/Token';
19
+ import {RadioList, RadioListItem} from '@astryxdesign/core/RadioList';
20
+ import {TextArea} from '@astryxdesign/core/TextArea';
21
+ import {Divider} from '@astryxdesign/core/Divider';
22
+ import {Banner} from '@astryxdesign/core/Banner';
23
+ import {Rocket, SlidersHorizontal, Hand} from 'lucide-react';
24
+
25
+ const CAMPAIGN_GOALS = [
26
+ 'Brand Awareness',
27
+ 'Product Sampling',
28
+ 'Product Launch',
29
+ 'Event Promotion',
30
+ 'Retail / In-Store',
31
+ 'Trade Show',
32
+ 'Influencer Activation',
33
+ 'Community Building',
34
+ 'Seasonal Campaign',
35
+ 'Other',
36
+ ];
37
+
38
+ const LAUNCH_OPTIONS = [
39
+ 'Within 30 days',
40
+ '1\u20133 months',
41
+ '3\u20136 months',
42
+ '6\u201312 months',
43
+ '12+ months',
44
+ ];
45
+
46
+ const BUDGET_OPTIONS = [
47
+ 'Under $5K/mo',
48
+ '$5K\u2013$15K/mo',
49
+ '$15K\u2013$50K/mo',
50
+ '$50K\u2013$100K/mo',
51
+ '$100K+/mo',
52
+ ];
53
+
54
+ const WHY_US = [
55
+ {
56
+ icon: Rocket,
57
+ title: 'We ship before sunrise',
58
+ description: 'We cut through the fog and land the work before dawn.',
59
+ },
60
+ {
61
+ icon: SlidersHorizontal,
62
+ title: 'We tune around you',
63
+ description: "Every dial set to what you're trying to summon.",
64
+ },
65
+ {
66
+ icon: Hand,
67
+ title: 'We answer after dark',
68
+ description: 'A dedicated coven that knows your brand and haunts your roadmap.',
69
+ },
70
+ ];
71
+
72
+ /**
73
+ * Contact Form — lead capture form template
74
+ */
75
+ export default function ContactForm() {
76
+ const [fullName, setFullName] = useState('');
77
+ const [email, setEmail] = useState('');
78
+ const [company, setCompany] = useState('');
79
+ const [phone, setPhone] = useState('');
80
+ const [goals, setGoals] = useState<string[]>([]);
81
+ const [timeline, setTimeline] = useState('');
82
+ const [budget, setBudget] = useState('');
83
+ const [message, setMessage] = useState('');
84
+ const [hearAboutUs, setHearAboutUs] = useState('');
85
+ const [isDecider, setIsDecider] = useState(false);
86
+ const [submitted, setSubmitted] = useState(false);
87
+
88
+ const errors = submitted
89
+ ? {
90
+ fullName: !fullName.trim() ? 'Required' : undefined,
91
+ email: !email.trim() ? 'Required' : undefined,
92
+ company: !company.trim() ? 'Required' : undefined,
93
+ phone: !phone.trim() ? 'Required' : undefined,
94
+ goals: goals.length === 0 ? 'Pick at least one' : undefined,
95
+ timeline: !timeline ? 'Required' : undefined,
96
+ budget: !budget ? 'Required' : undefined,
97
+ }
98
+ : {};
99
+
100
+ const toggleGoal = (goal: string) =>
101
+ setGoals(prev =>
102
+ prev.includes(goal) ? prev.filter(g => g !== goal) : [...prev, goal],
103
+ );
104
+
105
+ return (
106
+ <Center axis="horizontal">
107
+ <VStack hAlign="center" width="100%">
108
+ <Section
109
+ maxWidth={800}
110
+ width="100%"
111
+ padding={6}
112
+ paddingBlock={10}
113
+ variant="section">
114
+ <VStack gap={6}>
115
+ {/* Header */}
116
+ <VStack gap={2} hAlign="center" style={{textAlign: 'center'}}>
117
+ <Heading level={1} type="display-1">
118
+ Let&apos;s brew after dark
119
+ </Heading>
120
+ <Text type="body" color="secondary">
121
+ Tell us a bit about what you&apos;re summoning — the coven
122
+ would love to help it take flight.
123
+ </Text>
124
+ </VStack>
125
+
126
+ {/* Why work with us */}
127
+ <VStack gap={5}>
128
+ <Grid columns={{minWidth: 200}} gap={4}>
129
+ {WHY_US.map(item => (
130
+ <Card key={item.title}>
131
+ <VStack gap={3}>
132
+ <Icon icon={item.icon} size="lg" color="accent" />
133
+ <VStack gap={1}>
134
+ <Text type="body" weight="bold">
135
+ {item.title}
136
+ </Text>
137
+ <Text type="supporting" color="secondary">
138
+ {item.description}
139
+ </Text>
140
+ </VStack>
141
+ </VStack>
142
+ </Card>
143
+ ))}
144
+ </Grid>
145
+ </VStack>
146
+
147
+ {/* Your details */}
148
+ <VStack gap={5}>
149
+ <Grid columns={{minWidth: 260}} gap={4}>
150
+ <TextInput
151
+ label="Full Name"
152
+ placeholder="Full Name"
153
+ value={fullName}
154
+ onChange={setFullName}
155
+ status={
156
+ errors.fullName
157
+ ? {type: 'error', message: errors.fullName}
158
+ : undefined
159
+ }
160
+ />
161
+ <TextInput
162
+ label="Email"
163
+ placeholder="you@company.com"
164
+ value={email}
165
+ onChange={setEmail}
166
+ status={
167
+ errors.email
168
+ ? {type: 'error', message: errors.email}
169
+ : undefined
170
+ }
171
+ />
172
+ </Grid>
173
+ <Grid columns={{minWidth: 260}} gap={4}>
174
+ <TextInput
175
+ label="Company"
176
+ placeholder="Company"
177
+ value={company}
178
+ onChange={setCompany}
179
+ status={
180
+ errors.company
181
+ ? {type: 'error', message: errors.company}
182
+ : undefined
183
+ }
184
+ />
185
+ <TextInput
186
+ label="Phone"
187
+ placeholder="Phone number"
188
+ value={phone}
189
+ onChange={setPhone}
190
+ status={
191
+ errors.phone
192
+ ? {type: 'error', message: errors.phone}
193
+ : undefined
194
+ }
195
+ />
196
+ </Grid>
197
+ </VStack>
198
+
199
+ <Divider />
200
+
201
+ {/* Your project */}
202
+ <VStack gap={5}>
203
+ <VStack gap={2}>
204
+ <Text type="label" color="secondary">
205
+ What are you going for?
206
+ </Text>
207
+ <HStack gap={2} wrap="wrap">
208
+ {CAMPAIGN_GOALS.map(goal => (
209
+ <Token
210
+ key={goal}
211
+ label={goal}
212
+ color={goals.includes(goal) ? 'yellow' : 'default'}
213
+ onClick={() => toggleGoal(goal)}
214
+ />
215
+ ))}
216
+ </HStack>
217
+ {errors.goals && <Banner status="error" title={errors.goals} />}
218
+ </VStack>
219
+
220
+ <Selector
221
+ label="When are you thinking?"
222
+ placeholder="When are you thinking of launching?"
223
+ options={LAUNCH_OPTIONS}
224
+ value={timeline}
225
+ onChange={setTimeline}
226
+ status={
227
+ errors.timeline
228
+ ? {type: 'error', message: errors.timeline}
229
+ : undefined
230
+ }
231
+ />
232
+
233
+ <Selector
234
+ label="Ballpark budget?"
235
+ placeholder="What's your rough monthly budget?"
236
+ options={BUDGET_OPTIONS}
237
+ value={budget}
238
+ onChange={setBudget}
239
+ status={
240
+ errors.budget
241
+ ? {type: 'error', message: errors.budget}
242
+ : undefined
243
+ }
244
+ />
245
+
246
+ <RadioList
247
+ label="How did you hear about us?"
248
+ value={hearAboutUs}
249
+ onChange={setHearAboutUs}>
250
+ <RadioListItem label="Social media" value="social" />
251
+ <RadioListItem label="Word of mouth" value="word-of-mouth" />
252
+ <RadioListItem label="Search engine" value="search" />
253
+ <RadioListItem label="Event or conference" value="event" />
254
+ <RadioListItem label="Other" value="other" />
255
+ </RadioList>
256
+
257
+ <TextArea
258
+ label="Anything else?"
259
+ placeholder="Tell us whatever else is on your mind..."
260
+ value={message}
261
+ onChange={setMessage}
262
+ />
263
+
264
+ <CheckboxInput
265
+ label="I'm a budget decision-maker"
266
+ value={isDecider}
267
+ onChange={setIsDecider}
268
+ />
269
+ </VStack>
270
+
271
+ {/* Submit */}
272
+ <VStack gap={3}>
273
+ <Button
274
+ label="Submit"
275
+ variant="primary"
276
+ size="lg"
277
+ onClick={() => setSubmitted(true)}
278
+ />
279
+ <HStack gap={1} hAlign="center">
280
+ <Text type="supporting" color="secondary">
281
+ By submitting you agree to our{' '}
282
+ <Link href="#/templates/contact-form" type="supporting">
283
+ Privacy Policy
284
+ </Link>
285
+ .
286
+ </Text>
287
+ </HStack>
288
+ </VStack>
289
+ </VStack>
290
+ </Section>
291
+ </VStack>
292
+ </Center>
293
+ );
294
+ }
@@ -0,0 +1,6 @@
1
+ export default {
2
+ type: 'page',
3
+ name: 'Portfolio Dashboard',
4
+ description: 'Holdings chart, market cards, and trending table',
5
+ category: 'dashboard',
6
+ };