@stackshift-ui/header 6.0.3 → 6.0.5
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 +14 -13
- package/src/header.test.tsx +13 -0
- package/src/header.tsx +58 -0
- package/src/header_a.tsx +168 -0
- package/src/header_b.tsx +136 -0
- package/src/header_c.tsx +87 -0
- package/src/header_d.tsx +113 -0
- package/src/header_e.tsx +84 -0
- package/src/index.ts +9 -0
- package/src/types.ts +412 -0
package/package.json
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stackshift-ui/header",
|
|
3
3
|
"description": "",
|
|
4
|
-
"version": "6.0.
|
|
4
|
+
"version": "6.0.5",
|
|
5
5
|
"private": false,
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"main": "./dist/index.js",
|
|
8
8
|
"module": "./dist/index.mjs",
|
|
9
9
|
"types": "./dist/index.d.ts",
|
|
10
10
|
"files": [
|
|
11
|
-
"dist/**"
|
|
11
|
+
"dist/**",
|
|
12
|
+
"src"
|
|
12
13
|
],
|
|
13
14
|
"author": "WebriQ <info@webriq.com>",
|
|
14
15
|
"devDependencies": {
|
|
@@ -28,20 +29,20 @@
|
|
|
28
29
|
"typescript": "^5.6.2",
|
|
29
30
|
"vite-tsconfig-paths": "^5.0.1",
|
|
30
31
|
"vitest": "^2.1.1",
|
|
31
|
-
"@stackshift-ui/
|
|
32
|
-
"@stackshift-ui/
|
|
32
|
+
"@stackshift-ui/eslint-config": "6.0.2",
|
|
33
|
+
"@stackshift-ui/typescript-config": "6.0.2"
|
|
33
34
|
},
|
|
34
35
|
"dependencies": {
|
|
35
|
-
"@stackshift-ui/text": "6.0.2",
|
|
36
36
|
"@stackshift-ui/scripts": "6.0.2",
|
|
37
|
-
"@stackshift-ui/system": "6.0.
|
|
38
|
-
"@stackshift-ui/
|
|
39
|
-
"@stackshift-ui/
|
|
40
|
-
"@stackshift-ui/
|
|
41
|
-
"@stackshift-ui/
|
|
42
|
-
"@stackshift-ui/
|
|
43
|
-
"@stackshift-ui/
|
|
44
|
-
"@stackshift-ui/
|
|
37
|
+
"@stackshift-ui/system": "6.0.3",
|
|
38
|
+
"@stackshift-ui/text": "6.0.3",
|
|
39
|
+
"@stackshift-ui/button": "6.0.3",
|
|
40
|
+
"@stackshift-ui/heading": "6.0.3",
|
|
41
|
+
"@stackshift-ui/signin-signup": "6.0.4",
|
|
42
|
+
"@stackshift-ui/section": "6.0.3",
|
|
43
|
+
"@stackshift-ui/flex": "6.0.3",
|
|
44
|
+
"@stackshift-ui/container": "6.0.3",
|
|
45
|
+
"@stackshift-ui/image": "6.0.3"
|
|
45
46
|
},
|
|
46
47
|
"peerDependencies": {
|
|
47
48
|
"@types/react": "16.8 - 19",
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { cleanup, render, screen } from "@testing-library/react";
|
|
2
|
+
import { afterEach, describe, test } from "vitest";
|
|
3
|
+
import { Header } from "./header";
|
|
4
|
+
|
|
5
|
+
describe.concurrent("header", () => {
|
|
6
|
+
afterEach(cleanup);
|
|
7
|
+
|
|
8
|
+
test.skip("Dummy test - test if renders without errors", ({ expect }) => {
|
|
9
|
+
const clx = "my-class";
|
|
10
|
+
render(<Header />);
|
|
11
|
+
expect(screen.getByTestId("{ kebabCase name }}").classList).toContain(clx);
|
|
12
|
+
});
|
|
13
|
+
});
|
package/src/header.tsx
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { lazy } from "react";
|
|
2
|
+
|
|
3
|
+
import { SectionsProps, Images, MainImage, LabeledRouteWithKey, Form, Template } from "./types";
|
|
4
|
+
|
|
5
|
+
const Variants = {
|
|
6
|
+
variant_a: lazy(() => import("./header_a")),
|
|
7
|
+
variant_b: lazy(() => import("./header_b")),
|
|
8
|
+
variant_c: lazy(() => import("./header_c")),
|
|
9
|
+
variant_d: lazy(() => import("./header_d")),
|
|
10
|
+
variant_e: lazy(() => import("./header_e")),
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export interface ButtonProps {
|
|
14
|
+
as?: string;
|
|
15
|
+
label?: string;
|
|
16
|
+
link?: {
|
|
17
|
+
target?: string;
|
|
18
|
+
route?: string;
|
|
19
|
+
};
|
|
20
|
+
ariaLabel?: string;
|
|
21
|
+
variant?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface HeaderProps {
|
|
25
|
+
template?: Template;
|
|
26
|
+
mainImage?: MainImage;
|
|
27
|
+
images?: Images[];
|
|
28
|
+
title?: string;
|
|
29
|
+
description?: string;
|
|
30
|
+
primaryButton?: ButtonProps;
|
|
31
|
+
secondaryButton?: ButtonProps;
|
|
32
|
+
videoLink?: string;
|
|
33
|
+
formLinks?: LabeledRouteWithKey[];
|
|
34
|
+
form?: Form;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const displayName = "Header";
|
|
38
|
+
|
|
39
|
+
export const Header: React.FC<SectionsProps> = ({ data }) => {
|
|
40
|
+
const variant = data?.variant;
|
|
41
|
+
const Variant = variant && Variants[variant as keyof typeof Variants];
|
|
42
|
+
|
|
43
|
+
const props = {
|
|
44
|
+
mainImage: data?.variants?.mainImage ?? undefined,
|
|
45
|
+
images: data?.variants?.images ?? undefined,
|
|
46
|
+
title: data?.variants?.title ?? undefined,
|
|
47
|
+
description: data?.variants?.description ?? undefined,
|
|
48
|
+
primaryButton: data?.variants?.primaryButton ?? undefined,
|
|
49
|
+
secondaryButton: data?.variants?.secondaryButton ?? undefined,
|
|
50
|
+
videoLink: data?.variants?.youtubeLink ?? undefined,
|
|
51
|
+
formLinks: data?.variants?.formLinks ?? undefined,
|
|
52
|
+
form: data?.variants?.form ?? undefined,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
return Variant ? <Variant {...props} /> : null;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
Header.displayName = displayName;
|
package/src/header_a.tsx
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { Button } from "@stackshift-ui/button";
|
|
2
|
+
import { Container } from "@stackshift-ui/container";
|
|
3
|
+
import { Flex } from "@stackshift-ui/flex";
|
|
4
|
+
import { Heading } from "@stackshift-ui/heading";
|
|
5
|
+
import { Image } from "@stackshift-ui/image";
|
|
6
|
+
import { Section } from "@stackshift-ui/section";
|
|
7
|
+
import { Text } from "@stackshift-ui/text";
|
|
8
|
+
import React from "react";
|
|
9
|
+
import { ButtonProps, HeaderProps } from ".";
|
|
10
|
+
|
|
11
|
+
export default function Header_A({
|
|
12
|
+
mainImage,
|
|
13
|
+
title,
|
|
14
|
+
description,
|
|
15
|
+
primaryButton,
|
|
16
|
+
secondaryButton,
|
|
17
|
+
}: HeaderProps) {
|
|
18
|
+
return (
|
|
19
|
+
<Section className="py-20 bg-background">
|
|
20
|
+
<Container maxWidth={1280}>
|
|
21
|
+
<Flex align="center" gap={4} className="flex-col lg:flex-row">
|
|
22
|
+
<Flex align="center" direction="col" className="w-full basis-1/2">
|
|
23
|
+
<div className="max-w-md mx-auto text-center lg:text-left">
|
|
24
|
+
<TitleAndDescription title={title} description={description} />
|
|
25
|
+
<Buttons primaryButton={primaryButton} secondaryButton={secondaryButton} />
|
|
26
|
+
</div>
|
|
27
|
+
</Flex>
|
|
28
|
+
<MainImage mainImage={mainImage} />
|
|
29
|
+
</Flex>
|
|
30
|
+
</Container>
|
|
31
|
+
</Section>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function TitleAndDescription({ title, description }: { title?: string; description?: string }) {
|
|
36
|
+
return (
|
|
37
|
+
<React.Fragment>
|
|
38
|
+
{title && (
|
|
39
|
+
<Heading fontSize="3xl" className="mb-3">
|
|
40
|
+
{title}
|
|
41
|
+
</Heading>
|
|
42
|
+
)}
|
|
43
|
+
{description && (
|
|
44
|
+
<Text muted className="my-6">
|
|
45
|
+
{description}
|
|
46
|
+
</Text>
|
|
47
|
+
)}
|
|
48
|
+
</React.Fragment>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function Buttons({
|
|
53
|
+
primaryButton,
|
|
54
|
+
secondaryButton,
|
|
55
|
+
}: {
|
|
56
|
+
primaryButton?: ButtonProps;
|
|
57
|
+
secondaryButton?: ButtonProps;
|
|
58
|
+
}) {
|
|
59
|
+
return (
|
|
60
|
+
<Flex
|
|
61
|
+
align="center"
|
|
62
|
+
justify="center"
|
|
63
|
+
gap={2}
|
|
64
|
+
direction="col"
|
|
65
|
+
className="lg:justify-start md:flex-row">
|
|
66
|
+
{primaryButton?.label && (
|
|
67
|
+
<Button as="link" link={primaryButton} ariaLabel={primaryButton?.label}>
|
|
68
|
+
{primaryButton?.label}
|
|
69
|
+
</Button>
|
|
70
|
+
)}
|
|
71
|
+
{secondaryButton?.label && (
|
|
72
|
+
<Button
|
|
73
|
+
as="link"
|
|
74
|
+
link={secondaryButton}
|
|
75
|
+
className="bg-secondary hover:bg-secondary/50 inline-block rounded-global font-bold transition duration-200 px-3 py-4"
|
|
76
|
+
ariaLabel={secondaryButton?.label}>
|
|
77
|
+
{secondaryButton?.label}
|
|
78
|
+
</Button>
|
|
79
|
+
)}
|
|
80
|
+
</Flex>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
interface MainImageProps {
|
|
85
|
+
mainImage?: {
|
|
86
|
+
image?: string | any;
|
|
87
|
+
alt?: string;
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function MainImage({ mainImage }: MainImageProps) {
|
|
92
|
+
if (!mainImage?.image) return null;
|
|
93
|
+
|
|
94
|
+
return (
|
|
95
|
+
<div className="relative w-full max-w-md">
|
|
96
|
+
<Image
|
|
97
|
+
className="overflow-hidden rounded-global object-cover md:rounded-br-none lg:h-[448px] relative z-10"
|
|
98
|
+
src={`${mainImage.image}`}
|
|
99
|
+
sizes="(min-width: 520px) 448px, 90vw"
|
|
100
|
+
width={448}
|
|
101
|
+
height={448}
|
|
102
|
+
alt={mainImage.alt ?? "header-main-image"}
|
|
103
|
+
/>
|
|
104
|
+
<DecorativeImages />
|
|
105
|
+
</div>
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function DecorativeImages() {
|
|
110
|
+
return (
|
|
111
|
+
<>
|
|
112
|
+
<ImageElement
|
|
113
|
+
src="/assets/elements/webriq-blue-dark-up.png"
|
|
114
|
+
alt="webriq-blue-dark-up-mainImage-element"
|
|
115
|
+
className="absolute hidden md:block"
|
|
116
|
+
style={{ top: "-2rem", right: "3rem", zIndex: 2 }}
|
|
117
|
+
width={112}
|
|
118
|
+
height={112}
|
|
119
|
+
/>
|
|
120
|
+
<ImageElement
|
|
121
|
+
src="/assets/elements/wing-webriq-blue-down.png"
|
|
122
|
+
alt="wing-webriq-blue-down-mainImage-element"
|
|
123
|
+
className="absolute hidden md:block"
|
|
124
|
+
style={{ bottom: "-2rem", right: "-2rem", zIndex: 2 }}
|
|
125
|
+
width={144}
|
|
126
|
+
height={144}
|
|
127
|
+
/>
|
|
128
|
+
<ImageElement
|
|
129
|
+
src="/assets/elements/bullets-gray-right.svg"
|
|
130
|
+
alt="bullets-gray-right-mainImage-element"
|
|
131
|
+
className="absolute hidden md:block"
|
|
132
|
+
style={{ top: "3rem", right: "-3rem", zIndex: 2 }}
|
|
133
|
+
width={115}
|
|
134
|
+
height={157}
|
|
135
|
+
/>
|
|
136
|
+
<ImageElement
|
|
137
|
+
src="/assets/elements/bullets-gray-left.svg"
|
|
138
|
+
alt="bullets-gray-left-mainImage-element"
|
|
139
|
+
className="absolute hidden md:block"
|
|
140
|
+
style={{ bottom: "2.5rem", left: "-4.5rem", zIndex: 2 }}
|
|
141
|
+
width={157}
|
|
142
|
+
height={115}
|
|
143
|
+
/>
|
|
144
|
+
</>
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function ImageElement({
|
|
149
|
+
src,
|
|
150
|
+
alt,
|
|
151
|
+
className,
|
|
152
|
+
style,
|
|
153
|
+
width,
|
|
154
|
+
height,
|
|
155
|
+
}: {
|
|
156
|
+
src: string;
|
|
157
|
+
alt: string;
|
|
158
|
+
className?: string;
|
|
159
|
+
style?: React.CSSProperties;
|
|
160
|
+
width: number;
|
|
161
|
+
height: number;
|
|
162
|
+
}) {
|
|
163
|
+
return (
|
|
164
|
+
<Image src={src} alt={alt} className={className} style={style} width={width} height={height} />
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export { Header_A };
|
package/src/header_b.tsx
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { Button } from "@stackshift-ui/button";
|
|
2
|
+
import { Container } from "@stackshift-ui/container";
|
|
3
|
+
import { Flex } from "@stackshift-ui/flex";
|
|
4
|
+
import { Heading } from "@stackshift-ui/heading";
|
|
5
|
+
import { Image } from "@stackshift-ui/image";
|
|
6
|
+
import { Section } from "@stackshift-ui/section";
|
|
7
|
+
import { Text } from "@stackshift-ui/text";
|
|
8
|
+
import React from "react";
|
|
9
|
+
import { ButtonProps, HeaderProps } from ".";
|
|
10
|
+
import { Images } from "./types";
|
|
11
|
+
|
|
12
|
+
export default function Header_B({
|
|
13
|
+
images,
|
|
14
|
+
title,
|
|
15
|
+
description,
|
|
16
|
+
primaryButton,
|
|
17
|
+
secondaryButton,
|
|
18
|
+
}: HeaderProps) {
|
|
19
|
+
return (
|
|
20
|
+
<Section className="relative z-10 py-20 bg-background">
|
|
21
|
+
<Container maxWidth={1280}>
|
|
22
|
+
<Flex align="center" direction="col" gap={4} className="lg:flex-row">
|
|
23
|
+
<Flex align="center" direction="col" className="w-full basis-1/2">
|
|
24
|
+
<div className="max-w-md mx-auto text-center lg:text-left">
|
|
25
|
+
<TitleAndDescription title={title} description={description} />
|
|
26
|
+
<Buttons primaryButton={primaryButton} secondaryButton={secondaryButton} />
|
|
27
|
+
</div>
|
|
28
|
+
</Flex>
|
|
29
|
+
{images && <ImageGallery images={images} />}
|
|
30
|
+
</Flex>
|
|
31
|
+
</Container>
|
|
32
|
+
</Section>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function TitleAndDescription({ title, description }: { title?: string; description?: string }) {
|
|
37
|
+
return (
|
|
38
|
+
<React.Fragment>
|
|
39
|
+
{title && (
|
|
40
|
+
<Heading fontSize="3xl" className="mb-3">
|
|
41
|
+
{title}
|
|
42
|
+
</Heading>
|
|
43
|
+
)}
|
|
44
|
+
{description && (
|
|
45
|
+
<Text muted className="my-6">
|
|
46
|
+
{description}
|
|
47
|
+
</Text>
|
|
48
|
+
)}
|
|
49
|
+
</React.Fragment>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function Buttons({
|
|
54
|
+
primaryButton,
|
|
55
|
+
secondaryButton,
|
|
56
|
+
}: {
|
|
57
|
+
primaryButton?: ButtonProps;
|
|
58
|
+
secondaryButton?: ButtonProps;
|
|
59
|
+
}) {
|
|
60
|
+
return (
|
|
61
|
+
<Flex
|
|
62
|
+
align="center"
|
|
63
|
+
gap={2}
|
|
64
|
+
className="flex items-center justify-center lg:justify-start gap-2 flex-col md:flex-row">
|
|
65
|
+
{primaryButton?.label && (
|
|
66
|
+
<Button as="link" link={primaryButton} ariaLabel={primaryButton?.label}>
|
|
67
|
+
{primaryButton?.label}
|
|
68
|
+
</Button>
|
|
69
|
+
)}
|
|
70
|
+
{secondaryButton?.label && (
|
|
71
|
+
<Button
|
|
72
|
+
as="link"
|
|
73
|
+
link={secondaryButton}
|
|
74
|
+
className="bg-secondary hover:bg-secondary/50 inline-block rounded-global font-bold transition duration-200 px-6 py-3"
|
|
75
|
+
ariaLabel={secondaryButton?.label}>
|
|
76
|
+
{secondaryButton?.label}
|
|
77
|
+
</Button>
|
|
78
|
+
)}
|
|
79
|
+
</Flex>
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function ImageGallery({ images }: { images: Images[] }) {
|
|
84
|
+
if (!images) return null;
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<div className="w-full px-4 lg:w-1/2">
|
|
88
|
+
<div className="mb-3 sm:flex lg:mb-4 lg:ml-6">
|
|
89
|
+
{images?.[0]?.image && (
|
|
90
|
+
<Image
|
|
91
|
+
className="relative object-cover mb-3 mr-2 overflow-hidden rounded-xl sm:mb-0 sm:w-1/3 md:rounded-3xl lg:rounded-br-none"
|
|
92
|
+
sizes="100vw"
|
|
93
|
+
src={`${images?.[0]?.image}`}
|
|
94
|
+
width={941}
|
|
95
|
+
height={734}
|
|
96
|
+
alt={images?.[0]?.alt ?? "header-image-1"}
|
|
97
|
+
/>
|
|
98
|
+
)}
|
|
99
|
+
{images?.[1]?.image && (
|
|
100
|
+
<Image
|
|
101
|
+
className="relative object-cover overflow-hidden rounded-xl sm:ml-2 sm:w-2/3 md:rounded-3xl lg:rounded-bl-none"
|
|
102
|
+
sizes="100vw"
|
|
103
|
+
src={`${images?.[1]?.image}`}
|
|
104
|
+
width={1050}
|
|
105
|
+
height={701}
|
|
106
|
+
alt={images?.[1]?.alt ?? "header-image-2"}
|
|
107
|
+
/>
|
|
108
|
+
)}
|
|
109
|
+
</div>
|
|
110
|
+
<div className="mb-3 sm:flex lg:mb-4 lg:mr-6">
|
|
111
|
+
{images?.[2]?.image && (
|
|
112
|
+
<Image
|
|
113
|
+
className="object-cover mb-3 mr-2 overflow-hidden rounded-xl sm:w-2/3 md:mb-0 md:rounded-3xl lg:rounded-br-none"
|
|
114
|
+
sizes="100vw"
|
|
115
|
+
src={`${images?.[2]?.image}`}
|
|
116
|
+
width={1050}
|
|
117
|
+
height={701}
|
|
118
|
+
alt={images?.[2]?.alt ?? "header-image-3"}
|
|
119
|
+
/>
|
|
120
|
+
)}
|
|
121
|
+
{images?.[3]?.image && (
|
|
122
|
+
<Image
|
|
123
|
+
className="object-cover overflow-hidden rounded-xl sm:ml-2 sm:w-1/3 md:rounded-3xl lg:rounded-bl-none"
|
|
124
|
+
sizes="100vw"
|
|
125
|
+
src={`${images?.[3]?.image}`}
|
|
126
|
+
width={941}
|
|
127
|
+
height={734}
|
|
128
|
+
alt={images?.[3]?.alt ?? "header-image-4"}
|
|
129
|
+
/>
|
|
130
|
+
)}
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export { Header_B };
|
package/src/header_c.tsx
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { Button } from "@stackshift-ui/button";
|
|
2
|
+
import { Container } from "@stackshift-ui/container";
|
|
3
|
+
import { Flex } from "@stackshift-ui/flex";
|
|
4
|
+
import { Heading } from "@stackshift-ui/heading";
|
|
5
|
+
import { Section } from "@stackshift-ui/section";
|
|
6
|
+
import { ButtonProps, HeaderProps } from ".";
|
|
7
|
+
|
|
8
|
+
export default function Header_C({
|
|
9
|
+
videoLink,
|
|
10
|
+
title,
|
|
11
|
+
primaryButton,
|
|
12
|
+
secondaryButton,
|
|
13
|
+
}: HeaderProps) {
|
|
14
|
+
// get the video link ID
|
|
15
|
+
let videoLinkId;
|
|
16
|
+
|
|
17
|
+
if (videoLink) {
|
|
18
|
+
if (videoLink.includes("embed")) {
|
|
19
|
+
videoLinkId = videoLink.split("/")[4];
|
|
20
|
+
} else {
|
|
21
|
+
videoLinkId = videoLink.split("/watch?v=")[1] || videoLink.split("/")[3];
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<Section className="py-20 md:py-52 bg-background">
|
|
27
|
+
<Container maxWidth={1280}>
|
|
28
|
+
<div className="max-w-2xl mx-auto mb-12 text-center md:mb-20">
|
|
29
|
+
{title && (
|
|
30
|
+
<Heading fontSize="3xl" className="mb-10">
|
|
31
|
+
{title}
|
|
32
|
+
</Heading>
|
|
33
|
+
)}
|
|
34
|
+
<Buttons primaryButton={primaryButton} secondaryButton={secondaryButton} />
|
|
35
|
+
</div>
|
|
36
|
+
<div className="md:mx-20 lg:mx-60 xl:mx-60">
|
|
37
|
+
{videoLinkId && <VideoPlayer videoLinkId={videoLinkId} title={title} />}
|
|
38
|
+
</div>
|
|
39
|
+
</Container>
|
|
40
|
+
</Section>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function VideoPlayer({ videoLinkId, title }: { videoLinkId?: string; title?: string }) {
|
|
45
|
+
return (
|
|
46
|
+
<div className="aspect-video">
|
|
47
|
+
<iframe
|
|
48
|
+
aria-label="Show Video Frame"
|
|
49
|
+
className="w-full h-full border-4 rounded-3xl border-primary"
|
|
50
|
+
src={`https://www.youtube.com/embed/${videoLinkId}`}
|
|
51
|
+
srcDoc={`<style>*{padding:0;margin:0;overflow:hidden;border-radius:24px}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href=${`https://www.youtube.com/embed/${videoLinkId}`}><img src=${`https://i.ytimg.com/vi_webp/${videoLinkId}/maxresdefault.webp`} alt=${title} loading="lazy" /><span>▶</span></a>`}
|
|
52
|
+
loading="lazy"
|
|
53
|
+
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
|
|
54
|
+
allowFullScreen
|
|
55
|
+
/>
|
|
56
|
+
</div>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function Buttons({
|
|
61
|
+
primaryButton,
|
|
62
|
+
secondaryButton,
|
|
63
|
+
}: {
|
|
64
|
+
primaryButton?: ButtonProps;
|
|
65
|
+
secondaryButton?: ButtonProps;
|
|
66
|
+
}) {
|
|
67
|
+
return (
|
|
68
|
+
<Flex align="center" gap={4} justify="center" className="flex-col lg:flex-row">
|
|
69
|
+
{primaryButton?.label && (
|
|
70
|
+
<Button as="link" ariaLabel={primaryButton?.label} link={primaryButton}>
|
|
71
|
+
{primaryButton?.label}
|
|
72
|
+
</Button>
|
|
73
|
+
)}
|
|
74
|
+
{secondaryButton?.label && (
|
|
75
|
+
<Button
|
|
76
|
+
as="link"
|
|
77
|
+
ariaLabel={secondaryButton?.label}
|
|
78
|
+
link={secondaryButton}
|
|
79
|
+
className="bg-secondary hover:bg-secondary/50 inline-block rounded-global font-bold transition duration-200 px-3 py-4">
|
|
80
|
+
{secondaryButton?.label}
|
|
81
|
+
</Button>
|
|
82
|
+
)}
|
|
83
|
+
</Flex>
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export { Header_C };
|
package/src/header_d.tsx
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { Button } from "@stackshift-ui/button";
|
|
2
|
+
import { Container } from "@stackshift-ui/container";
|
|
3
|
+
import { Flex } from "@stackshift-ui/flex";
|
|
4
|
+
import { Heading } from "@stackshift-ui/heading";
|
|
5
|
+
import { Image } from "@stackshift-ui/image";
|
|
6
|
+
import { Section } from "@stackshift-ui/section";
|
|
7
|
+
import { Text } from "@stackshift-ui/text";
|
|
8
|
+
import React from "react";
|
|
9
|
+
import { ButtonProps, HeaderProps } from ".";
|
|
10
|
+
|
|
11
|
+
export default function Header_D({
|
|
12
|
+
title,
|
|
13
|
+
description,
|
|
14
|
+
primaryButton,
|
|
15
|
+
secondaryButton,
|
|
16
|
+
mainImage,
|
|
17
|
+
}: HeaderProps): JSX.Element {
|
|
18
|
+
return (
|
|
19
|
+
<Section className="py-20 bg-background">
|
|
20
|
+
<Container maxWidth={1280}>
|
|
21
|
+
<Flex align="center" className="flex-col lg:flex-row" gap={4}>
|
|
22
|
+
<Flex align="center" className="w-full basis-1/2" direction="col">
|
|
23
|
+
<Container className="mx-auto items-center text-center lg:text-left" maxWidth="md">
|
|
24
|
+
<TitleAndDescription title={title} description={description} />
|
|
25
|
+
<Buttons primaryButton={primaryButton} secondaryButton={secondaryButton} />
|
|
26
|
+
</Container>
|
|
27
|
+
</Flex>
|
|
28
|
+
<MainImage mainImage={mainImage} />
|
|
29
|
+
</Flex>
|
|
30
|
+
</Container>
|
|
31
|
+
</Section>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function TitleAndDescription({ title, description }: { title?: string; description?: string }) {
|
|
36
|
+
return (
|
|
37
|
+
<React.Fragment>
|
|
38
|
+
{title ? (
|
|
39
|
+
<Heading fontSize="3xl" className="mb-3" type="h1">
|
|
40
|
+
{title}
|
|
41
|
+
</Heading>
|
|
42
|
+
) : null}
|
|
43
|
+
{description ? (
|
|
44
|
+
<Text className="my-6" muted>
|
|
45
|
+
{description}
|
|
46
|
+
</Text>
|
|
47
|
+
) : null}
|
|
48
|
+
</React.Fragment>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function Buttons({
|
|
53
|
+
primaryButton,
|
|
54
|
+
secondaryButton,
|
|
55
|
+
}: {
|
|
56
|
+
primaryButton?: ButtonProps;
|
|
57
|
+
secondaryButton?: ButtonProps;
|
|
58
|
+
}) {
|
|
59
|
+
return (
|
|
60
|
+
<Flex
|
|
61
|
+
align="center"
|
|
62
|
+
className="flex items-center justify-center lg:justify-start gap-2 flex-col md:flex-row"
|
|
63
|
+
gap={2}>
|
|
64
|
+
{primaryButton?.label ? (
|
|
65
|
+
<Button
|
|
66
|
+
as="link"
|
|
67
|
+
link={primaryButton}
|
|
68
|
+
ariaLabel={primaryButton?.ariaLabel ?? primaryButton?.label}
|
|
69
|
+
variant="solid"
|
|
70
|
+
className="bg-primary hover:bg-primary/50 rounded-global px-6 py-3 text-white">
|
|
71
|
+
{primaryButton.label}
|
|
72
|
+
</Button>
|
|
73
|
+
) : null}
|
|
74
|
+
{secondaryButton?.label ? (
|
|
75
|
+
<Button
|
|
76
|
+
as="link"
|
|
77
|
+
link={secondaryButton}
|
|
78
|
+
ariaLabel={secondaryButton.ariaLabel ?? secondaryButton?.label}
|
|
79
|
+
variant="solid"
|
|
80
|
+
className="bg-secondary hover:bg-secondary/50 rounded-global px-6 py-3">
|
|
81
|
+
{secondaryButton.label}
|
|
82
|
+
</Button>
|
|
83
|
+
) : null}
|
|
84
|
+
</Flex>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
interface MainImageProps {
|
|
89
|
+
mainImage?: {
|
|
90
|
+
image?: string | any;
|
|
91
|
+
alt?: string;
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function MainImage({ mainImage }: MainImageProps) {
|
|
96
|
+
if (!mainImage?.image) return null;
|
|
97
|
+
|
|
98
|
+
return (
|
|
99
|
+
<div className="w-full h-full">
|
|
100
|
+
<Image
|
|
101
|
+
alt={mainImage.alt ?? "header-main-image"}
|
|
102
|
+
className="rounded-global"
|
|
103
|
+
height={700}
|
|
104
|
+
sizes="100vw"
|
|
105
|
+
src={`${mainImage?.image}`}
|
|
106
|
+
style={{ objectFit: "contain" }}
|
|
107
|
+
width={1050}
|
|
108
|
+
/>
|
|
109
|
+
</div>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export { Header_D };
|
package/src/header_e.tsx
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { Button } from "@stackshift-ui/button";
|
|
2
|
+
import { Container } from "@stackshift-ui/container";
|
|
3
|
+
import { Flex } from "@stackshift-ui/flex";
|
|
4
|
+
import { Heading } from "@stackshift-ui/heading";
|
|
5
|
+
import { Section } from "@stackshift-ui/section";
|
|
6
|
+
import { SigninSignup_A } from "@stackshift-ui/signin-signup";
|
|
7
|
+
import { Text } from "@stackshift-ui/text";
|
|
8
|
+
import React from "react";
|
|
9
|
+
import { ButtonProps, HeaderProps } from ".";
|
|
10
|
+
|
|
11
|
+
export default function Header_E({
|
|
12
|
+
title,
|
|
13
|
+
description,
|
|
14
|
+
primaryButton,
|
|
15
|
+
secondaryButton,
|
|
16
|
+
formLinks,
|
|
17
|
+
form,
|
|
18
|
+
}: HeaderProps) {
|
|
19
|
+
return (
|
|
20
|
+
<Section className="relative py-20 bg-background">
|
|
21
|
+
<Container maxWidth={1280}>
|
|
22
|
+
<Flex align="center" className="flex-col lg:flex-row" gap={4}>
|
|
23
|
+
<Flex align="center" direction="col" className="w-full basis-1/2">
|
|
24
|
+
<div className="max-w-md mx-auto text-center lg:text-left">
|
|
25
|
+
<TitleAndDescription title={title} description={description} />
|
|
26
|
+
<Buttons primaryButton={primaryButton} secondaryButton={secondaryButton} />
|
|
27
|
+
</div>
|
|
28
|
+
</Flex>
|
|
29
|
+
<div className="w-full lg:w-1/2">
|
|
30
|
+
<div className="max-w-sm mx-auto text-center">
|
|
31
|
+
<SigninSignup_A form={form} formLinks={formLinks} />
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
</Flex>
|
|
35
|
+
</Container>
|
|
36
|
+
</Section>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function TitleAndDescription({ title, description }: { title?: string; description?: string }) {
|
|
41
|
+
return (
|
|
42
|
+
<React.Fragment>
|
|
43
|
+
{title && (
|
|
44
|
+
<Heading fontSize="3xl" className="mb-3">
|
|
45
|
+
{title}
|
|
46
|
+
</Heading>
|
|
47
|
+
)}
|
|
48
|
+
{description && (
|
|
49
|
+
<Text muted className="my-6">
|
|
50
|
+
{description}
|
|
51
|
+
</Text>
|
|
52
|
+
)}
|
|
53
|
+
</React.Fragment>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function Buttons({
|
|
58
|
+
primaryButton,
|
|
59
|
+
secondaryButton,
|
|
60
|
+
}: {
|
|
61
|
+
primaryButton?: ButtonProps;
|
|
62
|
+
secondaryButton?: ButtonProps;
|
|
63
|
+
}) {
|
|
64
|
+
return (
|
|
65
|
+
<Flex align="center" gap={2} className="flex-col md:flex-row justify-center lg:justify-start">
|
|
66
|
+
{primaryButton?.label && (
|
|
67
|
+
<Button as="link" link={primaryButton} ariaLabel={primaryButton?.label}>
|
|
68
|
+
{primaryButton?.label}
|
|
69
|
+
</Button>
|
|
70
|
+
)}
|
|
71
|
+
{secondaryButton?.label && (
|
|
72
|
+
<Button
|
|
73
|
+
as="link"
|
|
74
|
+
link={secondaryButton}
|
|
75
|
+
className="bg-secondary hover:bg-secondary/50 inline-block rounded-global font-bold transition duration-200 px-6 py-3"
|
|
76
|
+
ariaLabel={secondaryButton?.label}>
|
|
77
|
+
{secondaryButton?.label}
|
|
78
|
+
</Button>
|
|
79
|
+
)}
|
|
80
|
+
</Flex>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export { Header_E };
|
package/src/index.ts
ADDED
package/src/types.ts
ADDED
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
export type StyleVariants<T extends string> = Record<T, string>;
|
|
2
|
+
|
|
3
|
+
export type Socials = "facebook" | "instagram" | "youtube" | "linkedin" | "twitter";
|
|
4
|
+
export interface MainImage {
|
|
5
|
+
image: string;
|
|
6
|
+
alt?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface LabeledRoute extends ConditionalLink {
|
|
10
|
+
ariaLabel?: string;
|
|
11
|
+
label?: string;
|
|
12
|
+
linkTarget?: string;
|
|
13
|
+
linkType?: string;
|
|
14
|
+
_type?: string;
|
|
15
|
+
linkInternal?: any;
|
|
16
|
+
}
|
|
17
|
+
export interface ConditionalLink {
|
|
18
|
+
type?: string;
|
|
19
|
+
internalLink?: string | null;
|
|
20
|
+
externalLink?: string | null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface StatItems {
|
|
24
|
+
label?: string;
|
|
25
|
+
mainImage?: MainImage;
|
|
26
|
+
value?: string;
|
|
27
|
+
_key?: string;
|
|
28
|
+
_type?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface Logo extends ConditionalLink {
|
|
32
|
+
alt?: string;
|
|
33
|
+
linkTarget?: string;
|
|
34
|
+
image?: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface Images {
|
|
38
|
+
image?: string;
|
|
39
|
+
_key?: string;
|
|
40
|
+
_type?: string;
|
|
41
|
+
alt?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface ContactDetails {
|
|
45
|
+
addressInfo?: string;
|
|
46
|
+
contactInfo?: string;
|
|
47
|
+
emailInfo?: string;
|
|
48
|
+
_key?: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface SocialLink {
|
|
52
|
+
socialMedia?: string | null;
|
|
53
|
+
socialMediaLink?: string | null;
|
|
54
|
+
_key?: string | null;
|
|
55
|
+
_type?: string | null;
|
|
56
|
+
socialMediaIcon?: {
|
|
57
|
+
alt?: string;
|
|
58
|
+
image?: string;
|
|
59
|
+
} | null;
|
|
60
|
+
socialMediaPlatform?: string | null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface LabeledRouteWithKey extends LabeledRoute {
|
|
64
|
+
_key?: string;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface ArrayOfImageTitleAndText {
|
|
68
|
+
mainImage?: {
|
|
69
|
+
alt?: string;
|
|
70
|
+
image?: string;
|
|
71
|
+
};
|
|
72
|
+
plainText?: string;
|
|
73
|
+
title?: string;
|
|
74
|
+
_key?: string;
|
|
75
|
+
_type?: string;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface FeaturedItem {
|
|
79
|
+
description?: string;
|
|
80
|
+
mainImage?: MainImage;
|
|
81
|
+
title?: string;
|
|
82
|
+
subtitle?: string;
|
|
83
|
+
_key?: string;
|
|
84
|
+
_type?: string;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export interface ArrayOfTitleAndText {
|
|
88
|
+
_key?: string;
|
|
89
|
+
plainText?: string;
|
|
90
|
+
title?: string;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface BlogPost extends SanityBody {
|
|
94
|
+
authors?: Author[] | null;
|
|
95
|
+
body?: any;
|
|
96
|
+
categories?: Category[] | null;
|
|
97
|
+
excerpt?: string | null;
|
|
98
|
+
link?: string | null;
|
|
99
|
+
mainImage?: string | null;
|
|
100
|
+
publishedAt?: string;
|
|
101
|
+
seo?: Seo | null;
|
|
102
|
+
slug?: SanitySlug | null;
|
|
103
|
+
title?: string;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export interface Seo {
|
|
107
|
+
_type?: string;
|
|
108
|
+
seoTitle?: string;
|
|
109
|
+
seoDescription?: string;
|
|
110
|
+
seoImage?: string;
|
|
111
|
+
seoKeywords?: string;
|
|
112
|
+
seoSynonyms?: string;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export interface SanitySlug {
|
|
116
|
+
current?: string;
|
|
117
|
+
_type?: "slug";
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export interface SanityBody {
|
|
121
|
+
_createdAt?: string;
|
|
122
|
+
_id?: string;
|
|
123
|
+
_rev?: string;
|
|
124
|
+
_type?: string;
|
|
125
|
+
_updatedAt?: string;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export interface Author extends SanityBody {
|
|
129
|
+
link?: string | null;
|
|
130
|
+
bio?: string | null;
|
|
131
|
+
name?: string | null;
|
|
132
|
+
slug?: SanitySlug | null;
|
|
133
|
+
image?: string | null;
|
|
134
|
+
profile?: {
|
|
135
|
+
alt: string;
|
|
136
|
+
image: string;
|
|
137
|
+
} | null;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export interface Category extends SanityBody {
|
|
141
|
+
title?: string;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export interface Form {
|
|
145
|
+
id?: string | null;
|
|
146
|
+
buttonLabel?: string | null;
|
|
147
|
+
name?: string | null;
|
|
148
|
+
subtitle?: string | null;
|
|
149
|
+
fields?: FormFields[] | null;
|
|
150
|
+
thankYouPage?: ThankYouPage | null;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export interface FormFields {
|
|
154
|
+
name?: string;
|
|
155
|
+
placeholder?: string;
|
|
156
|
+
pricingType?: string;
|
|
157
|
+
type?: FormTypes;
|
|
158
|
+
_key?: string;
|
|
159
|
+
_type?: string;
|
|
160
|
+
isRequired?: boolean;
|
|
161
|
+
label?: string;
|
|
162
|
+
items?: string[];
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export type FormTypes =
|
|
166
|
+
| "inputText"
|
|
167
|
+
| "inputEmail"
|
|
168
|
+
| "inputPassword"
|
|
169
|
+
| "inputNumber"
|
|
170
|
+
| "textarea"
|
|
171
|
+
| "inputFile"
|
|
172
|
+
| "inputRadio"
|
|
173
|
+
| "inputCheckbox"
|
|
174
|
+
| "inputSelect";
|
|
175
|
+
|
|
176
|
+
export interface ThankYouPage {
|
|
177
|
+
externalLink?: string | null;
|
|
178
|
+
internalLink?: string | null;
|
|
179
|
+
linkInternal?: any;
|
|
180
|
+
linkTarget?: string;
|
|
181
|
+
linkType?: string;
|
|
182
|
+
type?: string;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
//Used on different sections
|
|
186
|
+
export interface SectionsProps {
|
|
187
|
+
template?: Template;
|
|
188
|
+
data?: Sections;
|
|
189
|
+
variant?: string | null | undefined;
|
|
190
|
+
schema?: Variants;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export interface Sections extends SanityBody {
|
|
194
|
+
label?: string;
|
|
195
|
+
variant?: string;
|
|
196
|
+
variants?: Variants;
|
|
197
|
+
_key?: string;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
//*EDIT THIS SECTION WHEN CREATING/UPDATING SCHEMAS ON STUDIO */
|
|
201
|
+
export interface Variants {
|
|
202
|
+
template?: Template;
|
|
203
|
+
multipleMenus?: any;
|
|
204
|
+
arrayOfTitleAndText?: ArrayOfTitleAndText[] | null;
|
|
205
|
+
logo?: Logo | null;
|
|
206
|
+
primaryButton?: LabeledRoute | null;
|
|
207
|
+
secondaryButton?: LabeledRoute | null;
|
|
208
|
+
routes?: LabeledRouteWithKey[] | null;
|
|
209
|
+
menu?: LabeledRouteWithKey[] | null;
|
|
210
|
+
plans?: Plans[] | null;
|
|
211
|
+
formLinks?: LabeledRouteWithKey[] | null;
|
|
212
|
+
portfolios?: Portfolios[] | null;
|
|
213
|
+
portfoliosWithCategories?: PortfoliosWithCategories[] | null;
|
|
214
|
+
length?: number;
|
|
215
|
+
signInLink?: LabeledRoute | null;
|
|
216
|
+
signinLink?: LabeledRoute | null;
|
|
217
|
+
tags?: string[] | null;
|
|
218
|
+
posts?: BlogPost[] | null;
|
|
219
|
+
blogsPerPage?: number | null;
|
|
220
|
+
form?: Form | null;
|
|
221
|
+
collections?: Collection | null;
|
|
222
|
+
products?: CollectionProduct | null;
|
|
223
|
+
allProducts?: Collection[];
|
|
224
|
+
subtitle?: string | null;
|
|
225
|
+
caption?: string | null;
|
|
226
|
+
title?: string | null;
|
|
227
|
+
plainText?: string | null;
|
|
228
|
+
contactDescription?: string | null;
|
|
229
|
+
officeInformation?: string | null;
|
|
230
|
+
contactEmail?: string | null;
|
|
231
|
+
contactNumber?: string | null;
|
|
232
|
+
socialLinks?: SocialLink[] | null;
|
|
233
|
+
block?: any;
|
|
234
|
+
heading?: string | null;
|
|
235
|
+
acceptButtonLabel?: string | null;
|
|
236
|
+
declineButtonLabel?: string | null;
|
|
237
|
+
faqsWithCategories?: FaqsWithCategory[] | null;
|
|
238
|
+
faqs?: AskedQuestion[] | null;
|
|
239
|
+
arrayOfImageTitleAndText?: ArrayOfImageTitleAndText[] | null;
|
|
240
|
+
description?: string | null;
|
|
241
|
+
featuredItems?: FeaturedItem[] | null;
|
|
242
|
+
images?: Images[] | null;
|
|
243
|
+
contactDetails?: ContactDetails[] | null;
|
|
244
|
+
copyright?: string | null;
|
|
245
|
+
mainImage?: MainImage | null;
|
|
246
|
+
youtubeLink?: string | null;
|
|
247
|
+
banner?: any;
|
|
248
|
+
stats?: StatItems[] | null;
|
|
249
|
+
teams?: Team[] | null;
|
|
250
|
+
testimonials?: Testimonial[] | null;
|
|
251
|
+
selectStripeAccount?: string;
|
|
252
|
+
annualBilling?: string;
|
|
253
|
+
monthlyBilling?: string;
|
|
254
|
+
productDetails?: ProductDetail[];
|
|
255
|
+
btnLabel?: string;
|
|
256
|
+
selectAccount?: string;
|
|
257
|
+
hashtags?: string[];
|
|
258
|
+
numberOfPosts?: number;
|
|
259
|
+
text?: string;
|
|
260
|
+
button?: LabeledRoute;
|
|
261
|
+
features?: string[];
|
|
262
|
+
config?: {
|
|
263
|
+
enableAnalytics: boolean;
|
|
264
|
+
cookiePolicy?: {
|
|
265
|
+
siteName: string;
|
|
266
|
+
cookiePolicyPage: Reference;
|
|
267
|
+
};
|
|
268
|
+
consentModalPosition?: string;
|
|
269
|
+
};
|
|
270
|
+
contactLink?: LabeledRoute;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export interface Template {
|
|
274
|
+
bg?: string;
|
|
275
|
+
color?: string;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export type Plans = {
|
|
279
|
+
_key?: string | null;
|
|
280
|
+
_type?: "planItems" | null;
|
|
281
|
+
checkoutButtonName?: string | null;
|
|
282
|
+
description?: string | null;
|
|
283
|
+
monthlyPrice?: string | null;
|
|
284
|
+
planType?: string | null;
|
|
285
|
+
yearlyPrice?: string | null;
|
|
286
|
+
planIncludes?: string[] | null;
|
|
287
|
+
primaryButton?: LabeledRoute | null;
|
|
288
|
+
} & Record<string, string>;
|
|
289
|
+
|
|
290
|
+
export interface Portfolios {
|
|
291
|
+
dateAdded?: string | null;
|
|
292
|
+
mainImage?: {
|
|
293
|
+
image?: string | null;
|
|
294
|
+
alt?: string | null;
|
|
295
|
+
} | null;
|
|
296
|
+
primaryButton?: LabeledRoute | null;
|
|
297
|
+
title?: string | null;
|
|
298
|
+
_key?: string | null;
|
|
299
|
+
_type?: string | null;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
export interface PortfoliosWithCategories {
|
|
303
|
+
category?: string | null;
|
|
304
|
+
content?: Content[] | null;
|
|
305
|
+
primaryButton?: LabeledRoute | null;
|
|
306
|
+
_key?: string | null;
|
|
307
|
+
_type?: string | null;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
export interface Content extends Portfolios {
|
|
311
|
+
description?: string | null;
|
|
312
|
+
subtitle?: string | null;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
export interface Collection extends SanityBody {
|
|
316
|
+
collectionInfoVariant?: {
|
|
317
|
+
variant?: string;
|
|
318
|
+
} | null;
|
|
319
|
+
name?: string | null;
|
|
320
|
+
products?: CollectionProduct[] | null;
|
|
321
|
+
sections?: any; //todo
|
|
322
|
+
seo?: Seo | null;
|
|
323
|
+
slug?: SanitySlug | null;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
export interface CollectionProduct extends SanityBody {
|
|
327
|
+
compareToPrice?: number | null;
|
|
328
|
+
description?: string | null;
|
|
329
|
+
ecwidProductId?: number | null;
|
|
330
|
+
name?: string | null;
|
|
331
|
+
price?: number | null;
|
|
332
|
+
productInfo?: ProductInfo | null;
|
|
333
|
+
productInfoVariant?: {
|
|
334
|
+
variant?: string;
|
|
335
|
+
} | null;
|
|
336
|
+
sections?: any; //todo
|
|
337
|
+
seo?: Seo | null;
|
|
338
|
+
slug?: SanitySlug | null;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
//TODO, RECHECK PRODUCT INFO DATA FROM SANITY
|
|
342
|
+
interface ProductInfo {
|
|
343
|
+
btnLabel?: string | null;
|
|
344
|
+
images?: ProductInfoImage[] | null;
|
|
345
|
+
productDetails?: ProductDetail[] | null;
|
|
346
|
+
socialLinks?: SocialLink[] | null;
|
|
347
|
+
subtitle?: string | null;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
//TODO, RECHECK PRODUCT INFO DATA FROM SANITY
|
|
351
|
+
export interface ProductDetail {
|
|
352
|
+
blockContent?: any;
|
|
353
|
+
contentType?: string;
|
|
354
|
+
tabName?: string;
|
|
355
|
+
_key?: string;
|
|
356
|
+
[key: string]: any;
|
|
357
|
+
}
|
|
358
|
+
interface ProductInfoImage {
|
|
359
|
+
alt?: string | null;
|
|
360
|
+
_key: string;
|
|
361
|
+
_type: string;
|
|
362
|
+
image?: string | null;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
export interface FaqsWithCategory {
|
|
366
|
+
askedQuestions?: AskedQuestion[] | null;
|
|
367
|
+
category?: string | null;
|
|
368
|
+
_key?: string;
|
|
369
|
+
_type?: string;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
export interface AskedQuestion {
|
|
373
|
+
answer?: string | null;
|
|
374
|
+
question?: string | null;
|
|
375
|
+
hidden?: boolean;
|
|
376
|
+
_key?: string;
|
|
377
|
+
_type?: string;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
export interface Team {
|
|
381
|
+
jobTitle?: string;
|
|
382
|
+
mainImage?: MainImage;
|
|
383
|
+
name?: string;
|
|
384
|
+
plainText?: string;
|
|
385
|
+
_key?: string;
|
|
386
|
+
_type?: string;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
export interface Testimonial {
|
|
390
|
+
jobTitle?: string;
|
|
391
|
+
mainImage?: MainImage;
|
|
392
|
+
name?: string;
|
|
393
|
+
rating?: string;
|
|
394
|
+
testimony?: string;
|
|
395
|
+
_key?: string;
|
|
396
|
+
_type?: string;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
export declare interface Reference {
|
|
400
|
+
_type: string;
|
|
401
|
+
_ref: string;
|
|
402
|
+
_key?: string;
|
|
403
|
+
_weak?: boolean;
|
|
404
|
+
_strengthenOnPublish?: {
|
|
405
|
+
type: string;
|
|
406
|
+
weak?: boolean;
|
|
407
|
+
template?: {
|
|
408
|
+
id: string;
|
|
409
|
+
params: Record<string, string | number | boolean>;
|
|
410
|
+
};
|
|
411
|
+
};
|
|
412
|
+
}
|