@contentrain/astro-kit 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.
- package/README.md +3 -0
- package/catalog.json +19 -1
- package/components/footer/Footer.astro +5 -4
- package/components/footer/meta.json +1 -1
- package/components/header/Header.astro +24 -6
- package/components/header/meta.json +3 -0
- package/components/post-card/PostCard.astro +4 -2
- package/components/post-card/meta.json +2 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -69,6 +69,9 @@ theme applies them to the kit's markers, and only when the site sets them:
|
|
|
69
69
|
- `--spacing-section`: the distance between two consecutive sections; each
|
|
70
70
|
`[data-kit-section]` gets half of it as vertical padding, except
|
|
71
71
|
where `data-kit-spacing="none"`.
|
|
72
|
+
- `data-kit-brand` (the site title in Header and Footer) and `data-kit-tagline`
|
|
73
|
+
(Footer) take the theme's own sizes: the title from where it sits (body in
|
|
74
|
+
the header, a heading in the footer), the tagline from its preset.
|
|
72
75
|
|
|
73
76
|
The full list is in `catalog.json` under `tokens`.
|
|
74
77
|
|
package/catalog.json
CHANGED
|
@@ -739,7 +739,7 @@
|
|
|
739
739
|
},
|
|
740
740
|
"copyright": {
|
|
741
741
|
"type": "string",
|
|
742
|
-
"description": "Copyright line;
|
|
742
|
+
"description": "Copyright line; {year} is the current year. Defaults to © <year> <siteName>."
|
|
743
743
|
},
|
|
744
744
|
"navLabel": {
|
|
745
745
|
"type": "string",
|
|
@@ -937,6 +937,19 @@
|
|
|
937
937
|
"required": true,
|
|
938
938
|
"description": "Site title (site.title)."
|
|
939
939
|
},
|
|
940
|
+
"tagline": {
|
|
941
|
+
"type": "string",
|
|
942
|
+
"description": "A line under the site name, as themes that print the tagline in the header do (site.tagline)."
|
|
943
|
+
},
|
|
944
|
+
"brandSize": {
|
|
945
|
+
"type": "string",
|
|
946
|
+
"description": "The site name's size where the source theme sets its own (a CSS length)."
|
|
947
|
+
},
|
|
948
|
+
"linkNav": {
|
|
949
|
+
"type": "boolean",
|
|
950
|
+
"default": false,
|
|
951
|
+
"description": "The navigation in the site's link colour, as themes that colour every link do."
|
|
952
|
+
},
|
|
940
953
|
"logo": {
|
|
941
954
|
"type": "object",
|
|
942
955
|
"fields": {
|
|
@@ -1575,6 +1588,11 @@
|
|
|
1575
1588
|
"max": 3,
|
|
1576
1589
|
"default": 2,
|
|
1577
1590
|
"description": "Title heading level in the page outline."
|
|
1591
|
+
},
|
|
1592
|
+
"linkTitle": {
|
|
1593
|
+
"type": "boolean",
|
|
1594
|
+
"default": false,
|
|
1595
|
+
"description": "The title in the site's link colour (--color-link), as themes that colour every link do."
|
|
1578
1596
|
}
|
|
1579
1597
|
},
|
|
1580
1598
|
"slots": {},
|
|
@@ -33,7 +33,7 @@ interface Props {
|
|
|
33
33
|
/** A single row of links (the footer menu). */
|
|
34
34
|
links?: LinkInput[] | undefined
|
|
35
35
|
social?: LinkInput[] | undefined
|
|
36
|
-
/** The copyright line, e.g. "© 2026 Northwind Studio". */
|
|
36
|
+
/** The copyright line, e.g. "© 2026 Northwind Studio"; `{year}` is the current year. */
|
|
37
37
|
copyright?: string | undefined
|
|
38
38
|
/** Accessible name of the footer navigation ("Footer"). */
|
|
39
39
|
navLabel?: string | undefined
|
|
@@ -43,13 +43,14 @@ interface Props {
|
|
|
43
43
|
|
|
44
44
|
const { siteName, tagline, columns = [], links = [], social = [], copyright, navLabel = 'Footer', layout = 'simple', tone } = Astro.props
|
|
45
45
|
const { root, inner, muted, link } = footer({ layout, tone })
|
|
46
|
-
const
|
|
46
|
+
const year = String(new Date().getFullYear())
|
|
47
|
+
const line = copyright?.replaceAll('{year}', year) ?? `© ${year} ${siteName}`
|
|
47
48
|
---
|
|
48
49
|
<footer class={root()}>
|
|
49
50
|
<div class={inner()} style={layout === 'columns' ? `--footer-columns: ${Math.max(columns.length, 1)}` : undefined}>
|
|
50
51
|
<div class="flex flex-col gap-3">
|
|
51
|
-
<p class="text-base font-semibold">{siteName}</p>
|
|
52
|
-
{tagline && <p class={muted()}>{tagline}</p>}
|
|
52
|
+
<p class="text-base font-semibold" data-kit-brand>{siteName}</p>
|
|
53
|
+
{tagline && <p class={muted()} data-kit-tagline>{tagline}</p>}
|
|
53
54
|
{layout === 'columns' && <p class:list={[muted(), 'mt-auto pt-6']}>{line}</p>}
|
|
54
55
|
</div>
|
|
55
56
|
{layout === 'columns'
|
|
@@ -31,6 +31,12 @@ const header = tv({
|
|
|
31
31
|
|
|
32
32
|
interface Props {
|
|
33
33
|
siteName: string
|
|
34
|
+
/** A line under the site name, as themes that print the site's tagline in the header do. */
|
|
35
|
+
tagline?: string | undefined
|
|
36
|
+
/** The site name's size, where the source theme sets its own (a CSS length). */
|
|
37
|
+
brandSize?: string | undefined
|
|
38
|
+
/** The navigation in the site's link colour, as themes that colour every link do (Hello Elementor). */
|
|
39
|
+
linkNav?: boolean | undefined
|
|
34
40
|
logo?: ImageInput | undefined
|
|
35
41
|
/** Show the site name next to the logo. */
|
|
36
42
|
showName?: boolean | undefined
|
|
@@ -45,16 +51,28 @@ interface Props {
|
|
|
45
51
|
position?: 'static' | 'sticky' | undefined
|
|
46
52
|
}
|
|
47
53
|
|
|
48
|
-
const { siteName, logo, showName = true, homeHref = '/', items, action, navLabel, menuLabel, closeLabel, layout, tone, position } = Astro.props
|
|
54
|
+
const { siteName, tagline, brandSize, linkNav, logo, showName = true, homeHref = '/', items, action, navLabel, menuLabel, closeLabel, layout, tone, position } = Astro.props
|
|
49
55
|
const { root, inner, brand } = header({ layout, tone, position })
|
|
50
56
|
---
|
|
51
57
|
<header class={root()}>
|
|
52
58
|
<div class={inner()}>
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
59
|
+
{tagline
|
|
60
|
+
? (
|
|
61
|
+
<div class="flex flex-col gap-1">
|
|
62
|
+
<a href={homeHref} class={brand()} aria-label={showName ? undefined : siteName} style={brandSize ? `font-size: ${brandSize}` : undefined} data-kit-brand>
|
|
63
|
+
{logo && <KitImage image={logo} priority class="h-8 w-auto" sizes="160px" />}
|
|
64
|
+
{showName && <span>{siteName}</span>}
|
|
65
|
+
</a>
|
|
66
|
+
<p class="opacity-75" data-kit-tagline>{tagline}</p>
|
|
67
|
+
</div>
|
|
68
|
+
)
|
|
69
|
+
: (
|
|
70
|
+
<a href={homeHref} class={brand()} aria-label={showName ? undefined : siteName} style={brandSize ? `font-size: ${brandSize}` : undefined} data-kit-brand>
|
|
71
|
+
{logo && <KitImage image={logo} priority class="h-8 w-auto" sizes="160px" />}
|
|
72
|
+
{showName && <span>{siteName}</span>}
|
|
73
|
+
</a>
|
|
74
|
+
)}
|
|
75
|
+
<div class:list={['flex items-center gap-4', layout === 'centered' ? 'justify-center' : 'ml-auto', linkNav && 'text-[color:var(--color-link,var(--color-accent))]']}>
|
|
58
76
|
<Nav items={items} label={navLabel} menuLabel={menuLabel} closeLabel={closeLabel} part="nav-header" align={layout === 'centered' ? 'center' : 'end'} />
|
|
59
77
|
{action && <Button action={action} size="sm" class="hidden md:inline-flex" />}
|
|
60
78
|
</div>
|
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
},
|
|
13
13
|
"props": {
|
|
14
14
|
"siteName": { "type": "string", "required": true, "description": "Site title (site.title)." },
|
|
15
|
+
"tagline": { "type": "string", "description": "A line under the site name, as themes that print the tagline in the header do (site.tagline)." },
|
|
16
|
+
"brandSize": { "type": "string", "description": "The site name's size where the source theme sets its own (a CSS length)." },
|
|
17
|
+
"linkNav": { "type": "boolean", "default": false, "description": "The navigation in the site's link colour, as themes that colour every link do." },
|
|
15
18
|
"logo": { "type": "object", "fields": { "src": { "type": "image", "required": true }, "alt": { "type": "string", "required": true }, "width": { "type": "integer" }, "height": { "type": "integer" } }, "description": "Logo image (site.logo)." },
|
|
16
19
|
"showName": { "type": "boolean", "default": true, "description": "Show the site name next to the logo." },
|
|
17
20
|
"homeHref": { "type": "url", "default": "/", "description": "Where the brand links." },
|
|
@@ -37,9 +37,11 @@ interface Props {
|
|
|
37
37
|
author?: string | undefined
|
|
38
38
|
headingLevel?: 2 | 3 | undefined
|
|
39
39
|
layout?: 'vertical' | 'horizontal' | 'minimal' | undefined
|
|
40
|
+
/** The title in the site's link colour, as themes that colour every link do (Hello Elementor). */
|
|
41
|
+
linkTitle?: boolean | undefined
|
|
40
42
|
}
|
|
41
43
|
|
|
42
|
-
const { title, href, excerpt, date: rawDate, locale = 'en', image, category, author, headingLevel = 2, layout } = Astro.props
|
|
44
|
+
const { title, href, excerpt, date: rawDate, locale = 'en', image, category, author, headingLevel = 2, layout, linkTitle } = Astro.props
|
|
43
45
|
const date = rawDate === undefined ? undefined : new Date(rawDate)
|
|
44
46
|
const slots = card({ layout })
|
|
45
47
|
const Heading = `h${headingLevel}` as 'h2' | 'h3'
|
|
@@ -58,7 +60,7 @@ const Heading = `h${headingLevel}` as 'h2' | 'h3'
|
|
|
58
60
|
{date && <time datetime={date.toISOString()}>{date.toLocaleDateString(locale, { dateStyle: 'long', timeZone: 'UTC' })}</time>}
|
|
59
61
|
</p>
|
|
60
62
|
)}
|
|
61
|
-
<Heading class={slots.title()}>
|
|
63
|
+
<Heading class={slots.title({ class: linkTitle ? 'text-[color:var(--color-link,var(--color-accent))]' : undefined })}>
|
|
62
64
|
<a href={href} class="text-current no-underline after:absolute after:inset-0 after:content-[''] hover:text-accent">{title}</a>
|
|
63
65
|
</Heading>
|
|
64
66
|
{excerpt && <p class={slots.excerpt()}>{excerpt}</p>}
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
"image": { "type": "object", "fields": { "src": { "type": "image", "required": true }, "alt": { "type": "string", "required": true }, "width": { "type": "integer" }, "height": { "type": "integer" } }, "description": "Cover (posts.cover → media)." },
|
|
18
18
|
"category": { "type": "object", "fields": { "label": { "type": "string", "required": true }, "href": { "type": "url", "required": true } }, "description": "Primary category and its archive." },
|
|
19
19
|
"author": { "type": "string", "description": "Author name (posts.author → authors.name)." },
|
|
20
|
-
"headingLevel": { "type": "integer", "min": 2, "max": 3, "default": 2, "description": "Title heading level in the page outline." }
|
|
20
|
+
"headingLevel": { "type": "integer", "min": 2, "max": 3, "default": 2, "description": "Title heading level in the page outline." },
|
|
21
|
+
"linkTitle": { "type": "boolean", "default": false, "description": "The title in the site's link colour (--color-link), as themes that colour every link do." }
|
|
21
22
|
},
|
|
22
23
|
"slots": {},
|
|
23
24
|
"js": "none",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentrain/astro-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.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.28.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@types/node": "^22.10.0",
|