@netlify/spark-ui 1.20.0 → 1.21.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.
package/package.json
CHANGED
|
@@ -28,7 +28,8 @@ const {
|
|
|
28
28
|
} = Astro.props;
|
|
29
29
|
|
|
30
30
|
const isAnchorHeadline = isCardClickable && headline && !link?.text && link?.href;
|
|
31
|
-
const isExternal =
|
|
31
|
+
const isExternal =
|
|
32
|
+
link?.href && !new URL(link.href, 'https://www.netlify.com').hostname.endsWith('netlify.com');
|
|
32
33
|
---
|
|
33
34
|
|
|
34
35
|
<Element
|
|
@@ -68,7 +69,12 @@ const isExternal = link?.href && !new URL(link.href, 'https://www.netlify.com').
|
|
|
68
69
|
<slot />
|
|
69
70
|
{
|
|
70
71
|
link && link.text && (
|
|
71
|
-
<ActionLink
|
|
72
|
+
<ActionLink
|
|
73
|
+
class="n-card-link"
|
|
74
|
+
id={link.id}
|
|
75
|
+
href={link.href}
|
|
76
|
+
{...(isExternal && { target: '_blank', rel: 'noopener' })}
|
|
77
|
+
>
|
|
72
78
|
{link.text}
|
|
73
79
|
</ActionLink>
|
|
74
80
|
)
|
|
@@ -163,6 +169,7 @@ const isExternal = link?.href && !new URL(link.href, 'https://www.netlify.com').
|
|
|
163
169
|
}
|
|
164
170
|
|
|
165
171
|
.n-card-clickable .n-action-arrow {
|
|
172
|
+
margin-block-start: auto;
|
|
166
173
|
margin-inline-start: auto;
|
|
167
174
|
}
|
|
168
175
|
|
package/skills/landing-page.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
Build a marketing landing page using Netlify Spark UI. Follow these guidelines strictly.
|
|
4
4
|
|
|
5
|
+
## Template Reference
|
|
6
|
+
|
|
7
|
+
Before building, read the template pages under `docs/src/content/docs/templates/`. They contain complete, working examples of full landing pages and individual sections with recommended layouts and usage patterns:
|
|
8
|
+
|
|
9
|
+
- `docs/src/content/docs/templates/page.mdx` — Full landing page example showing a recommended section order and composition
|
|
10
|
+
- `docs/src/content/docs/templates/cards.mdx` — Cards section layout and usage patterns
|
|
11
|
+
- `docs/src/content/docs/templates/switchback.mdx` — Switchback section layout and usage patterns
|
|
12
|
+
- `docs/src/content/docs/templates/tabbed-content.mdx` — Tabbed content section layout and usage patterns
|
|
13
|
+
|
|
14
|
+
Treat these templates as the authoritative reference for structure and layout decisions. Where template examples differ from or extend the guidelines below, prefer the template.
|
|
15
|
+
|
|
5
16
|
## Page Structure
|
|
6
17
|
|
|
7
18
|
Wrap every section in `<PageSection>` (props: `spaceTop`, `spaceBottom`, `theme`). Use this order (include only what fits the request):
|
|
@@ -80,8 +91,8 @@ import tickerData from '../data/trust-bar-ticker.json';
|
|
|
80
91
|
<PageSection>
|
|
81
92
|
<HeadingBlock eyebrow={cardData.eyebrow} heading={cardData.heading} text={cardData.text} alignment="center" />
|
|
82
93
|
<div class="ntl-grid" style="--ntl-grid-column-min-size: 20rem;">
|
|
83
|
-
{cardData.items.map(({
|
|
84
|
-
<Card
|
|
94
|
+
{cardData.items.map(({ image, ...card }) => (
|
|
95
|
+
<Card {...card}>
|
|
85
96
|
{image && <Image slot="image" src={image.src} alt={image.alt} width={image.width} height={image.height} />}
|
|
86
97
|
</Card>
|
|
87
98
|
))}
|
|
@@ -92,9 +103,8 @@ import tickerData from '../data/trust-bar-ticker.json';
|
|
|
92
103
|
<PageSection>
|
|
93
104
|
<HeadingBlock eyebrow={switchbackData.eyebrow} heading={switchbackData.heading} />
|
|
94
105
|
<SwitchbackGroup>
|
|
95
|
-
{switchbackData.items.map(({
|
|
96
|
-
<Switchback
|
|
97
|
-
isReversed={i % 2 === 0} mediaPattern={mediaPattern}>
|
|
106
|
+
{switchbackData.items.map(({ image, ...item }, i) => (
|
|
107
|
+
<Switchback {...item} isReversed={i % 2 === 0}>
|
|
98
108
|
<Image slot="media" src={image.src} alt={image.alt} width={image.width} height={image.height} />
|
|
99
109
|
</Switchback>
|
|
100
110
|
))}
|
|
@@ -111,8 +121,8 @@ import tickerData from '../data/trust-bar-ticker.json';
|
|
|
111
121
|
))}
|
|
112
122
|
</TabList>
|
|
113
123
|
<TabPanelGroup isUniformHeight noPadding>
|
|
114
|
-
{tabbedContentData.items.map(({
|
|
115
|
-
<TabbedContentPanel isHidden={!isSelected}
|
|
124
|
+
{tabbedContentData.items.map(({ title, icon, isSelected, ...panel }) => (
|
|
125
|
+
<TabbedContentPanel {...panel} isHidden={!isSelected} />
|
|
116
126
|
))}
|
|
117
127
|
</TabPanelGroup>
|
|
118
128
|
</TabbedContent>
|
|
@@ -146,7 +156,7 @@ HeadingBlock props: `heading`, `headingLevel` (1-4, default 2), `text`, `eyebrow
|
|
|
146
156
|
Keep content in JSON files. Key shapes:
|
|
147
157
|
|
|
148
158
|
- **Hero:** `{ heading, text, ctas: [{ id, text, href, variant? }] }`
|
|
149
|
-
- **Card item:** `{ eyebrow,
|
|
159
|
+
- **Card item:** `{ eyebrow, headline, paragraph (HTML ok), link: { id, href, text }, image?: { src, alt, width, height }, isCardClickable? }`
|
|
150
160
|
- **Switchback item:** `{ eyebrow, heading, text, list: string[], cta: { id, href, text }, mediaPattern: 1|2|3, image: { src, alt, width, height } }`
|
|
151
161
|
- **TabbedContent item:** `{ title, icon?, isSelected, heading, text?, list?: string[], ctas?, codeBlock?: { heading?, icon?, lang, code } }`
|
|
152
162
|
- **TrustBarTicker:** `{ stats: [{ iconSrc, text }], logos: [{ src, alt, width, height }] }`
|