astryx-dracula 0.3.0 → 0.4.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.
@@ -1,6 +1,6 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
  // XLE (canonical structure, validated with `bunx astryx layout check`):
3
- // Ctr > C[p=4 mw=400] > V[g=4] > ((V[g=1 a=center] > Hd"Welcome back to the night"[level=1] + Tx"Whisper your details to enter the night"[t=body]) + TI"Work email"[t=email] + Lk"Having trouble signing in?" + B.primary"Continue" + D"Or continue with" + B.secondary"Continue with SSO" + (V[a=center] > Tx"New to the castle?"[t=supporting] + Lk"Request access") + (V[g=2 a=center] > Av + Hd"Sign in with Google Workspace"[level=1] + Tx"You will be redirected back after signing in."[t=body]) + (C[p=0] > S[p=4 muted] > (H[g=2 a=center] > Ic + (V[g=0] > Tx"Google Workspace"[t=label] + Tx"vlad@castle.ro"[t=supporting]))) + (V[g=3] > B.primary"Continue with Google Workspace" + B.ghost"Use a different email") + (V[g=1 a=center] > Hd"Welcome back to the night"[level=1] + Tx"vlad@castle.ro"[t=body]) + (V[g=4] > (V[g=1] > TI"Password"[t=password] + Lk"Forgot password?") + B.primary"Enter the night" + B.ghost"Use a different email") + (V[a=center] > Tx"By clicking continue, you agree to our Terms of service and Privacy policy"[t=supporting]))
3
+ // Ctr > C[p=4 mw=400] > V[g=4] > ((V[g=1 a=center] > Hd"Welcome back to the night"[level=1] + Tx"Whisper your details to enter the night"[t=body]) + (V[g=1] > TI"Work email"[t=email] + Lk"Having trouble signing in?") + B.primary"Continue" + D"Or continue with" + B.secondary"Continue with SSO" + (V[a=center] > Tx"New to the castle?"[t=supporting] + Lk"Request access") + (V[g=2 a=center] > Av + Hd"Sign in with Google Workspace"[level=1] + Tx"You will be redirected back after signing in."[t=body]) + (C[p=0] > S[p=4 muted] > (H[g=2 a=center] > Ic + (V[g=0] > Tx"Google Workspace"[t=label] + Tx"vlad@castle.ro"[t=supporting]))) + (V[g=3] > B.primary"Continue with Google Workspace" + B.ghost"Use a different email") + (V[g=1 a=center] > Hd"Welcome back to the night"[level=1] + Tx"vlad@castle.ro"[t=body]) + (V[g=4] > (V[g=1] > TI"Password"[t=password] + Lk"Forgot password?") + (V[g=3] > B.primary"Enter the night" + B.ghost"Use a different email")) + (V[a=center] > Tx"By clicking continue, you agree to our Terms of service and Privacy policy"[t=supporting]))
4
4
 
5
5
  // Step-conditional h1: the email and SSO-confirm steps each render their own
6
6
  // h1 (email entry vs provider confirm); the password fallback reuses the
