Skip to content

Commit 5dba03e

Browse files
committed
Styling fixes to newsletter cta on home page
1 parent 90edf28 commit 5dba03e

19 files changed

Lines changed: 760 additions & 381 deletions

File tree

src/components/Animations/Confetti/index.astro

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,12 @@
66
*/
77
---
88

9-
<confetti-animation class="confetti-animation block" data-testid="confetti-animation">
10-
<canvas data-confetti-canvas aria-hidden="true"></canvas>
9+
<confetti-animation class="confetti-animation relative block" data-testid="confetti-animation">
10+
<canvas
11+
data-confetti-canvas
12+
aria-hidden="true"
13+
class="absolute inset-0 w-full h-full pointer-events-none z-(--z-content-overlay)"
14+
></canvas>
1115
<slot />
1216
</confetti-animation>
1317

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
---
2+
import GDPRConsent from '@components/Consent/Checkbox/index.astro'
3+
import Confetti from '@components/Animations/Confetti/index.astro'
4+
import type { NewsletterProps } from './client/@types'
5+
6+
export type Props = Omit<NewsletterProps, 'variant'>
7+
8+
const {
9+
title = 'Stay Updated',
10+
description = 'Subscribe to our newsletter for the latest insights on web development and digital solutions.',
11+
placeholder = 'Enter your email address',
12+
buttonText = 'Subscribe',
13+
} = Astro.props
14+
---
15+
16+
<section>
17+
<div class="bg-content border border-trim rounded-xl p-6 md:p-8 font-mono">
18+
<div class="flex items-center gap-2 mb-4 pb-4 border-b border-page-base/20">
19+
<div class="w-3 h-3 rounded-full bg-danger"></div>
20+
<div class="w-3 h-3 rounded-full bg-warning"></div>
21+
<div class="w-3 h-3 rounded-full bg-success"></div>
22+
<span class="text-xs text-page-base/50 ml-2">newsletter.subscribe</span>
23+
</div>
24+
25+
<div class="space-y-3">
26+
<p class="text-page-base">
27+
<span class="text-success">$</span>
28+
{` ${title}`}
29+
</p>
30+
<p class="text-page-base/70 text-sm">
31+
<span class="text-page-base/50">&gt;</span>
32+
{` ${description}`}
33+
</p>
34+
35+
<form id="newsletter-form" class="space-y-4">
36+
<div class="flex gap-3 pt-4">
37+
<div class="relative flex items-center gap-2 flex-1 after:pointer-events-none after:absolute after:content-[''] after:inset-0 after:rounded-none after:border-2 after:border-transparent focus-within:after:-inset-1 focus-within:after:border-spotlight">
38+
<span class="text-success">$</span>
39+
<label id="newsletter-email-label" for="newsletter-email" class="sr-only">
40+
Email address
41+
</label>
42+
<input
43+
type="email"
44+
id="newsletter-email"
45+
name="email"
46+
placeholder={placeholder}
47+
class="flex-1 px-3 py-2 bg-page-base/10 border border-page-base/20 rounded text-page-base text-sm placeholder:text-page-base/40 focus:outline-none focus-visible:outline-none"
48+
required
49+
aria-describedby="newsletter-message"
50+
/>
51+
</div>
52+
<Confetti>
53+
<button
54+
type="submit"
55+
id="newsletter-submit"
56+
data-e2e-state="idle"
57+
class="relative px-6 py-2 bg-primary hover:bg-primary-offset text-page-base font-semibold rounded text-sm transition-colors whitespace-nowrap disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-none after:pointer-events-none after:absolute after:content-[''] after:inset-0 after:rounded-none after:border-2 after:border-transparent focus-visible:after:-inset-1 focus-visible:after:border-spotlight"
58+
>
59+
<span id="button-text">{buttonText}</span>
60+
<svg
61+
id="button-arrow"
62+
class="inline-block w-4 h-4 ml-2"
63+
fill="none"
64+
stroke="currentColor"
65+
viewBox="0 0 24 24"
66+
aria-hidden="true"
67+
focusable="false"
68+
>
69+
<path
70+
stroke-linecap="round"
71+
stroke-linejoin="round"
72+
stroke-width="2"
73+
d="M14 5l7 7m0 0l-7 7m7-7H3"
74+
></path>
75+
</svg>
76+
<svg
77+
id="button-spinner"
78+
class="hidden w-4 h-4 ml-2 animate-spin"
79+
fill="none"
80+
viewBox="0 0 24 24"
81+
aria-hidden="true"
82+
focusable="false"
83+
>
84+
<circle
85+
class="opacity-25"
86+
cx="12"
87+
cy="12"
88+
r="10"
89+
stroke="currentColor"
90+
stroke-width="4"
91+
></circle>
92+
<path
93+
class="opacity-75"
94+
fill="currentColor"
95+
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
96+
></path>
97+
</svg>
98+
</button>
99+
</Confetti>
100+
</div>
101+
102+
<div class="pt-3 border-t border-page-base/20 mt-4">
103+
<GDPRConsent
104+
purpose="marketing communications (unsubscribe anytime)"
105+
id="newsletter-gdpr-consent"
106+
name="consent"
107+
formId="newsletter_form"
108+
variant="newsletter-cta-article"
109+
/>
110+
</div>
111+
112+
<p
113+
id="newsletter-message"
114+
class="text-xs text-page-base/60 leading-relaxed"
115+
role="status"
116+
aria-live="polite"
117+
aria-atomic="true"
118+
>
119+
You'll receive a confirmation email. Click the link to complete your subscription.
120+
</p>
121+
</form>
122+
</div>
123+
</div>
124+
</section>

