create-velocity-astro 1.5.3 → 1.6.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/dist/index.js +627 -215
- package/dist/index.js.map +1 -1
- package/package.json +1 -4
- package/templates/i18n/src/components/hero/Hero.astro +154 -154
|
@@ -1,154 +1,154 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { HTMLAttributes } from 'astro/types';
|
|
3
|
-
import { cn } from '@/lib/cn';
|
|
4
|
-
|
|
5
|
-
interface Props extends HTMLAttributes<'section'> {
|
|
6
|
-
/** Layout mode: centered single column or split two-column */
|
|
7
|
-
layout?: 'centered' | 'split';
|
|
8
|
-
/** Vertical padding size */
|
|
9
|
-
size?: 'sm' | 'md' | 'lg' | 'xl';
|
|
10
|
-
/** Show background grid pattern */
|
|
11
|
-
showGrid?: boolean;
|
|
12
|
-
/** Show decorative gradient blob */
|
|
13
|
-
showBlob?: boolean;
|
|
14
|
-
/** Blob position (only applies when showBlob is true) */
|
|
15
|
-
blobPosition?: 'left' | 'right' | 'center';
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const {
|
|
19
|
-
layout = 'centered',
|
|
20
|
-
size = 'lg',
|
|
21
|
-
showGrid = false,
|
|
22
|
-
showBlob = false,
|
|
23
|
-
blobPosition = 'right',
|
|
24
|
-
class: className,
|
|
25
|
-
...attrs
|
|
26
|
-
} = Astro.props;
|
|
27
|
-
|
|
28
|
-
// Check which slots are provided
|
|
29
|
-
const hasBadgeSlot = Astro.slots.has('badge');
|
|
30
|
-
const hasTitleSlot = Astro.slots.has('title');
|
|
31
|
-
const hasDescriptionSlot = Astro.slots.has('description');
|
|
32
|
-
const hasActionsSlot = Astro.slots.has('actions');
|
|
33
|
-
const hasAsideSlot = Astro.slots.has('aside');
|
|
34
|
-
|
|
35
|
-
// Size (padding) variants - asymmetric: more top padding for header clearance
|
|
36
|
-
const sizes: Record<NonNullable<Props['size']>, string> = {
|
|
37
|
-
sm: 'pt-[var(--space-page-top-sm)] pb-[var(--space-section-sm)]',
|
|
38
|
-
md: 'pt-[var(--space-page-top)] pb-[var(--space-section-md)]',
|
|
39
|
-
lg: 'pt-[calc(var(--space-page-top)+var(--space-8))] pb-[var(--space-section-lg)]',
|
|
40
|
-
xl: 'pt-[calc(var(--space-page-top)+var(--space-16))] pb-[var(--space-section-xl)]',
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
// Blob position variants
|
|
44
|
-
const blobPositions: Record<NonNullable<Props['blobPosition']>, string> = {
|
|
45
|
-
left: '-left-20 -top-20',
|
|
46
|
-
right: '-right-20 -top-20',
|
|
47
|
-
center: 'left-1/2 -translate-x-1/2 -top-20',
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
// Compute alignment based on layout
|
|
51
|
-
const alignment = layout === 'centered' ? 'text-center items-center' : 'text-left items-start';
|
|
52
|
-
|
|
53
|
-
// Compute classes
|
|
54
|
-
const sectionClasses = cn(
|
|
55
|
-
'relative overflow-hidden bg-background',
|
|
56
|
-
sizes[size],
|
|
57
|
-
className
|
|
58
|
-
);
|
|
59
|
-
|
|
60
|
-
const contentClasses = cn(
|
|
61
|
-
'z-10 flex flex-col',
|
|
62
|
-
alignment
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
const gridClasses = cn(
|
|
66
|
-
'mx-auto grid max-w-6xl grid-cols-1 items-center gap-[var(--space-section-gap)] px-6',
|
|
67
|
-
layout === 'split' && 'lg:grid-cols-2 lg:gap-[var(--space-section-gap)]'
|
|
68
|
-
);
|
|
69
|
-
---
|
|
70
|
-
|
|
71
|
-
<section class={sectionClasses} {...attrs}>
|
|
72
|
-
{/* Background grid pattern */}
|
|
73
|
-
{showGrid && (
|
|
74
|
-
<div
|
|
75
|
-
class="bg-grid-pattern pointer-events-none absolute inset-0 [mask-image:linear-gradient(to_bottom,white,transparent)] opacity-40"
|
|
76
|
-
aria-hidden="true"
|
|
77
|
-
/>
|
|
78
|
-
)}
|
|
79
|
-
|
|
80
|
-
<div class={gridClasses}>
|
|
81
|
-
{/* Content Column */}
|
|
82
|
-
<div class={cn(contentClasses, 'order-1 lg:order-none')}>
|
|
83
|
-
{/* Badge Slot */}
|
|
84
|
-
{hasBadgeSlot && (
|
|
85
|
-
<div class="mb-[var(--space-heading-gap)]">
|
|
86
|
-
<slot name="badge" />
|
|
87
|
-
</div>
|
|
88
|
-
)}
|
|
89
|
-
|
|
90
|
-
{/* Title Slot */}
|
|
91
|
-
{hasTitleSlot && (
|
|
92
|
-
<div class={cn(
|
|
93
|
-
'mb-[var(--space-heading-gap)]',
|
|
94
|
-
'[&>h1]:font-display [&>h1]:text-5xl [&>h1]:leading-[1.1] [&>h1]:font-bold [&>h1]:tracking-tight [&>h1]:text-balance [&>h1]:text-foreground md:[&>h1]:text-6xl lg:[&>h1]:text-7xl',
|
|
95
|
-
'[&>h2]:font-display [&>h2]:text-4xl [&>h2]:leading-[1.1] [&>h2]:font-bold [&>h2]:tracking-tight [&>h2]:text-balance [&>h2]:text-foreground md:[&>h2]:text-5xl lg:[&>h2]:text-6xl'
|
|
96
|
-
)}>
|
|
97
|
-
<slot name="title" />
|
|
98
|
-
</div>
|
|
99
|
-
)}
|
|
100
|
-
|
|
101
|
-
{/* Description Slot */}
|
|
102
|
-
{hasDescriptionSlot && (
|
|
103
|
-
<div class={cn(
|
|
104
|
-
'mb-[var(--space-stack-lg)] max-w-xl text-lg leading-relaxed text-foreground-muted',
|
|
105
|
-
'[&>p]:text-lg [&>p]:leading-relaxed [&>p]:text-foreground-muted',
|
|
106
|
-
layout === 'centered' && 'mx-auto'
|
|
107
|
-
)}>
|
|
108
|
-
<slot name="description" />
|
|
109
|
-
</div>
|
|
110
|
-
)}
|
|
111
|
-
|
|
112
|
-
{/* Actions Slot */}
|
|
113
|
-
{hasActionsSlot && (
|
|
114
|
-
<div class={cn(
|
|
115
|
-
'flex w-full flex-col gap-4 sm:w-auto sm:flex-row',
|
|
116
|
-
layout === 'centered' && 'justify-center'
|
|
117
|
-
)}>
|
|
118
|
-
<slot name="actions" />
|
|
119
|
-
</div>
|
|
120
|
-
)}
|
|
121
|
-
|
|
122
|
-
{/* Default slot for additional content (social proof, etc.) */}
|
|
123
|
-
<slot />
|
|
124
|
-
</div>
|
|
125
|
-
|
|
126
|
-
{/* Aside Column (for split layout) */}
|
|
127
|
-
{layout === 'split' && hasAsideSlot && (
|
|
128
|
-
<div class="relative z-10 w-full order-2 lg:order-none">
|
|
129
|
-
<slot name="aside" />
|
|
130
|
-
{/* Decorative blob for split layout */}
|
|
131
|
-
{showBlob && (
|
|
132
|
-
<div
|
|
133
|
-
class={cn(
|
|
134
|
-
'bg-brand-200/20 pointer-events-none absolute h-64 w-64 rounded-full blur-3xl',
|
|
135
|
-
blobPositions[blobPosition]
|
|
136
|
-
)}
|
|
137
|
-
aria-hidden="true"
|
|
138
|
-
/>
|
|
139
|
-
)}
|
|
140
|
-
</div>
|
|
141
|
-
)}
|
|
142
|
-
|
|
143
|
-
{/* Decorative blob for centered layout */}
|
|
144
|
-
{layout === 'centered' && showBlob && (
|
|
145
|
-
<div
|
|
146
|
-
class={cn(
|
|
147
|
-
'bg-brand-200/20 pointer-events-none absolute h-64 w-64 rounded-full blur-3xl',
|
|
148
|
-
blobPositions[blobPosition]
|
|
149
|
-
)}
|
|
150
|
-
aria-hidden="true"
|
|
151
|
-
/>
|
|
152
|
-
)}
|
|
153
|
-
</div>
|
|
154
|
-
</section>
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from 'astro/types';
|
|
3
|
+
import { cn } from '@/lib/cn';
|
|
4
|
+
|
|
5
|
+
interface Props extends HTMLAttributes<'section'> {
|
|
6
|
+
/** Layout mode: centered single column or split two-column */
|
|
7
|
+
layout?: 'centered' | 'split';
|
|
8
|
+
/** Vertical padding size */
|
|
9
|
+
size?: 'sm' | 'md' | 'lg' | 'xl';
|
|
10
|
+
/** Show background grid pattern */
|
|
11
|
+
showGrid?: boolean;
|
|
12
|
+
/** Show decorative gradient blob */
|
|
13
|
+
showBlob?: boolean;
|
|
14
|
+
/** Blob position (only applies when showBlob is true) */
|
|
15
|
+
blobPosition?: 'left' | 'right' | 'center';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const {
|
|
19
|
+
layout = 'centered',
|
|
20
|
+
size = 'lg',
|
|
21
|
+
showGrid = false,
|
|
22
|
+
showBlob = false,
|
|
23
|
+
blobPosition = 'right',
|
|
24
|
+
class: className,
|
|
25
|
+
...attrs
|
|
26
|
+
} = Astro.props;
|
|
27
|
+
|
|
28
|
+
// Check which slots are provided
|
|
29
|
+
const hasBadgeSlot = Astro.slots.has('badge');
|
|
30
|
+
const hasTitleSlot = Astro.slots.has('title');
|
|
31
|
+
const hasDescriptionSlot = Astro.slots.has('description');
|
|
32
|
+
const hasActionsSlot = Astro.slots.has('actions');
|
|
33
|
+
const hasAsideSlot = Astro.slots.has('aside');
|
|
34
|
+
|
|
35
|
+
// Size (padding) variants - asymmetric: more top padding for header clearance
|
|
36
|
+
const sizes: Record<NonNullable<Props['size']>, string> = {
|
|
37
|
+
sm: 'pt-[var(--space-page-top-sm)] pb-[var(--space-section-sm)]',
|
|
38
|
+
md: 'pt-[var(--space-page-top)] pb-[var(--space-section-md)]',
|
|
39
|
+
lg: 'pt-[calc(var(--space-page-top)+var(--space-8))] pb-[var(--space-section-lg)]',
|
|
40
|
+
xl: 'pt-[calc(var(--space-page-top)+var(--space-16))] pb-[var(--space-section-xl)]',
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// Blob position variants
|
|
44
|
+
const blobPositions: Record<NonNullable<Props['blobPosition']>, string> = {
|
|
45
|
+
left: '-left-20 -top-20',
|
|
46
|
+
right: '-right-20 -top-20',
|
|
47
|
+
center: 'left-1/2 -translate-x-1/2 -top-20',
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// Compute alignment based on layout
|
|
51
|
+
const alignment = layout === 'centered' ? 'text-center items-center' : 'text-left items-start';
|
|
52
|
+
|
|
53
|
+
// Compute classes
|
|
54
|
+
const sectionClasses = cn(
|
|
55
|
+
'relative overflow-hidden bg-background',
|
|
56
|
+
sizes[size],
|
|
57
|
+
className
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
const contentClasses = cn(
|
|
61
|
+
'z-10 flex flex-col',
|
|
62
|
+
alignment
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
const gridClasses = cn(
|
|
66
|
+
'mx-auto grid max-w-6xl grid-cols-1 items-center gap-[var(--space-section-gap)] px-6',
|
|
67
|
+
layout === 'split' && 'lg:grid-cols-2 lg:gap-[var(--space-section-gap)]'
|
|
68
|
+
);
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
<section class={sectionClasses} {...attrs}>
|
|
72
|
+
{/* Background grid pattern */}
|
|
73
|
+
{showGrid && (
|
|
74
|
+
<div
|
|
75
|
+
class="bg-grid-pattern pointer-events-none absolute inset-0 [mask-image:linear-gradient(to_bottom,white,transparent)] opacity-40"
|
|
76
|
+
aria-hidden="true"
|
|
77
|
+
/>
|
|
78
|
+
)}
|
|
79
|
+
|
|
80
|
+
<div class={gridClasses}>
|
|
81
|
+
{/* Content Column */}
|
|
82
|
+
<div class={cn(contentClasses, 'order-1 lg:order-none')}>
|
|
83
|
+
{/* Badge Slot */}
|
|
84
|
+
{hasBadgeSlot && (
|
|
85
|
+
<div class="mb-[var(--space-heading-gap)]">
|
|
86
|
+
<slot name="badge" />
|
|
87
|
+
</div>
|
|
88
|
+
)}
|
|
89
|
+
|
|
90
|
+
{/* Title Slot */}
|
|
91
|
+
{hasTitleSlot && (
|
|
92
|
+
<div class={cn(
|
|
93
|
+
'mb-[var(--space-heading-gap)]',
|
|
94
|
+
'[&>h1]:font-display [&>h1]:text-5xl [&>h1]:leading-[1.1] [&>h1]:font-bold [&>h1]:tracking-tight [&>h1]:text-balance [&>h1]:text-foreground md:[&>h1]:text-6xl lg:[&>h1]:text-7xl',
|
|
95
|
+
'[&>h2]:font-display [&>h2]:text-4xl [&>h2]:leading-[1.1] [&>h2]:font-bold [&>h2]:tracking-tight [&>h2]:text-balance [&>h2]:text-foreground md:[&>h2]:text-5xl lg:[&>h2]:text-6xl'
|
|
96
|
+
)}>
|
|
97
|
+
<slot name="title" />
|
|
98
|
+
</div>
|
|
99
|
+
)}
|
|
100
|
+
|
|
101
|
+
{/* Description Slot */}
|
|
102
|
+
{hasDescriptionSlot && (
|
|
103
|
+
<div class={cn(
|
|
104
|
+
'mb-[var(--space-stack-lg)] max-w-xl text-lg leading-relaxed text-foreground-muted',
|
|
105
|
+
'[&>p]:text-lg [&>p]:leading-relaxed [&>p]:text-foreground-muted',
|
|
106
|
+
layout === 'centered' && 'mx-auto'
|
|
107
|
+
)}>
|
|
108
|
+
<slot name="description" />
|
|
109
|
+
</div>
|
|
110
|
+
)}
|
|
111
|
+
|
|
112
|
+
{/* Actions Slot */}
|
|
113
|
+
{hasActionsSlot && (
|
|
114
|
+
<div class={cn(
|
|
115
|
+
'flex w-full flex-col gap-4 sm:w-auto sm:flex-row',
|
|
116
|
+
layout === 'centered' && 'justify-center'
|
|
117
|
+
)}>
|
|
118
|
+
<slot name="actions" />
|
|
119
|
+
</div>
|
|
120
|
+
)}
|
|
121
|
+
|
|
122
|
+
{/* Default slot for additional content (social proof, etc.) */}
|
|
123
|
+
<slot />
|
|
124
|
+
</div>
|
|
125
|
+
|
|
126
|
+
{/* Aside Column (for split layout) */}
|
|
127
|
+
{layout === 'split' && hasAsideSlot && (
|
|
128
|
+
<div class="relative z-10 w-full order-2 lg:order-none">
|
|
129
|
+
<slot name="aside" />
|
|
130
|
+
{/* Decorative blob for split layout */}
|
|
131
|
+
{showBlob && (
|
|
132
|
+
<div
|
|
133
|
+
class={cn(
|
|
134
|
+
'bg-brand-200/20 pointer-events-none absolute h-64 w-64 rounded-full blur-3xl',
|
|
135
|
+
blobPositions[blobPosition]
|
|
136
|
+
)}
|
|
137
|
+
aria-hidden="true"
|
|
138
|
+
/>
|
|
139
|
+
)}
|
|
140
|
+
</div>
|
|
141
|
+
)}
|
|
142
|
+
|
|
143
|
+
{/* Decorative blob for centered layout */}
|
|
144
|
+
{layout === 'centered' && showBlob && (
|
|
145
|
+
<div
|
|
146
|
+
class={cn(
|
|
147
|
+
'bg-brand-200/20 pointer-events-none absolute h-64 w-64 rounded-full blur-3xl',
|
|
148
|
+
blobPositions[blobPosition]
|
|
149
|
+
)}
|
|
150
|
+
aria-hidden="true"
|
|
151
|
+
/>
|
|
152
|
+
)}
|
|
153
|
+
</div>
|
|
154
|
+
</section>
|