@contentrain/astro-kit 0.23.6 → 0.24.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/catalog.json
CHANGED
|
@@ -1280,6 +1280,10 @@
|
|
|
1280
1280
|
"type": "string",
|
|
1281
1281
|
"description": "Font size of the footer's links, a CSS length such as 17.88px; absent, the footer's own."
|
|
1282
1282
|
},
|
|
1283
|
+
"linkSizeNarrow": {
|
|
1284
|
+
"type": "string",
|
|
1285
|
+
"description": "Font size of the footer's links below the md breakpoint, a CSS length such as 16.4px; absent, linkSize holds at every width."
|
|
1286
|
+
},
|
|
1283
1287
|
"border": {
|
|
1284
1288
|
"type": "boolean",
|
|
1285
1289
|
"content": false,
|
|
@@ -1308,7 +1312,8 @@
|
|
|
1308
1312
|
},
|
|
1309
1313
|
"a11y": "One <footer> landmark; each link group is a <nav> named by its title. Social links open in a new tab with rel=me.",
|
|
1310
1314
|
"files": [
|
|
1311
|
-
"Footer.astro"
|
|
1315
|
+
"Footer.astro",
|
|
1316
|
+
"footer.ts"
|
|
1312
1317
|
]
|
|
1313
1318
|
},
|
|
1314
1319
|
{
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// links and the copyright line.
|
|
4
4
|
import { tv } from 'tailwind-variants'
|
|
5
5
|
import type { LinkInput } from '../_shared/types'
|
|
6
|
+
import { footerLinkSizeClasses, footerVars } from './footer'
|
|
6
7
|
|
|
7
8
|
const footer = tv({
|
|
8
9
|
slots: {
|
|
@@ -67,14 +68,16 @@ interface Props {
|
|
|
67
68
|
packGapNarrow?: string | undefined
|
|
68
69
|
/** The links' font size, a CSS length (`17.88px`); absent, the footer's own. */
|
|
69
70
|
linkSize?: string | undefined
|
|
71
|
+
/** The links' font size below `md`, a CSS length; absent, `linkSize` holds at every width. */
|
|
72
|
+
linkSizeNarrow?: string | undefined
|
|
70
73
|
/** A border on the footer's top side: absent, the default tone has one and the others do not. */
|
|
71
74
|
border?: boolean | undefined
|
|
72
75
|
}
|
|
73
76
|
|
|
74
|
-
const { siteName, tagline, columns = [], links = [], social = [], contact, copyright, consentLabel, navLabel = 'Footer', layout = 'simple', tone, align, pack, packGap, narrow, packGapNarrow, linkSize, border } = Astro.props
|
|
77
|
+
const { siteName, tagline, columns = [], links = [], social = [], contact, copyright, consentLabel, navLabel = 'Footer', layout = 'simple', tone, align, pack, packGap, narrow, packGapNarrow, linkSize, linkSizeNarrow, border } = Astro.props
|
|
75
78
|
const { root, inner, muted, link } = footer({ layout, tone, align, pack: layout === 'columns' ? pack : undefined, narrow: layout === 'columns' && pack === 'end' ? narrow : undefined, border: (border ?? (tone ?? 'default') === 'default') ? 'on' : 'off' })
|
|
76
79
|
// Custom properties the packed columns and sized links read; none when none is set.
|
|
77
|
-
const vars =
|
|
80
|
+
const vars = footerVars({ layout, columnCount: columns.length, pack, narrow, packGap, packGapNarrow, linkSize, linkSizeNarrow })
|
|
78
81
|
const year = String(new Date().getFullYear())
|
|
79
82
|
const phoneHref = contact?.phone?.replace(/[^\d+]/g, '')
|
|
80
83
|
const hasContact = Boolean(contact?.address || contact?.phone || contact?.email)
|
|
@@ -84,7 +87,7 @@ const hasBottom = Boolean(line || consentLabel)
|
|
|
84
87
|
---
|
|
85
88
|
<!-- The cookie settings control is a button, not a link: the Consent component's listener reopens its bar on any [data-kit-consent-open]. -->
|
|
86
89
|
<footer class={root()}>
|
|
87
|
-
<div class:list={[inner(), linkSize
|
|
90
|
+
<div class:list={[inner(), ...footerLinkSizeClasses({ linkSize, linkSizeNarrow })]} data-kit-footer style={vars || undefined}>
|
|
88
91
|
<div class="flex flex-col gap-3">
|
|
89
92
|
<p class="text-base font-semibold" data-kit-brand>{siteName}</p>
|
|
90
93
|
{tagline && <p class={muted()} data-kit-tagline>{tagline}</p>}
|
|
@@ -5,5 +5,6 @@
|
|
|
5
5
|
{ "name": "centered", "props": { "siteName": "Golden Agency", "tagline": "Websites for makers", "align": "center", "copyright": "© 2026 Golden Agency", "links": [{ "label": "Services", "href": "/services/" }, { "label": "Contact", "href": "/contact/" }], "social": [{ "label": "Instagram", "href": "https://instagram.com/" }] } },
|
|
6
6
|
{ "name": "consent-settings", "props": { "siteName": "Golden Agency", "copyright": "© 2026 Golden Agency", "consentLabel": "Cookie settings", "links": [{ "label": "Privacy", "href": "/privacy/" }] } },
|
|
7
7
|
{ "name": "columns-end", "props": { "siteName": "Golden Works", "tagline": "Websites for makers", "layout": "columns", "pack": "end", "packGap": "128px", "linkSize": "17.88px", "copyright": "© 2026 Golden Works", "columns": [{ "label": "Studio", "links": [{ "label": "About", "href": "/about/" }, { "label": "Work", "href": "/work/" }] }, { "label": "Contact", "links": [{ "label": "Email", "href": "mailto:hello@example.com" }, { "label": "Press", "href": "/press/" }] }] } },
|
|
8
|
-
{ "name": "columns-end-row", "props": { "siteName": "Golden Works", "layout": "columns", "pack": "end", "narrow": "row", "packGap": "128px", "packGapNarrow": "48px", "linkSize": "17.88px", "copyright": "© 2026 Golden Works", "columns": [{ "label": "Studio", "links": [{ "label": "About", "href": "/about/" }, { "label": "Work", "href": "/work/" }] }, { "label": "Contact", "links": [{ "label": "Email", "href": "mailto:hello@example.com" }] }] } }
|
|
8
|
+
{ "name": "columns-end-row", "props": { "siteName": "Golden Works", "layout": "columns", "pack": "end", "narrow": "row", "packGap": "128px", "packGapNarrow": "48px", "linkSize": "17.88px", "copyright": "© 2026 Golden Works", "columns": [{ "label": "Studio", "links": [{ "label": "About", "href": "/about/" }, { "label": "Work", "href": "/work/" }] }, { "label": "Contact", "links": [{ "label": "Email", "href": "mailto:hello@example.com" }] }] } },
|
|
9
|
+
{ "name": "columns-end-row-narrow-size", "props": { "siteName": "Golden Works", "layout": "columns", "pack": "end", "narrow": "row", "packGap": "128px", "packGapNarrow": "48px", "linkSize": "17.88px", "linkSizeNarrow": "16.4px", "copyright": "© 2026 Golden Works", "columns": [{ "label": "Studio", "links": [{ "label": "About", "href": "/about/" }, { "label": "Work", "href": "/work/" }] }, { "label": "Contact", "links": [{ "label": "Email", "href": "mailto:hello@example.com" }] }] } }
|
|
9
10
|
]
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export interface FooterVarsInput {
|
|
2
|
+
layout: 'simple' | 'columns'
|
|
3
|
+
columnCount: number
|
|
4
|
+
pack?: 'spread' | 'end' | undefined
|
|
5
|
+
narrow?: 'stack' | 'row' | undefined
|
|
6
|
+
packGap?: string | undefined
|
|
7
|
+
packGapNarrow?: string | undefined
|
|
8
|
+
linkSize?: string | undefined
|
|
9
|
+
linkSizeNarrow?: string | undefined
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The custom properties the packed columns and sized links read, as one `style` value (empty: none). `linkSizeNarrow` is
|
|
14
|
+
* its own property, applied below `md` by the class below whether the columns stack or stay in a row.
|
|
15
|
+
*/
|
|
16
|
+
export function footerVars(i: FooterVarsInput): string {
|
|
17
|
+
const columns = i.layout === 'columns'
|
|
18
|
+
const packed = columns && i.pack === 'end'
|
|
19
|
+
return [
|
|
20
|
+
columns ? `--footer-columns: ${Math.max(i.columnCount, 1)}` : '',
|
|
21
|
+
packed && i.packGap ? `--footer-gap: ${i.packGap}` : '',
|
|
22
|
+
packed && i.narrow === 'row' && i.packGapNarrow ? `--footer-gap-narrow: ${i.packGapNarrow}` : '',
|
|
23
|
+
i.linkSize ? `--footer-link-size: ${i.linkSize}` : '',
|
|
24
|
+
i.linkSizeNarrow ? `--footer-link-size-narrow: ${i.linkSizeNarrow}` : '',
|
|
25
|
+
].filter(Boolean).join('; ')
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** The link-size classes: the wide size everywhere, the narrow one (when given) overriding it below `md`. */
|
|
29
|
+
export function footerLinkSizeClasses(i: Pick<FooterVarsInput, 'linkSize' | 'linkSizeNarrow'>): string[] {
|
|
30
|
+
return [
|
|
31
|
+
i.linkSize ? '[&_nav_a]:text-[length:var(--footer-link-size)]' : '',
|
|
32
|
+
i.linkSizeNarrow ? 'max-md:[&_nav_a]:text-[length:var(--footer-link-size-narrow)]' : '',
|
|
33
|
+
].filter(Boolean)
|
|
34
|
+
}
|
|
@@ -148,6 +148,10 @@
|
|
|
148
148
|
"type": "string",
|
|
149
149
|
"description": "Font size of the footer's links, a CSS length such as 17.88px; absent, the footer's own."
|
|
150
150
|
},
|
|
151
|
+
"linkSizeNarrow": {
|
|
152
|
+
"type": "string",
|
|
153
|
+
"description": "Font size of the footer's links below the md breakpoint, a CSS length such as 16.4px; absent, linkSize holds at every width."
|
|
154
|
+
},
|
|
151
155
|
"border": {
|
|
152
156
|
"type": "boolean",
|
|
153
157
|
"content": false,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentrain/astro-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Copy-in Astro components for Contentrain sites (shadcn model): typed props, tailwind-variants, zero JavaScript by default — with a machine-readable catalog",
|
|
6
6
|
"type": "module",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"mapping"
|
|
43
43
|
],
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@contentrain/types": "1.
|
|
45
|
+
"@contentrain/types": "1.48.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@types/node": "^22.10.0",
|