spoko-design-system 0.3.3 → 0.3.9

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.
@@ -0,0 +1,153 @@
1
+ ---
2
+ import type { Author, Category } from './types';
3
+ import DefaultVariant from './variants/Default.astro';
4
+ import HeroVariant from './variants/Hero.astro';
5
+ import PostVariant from './variants/Post.astro';
6
+ import PostSplitVariant from './variants/PostSplit.astro';
7
+
8
+ interface Props {
9
+ variant?: "default" | "hero" | "post" | "post-split";
10
+ title?: string;
11
+ image?: string;
12
+ small?: boolean;
13
+ description?: string;
14
+ info?: string;
15
+ date?: string;
16
+ author?: Author;
17
+ categories?: Category[];
18
+ backgroundClass?: string;
19
+ }
20
+
21
+ const {
22
+ variant = "default",
23
+ title = "",
24
+ image,
25
+ small = false,
26
+ description,
27
+ info,
28
+ date,
29
+ author,
30
+ categories = [],
31
+ backgroundClass = 'bg-blue-darker'
32
+ } = Astro.props;
33
+
34
+ // Helper (function to check if a slot has content)
35
+ const hasSlotContent = async (slotName) => {
36
+ const slot = await Astro.slots.render(slotName);
37
+ return slot?.trim().length > 0;
38
+ };
39
+
40
+ // Get content status
41
+ const hasIntroContent = await hasSlotContent('intro');
42
+ const hasSubtitleContent = await hasSlotContent('subtitle');
43
+ const hasCtaContent = await hasSlotContent('cta-content');
44
+
45
+ // Content helpers
46
+ const hasMetadata = author || date;
47
+ const hasCategories = categories.length > 0;
48
+
49
+ // Props to pass to variants
50
+ const commonProps = {
51
+ title,
52
+ image,
53
+ hasIntroContent,
54
+ hasSubtitleContent,
55
+ hasCtaContent,
56
+ hasMetadata,
57
+ hasCategories,
58
+ backgroundClass,
59
+ };
60
+ ---
61
+
62
+ {variant === "default" && (
63
+ <DefaultVariant
64
+ {...commonProps}
65
+ small={small}
66
+ >
67
+ <slot name="intro" slot="intro" />
68
+ <slot name="subtitle" slot="subtitle" />
69
+ <slot name="cta-content" slot="cta-content" />
70
+ </DefaultVariant>
71
+ )}
72
+
73
+ {variant === "hero" && (
74
+ <HeroVariant
75
+ {...commonProps}
76
+ description={description}
77
+ info={info}
78
+ />
79
+ )}
80
+
81
+ {variant === "post" && (
82
+ <PostVariant
83
+ {...commonProps}
84
+ author={author}
85
+ date={date}
86
+ categories={categories}
87
+ />
88
+ )}
89
+
90
+ {variant === "post-split" && (
91
+ <PostSplitVariant
92
+ {...commonProps}
93
+ author={author}
94
+ date={date}
95
+ categories={categories}
96
+ />
97
+ )}
98
+
99
+ <style is:global>
100
+ .bg-vw {
101
+ background: radial-gradient(circle at 50% 85%, #00437a 0%, #001e50 100%);
102
+ }
103
+
104
+ .featured-image-overlay {
105
+ @apply absolute top-0 bottom-0 left-0 right-0 overflow-hidden w-full bg-gray-100 z-1;
106
+
107
+ &:before,
108
+ &:after {
109
+ @apply content-empty top-0 bottom-0 left-0 right-0 absolute;
110
+ }
111
+
112
+ &:before {
113
+ z-index: 5;
114
+ background: linear-gradient(
115
+ 0deg,
116
+ rgba(0, 0, 0, 0.95),
117
+ transparent 30%,
118
+ transparent 70%,
119
+ rgba(0, 0, 0, 0.95)
120
+ );
121
+ opacity: 0.5;
122
+ }
123
+
124
+ &:after {
125
+ background: radial-gradient(circle at 50% 85%, #00437a 0, #001e50 100%);
126
+ opacity: 0.8;
127
+ }
128
+ }
129
+
130
+ .featured-image {
131
+ width: 100%;
132
+ @apply bg-blue-900;
133
+
134
+ img {
135
+ width: 100%;
136
+ object-fit: cover;
137
+ max-width: 100%;
138
+ display: block;
139
+ }
140
+ }
141
+
142
+ h1 {
143
+ b {
144
+ @apply font-headregular whitespace-nowrap;
145
+ }
146
+ small {
147
+ @apply text-6 whitespace-nowrap;
148
+ }
149
+ span {
150
+ @apply text-accent-light;
151
+ }
152
+ }
153
+ </style>
File without changes
@@ -0,0 +1,29 @@
1
+ // types.ts
2
+ export interface Author {
3
+ firstName?: string;
4
+ name: string;
5
+ }
6
+
7
+ export interface Category {
8
+ name: string;
9
+ uri: string;
10
+ }
11
+
12
+ export interface Props {
13
+ // Common props
14
+ variant?: "default" | "hero" | "post" | "post-split";
15
+ title?: string;
16
+ image?: string;
17
+ backgroundClass?: string;
18
+
19
+
20
+ // Default & Hero variant props
21
+ small?: boolean;
22
+ description?: string;
23
+ info?: string;
24
+
25
+ // Post variants props
26
+ date?: string;
27
+ author?: Author;
28
+ categories?: Category[];
29
+ }
@@ -0,0 +1,40 @@
1
+ ---
2
+ // variants/Default.astro
3
+ interface Props {
4
+ title?: string;
5
+ small?: boolean;
6
+ hasIntroContent: boolean;
7
+ hasSubtitleContent: boolean;
8
+ hasCtaContent: boolean;
9
+ }
10
+
11
+ const {
12
+ title = "",
13
+ small = false,
14
+ hasIntroContent,
15
+ hasSubtitleContent,
16
+ hasCtaContent,
17
+ } = Astro.props;
18
+ ---
19
+
20
+ <header
21
+ class:list={[
22
+ "flow content-grid", // globalne klasy
23
+ "jumbotron-header-base bg-vw", // klasy bazowe i tło
24
+ small ? "jumbotron-container-small" : "jumbotron-container-large" // wariant rozmiaru
25
+ ]}
26
+ >
27
+ {hasIntroContent ? (
28
+ <slot name="intro" />
29
+ ) : (
30
+ <h1 class="jumbotron-title-default" set:html={title} />
31
+ )}
32
+
33
+ {hasSubtitleContent && <slot name="subtitle" />}
34
+
35
+ {hasCtaContent && (
36
+ <div class="jumbotron-cta-wrapper">
37
+ <slot name="cta-content" />
38
+ </div>
39
+ )}
40
+ </header>
@@ -0,0 +1,54 @@
1
+ ---
2
+ // variants/Hero.astro
3
+ interface Props {
4
+ title?: string;
5
+ image?: string;
6
+ description?: string;
7
+ info?: string;
8
+ backgroundClass?: string;
9
+ }
10
+
11
+ const {
12
+ title = "",
13
+ image,
14
+ description,
15
+ info,
16
+ backgroundClass
17
+ } = Astro.props;
18
+
19
+ console.log('Received backgroundClass:', backgroundClass); // debug
20
+ ---
21
+
22
+ <div class={`relative w-full ${backgroundClass}`}>
23
+ {image && (
24
+ <div class="absolute inset-0 w-full h-full">
25
+ <div class="absolute inset-0 bg-gradient-to-r from-blue-900 to-transparent opacity-90 z-1" />
26
+ <img
27
+ class="w-full h-full object-cover"
28
+ src={image}
29
+ alt={title}
30
+ />
31
+ </div>
32
+ )}
33
+
34
+ <div class="xl:container mx-auto px-3.5 md:px-8 py-8 h-56 sm:h-72 md:max-h-72 items-center flex">
35
+ <header class="relative z-10 text-white">
36
+ <h1
37
+ class="font-headlight text-3xl sm:text-4xl md:text-5xl xl:text-6xl mt-1 line-clamp-3 leading-tight"
38
+ set:html={title}
39
+ />
40
+ {description && (
41
+ <div
42
+ class="mb-1 line-clamp-3 text-base sm:text-lg leading-none mt-4"
43
+ set:html={description}
44
+ />
45
+ )}
46
+ {info && (
47
+ <div
48
+ class="font-medium mb-4 line-clamp-1 text-base sm:text-lg mt-2"
49
+ set:html={info}
50
+ />
51
+ )}
52
+ </header>
53
+ </div>
54
+ </div>
@@ -0,0 +1,62 @@
1
+ ---
2
+ // variants/Post.astro
3
+ import type { Author, Category } from '../types';
4
+ import CategoryLink from "../../CategoryLink.astro";
5
+ import Date from "../../Date.astro";
6
+
7
+ interface Props {
8
+ title?: string;
9
+ image?: string;
10
+ author?: Author;
11
+ date?: string;
12
+ categories?: Category[];
13
+ hasMetadata: boolean;
14
+ hasCategories: boolean;
15
+ }
16
+
17
+ const {
18
+ title = "",
19
+ image,
20
+ author,
21
+ date,
22
+ categories = [],
23
+ hasMetadata,
24
+ hasCategories,
25
+ } = Astro.props;
26
+ ---
27
+
28
+ <header class="post-header pt-11 w-full justify-center text-white z-2 bg-blue-darkest relative">
29
+ <div class="heading text-white relative flex items-center justify-center mt-auto w-full z-[2]">
30
+ <div class="w-full sm:max-w-[640px] md:max-w-3xl lg:max-w-5xl xl:max-w-7xl 2xl:max-w-[1536px] px-4 py-5 flex flex-col flex-wrap">
31
+ <h1 class="font-headlight text-2xl mb-1 sm:text-3xl md:(text-4xl mb-3) xl:text-6xl mt-1 order-2 line-clamp-3 pb-1">
32
+ {title}
33
+ </h1>
34
+
35
+ {hasCategories && (
36
+ <div class="order-1">
37
+ <CategoryLink categories={categories} />
38
+ </div>
39
+ )}
40
+
41
+ {hasMetadata && (
42
+ <div class="order-3 flex items-center text-gray-100">
43
+ {author && (
44
+ <span class="text-sm" title={author.firstName}>
45
+ {author.name}
46
+ </span>
47
+ )}
48
+ {author && date && <span class="mx-1">-</span>}
49
+ {date && <Date date={date} />}
50
+ </div>
51
+ )}
52
+ </div>
53
+ </div>
54
+
55
+ <div class="featured-image-overlay">
56
+ <img
57
+ src={image}
58
+ alt={title}
59
+ class="w-full h-full object-cover block max-w-full"
60
+ />
61
+ </div>
62
+ </header>
@@ -0,0 +1,71 @@
1
+ ---
2
+ import type { Author, Category } from '../types';
3
+ import CategoryLink from "../../CategoryLink.astro";
4
+ import Date from "../../Date.astro";
5
+ import { Image } from "astro:assets";
6
+
7
+ interface Props {
8
+ title?: string;
9
+ image?: string;
10
+ author?: Author;
11
+ date?: string;
12
+ categories?: Category[];
13
+ hasMetadata: boolean;
14
+ hasCategories: boolean;
15
+ }
16
+
17
+ const {
18
+ title = "",
19
+ image,
20
+ author,
21
+ date,
22
+ categories = [],
23
+ hasMetadata,
24
+ hasCategories,
25
+ } = Astro.props;
26
+ ---
27
+
28
+ <div class="jumbotron-split-wrapper bg-blue-900 bg-vw">
29
+ <div class="jumbotron-split-container">
30
+ <header class="jumbotron-split-header">
31
+ <div class="heading flex flex-wrap text-white relative items-center justify-center mt-auto w-full z-[2]">
32
+ <div class="jumbotron-split-content">
33
+ <h1 class="jumbotron-split-title" set:html={title} />
34
+
35
+ {hasCategories && (
36
+ <div class="jumbotron-categories">
37
+ <CategoryLink categories={categories} />
38
+ </div>
39
+ )}
40
+
41
+ {hasMetadata && (
42
+ <div class="jumbotron-split-meta">
43
+ {author && (
44
+ <span class="text-sm" title={author.firstName} data-pagefind-ignore>
45
+ {author.name}
46
+ </span>
47
+ )}
48
+ {author && date && <span class="mx-1">-</span>}
49
+ {date && <Date date={date} />}
50
+ </div>
51
+ )}
52
+ </div>
53
+ </div>
54
+
55
+ {image && (
56
+ <div class="jumbotron-split-image-wrapper">
57
+ <div class="jumbotron-split-image">
58
+ <Image
59
+ class="jumbotron-split-img"
60
+ src={image}
61
+ alt={title}
62
+ width={768}
63
+ height={432}
64
+ loading="eager"
65
+ />
66
+ </div>
67
+ </div>
68
+ )}
69
+ </header>
70
+ </div>
71
+ </div>
@@ -0,0 +1,12 @@
1
+ ---
2
+ import type { Props } from "./Jumbotron/types";
3
+ import BaseJumbotron from "./Jumbotron/index.astro";
4
+
5
+ const props = Astro.props as Props;
6
+ ---
7
+
8
+ <BaseJumbotron {...props}>
9
+ <slot name="intro" slot="intro" />
10
+ <slot name="subtitle" slot="subtitle" />
11
+ <slot name="cta-content" slot="cta-content" />
12
+ </BaseJumbotron>
package/src/config.ts CHANGED
@@ -37,7 +37,7 @@ export const SIDEBAR = [
37
37
  { text: "Icons", link: "/components/icons/" },
38
38
  { text: "Image", link: "/components/image/" },
39
39
  { text: "Input", link: "/components/input/" },
40
- { text: "Jumbatron", link: "/components/jumbatron/" },
40
+ { text: "Jumbotron", link: "/components/jumbotron/" },
41
41
  { text: "Modal", link: "/components/modal/" },
42
42
  { text: "PostHeader", link: "/components/post-header/" },
43
43
  { text: "PR-Code", link: "/components/pr-code/" },
@@ -45,7 +45,7 @@ const canonicalURL = new URL(Astro.url.pathname, Astro.site).toString();
45
45
  createdy by
46
46
  </div>
47
47
  <img
48
- class="h-4 w-min md:h-5 "
48
+ class="h-4 w-min md:h-5"
49
49
  src="spoko.space.svg"
50
50
  alt="Modern Websites"
51
51
  width="126"
@@ -58,3 +58,4 @@ const canonicalURL = new URL(Astro.url.pathname, Astro.site).toString();
58
58
  </footer>
59
59
  </body>
60
60
  </html>
61
+
@@ -1,5 +1,5 @@
1
1
  ---
2
- title: "Jumbatron"
2
+ title: "Jumbotron"
3
3
  layout: "../../layouts/MainLayout.astro"
4
4
  ---
5
5
  import Image from '../../components/Image.astro'