src/components/CallToAction/Newsletter/props.ts renamed to src/components/CallToAction/Newsletter/client/@types/index.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,6 @@ export interface NewsletterProps {
77
placeholder?: string
88
/** Submit button text */
99
buttonText?: string
10+
/** Choose which variant to show */
11+
variant: 'article' | 'home'
1012
}

src/components/CallToAction/Newsletter/client/__tests__/index.spec.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'
22
import { experimental_AstroContainer as AstroContainer } from 'astro/container'
33
import { TestError } from '@test/errors'
44
import Newsletter from '@components/CallToAction/Newsletter/index.astro'
5-
import type { NewsletterProps } from '@components/CallToAction/Newsletter/props'
5+
import type { NewsletterProps } from '@components/CallToAction/Newsletter/client/@types'
66
import type { NewsletterFormElement } from '@components/CallToAction/Newsletter/client'
77
import type { WebComponentModule } from '@components/scripts/@types/webComponentModule'
88
import { executeRender } from '@test/unit/helpers/litRuntime'
@@ -29,8 +29,11 @@ const defaultNewsletterProps: NewsletterProps = {
2929
description: 'Test description for newsletter signup',
3030
placeholder: 'test@example.com',
3131
buttonText: 'Subscribe',
32+
variant: 'article',
3233
}
3334

35+
const newsletterVariants: NewsletterProps['variant'][] = ['article', 'home']
36+
3437
const getElements = (root: NewsletterFormElement) => {
3538
const selectElement = <T extends Element>(selector: string): T => {
3639
const element = root.querySelector(selector)
@@ -53,7 +56,7 @@ const getElements = (root: NewsletterFormElement) => {
5356
}
5457
}
5558

56-
describe('NewsletterFormElement web component', () => {
59+
describe.each(newsletterVariants)('NewsletterFormElement web component (%s)', variant => {
5760
let container: AstroContainer
5861

5962
beforeEach(async () => {
@@ -79,6 +82,7 @@ describe('NewsletterFormElement web component', () => {
7982
args: {
8083
props: {
8184
...defaultNewsletterProps,
85+
variant,
8286
...props,
8387
},
8488
},

src/components/CallToAction/Newsletter/client/__tests__/selectors.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { beforeEach, describe, expect, test } from 'vitest'
22
import { experimental_AstroContainer as AstroContainer } from 'astro/container'
33
import Newsletter from '@components/CallToAction/Newsletter/index.astro'
4-
import type { NewsletterProps } from '@components/CallToAction/Newsletter/props'
4+
import type { NewsletterProps } from '@components/CallToAction/Newsletter/client/@types'
55
import type { NewsletterFormElement } from '@components/CallToAction/Newsletter/client'
66
import {
77
SELECTORS,

0 commit comments

Comments
 (0)