foundry-component-library 0.2.6 → 0.2.8
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/lib/components/Hero/index.tsx +0 -2
- package/lib/components/StickyTiles/Tile.tsx +72 -0
- package/lib/components/StickyTiles/index.tsx +67 -0
- package/lib/components/StickyTiles/styles.module.scss +165 -0
- package/lib/index.ts +2 -0
- package/lib/queries/getHubBySlug.ts +15 -0
- package/lib/types/index.ts +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { MouseEventHandler, useRef } from "react";
|
|
2
|
+
import styles from "./styles.module.scss";
|
|
3
|
+
import Plus from "../../assets/svg/plus.svg";
|
|
4
|
+
import { NextLink } from "../../types";
|
|
5
|
+
import Arrow from "../../assets/svg/arrow.svg";
|
|
6
|
+
import { useScroll } from "motion/react";
|
|
7
|
+
import { motion, useTransform } from "framer-motion";
|
|
8
|
+
|
|
9
|
+
const Tile = ({
|
|
10
|
+
text,
|
|
11
|
+
background,
|
|
12
|
+
href,
|
|
13
|
+
onClick,
|
|
14
|
+
Link,
|
|
15
|
+
hoverText,
|
|
16
|
+
}: {
|
|
17
|
+
text: string;
|
|
18
|
+
background: "pink" | "yellow" | "brown" | "blue";
|
|
19
|
+
href: string;
|
|
20
|
+
i: number;
|
|
21
|
+
onClick?: MouseEventHandler<HTMLAnchorElement>;
|
|
22
|
+
Link: NextLink;
|
|
23
|
+
hoverText: string;
|
|
24
|
+
isLast: boolean;
|
|
25
|
+
}) => {
|
|
26
|
+
const ref = useRef(null);
|
|
27
|
+
const { scrollYProgress } = useScroll({
|
|
28
|
+
target: ref,
|
|
29
|
+
offset: ["start 0.8", "start 0.3"],
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const scale = useTransform(scrollYProgress, [0, 1], [0.8, 1]);
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<motion.div
|
|
36
|
+
ref={ref}
|
|
37
|
+
className={styles.tileWrapper}
|
|
38
|
+
style={{
|
|
39
|
+
scale: scale,
|
|
40
|
+
}}>
|
|
41
|
+
<div className={styles.videoWrapper}>
|
|
42
|
+
<video
|
|
43
|
+
className={styles.video}
|
|
44
|
+
autoPlay
|
|
45
|
+
loop
|
|
46
|
+
playsInline
|
|
47
|
+
src="https://data.foundry.ch/wp-content/uploads/2025/07/foundry-sennheiser-hear-more-thumbnail-video.mp4"
|
|
48
|
+
/>
|
|
49
|
+
</div>
|
|
50
|
+
<Link
|
|
51
|
+
href={href}
|
|
52
|
+
onClick={onClick}
|
|
53
|
+
draggable="false"
|
|
54
|
+
className={`${styles.tile} ${styles[background]}`}>
|
|
55
|
+
<div className={styles.face}>
|
|
56
|
+
<div className={styles.text}>{text}</div>
|
|
57
|
+
<div>
|
|
58
|
+
<Plus />
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
<div className={styles.tails}>
|
|
62
|
+
<div className={styles.tailsText}>{hoverText}</div>
|
|
63
|
+
<div>
|
|
64
|
+
Learn More <Arrow />
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
</Link>
|
|
68
|
+
</motion.div>
|
|
69
|
+
);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export default Tile;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useRef } from "react";
|
|
3
|
+
import Container from "../Container";
|
|
4
|
+
import styles from "./styles.module.scss";
|
|
5
|
+
import TextSection from "../TextSection";
|
|
6
|
+
import Tile from "./Tile";
|
|
7
|
+
import { NextLink } from "../../types";
|
|
8
|
+
import { motion } from "framer-motion";
|
|
9
|
+
|
|
10
|
+
const ServiceHubsTeaser = ({
|
|
11
|
+
caption,
|
|
12
|
+
heading,
|
|
13
|
+
text,
|
|
14
|
+
tiles,
|
|
15
|
+
Link,
|
|
16
|
+
}: {
|
|
17
|
+
caption: string;
|
|
18
|
+
heading: string;
|
|
19
|
+
text: string;
|
|
20
|
+
tiles: {
|
|
21
|
+
id: string;
|
|
22
|
+
uri: string;
|
|
23
|
+
title: string;
|
|
24
|
+
customFieldsHub: {
|
|
25
|
+
heading: string;
|
|
26
|
+
};
|
|
27
|
+
}[];
|
|
28
|
+
Link: NextLink;
|
|
29
|
+
}) => {
|
|
30
|
+
const wrapperRef = useRef<HTMLDivElement>(null);
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<div className={styles.benefits}>
|
|
34
|
+
<TextSection caption={caption} heading={heading} text={text} isSmall />
|
|
35
|
+
<Container noMobilePadding>
|
|
36
|
+
<div className={styles.wrapper} ref={wrapperRef}>
|
|
37
|
+
<motion.div className={styles.tiles}>
|
|
38
|
+
{tiles.map((tile, i) => {
|
|
39
|
+
const colors: Array<"pink" | "yellow" | "brown" | "blue"> = [
|
|
40
|
+
"pink",
|
|
41
|
+
"yellow",
|
|
42
|
+
"brown",
|
|
43
|
+
"blue",
|
|
44
|
+
];
|
|
45
|
+
const background = colors[i % colors.length];
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<Tile
|
|
49
|
+
key={tile.id}
|
|
50
|
+
text={tile.title}
|
|
51
|
+
hoverText={tile.customFieldsHub.heading}
|
|
52
|
+
background={background}
|
|
53
|
+
href={tile.uri}
|
|
54
|
+
i={i}
|
|
55
|
+
Link={Link}
|
|
56
|
+
isLast={i === tiles.length - 1}
|
|
57
|
+
/>
|
|
58
|
+
);
|
|
59
|
+
})}
|
|
60
|
+
</motion.div>
|
|
61
|
+
</div>
|
|
62
|
+
</Container>
|
|
63
|
+
</div>
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export default ServiceHubsTeaser;
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
@use "../variables" as *;
|
|
2
|
+
|
|
3
|
+
.benefits {
|
|
4
|
+
// overflow: hidden;
|
|
5
|
+
margin-bottom: 80px;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.wrapper {
|
|
9
|
+
width: 100%;
|
|
10
|
+
// overflow-x: scroll;
|
|
11
|
+
user-select: none;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.tiles {
|
|
15
|
+
gap: 16px;
|
|
16
|
+
padding-bottom: 64px;
|
|
17
|
+
|
|
18
|
+
@media #{$QUERY-sm} {
|
|
19
|
+
padding-bottom: 32px;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.tileWrapper {
|
|
24
|
+
z-index: 0;
|
|
25
|
+
position: relative;
|
|
26
|
+
margin-left: auto;
|
|
27
|
+
margin-right: auto;
|
|
28
|
+
position: sticky;
|
|
29
|
+
top: 90px;
|
|
30
|
+
height: 80vh;
|
|
31
|
+
width: 800px;
|
|
32
|
+
max-width: 90%;
|
|
33
|
+
|
|
34
|
+
@media screen and (max-width: $screen-sm) {
|
|
35
|
+
height: 500px;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.videoWrapper {
|
|
40
|
+
position: absolute;
|
|
41
|
+
top: 0;
|
|
42
|
+
left: 0;
|
|
43
|
+
width: 100%;
|
|
44
|
+
height: 100%;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.video {
|
|
48
|
+
width: 100%;
|
|
49
|
+
height: 100%;
|
|
50
|
+
object-fit: cover;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.tile {
|
|
54
|
+
flex-shrink: 0;
|
|
55
|
+
white-space: pre-wrap;
|
|
56
|
+
padding: 16px;
|
|
57
|
+
display: flex;
|
|
58
|
+
flex-direction: column;
|
|
59
|
+
align-items: center;
|
|
60
|
+
justify-content: center;
|
|
61
|
+
text-align: center;
|
|
62
|
+
box-sizing: border-box;
|
|
63
|
+
background-color: rgba($color-pink, 1);
|
|
64
|
+
color: $color-brown;
|
|
65
|
+
font-size: 34px;
|
|
66
|
+
width: 100%;
|
|
67
|
+
height: 100%;
|
|
68
|
+
font-family: $font-secondary;
|
|
69
|
+
box-shadow: 0 0 10px rgba($color-brown, 0.2);
|
|
70
|
+
position: relative;
|
|
71
|
+
z-index: 2;
|
|
72
|
+
transition: background-color 0.3s;
|
|
73
|
+
|
|
74
|
+
path {
|
|
75
|
+
stroke: $color-brown;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
&.yellow {
|
|
79
|
+
background-color: rgba($color-yellow, 1);
|
|
80
|
+
color: $color-blue;
|
|
81
|
+
box-shadow: 0 0 10px rgba($color-blue, 0.2);
|
|
82
|
+
|
|
83
|
+
path {
|
|
84
|
+
stroke: $color-blue;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
&.brown {
|
|
89
|
+
background-color: rgba($color-brown, 1);
|
|
90
|
+
color: $color-pink;
|
|
91
|
+
box-shadow: 0 0 10px rgba($color-pink, 0.2);
|
|
92
|
+
|
|
93
|
+
path {
|
|
94
|
+
stroke: $color-pink;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
&.blue {
|
|
99
|
+
background-color: rgba($color-blue, 1);
|
|
100
|
+
color: $color-white;
|
|
101
|
+
box-shadow: 0 0 10px rgba($color-black, 0.2);
|
|
102
|
+
|
|
103
|
+
path {
|
|
104
|
+
stroke: $color-white;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
&:hover {
|
|
109
|
+
background-color: rgba($color-pink, 0.2);
|
|
110
|
+
|
|
111
|
+
&.yellow {
|
|
112
|
+
background-color: rgba($color-yellow, 0.2);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
&.brown {
|
|
116
|
+
background-color: rgba($color-brown, 0.2);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
&.blue {
|
|
120
|
+
background-color: rgba($color-blue, 0.2);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.face {
|
|
124
|
+
display: none;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.tails {
|
|
128
|
+
display: block;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.text {
|
|
134
|
+
margin-bottom: 42px;
|
|
135
|
+
|
|
136
|
+
&:last-child {
|
|
137
|
+
margin-bottom: 0;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.face {
|
|
142
|
+
display: block;
|
|
143
|
+
font-size: 42px;
|
|
144
|
+
|
|
145
|
+
@media #{$QUERY-sm} {
|
|
146
|
+
font-size: 34px;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.tails {
|
|
151
|
+
padding-left: 30px;
|
|
152
|
+
display: none;
|
|
153
|
+
font-size: 34px;
|
|
154
|
+
font-family: $font-secondary;
|
|
155
|
+
color: $color-white;
|
|
156
|
+
|
|
157
|
+
path {
|
|
158
|
+
stroke: $color-white !important;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.tailsText {
|
|
163
|
+
margin-bottom: 30px;
|
|
164
|
+
max-width: 500px;
|
|
165
|
+
}
|
package/lib/index.ts
CHANGED
|
@@ -37,6 +37,7 @@ import TeamBenefits from "./components/TeamBenefits";
|
|
|
37
37
|
import TeamPhotos from "./components/TeamPhotos";
|
|
38
38
|
import TextSection from "./components/TextSection";
|
|
39
39
|
import Tiles from "./components/Tiles";
|
|
40
|
+
import StickyTiles from "./components/StickyTiles";
|
|
40
41
|
import VideoTeaser from "./components/VideoTeaser";
|
|
41
42
|
|
|
42
43
|
export {
|
|
@@ -79,5 +80,6 @@ export {
|
|
|
79
80
|
TeamPhotos,
|
|
80
81
|
TextSection,
|
|
81
82
|
Tiles,
|
|
83
|
+
StickyTiles,
|
|
82
84
|
VideoTeaser,
|
|
83
85
|
};
|
|
@@ -83,6 +83,21 @@ export default async function getHubBySlug({
|
|
|
83
83
|
quoteName
|
|
84
84
|
quotePosition
|
|
85
85
|
quoteText
|
|
86
|
+
caseStudies {
|
|
87
|
+
... on Case {
|
|
88
|
+
title
|
|
89
|
+
uri
|
|
90
|
+
id
|
|
91
|
+
case {
|
|
92
|
+
thumbnailImage {
|
|
93
|
+
sourceUrl
|
|
94
|
+
}
|
|
95
|
+
mainImage {
|
|
96
|
+
sourceUrl
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
86
101
|
}
|
|
87
102
|
}
|
|
88
103
|
contactPage: page(id: "${contactPage}", idType: URI) {
|
package/lib/types/index.ts
CHANGED