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