@@ -135,29 +135,35 @@ export default function LoginSso() {
135
135
  </Text>
136
136
  </VStack>
137
137
 
138
- <TextInput
139
- label="Work email"
140
- isLabelHidden
141
- type="email"
142
- {...inputAutoComplete('email')}
143
- placeholder={AUTH_EMAIL_PLACEHOLDER}
144
- value={email}
145
- onChange={(v: string) => {
146
- setEmail(v);
147
- setError(null);
148
- }}
149
- size="lg"
150
- onKeyDown={(e: React.KeyboardEvent) => {
151
- if (e.key === 'Enter') {
152
- handleContinue();
153
- }
154
- }}
155
- status={error ? {type: 'error', message: error} : undefined}
156
- />
138
+ {/* The helper link belongs to the field above it, so the two
139
+ share a gap={1} group — as the password step below groups
140
+ its own. As siblings in the outer gap={4} flow it read as
141
+ one more control in the button column, 16px from each. */}
142
+ <VStack gap={1}>
143
+ <TextInput
144
+ label="Work email"
145
+ isLabelHidden
146
+ type="email"
147
+ {...inputAutoComplete('email')}
148
+ placeholder={AUTH_EMAIL_PLACEHOLDER}
149
+ value={email}
150
+ onChange={(v: string) => {
151
+ setEmail(v);
152
+ setError(null);
153
+ }}
154
+ size="lg"
155
+ onKeyDown={(e: React.KeyboardEvent) => {
156
+ if (e.key === 'Enter') {
157
+ handleContinue();
158
+ }
159
+ }}
160
+ status={error ? {type: 'error', message: error} : undefined}
161
+ />
157
162
 
158
- <Link href="#/templates/login-sso">
159
- Having trouble signing in?
160
- </Link>
163
+ <Link href="#/templates/login-sso" isStandalone>
164
+ Having trouble signing in?
165
+ </Link>
166
+ </VStack>
161
167
 
162
168
  <Button
163
169
  label="Continue"
@@ -175,10 +181,13 @@ export default function LoginSso() {
175
181
  onClick={handleContinue}
176
182
  />
177
183
 
184
+ {/* Prose link: colour alone is not a cue inside a sentence
185
+ (WCAG 1.4.1 / F73), so it asks for the underline the kit
186
+ only gives on hover. */}
178
187
  <VStack hAlign="center">
179
188
  <Text type="supporting" color="secondary">
180
189
  {AUTH_SIGNUP_PROMPT}{' '}
181
- <Link href="#/templates/login-sso" type="supporting">
190
+ <Link href="#/templates/login-sso" type="supporting" hasUnderline>
182
191
  Request access
183
192
  </Link>
184
193
  </Text>
@@ -271,26 +280,33 @@ export default function LoginSso() {
271
280
  />
272
281
  {error && (
273
282
  <VStack hAlign="end">
274
- <Link href="#/templates/login-sso">
283
+ <Link href="#/templates/login-sso" isStandalone>
275
284
  {AUTH_FORGOT_PASSWORD}
276
285
  </Link>
277
286
  </VStack>
278
287
  )}
279
288
  </VStack>
280
289
 
281
- <Button
282
- label={AUTH_PRIMARY_CTA}
283
- variant="primary"
284
- size="lg"
285
- isLoading={isLoading}
286
- onClick={handleSignIn}
287
- />
288
- <Button
289
- label="Use a different email"
290
- variant="ghost"
291
- size="lg"
292
- onClick={handleBack}
293
- />
290
+ {/* gap={3} is the family rhythm for a button pair: the
291
+ primary/ghost pair in the confirm step above, the social
292
+ pairs in login-card and login-split. At the outer gap={4}
293
+ the same two buttons sat 4px further apart in this step
294
+ than in the step above it. */}
295
+ <VStack gap={3}>
296
+ <Button
297
+ label={AUTH_PRIMARY_CTA}
298
+ variant="primary"
299
+ size="lg"
300
+ isLoading={isLoading}
301
+ onClick={handleSignIn}
302
+ />
303
+ <Button
304
+ label="Use a different email"
305
+ variant="ghost"
306
+ size="lg"
307
+ onClick={handleBack}
308
+ />
309
+ </VStack>
294
310
  </VStack>
295
311
  </>
296
312
  )}
@@ -299,14 +315,14 @@ export default function LoginSso() {
299
315
  <VStack hAlign="center" width="100%">
300
316
  <Text type="supporting" color="secondary" justify="center">
301
317
  {AUTH_TERMS_PREFIX}{' '}
302
- <Link href="#/templates/login-sso" type="supporting">
318
+ <Link href="#/templates/login-sso" type="supporting" hasUnderline>
303
319
  {AUTH_TERMS_SERVICE}
304
320
  </Link>{' '}
305
321
  and{' '}
306
- <Link href="#/templates/login-sso" type="supporting">
322
+ <Link href="#/templates/login-sso" type="supporting" hasUnderline>
307
323
  {AUTH_TERMS_PRIVACY}
308
324
  </Link>
309
- .
325
+ .
310
326
  </Text>
311
327
  </VStack>
312
328
  </VStack>
@@ -87,26 +87,27 @@ export default function LoginPage() {
87
87
  />
88
88
 
89
89
  <VStack gap={1}>
90
- <TextInput
91
- label="Password"
92
- isLabelHidden
93
- value={password}
94
- onChange={v => {
95
- setPassword(v);
96
- setError(null);
97
- }}
98
- placeholder={AUTH_PASSWORD_PLACEHOLDER}
99
- type="password"
100
- {...inputAutoComplete('current-password')}
101
- size="lg"
102
- onEnter={handleSignIn}
103
- status={error ? {type: 'error', message: error} : undefined}
104
- />
90
+ <TextInput
91
+ label="Password"
92
+ isLabelHidden
93
+ value={password}
94
+ onChange={v => {
95
+ setPassword(v);
96
+ setError(null);
97
+ }}
98
+ placeholder={AUTH_PASSWORD_PLACEHOLDER}
99
+ type="password"
100
+ {...inputAutoComplete('current-password')}
101
+ size="lg"
102
+ onEnter={handleSignIn}
103
+ status={error ? {type: 'error', message: error} : undefined}
104
+ />
105
105
  {error && (
106
106
  <VStack hAlign="end">
107
107
  <Link
108
108
  href="#/templates/login"
109
- color="secondary">
109
+ color="secondary"
110
+ isStandalone>
110
111
  {AUTH_FORGOT_PASSWORD}
111
112
  </Link>
112
113
  </VStack>
@@ -122,11 +123,13 @@ export default function LoginPage() {
122
123
  onClick={handleSignIn}
123
124
  />
124
125
 
125
- {/* Sign up link */}
126
+ {/* Prose links. A link inside a sentence needs a persistent
127
+ underline — colour alone is not a cue (WCAG 1.4.1 / F73),
128
+ and the kit underlines on hover only. */}
126
129
  <VStack hAlign="center">
127
130
  <Text type="supporting" color="secondary">
128
131
  {AUTH_SIGNUP_PROMPT}{' '}
129
- <Link href="#/templates/login" type="supporting">
132
+ <Link href="#/templates/login" type="supporting" hasUnderline>
130
133
  {AUTH_SIGNUP_LINK}
131
134
  </Link>
132
135
  </Text>
@@ -138,11 +141,11 @@ export default function LoginPage() {
138
141
  <VStack hAlign="center" width="100%">
139
142
  <Text type="supporting" color="secondary" justify="center">
140
143
  {AUTH_TERMS_PREFIX}{' '}
141
- <Link href="#/templates/login" type="supporting">
144
+ <Link href="#/templates/login" type="supporting" hasUnderline>
142
145
  {AUTH_TERMS_SERVICE}
143
146
  </Link>{' '}
144
147
  and{' '}
145
- <Link href="#/templates/login" type="supporting">
148
+ <Link href="#/templates/login" type="supporting" hasUnderline>
146
149
  {AUTH_TERMS_PRIVACY}
147
150
  </Link>
148
151
  .
@@ -1,6 +1,6 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
  // XLE (canonical structure, validated with `bunx astryx layout check`):
3
- // L > LC[p=0] > Ctr > S.transparent[p=6 mw=1100] > V[g=5] > (V[g=6] > (V[g=2] > (Hd"Payment Request"[level=1 t=display-2] + Tx"Review your order"[t=body]) + D) + H[g=8] > (SI > V[g=8] > (V[g=1] > (H[j=between] > (Hd"Sign in to check out"[level=2] + B"Sign in") + Tx"Sign in to track your order"[t=body]) + V[g=3] > (Hd"Contact information"[level=2] + TI"Email" + CB"Email offers") + V[g=3] > (Hd"Shipping information"[level=2] + G[c=2 g=3] > (TI"First Name" + TI"Last Name") + TI"Address" + G[c=2 g=3] > (TI"City" + TI"ZIP Code") + SE"State" + TI"Phone Number" + CB"Save information") + V[g=3] > (V[g=1] > (Hd"Delivery"[level=2] + Tx"Processing time"[t=body]) + RL"Delivery method" > RLI*2) + V[g=3] > (V[g=1] > (Hd"Payment method"[level=2] + Tx"Encrypted"[t=body]) + G[c=2 g=3] > (B"PayPal" + B"Google Pay") + D"Or pay with card" + TI"Card Number" + G[c=3 g=3] > (SE"Expiry Month" + SE"Expiry Year" + TI"CVC") + TI"Name on Card" + CB"Billing address") + V[g=3] > (Hd"Promo code"[level=2] + H[g=2] > (TI"Promo code" + B"Apply")) + V[g=3] > (Hd"Gift options"[level=2] + CB"Gift message" + TA"Gift message") + V[g=4] > (H[g=5] > (H[g=1] > (Ic + Tx))*3 + V[g=2] > (B"Place order"[primary] + B"Continue shopping") + D + H[g=4] > (Lk"Refund policy" + Lk"Privacy policy" + Lk"Terms" + Lk"Cancellations"))) + SI > C[p=4] > Col"Order Summary" > V[g=4] > (V[g=3] > V[g=3] > (H[g=3] > (Tmb + V[g=1] > (Tx"Obsidian Ritual Chalice" + Tx"Hand-carved"[t=supporting])) + D)*3 + V[g=3] > (Hd"Order Total"[level=3] + H[j=between] > (Tx"Subtotal" + Tx"$91.20") + D + H[j=between] > (Tx"Total"[t=large] + Tx"$91.20"[t=large]) + Bn"Free shipping over $300"))))
3
+ // L > LC[p=0] > Ctr > S.transparent[p=6 mw=1100] > V[g=5] > (V[g=6] > (V[g=2] > (Hd"Payment Request"[level=1 t=display-2] + Tx"Review your order"[t=body]) + D) + H[g=8] > (SI > V[g=8] > (V[g=1] > (H[j=between] > (Hd"Sign in to check out"[level=2] + B"Sign in") + Tx"Sign in to track your order"[t=body]) + V[g=3] > (Hd"Contact information"[level=2] + TI"Email" + CB"Email offers") + V[g=3] > (Hd"Shipping information"[level=2] + G[c=2 g=3] > (TI"First Name" + TI"Last Name") + TI"Address" + G[c=2 g=3] > (TI"City" + TI"ZIP Code") + SE"State" + TI"Phone Number" + CB"Save information") + V[g=3] > (V[g=1] > (Hd"Delivery"[level=2] + Tx"Processing time"[t=body]) + RL"Delivery method" > RLI*2) + V[g=3] > (V[g=1] > (Hd"Payment method"[level=2] + Tx"Encrypted"[t=body]) + G[c=2 g=3] > (B"PayPal" + B"Google Pay") + D"Or pay with card" + TI"Card Number" + G[c=3 g=3] > (SE"Expiry Month" + SE"Expiry Year" + TI"CVC") + TI"Name on Card" + CB"Billing address") + V[g=3] > (Hd"Promo code"[level=2] + H[g=2] > (TI"Promo code" + B"Apply")) + V[g=3] > (Hd"Gift options"[level=2] + CB"Gift message" + TA"Gift message") + V[g=4] > (H[g=5] > (H[g=1] > (Ic + Tx))*3 + V[g=2] > (B"Place order"[primary] + B"Continue shopping") + D + H[g=4] > (Lk"Refund policy" + Lk"Privacy policy" + Lk"Terms" + Lk"Cancellations"))) + SI > C[p=4] > Col"Order Summary" > V[g=4] > (V[g=3] > H[g=3] > (Tmb + V[g=1] > (Tx"Obsidian Ritual Chalice" + Tx"Hand-carved"[t=supporting])))*3 + V[g=3] > (Hd"Order Total"[level=3] + H[j=between] > (Tx"Subtotal" + Tx"$91.20") + D + H[j=between] > (Tx"Total"[t=large] + Tx"$91.20"[t=large]) + Bn"Free shipping over $300"))))
4
4
 
5
5
  import {useState, type CSSProperties} from 'react';
6
6
  import {
@@ -202,53 +202,47 @@ function OrderLineItem({
202
202
  onChangeQty: (v: number) => void;
203
203
  }) {
204
204
  return (
205
- <VStack gap={3}>
206
- <HStack gap={3} vAlign="start">
207
- <OrderItemPhoto item={item} />
208
- <StackItem size="fill">
209
- <VStack gap={1}>
210
- <HStack gap={2} hAlign="between" vAlign="start">
211
- <HStack gap={2} vAlign="center" wrap="wrap">
212
- <Text type="body" weight="semibold">
213
- {item.name}
214
- </Text>
215
- {item.limited && (
216
- <HStack gap={1} vAlign="center">
217
- <StatusDot variant="warning" label="Limited edition" />
218
- <Text type="supporting" color="secondary">
219
- Limited edition
220
- </Text>
221
- </HStack>
222
- )}
223
- </HStack>
224
- <Text type="body" hasTabularNumbers>
225
- {fmt(item.price)}
205
+ <HStack gap={3} vAlign="start">
206
+ <OrderItemPhoto item={item} />
207
+ <StackItem size="fill">
208
+ <VStack gap={1}>
209
+ <HStack gap={2} hAlign="between" vAlign="start">
210
+ <HStack gap={2} vAlign="center" wrap="wrap">
211
+ <Text type="body" weight="semibold">
212
+ {item.name}
226
213
  </Text>
214
+ {item.limited && (
215
+ <HStack gap={1} vAlign="center">
216
+ <StatusDot variant="warning" label="Limited edition" />
217
+ <Text type="supporting" color="secondary">
218
+ Limited edition
219
+ </Text>
220
+ </HStack>
221
+ )}
227
222
  </HStack>
228
- <Text type="supporting" color="secondary">
229
- {item.variant}
223
+ <Text type="body" hasTabularNumbers>
224
+ {fmt(item.price)}
230
225
  </Text>
231
- <HStack gap={2} vAlign="end" wrap="wrap">
232
- <NumberInput
233
- label="Qty"
234
- value={qty}
235
- onChange={onChangeQty}
236
- min={1}
237
- max={10}
238
- isIntegerOnly
239
- />
240
- <Link href={SELF_HREF} type="supporting">
241
- Remove
242
- </Link>
243
- <Link href={SELF_HREF} type="supporting">
244
- Save
245
- </Link>
246
- </HStack>
247
- </VStack>
248
- </StackItem>
249
- </HStack>
250
- <Divider />
251
- </VStack>
226
+ </HStack>
227
+ <Text type="supporting" color="secondary">
228
+ {item.variant}
229
+ </Text>
230
+ <HStack gap={2} vAlign="end" wrap="wrap">
231
+ <NumberInput
232
+ label="Qty"
233
+ value={qty}
234
+ onChange={onChangeQty}
235
+ min={1}
236
+ max={10}
237
+ isIntegerOnly
238
+ />
239
+ {/* Editing the order in place — an action, never a destination. */}
240
+ <Button label="Remove" variant="ghost" onClick={() => {}} />
241
+ <Button label="Save" variant="ghost" onClick={() => {}} />
242
+ </HStack>
243
+ </VStack>
244
+ </StackItem>
245
+ </HStack>
252
246
  );
253
247
  }
254
248
 
@@ -16,7 +16,6 @@ import {
16
16
  } from '@astryxdesign/core/SegmentedControl';
17
17
  import {Token} from '@astryxdesign/core/Token';
18
18
  import {Banner} from '@astryxdesign/core/Banner';
19
- import {Divider} from '@astryxdesign/core/Divider';
20
19
  import {Collapsible, CollapsibleGroup} from '@astryxdesign/core/Collapsible';
21
20
  import {AspectRatio} from '@astryxdesign/core/AspectRatio';
22
21
  import {SelectableCard} from '@astryxdesign/core/SelectableCard';
@@ -282,8 +281,10 @@ function ProductInfo() {
282
281
  }
283
282
  />
284
283
  </VStack>
285
- <CollapsibleGroup type="multiple" defaultValue={['composition']}>
286
- <Divider />
284
+ <CollapsibleGroup
285
+ type="multiple"
286
+ defaultValue={['composition']}
287
+ hasDividers>
287
288
  <Collapsible
288
289
  value="composition"
289
290
  trigger={
@@ -293,7 +294,6 @@ function ProductInfo() {
293
294
  }>
294
295
  <Text type="body">{PRODUCT.composition}</Text>
295
296
  </Collapsible>
296
- <Divider />
297
297
  <Collapsible
298
298
  value="delivery"
299
299
  defaultIsOpen={false}
@@ -304,7 +304,6 @@ function ProductInfo() {
304
304
  }>
305
305
  <Text type="body">{PRODUCT.deliveryReturns}</Text>
306
306
  </Collapsible>
307
- <Divider />
308
307
  <Collapsible
309
308
  value="dimensions"
310
309
  defaultIsOpen={false}
@@ -317,7 +316,6 @@ function ProductInfo() {
317
316
  {PRODUCT.dimensions}
318
317
  </Text>
319
318
  </Collapsible>
320
- <Divider />
321
319
  </CollapsibleGroup>
322
320
  </VStack>
323
321
  );
@@ -1,6 +1,6 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
  // XLE (canonical structure, validated with `bunx astryx layout check`):
3
- // A[cp=0 @sideNav=(SN > (SNS"Getting started" > (SNI"Introduction"! + SNI"Install")) + (SNS"The brand" > (SNI"Palette" + SNI"Type and shape")) + (SNS"In practice" > (SNI"Components" + SNI"Templates")) + (SNS"Reference" > (SNI"Tokens" + SNI"Migrating")))] > L[h=auto] > (LC[p=8 !scroll] > V[g=8] > (V[g=2] > (H[g=2 a=center] > MNT + Tx[t=supporting]) + Hd"Introduction"[level=1 t=display-2] + Tx"v0.3.0"[t=supporting]) + Tx"Intro"[t=large] + AR + (V[g=8] > (V[g=3] > Hd"What it is"[level=2] + Tx"Body"[t=body] + UL + Cd)*2) + D + (H[j=between] > B.secondary"Previous" + B.secondary"Next")) + (LP[!scroll] > Outline)
3
+ // A[cp=0 @sideNav=(SN > (SNS"Getting started" > (SNI"Introduction"! + SNI"Install")) + (SNS"The brand" > (SNI"Palette" + SNI"Type and shape")) + (SNS"In practice" > (SNI"Components" + SNI"Templates")) + (SNS"Reference" > (SNI"Tokens" + SNI"Migrating")))] > L[h=auto] > (LC[p=8 !scroll] > V[g=8] > (V[g=2] > (H[g=2 a=center] > MNT + Tx[t=supporting]) + Hd"Introduction"[level=1 t=display-2] + Tx"v0.4.0"[t=supporting]) + Tx"Intro"[t=large] + AR + (V[g=8] > (V[g=3] > Hd"What it is"[level=2] + Tx"Body"[t=body] + UL + Cd)*2) + D + (H[j=between] > B.secondary"Previous" + B.secondary"Next")) + (LP[!scroll] > Outline)
4
4
 
5
5
  /**
6
6
  * Product Tour — a chaptered walkthrough of this theme.
@@ -909,7 +909,7 @@ export default function ProductTour() {
909
909
  railHref={SELF_HASH}
910
910
  railIcon={<Icon icon={Sparkles} size="sm" />}
911
911
  eyebrow="Documentation"
912
- badge={() => 'astryx-dracula v0.3.0'}
912
+ badge={() => 'astryx-dracula v0.4.0'}
913
913
  art={chapterId => <ChapterArt chapterId={chapterId} />}
914
914
  />
915
915
  );