@stackshift-ui/footer 6.0.3 → 6.0.5-beta.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/dist/chunk-66FDHHFF.mjs +1 -0
- package/dist/chunk-B35XIAPE.mjs +1 -0
- package/dist/{chunk-GFRHEA26.mjs → chunk-DZ5TRQZG.mjs} +1 -1
- package/dist/chunk-Q4GGVZTN.mjs +1 -0
- package/dist/footer.js +1 -1
- package/dist/footer.mjs +1 -1
- package/dist/footer_a.js +1 -1
- package/dist/footer_a.mjs +1 -1
- package/dist/footer_b.js +1 -1
- package/dist/footer_b.mjs +1 -1
- package/dist/footer_c.js +1 -1
- package/dist/footer_c.mjs +1 -1
- package/dist/footer_d.js +1 -1
- package/dist/footer_d.mjs +1 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +14 -13
- package/src/footer.test.tsx +13 -0
- package/src/footer.tsx +40 -0
- package/src/footer_a.tsx +160 -0
- package/src/footer_b.tsx +154 -0
- package/src/footer_c.tsx +154 -0
- package/src/footer_d.tsx +154 -0
- package/src/helper/index.tsx +15 -0
- package/src/index.ts +8 -0
- package/src/types.ts +412 -0
- package/dist/chunk-IGSPTOUI.mjs +0 -1
- package/dist/chunk-OMNHML2T.mjs +0 -1
- package/dist/chunk-R4624UNS.mjs +0 -1
- /package/dist/{chunk-B6E6J67M.mjs → chunk-3JQORTK4.mjs} +0 -0
package/src/footer_a.tsx
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { Container } from "@stackshift-ui/container";
|
|
2
|
+
import { Flex } from "@stackshift-ui/flex";
|
|
3
|
+
import { Grid } from "@stackshift-ui/grid";
|
|
4
|
+
import { GridItem } from "@stackshift-ui/grid-item";
|
|
5
|
+
import { Image } from "@stackshift-ui/image";
|
|
6
|
+
import { Link } from "@stackshift-ui/link";
|
|
7
|
+
import { Section } from "@stackshift-ui/section";
|
|
8
|
+
import { SocialIcons } from "@stackshift-ui/social-icons";
|
|
9
|
+
import { Text } from "@stackshift-ui/text";
|
|
10
|
+
|
|
11
|
+
import { FooterProps } from ".";
|
|
12
|
+
import { logoLink } from "./helper";
|
|
13
|
+
import { ContactDetails, Logo, SocialLink, Socials } from "./types";
|
|
14
|
+
|
|
15
|
+
export default function Footer_A({ logo, text, contacts, copyright, socialMedia }: FooterProps) {
|
|
16
|
+
return (
|
|
17
|
+
<Section className="py-20 bg-background">
|
|
18
|
+
<Container maxWidth={1000}>
|
|
19
|
+
<Flex wrap className="mb-5 lg:mb-20">
|
|
20
|
+
<LogoSection logo={logo} />
|
|
21
|
+
<TextContainer text={text} />
|
|
22
|
+
<ContactsContainer contacts={contacts} />
|
|
23
|
+
</Flex>
|
|
24
|
+
<Flex justify="between" align="center" className="w-full mx-auto lg:flex">
|
|
25
|
+
<CopyrightContainer copyright={copyright} />
|
|
26
|
+
<SocialMediaContainer socialMedia={socialMedia} />
|
|
27
|
+
</Flex>
|
|
28
|
+
</Container>
|
|
29
|
+
</Section>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function LogoSection({ logo }: { logo?: Logo }) {
|
|
34
|
+
if (!logo?.image) return null;
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<div className="w-full mb-5 lg:w-1/5">
|
|
38
|
+
<Link
|
|
39
|
+
aria-label={logoLink(logo) === "/" ? "Go to home page" : `Go to ${logoLink(logo)}`}
|
|
40
|
+
className="text-3xl font-bold leading-none"
|
|
41
|
+
href={logoLink(logo)}
|
|
42
|
+
target={logo?.linkTarget}
|
|
43
|
+
rel={logo?.linkTarget === "_blank" ? "noopener noreferrer" : ""}>
|
|
44
|
+
<Image
|
|
45
|
+
className="h-14"
|
|
46
|
+
src={`${logo?.image}`}
|
|
47
|
+
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
|
|
48
|
+
width={132}
|
|
49
|
+
height={56}
|
|
50
|
+
alt={logo?.alt ?? "footer-logo"}
|
|
51
|
+
/>
|
|
52
|
+
</Link>
|
|
53
|
+
</div>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function TextContainer({ text }: { text?: string }) {
|
|
58
|
+
if (!text) return null;
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<Container className="w-full mb-5 lg:w-1/5" maxWidth={1000}>
|
|
62
|
+
<Text muted className="leading-loose">
|
|
63
|
+
{text}
|
|
64
|
+
</Text>
|
|
65
|
+
</Container>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function ContactsContainer({ contacts }: { contacts?: ContactDetails[] }) {
|
|
70
|
+
if (!contacts) return null;
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<Container className="w-full mt-1 ml-auto lg:w-1/2" maxWidth={1000}>
|
|
74
|
+
{contacts?.map((contact, index) => (
|
|
75
|
+
<Grid columns={1} gap={4} className="lg:gap-10 md:grid-cols-3" key={index}>
|
|
76
|
+
<GridItem span={1}>
|
|
77
|
+
<Text weight="bold" className="mb-4">
|
|
78
|
+
Address
|
|
79
|
+
</Text>
|
|
80
|
+
<Text muted className="mb-5">
|
|
81
|
+
{contact?.addressInfo}
|
|
82
|
+
</Text>
|
|
83
|
+
</GridItem>
|
|
84
|
+
<GridItem span={1}>
|
|
85
|
+
<Text weight="bold" className="mb-4">
|
|
86
|
+
Email
|
|
87
|
+
</Text>
|
|
88
|
+
<Text muted className="mb-5">
|
|
89
|
+
<a
|
|
90
|
+
href={`mailto:${contact?.emailInfo}`}
|
|
91
|
+
style={{ color: "inherit", textDecoration: "none" }}>
|
|
92
|
+
{contact?.emailInfo}
|
|
93
|
+
</a>
|
|
94
|
+
</Text>
|
|
95
|
+
</GridItem>
|
|
96
|
+
<GridItem span={1}>
|
|
97
|
+
<Text weight="bold" className="mb-4">
|
|
98
|
+
Number
|
|
99
|
+
</Text>
|
|
100
|
+
<Text muted className="mb-5">
|
|
101
|
+
<a
|
|
102
|
+
href={`tel:${contact?.contactInfo}`}
|
|
103
|
+
style={{ color: "inherit", textDecoration: "none" }}>
|
|
104
|
+
{contact?.contactInfo}
|
|
105
|
+
</a>
|
|
106
|
+
</Text>
|
|
107
|
+
</GridItem>
|
|
108
|
+
</Grid>
|
|
109
|
+
))}
|
|
110
|
+
</Container>
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function CopyrightContainer({ copyright }: { copyright?: string }) {
|
|
115
|
+
if (!copyright) return null;
|
|
116
|
+
|
|
117
|
+
return (
|
|
118
|
+
<Text muted className="text-sm">
|
|
119
|
+
{copyright}
|
|
120
|
+
</Text>
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function SocialMediaContainer({ socialMedia }: { socialMedia?: SocialLink[] }) {
|
|
125
|
+
if (!socialMedia) return null;
|
|
126
|
+
|
|
127
|
+
return (
|
|
128
|
+
<Flex wrap className="space-x-2 lg:mx-10 lg:space-x-4">
|
|
129
|
+
{socialMedia?.map((social, index) => <SocialMediaLink social={social} index={index} />)}
|
|
130
|
+
</Flex>
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function SocialMediaLink({ social, index }: { social?: SocialLink; index?: number }) {
|
|
135
|
+
if (!social?.socialMediaLink) return null;
|
|
136
|
+
|
|
137
|
+
return (
|
|
138
|
+
<Link
|
|
139
|
+
aria-label={social?.socialMedia || social?.socialMediaPlatform || ""}
|
|
140
|
+
className="inline-block p-2 mr-2 rounded"
|
|
141
|
+
target="_blank"
|
|
142
|
+
rel="noopener noreferrer"
|
|
143
|
+
href={social?.socialMediaLink}
|
|
144
|
+
key={index}>
|
|
145
|
+
{social?.socialMediaIcon?.image ? (
|
|
146
|
+
<Image
|
|
147
|
+
className="h-6"
|
|
148
|
+
src={`${social?.socialMediaIcon?.image}`}
|
|
149
|
+
width={24}
|
|
150
|
+
height={24}
|
|
151
|
+
alt={social?.socialMediaIcon?.alt ?? "contact-socialMedia-icon"}
|
|
152
|
+
/>
|
|
153
|
+
) : (
|
|
154
|
+
<SocialIcons social={social?.socialMedia as Socials} />
|
|
155
|
+
)}
|
|
156
|
+
</Link>
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export { Footer_A };
|
package/src/footer_b.tsx
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { Button } from "@stackshift-ui/button";
|
|
2
|
+
import { Container } from "@stackshift-ui/container";
|
|
3
|
+
import { Flex } from "@stackshift-ui/flex";
|
|
4
|
+
import { Image } from "@stackshift-ui/image";
|
|
5
|
+
import { Link } from "@stackshift-ui/link";
|
|
6
|
+
import { Section } from "@stackshift-ui/section";
|
|
7
|
+
import { SocialIcons } from "@stackshift-ui/social-icons";
|
|
8
|
+
import { Text } from "@stackshift-ui/text";
|
|
9
|
+
import React from "react";
|
|
10
|
+
|
|
11
|
+
import { FooterProps } from ".";
|
|
12
|
+
import { logoLink } from "./helper";
|
|
13
|
+
import { LabeledRoute, LabeledRouteWithKey, Logo, SocialLink, Socials } from "./types";
|
|
14
|
+
|
|
15
|
+
export default function Footer_B({ logo, copyright, socialMedia, menu }: FooterProps) {
|
|
16
|
+
return (
|
|
17
|
+
<Section className="py-20 bg-background">
|
|
18
|
+
<Container maxWidth={1280}>
|
|
19
|
+
<Flex wrap align="center" justify="between" className="pb-12 border-b border-gray-100">
|
|
20
|
+
<LogoSection logo={logo} />
|
|
21
|
+
<MenuLists menu={menu} />
|
|
22
|
+
</Flex>
|
|
23
|
+
<Flex wrap align="center" justify="between" className="mt-8">
|
|
24
|
+
<CopyrightContainer copyright={copyright} />
|
|
25
|
+
<SocialMediaContainer socialMedia={socialMedia} />
|
|
26
|
+
</Flex>
|
|
27
|
+
</Container>
|
|
28
|
+
</Section>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function LogoSection({ logo }: { logo?: Logo }) {
|
|
33
|
+
if (!logo?.image) return null;
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<div className="flex items-end h-full w-full lg:w-1/5">
|
|
37
|
+
<Link
|
|
38
|
+
aria-label={logoLink(logo) === "/" ? "Go to home page" : `Go to ${logoLink(logo)}`}
|
|
39
|
+
className="inline-block text-3xl font-bold leading-none"
|
|
40
|
+
href={logoLink(logo)}
|
|
41
|
+
target={logo?.linkTarget}
|
|
42
|
+
rel={logo?.linkTarget === "_blank" ? "noopener noreferrer" : ""}>
|
|
43
|
+
<Image
|
|
44
|
+
src={logo?.image}
|
|
45
|
+
alt={logo?.alt ?? "footer-logo"}
|
|
46
|
+
width={132}
|
|
47
|
+
height={132}
|
|
48
|
+
className="inline-block text-3xl font-bold leading-none"
|
|
49
|
+
/>
|
|
50
|
+
</Link>
|
|
51
|
+
</div>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function MenuLists({ menu }: { menu?: LabeledRouteWithKey[] }) {
|
|
56
|
+
if (!menu) return null;
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<div className="w-full lg:w-auto">
|
|
60
|
+
<Flex wrap align="center" justify="between" as="ul" className=" mt-8 lg:space-x-5">
|
|
61
|
+
{menu?.map((links, index, { length }) => (
|
|
62
|
+
<React.Fragment key={links?._key || index}>
|
|
63
|
+
<MenuList links={links} />
|
|
64
|
+
{index + 1 !== length ? <MenuSeparatorIcon /> : null}
|
|
65
|
+
</React.Fragment>
|
|
66
|
+
))}
|
|
67
|
+
</Flex>
|
|
68
|
+
</div>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function MenuList({ links, index }: { links?: LabeledRoute; index?: number }) {
|
|
73
|
+
if (!links) return null;
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<li className="w-full mb-2 md:mb-0 md:w-auto" key={index}>
|
|
77
|
+
<Button
|
|
78
|
+
as="link"
|
|
79
|
+
link={links}
|
|
80
|
+
className="text-gray-500 no-underline lg:text-sm hover:text-gray-700"
|
|
81
|
+
ariaLabel={links?.label}>
|
|
82
|
+
{links?.label}
|
|
83
|
+
</Button>
|
|
84
|
+
</li>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function MenuSeparatorIcon() {
|
|
89
|
+
return (
|
|
90
|
+
<li className="hidden md:block">
|
|
91
|
+
<svg
|
|
92
|
+
className="w-4 h-4 mx-4 text-gray-500"
|
|
93
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
94
|
+
fill="none"
|
|
95
|
+
viewBox="0 0 24 24"
|
|
96
|
+
stroke="currentColor">
|
|
97
|
+
<path
|
|
98
|
+
strokeLinecap="round"
|
|
99
|
+
strokeLinejoin="round"
|
|
100
|
+
strokeWidth="2"
|
|
101
|
+
d="M12 5v.01M12 12v.01M12 19v.01M12 6a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2z"
|
|
102
|
+
/>
|
|
103
|
+
</svg>
|
|
104
|
+
</li>
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function CopyrightContainer({ copyright }: { copyright?: string }) {
|
|
109
|
+
if (!copyright) return null;
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
<Text muted className="order-last text-sm ">
|
|
113
|
+
{copyright}
|
|
114
|
+
</Text>
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function SocialMediaContainer({ socialMedia }: { socialMedia?: SocialLink[] }) {
|
|
119
|
+
if (!socialMedia) return null;
|
|
120
|
+
|
|
121
|
+
return (
|
|
122
|
+
<div className="order-first mb-4 lg:order-last lg:mb-0">
|
|
123
|
+
{socialMedia?.map(social => <SocialMediaLink social={social} />)}
|
|
124
|
+
</div>
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function SocialMediaLink({ social }: { social?: SocialLink }) {
|
|
129
|
+
if (!social?.socialMediaLink) return null;
|
|
130
|
+
|
|
131
|
+
return (
|
|
132
|
+
<Link
|
|
133
|
+
aria-label={social?.socialMedia || social?.socialMediaPlatform || ""}
|
|
134
|
+
className="inline-block p-2 mr-2 rounded"
|
|
135
|
+
target="_blank"
|
|
136
|
+
rel="noopener noreferrer"
|
|
137
|
+
href={social?.socialMediaLink}
|
|
138
|
+
key={social?._key}>
|
|
139
|
+
{social?.socialMediaIcon?.image ? (
|
|
140
|
+
<Image
|
|
141
|
+
className="h-6"
|
|
142
|
+
src={`${social?.socialMediaIcon?.image}`}
|
|
143
|
+
width={24}
|
|
144
|
+
height={24}
|
|
145
|
+
alt={social?.socialMediaIcon?.alt ?? "contact-socialMedia-icon"}
|
|
146
|
+
/>
|
|
147
|
+
) : (
|
|
148
|
+
<SocialIcons social={social?.socialMedia as Socials} />
|
|
149
|
+
)}
|
|
150
|
+
</Link>
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export { Footer_B };
|
package/src/footer_c.tsx
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { Button } from "@stackshift-ui/button";
|
|
2
|
+
import { Container } from "@stackshift-ui/container";
|
|
3
|
+
import { Flex } from "@stackshift-ui/flex";
|
|
4
|
+
import { Image } from "@stackshift-ui/image";
|
|
5
|
+
import { Link } from "@stackshift-ui/link";
|
|
6
|
+
import { Section } from "@stackshift-ui/section";
|
|
7
|
+
import { SocialIcons } from "@stackshift-ui/social-icons";
|
|
8
|
+
import { Text } from "@stackshift-ui/text";
|
|
9
|
+
|
|
10
|
+
import { FooterProps } from ".";
|
|
11
|
+
import { logoLink } from "./helper";
|
|
12
|
+
import { LabeledRoute, LabeledRouteWithKey, Logo, SocialLink, Socials } from "./types";
|
|
13
|
+
|
|
14
|
+
export default function Footer_C({ logo, menu, copyright, socialMedia }: FooterProps) {
|
|
15
|
+
return (
|
|
16
|
+
<Section className="bg-background">
|
|
17
|
+
<BorderStyle />
|
|
18
|
+
<Container maxWidth={1000}>
|
|
19
|
+
<div className="pt-10 pb-12">
|
|
20
|
+
<Flex
|
|
21
|
+
justify="between"
|
|
22
|
+
align="center"
|
|
23
|
+
className="relative flex-col gap-8 mb-8 md:flex-row lg:border-b lg:border-gray-300 lg:pb-8">
|
|
24
|
+
<CopyrightSection copyright={copyright} />
|
|
25
|
+
<MenuLists menu={menu} />
|
|
26
|
+
<LogoSection logo={logo} />
|
|
27
|
+
</Flex>
|
|
28
|
+
<SocialMediaContainer socialMedia={socialMedia} />
|
|
29
|
+
</div>
|
|
30
|
+
</Container>
|
|
31
|
+
</Section>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function CopyrightSection({ copyright }: { copyright?: string }) {
|
|
36
|
+
if (!copyright) return null;
|
|
37
|
+
|
|
38
|
+
return <Text className="w-full text-sm text-center">{copyright}</Text>;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function LogoSection({ logo }: { logo?: Logo }) {
|
|
42
|
+
if (!logo?.image) return null;
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<div className="w-full text-center">
|
|
46
|
+
<Link
|
|
47
|
+
className="inline-block text-xl font-bold leading-none"
|
|
48
|
+
aria-label={logoLink(logo) === "/" ? "Go to home page" : `Go to ${logoLink(logo)}`}
|
|
49
|
+
href={logoLink(logo)}
|
|
50
|
+
target={logo?.linkTarget}
|
|
51
|
+
rel={logo?.linkTarget === "_blank" ? "noopener noreferrer" : ""}>
|
|
52
|
+
<Image
|
|
53
|
+
src={logo?.image}
|
|
54
|
+
alt={logo?.alt ?? "footer-logo"}
|
|
55
|
+
className="inline-block text-xl font-bold leading-none"
|
|
56
|
+
width={64}
|
|
57
|
+
height={64}
|
|
58
|
+
/>
|
|
59
|
+
</Link>
|
|
60
|
+
</div>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function MenuLists({ menu }: { menu?: LabeledRouteWithKey[] }) {
|
|
65
|
+
if (!menu) return null;
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<div className="mx-auto">
|
|
69
|
+
<Flex
|
|
70
|
+
className="flex-col gap-0 lg:flex-row lg:gap-10"
|
|
71
|
+
as="ul"
|
|
72
|
+
align="center"
|
|
73
|
+
justify="center">
|
|
74
|
+
{menu?.map((links, index) => <MenuList links={links} index={index} />)}
|
|
75
|
+
</Flex>
|
|
76
|
+
</div>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function MenuList({ links, index }: { links?: LabeledRoute; index?: number }) {
|
|
81
|
+
if (!links) return null;
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<li className="w-full text-center" key={index}>
|
|
85
|
+
<Button
|
|
86
|
+
as="link"
|
|
87
|
+
link={links}
|
|
88
|
+
className="text-sm text-center text-black no-underline hover:text-gray-500 whitespace-nowrap"
|
|
89
|
+
ariaLabel={links?.label}>
|
|
90
|
+
{links?.label}
|
|
91
|
+
</Button>
|
|
92
|
+
</li>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function SocialMediaContainer({ socialMedia }: { socialMedia?: SocialLink[] }) {
|
|
97
|
+
if (!socialMedia) return null;
|
|
98
|
+
|
|
99
|
+
return (
|
|
100
|
+
<Flex wrap justify="center" className="space-y-2 sm:space-y-0">
|
|
101
|
+
{socialMedia?.map((social, index) => <SocialMediaLink social={social} index={index} />)}
|
|
102
|
+
</Flex>
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function SocialMediaLink({ social, index }: { social?: SocialLink; index?: number }) {
|
|
107
|
+
if (!social?.socialMediaLink) return null;
|
|
108
|
+
|
|
109
|
+
return (
|
|
110
|
+
<Link
|
|
111
|
+
aria-label={social?.socialMedia || social?.socialMediaPlatform || ""}
|
|
112
|
+
className="inline-block p-2 mr-2 rounded"
|
|
113
|
+
target="_blank"
|
|
114
|
+
rel="noopener noreferrer"
|
|
115
|
+
href={social?.socialMediaLink}
|
|
116
|
+
key={index}>
|
|
117
|
+
{social?.socialMediaIcon?.image ? (
|
|
118
|
+
<Image
|
|
119
|
+
className="h-6"
|
|
120
|
+
src={`${social?.socialMediaIcon?.image}`}
|
|
121
|
+
width={56}
|
|
122
|
+
height={56}
|
|
123
|
+
alt={social?.socialMediaIcon?.alt ?? "contact-socialMedia-icon"}
|
|
124
|
+
/>
|
|
125
|
+
) : (
|
|
126
|
+
<SocialIcons social={social?.socialMedia as Socials} />
|
|
127
|
+
)}
|
|
128
|
+
</Link>
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function BorderStyle() {
|
|
133
|
+
return (
|
|
134
|
+
<div className="flex w-full">
|
|
135
|
+
<div className="flex w-1/3">
|
|
136
|
+
<div className="w-1/3 py-1 bg-secondary" />
|
|
137
|
+
<div className="w-1/3 py-1 bg-primary" />
|
|
138
|
+
<div className="w-1/3 py-1 bg-primary" />
|
|
139
|
+
</div>
|
|
140
|
+
<div className="flex w-1/3">
|
|
141
|
+
<div className="w-1/3 py-1 bg-secondary" />
|
|
142
|
+
<div className="w-1/3 py-1 bg-primary" />
|
|
143
|
+
<div className="w-1/3 py-1 bg-primary" />
|
|
144
|
+
</div>
|
|
145
|
+
<div className="flex w-1/3">
|
|
146
|
+
<div className="w-1/3 py-1 bg-secondary" />
|
|
147
|
+
<div className="w-1/3 py-1 bg-primary" />
|
|
148
|
+
<div className="w-1/3 py-1 bg-primary" />
|
|
149
|
+
</div>
|
|
150
|
+
</div>
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export { Footer_C };
|
package/src/footer_d.tsx
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { Button } from "@stackshift-ui/button";
|
|
2
|
+
import { Container } from "@stackshift-ui/container";
|
|
3
|
+
import { Flex } from "@stackshift-ui/flex";
|
|
4
|
+
import { Image } from "@stackshift-ui/image";
|
|
5
|
+
import { Link } from "@stackshift-ui/link";
|
|
6
|
+
import { Section } from "@stackshift-ui/section";
|
|
7
|
+
import { SocialIcons } from "@stackshift-ui/social-icons";
|
|
8
|
+
import { Text } from "@stackshift-ui/text";
|
|
9
|
+
|
|
10
|
+
import { FooterProps } from ".";
|
|
11
|
+
import { logoLink } from "./helper";
|
|
12
|
+
import { Logo, SocialLink, Socials } from "./types";
|
|
13
|
+
|
|
14
|
+
export default function Footer_D({
|
|
15
|
+
logo,
|
|
16
|
+
multipleMenus,
|
|
17
|
+
copyright,
|
|
18
|
+
socialMedia,
|
|
19
|
+
text,
|
|
20
|
+
}: FooterProps) {
|
|
21
|
+
return (
|
|
22
|
+
<Section className="py-20 overflow-hidden bg-background">
|
|
23
|
+
<Container maxWidth={1280}>
|
|
24
|
+
<Flex wrap className="space-y-4 lg:space-y-0">
|
|
25
|
+
<div className="w-full max-w-2xl space-y-4 lg:w-1/4">
|
|
26
|
+
<LogoSection logo={logo} />
|
|
27
|
+
<TextSection text={text} />
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
<MenuSection multipleMenus={multipleMenus} />
|
|
31
|
+
<SocialMediaContainer socialMedia={socialMedia} />
|
|
32
|
+
</Flex>
|
|
33
|
+
<CopyrightSection copyright={copyright} />
|
|
34
|
+
</Container>
|
|
35
|
+
</Section>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function LogoSection({ logo }: { logo?: Logo }) {
|
|
40
|
+
if (!logo?.image) return null;
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<Link
|
|
44
|
+
className="inline-block text-xl font-bold leading-none"
|
|
45
|
+
aria-label={logoLink(logo) === "/" ? "Go to home page" : `Go to ${logoLink(logo)}`}
|
|
46
|
+
href={logoLink(logo)}
|
|
47
|
+
target={logo?.linkTarget}
|
|
48
|
+
rel={logo?.linkTarget === "_blank" ? "noopener noreferrer" : ""}>
|
|
49
|
+
<Image
|
|
50
|
+
className="h-14"
|
|
51
|
+
src={`${logo?.image}`}
|
|
52
|
+
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
|
|
53
|
+
width={132}
|
|
54
|
+
height={56}
|
|
55
|
+
alt={logo?.alt ?? "footer-logo"}
|
|
56
|
+
/>
|
|
57
|
+
</Link>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function TextSection({ text }: { text?: string }) {
|
|
62
|
+
if (!text) return null;
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<Text muted className="leading-normal">
|
|
66
|
+
{text}
|
|
67
|
+
</Text>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function CopyrightSection({ copyright }: { copyright?: string }) {
|
|
72
|
+
if (!copyright) return null;
|
|
73
|
+
|
|
74
|
+
return <Text className="pt-10 text-sm">{copyright}</Text>;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function MenuSection({ multipleMenus }: { multipleMenus?: any[] }) {
|
|
78
|
+
if (!multipleMenus) return null;
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<Flex wrap className="flex-grow lg:justify-around" gap={4}>
|
|
82
|
+
{multipleMenus?.map(menu => <MenuLinks key={menu?._key} menu={menu} />)}
|
|
83
|
+
</Flex>
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Individual Menu Links Component
|
|
88
|
+
function MenuLinks({ menu }: { menu?: any }) {
|
|
89
|
+
if (!menu) return null;
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<div className="w-[200px] flex-none">
|
|
93
|
+
{menu?.title && (
|
|
94
|
+
<Text weight="bold" className="mb-3">
|
|
95
|
+
{menu?.title}
|
|
96
|
+
</Text>
|
|
97
|
+
)}
|
|
98
|
+
{menu?.links?.length > 0 && (
|
|
99
|
+
<Flex as="ul" direction="col" className="space-y-2">
|
|
100
|
+
{menu?.links?.map((link: any) => (
|
|
101
|
+
<li key={link?._key}>
|
|
102
|
+
<Button
|
|
103
|
+
as="link"
|
|
104
|
+
link={link}
|
|
105
|
+
className="text-gray-500 no-underline hover:text-gray-700"
|
|
106
|
+
ariaLabel={link?.label}>
|
|
107
|
+
{link?.label}
|
|
108
|
+
</Button>
|
|
109
|
+
</li>
|
|
110
|
+
))}
|
|
111
|
+
</Flex>
|
|
112
|
+
)}
|
|
113
|
+
</div>
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function SocialMediaContainer({ socialMedia }: { socialMedia?: SocialLink[] }) {
|
|
118
|
+
if (!socialMedia) return null;
|
|
119
|
+
|
|
120
|
+
return (
|
|
121
|
+
<Flex className="w-full ml-auto lg:justify-end lg:w-1/6">
|
|
122
|
+
{socialMedia?.map(social => social?.socialMediaLink && <SocialMediaLink social={social} />)}
|
|
123
|
+
</Flex>
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function SocialMediaLink({ social }: { social?: SocialLink }) {
|
|
128
|
+
if (!social?.socialMediaLink) return null;
|
|
129
|
+
|
|
130
|
+
return (
|
|
131
|
+
<span key={social?._key}>
|
|
132
|
+
<Link
|
|
133
|
+
aria-label={social?.socialMedia || social?.socialMediaPlatform || ""}
|
|
134
|
+
className="inline-block p-2 mr-2 rounded"
|
|
135
|
+
target="_blank"
|
|
136
|
+
rel="noopener noreferrer"
|
|
137
|
+
href={social?.socialMediaLink}>
|
|
138
|
+
{social?.socialMediaIcon?.image ? (
|
|
139
|
+
<Image
|
|
140
|
+
className="h-6"
|
|
141
|
+
src={`${social?.socialMediaIcon?.image}`}
|
|
142
|
+
width={24}
|
|
143
|
+
height={24}
|
|
144
|
+
alt={social?.socialMediaIcon?.alt ?? "contact-socialMedia-icon"}
|
|
145
|
+
/>
|
|
146
|
+
) : (
|
|
147
|
+
<SocialIcons social={social?.socialMedia as Socials} />
|
|
148
|
+
)}
|
|
149
|
+
</Link>
|
|
150
|
+
</span>
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export { Footer_D };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Logo } from "../types";
|
|
2
|
+
|
|
3
|
+
// Logo link
|
|
4
|
+
export const logoLink = (logo: Logo) => {
|
|
5
|
+
if (logo?.internalLink && logo?.type === "linkInternal") {
|
|
6
|
+
if (logo?.internalLink?.toLowerCase()?.includes("home")) {
|
|
7
|
+
return "/";
|
|
8
|
+
}
|
|
9
|
+
return `/${logo.internalLink}`;
|
|
10
|
+
} else if (logo?.externalLink && logo?.type === "linkExternal") {
|
|
11
|
+
return logo?.externalLink ?? "/";
|
|
12
|
+
} else {
|
|
13
|
+
return "/";
|
|
14
|
+
}
|
|
15
|
+
};
|