@stackshift-ui/footer 6.0.14 → 7.0.0-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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stackshift-ui/footer",
3
3
  "description": "",
4
- "version": "6.0.14",
4
+ "version": "7.0.0-beta.0",
5
5
  "private": false,
6
6
  "sideEffects": false,
7
7
  "main": "./dist/index.js",
@@ -29,30 +29,31 @@
29
29
  "typescript": "^5.6.2",
30
30
  "vite-tsconfig-paths": "^5.0.1",
31
31
  "vitest": "^2.1.1",
32
- "@stackshift-ui/typescript-config": "6.0.10",
33
- "@stackshift-ui/eslint-config": "6.0.10"
32
+ "@stackshift-ui/eslint-config": "6.0.10",
33
+ "@stackshift-ui/typescript-config": "6.0.10"
34
34
  },
35
35
  "dependencies": {
36
+ "@portabletext/react": "^3.1.0",
36
37
  "classnames": "^2.5.1",
37
- "@stackshift-ui/social-icons": "6.0.12",
38
- "@stackshift-ui/scripts": "6.0.10",
39
- "@stackshift-ui/image": "6.0.11",
40
- "@stackshift-ui/text": "6.0.11",
41
- "@stackshift-ui/link": "6.0.11",
42
- "@stackshift-ui/section": "6.0.11",
43
- "@stackshift-ui/container": "6.0.11",
44
- "@stackshift-ui/grid-item": "6.0.11",
45
- "@stackshift-ui/system": "6.0.11",
46
- "@stackshift-ui/flex": "6.0.11",
47
- "@stackshift-ui/button": "6.0.11",
48
- "@stackshift-ui/grid": "6.0.11"
38
+ "@stackshift-ui/button": "6.1.0-beta.0",
39
+ "@stackshift-ui/image": "6.1.0-beta.0",
40
+ "@stackshift-ui/system": "6.1.0-beta.0",
41
+ "@stackshift-ui/scripts": "6.1.0-beta.0",
42
+ "@stackshift-ui/text": "7.0.0-beta.0",
43
+ "@stackshift-ui/link": "6.0.12-beta.0",
44
+ "@stackshift-ui/social-icons": "7.0.0-beta.0",
45
+ "@stackshift-ui/section": "7.0.0-beta.0",
46
+ "@stackshift-ui/flex": "7.0.0-beta.0",
47
+ "@stackshift-ui/container": "7.0.0-beta.0",
48
+ "@stackshift-ui/grid-item": "7.0.0-beta.0",
49
+ "@stackshift-ui/grid": "7.0.0-beta.0"
49
50
  },
50
51
  "peerDependencies": {
51
52
  "@types/react": "16.8 - 19",
52
53
  "next": "10 - 14",
53
54
  "react": "16.8 - 19",
54
55
  "react-dom": "16.8 - 19",
55
- "@stackshift-ui/system": ">=6.0.11"
56
+ "@stackshift-ui/system": ">=6.1.0-beta.0"
56
57
  },
57
58
  "peerDependenciesMeta": {
58
59
  "next": {
@@ -7,7 +7,7 @@ describe.concurrent("footer", () => {
7
7
 
8
8
  test.skip("Dummy test - test if renders without errors", ({ expect }) => {
9
9
  const clx = "my-class";
10
- render(<Footer />);
11
- expect(screen.getByTestId("{ kebabCase name }}").classList).toContain(clx);
10
+ render(<Footer data-testid="footer" />);
11
+ expect(screen.getByTestId("footer").classList).toContain(clx);
12
12
  });
13
13
  });
package/src/footer_b.tsx CHANGED
@@ -9,7 +9,7 @@ import { Text } from "@stackshift-ui/text";
9
9
  import React from "react";
10
10
 
11
11
  import { FooterProps } from ".";
12
- import { logoLink } from "./helper";
12
+ import { ConditionalLink, logoLink } from "./helper";
13
13
  import { LabeledRoute, LabeledRouteWithKey, Logo, SocialLink, Socials } from "./types";
14
14
 
15
15
  export default function Footer_B({ logo, copyright, socialMedia, menu }: FooterProps) {
@@ -69,11 +69,13 @@ function MenuList({ links, index }: { links?: LabeledRoute; index?: number }) {
69
69
  return (
70
70
  <li className="w-full mb-2 md:mb-0 md:w-auto" key={index}>
71
71
  <Button
72
- as="link"
73
- link={links}
72
+ variant="unstyled"
74
73
  className="text-gray-500 no-underline lg:text-sm hover:text-gray-700"
75
- ariaLabel={links?.label}>
76
- {links?.label}
74
+ aria-label={links?.label}
75
+ asChild>
76
+ <ConditionalLink link={links} ariaLabel={links?.label ?? "Footer menu link"}>
77
+ {links?.label}
78
+ </ConditionalLink>
77
79
  </Button>
78
80
  </li>
79
81
  );
package/src/footer_c.tsx CHANGED
@@ -8,7 +8,7 @@ import { SocialIcons } from "@stackshift-ui/social-icons";
8
8
  import { Text } from "@stackshift-ui/text";
9
9
 
10
10
  import { FooterProps } from ".";
11
- import { logoLink } from "./helper";
11
+ import { ConditionalLink, logoLink } from "./helper";
12
12
  import { LabeledRoute, LabeledRouteWithKey, Logo, SocialLink, Socials } from "./types";
13
13
 
14
14
  export default function Footer_C({ logo, menu, copyright, socialMedia }: FooterProps) {
@@ -83,11 +83,13 @@ function MenuList({ links, index }: { links?: LabeledRoute; index?: number }) {
83
83
  return (
84
84
  <li className="w-full text-center" key={index}>
85
85
  <Button
86
- as="link"
87
- link={links}
86
+ variant="unstyled"
87
+ asChild
88
88
  className="text-sm text-center text-black no-underline hover:text-gray-500 whitespace-nowrap"
89
- ariaLabel={links?.label}>
90
- {links?.label}
89
+ aria-label={links?.label}>
90
+ <ConditionalLink link={links} ariaLabel={links?.label ?? "Footer menu link"}>
91
+ {links?.label}
92
+ </ConditionalLink>
91
93
  </Button>
92
94
  </li>
93
95
  );
@@ -130,23 +132,23 @@ function SocialMediaLink({ social }: { social?: SocialLink }) {
130
132
 
131
133
  function BorderStyle() {
132
134
  return (
133
- <div className="flex w-full">
134
- <div className="flex w-1/3">
135
+ <Flex className="w-full">
136
+ <Flex className="w-1/3">
135
137
  <div className="w-1/3 py-1 bg-secondary" />
136
138
  <div className="w-1/3 py-1 bg-primary" />
137
139
  <div className="w-1/3 py-1 bg-primary" />
138
- </div>
139
- <div className="flex w-1/3">
140
+ </Flex>
141
+ <Flex className="w-1/3">
140
142
  <div className="w-1/3 py-1 bg-secondary" />
141
143
  <div className="w-1/3 py-1 bg-primary" />
142
144
  <div className="w-1/3 py-1 bg-primary" />
143
- </div>
144
- <div className="flex w-1/3">
145
+ </Flex>
146
+ <Flex className="w-1/3">
145
147
  <div className="w-1/3 py-1 bg-secondary" />
146
148
  <div className="w-1/3 py-1 bg-primary" />
147
149
  <div className="w-1/3 py-1 bg-primary" />
148
- </div>
149
- </div>
150
+ </Flex>
151
+ </Flex>
150
152
  );
151
153
  }
152
154
 
package/src/footer_d.tsx CHANGED
@@ -8,7 +8,7 @@ import { SocialIcons } from "@stackshift-ui/social-icons";
8
8
  import { Text } from "@stackshift-ui/text";
9
9
 
10
10
  import { FooterProps } from ".";
11
- import { logoLink } from "./helper";
11
+ import { ConditionalLink, logoLink } from "./helper";
12
12
  import { Logo, SocialLink, Socials } from "./types";
13
13
 
14
14
  export default function Footer_D({
@@ -21,29 +21,29 @@ export default function Footer_D({
21
21
  return (
22
22
  <Section className="py-20 overflow-hidden bg-background">
23
23
  <Container maxWidth={1280}>
24
- <div className="flex flex-col lg:flex-row w-full gap-5 lg:items-center lg:justify-between xl:items-start">
24
+ <Flex className="flex-col lg:flex-row w-full gap-5 lg:items-center lg:justify-between xl:items-start">
25
25
  <div className="w-full lg:max-w-sm xl:max-w-xs space-y-4">
26
26
  <LogoSection logo={logo} />
27
27
  <TextSection text={text} />
28
28
  </div>
29
29
 
30
- <div className="flex flex-col space-y-8 lg:space-y-0">
31
- <div className="flex flex-col lg:flex-row w-full justify-between items-start lg:items-center">
30
+ <Flex className="flex-col space-y-8 lg:space-y-0">
31
+ <Flex className=" flex-col lg:flex-row w-full justify-between items-start lg:items-center">
32
32
  <MenuSection multipleMenus={multipleMenus} />
33
- </div>
34
- </div>
33
+ </Flex>
34
+ </Flex>
35
35
 
36
36
  <div className="hidden [@media(min-width:1444px)]:block">
37
37
  <SocialMediaContainer socialMedia={socialMedia} />
38
38
  </div>
39
- </div>
39
+ </Flex>
40
40
  <div className="hidden [@media(min-width:1444px)]:block items-center">
41
41
  <CopyrightSection copyright={copyright} />
42
42
  </div>
43
- <div className="flex flex-col sm:flex-row w-full sm:items-center sm:justify-between pt-10 gap-5 [@media(min-width:1444px)]:hidden">
43
+ <Flex className="flex-col sm:flex-row w-full sm:items-center sm:justify-between pt-10 gap-5 [@media(min-width:1444px)]:hidden">
44
44
  <CopyrightSection copyright={copyright} />
45
45
  <SocialMediaContainer socialMedia={socialMedia} />
46
- </div>
46
+ </Flex>
47
47
  </Container>
48
48
  </Section>
49
49
  );
@@ -110,11 +110,13 @@ function MenuLinks({ menu }: { menu?: any }) {
110
110
  {menu?.links?.map((link: any) => (
111
111
  <li key={link?._key}>
112
112
  <Button
113
- as="link"
114
- link={link}
115
- className="text-gray-500 no-underline hover:text-gray-700"
116
- ariaLabel={link?.label}>
117
- {link?.label}
113
+ variant="unstyled"
114
+ className="text-gray-500 no-underline hover:text-gray-700 px-0 py-0"
115
+ aria-label={link?.label}
116
+ asChild>
117
+ <ConditionalLink link={link} ariaLabel={link?.label ?? "Footer menu link"}>
118
+ {link?.label}
119
+ </ConditionalLink>
118
120
  </Button>
119
121
  </li>
120
122
  ))}
@@ -1,4 +1,5 @@
1
- import { Logo } from "../types";
1
+ import { Link } from "@stackshift-ui/link";
2
+ import { ConditionalLinkTypes, Logo } from "../types";
2
3
 
3
4
  // Logo link
4
5
  export const logoLink = (logo: Logo) => {
@@ -13,3 +14,118 @@ export const logoLink = (logo: Logo) => {
13
14
  return "/";
14
15
  }
15
16
  };
17
+
18
+ export const ConditionalLink = ({
19
+ className,
20
+ ariaLabel,
21
+ style = {},
22
+ children,
23
+ link,
24
+ target,
25
+ }: ConditionalLinkTypes) => {
26
+ const defaultStyle =
27
+ "inline-block py-2 px-6 rounded-l-xl rounded-t-xl bg-primary hover:bg-primary-foreground text-gray-50 font-bold leading-loose outline-none transition duration-200";
28
+
29
+ if (!link?.internalLink && !link?.externalLink) {
30
+ return (
31
+ <a
32
+ className={className ?? defaultStyle}
33
+ aria-label={ariaLabel}
34
+ //style={style}
35
+ target={target}
36
+ href="/page-not-found">
37
+ {children}
38
+ </a>
39
+ );
40
+ } else if (
41
+ (link?.type === "linkInternal" || link.linkType === "linkInternal") &&
42
+ // link?.internalLink?.toLowerCase()?.includes("home")
43
+ link?.internalLink?.toLowerCase() === "home"
44
+ ) {
45
+ return (
46
+ <Link
47
+ href={link?.referenceType === "projects" ? "/projects" : "/"}
48
+ aria-label={ariaLabel}
49
+ className={className ?? defaultStyle}
50
+ //style={style}
51
+ target={target}>
52
+ {children}
53
+ </Link>
54
+ );
55
+ } else if (link?.type === "linkInternal" || link?.linkType === "linkInternal") {
56
+ let hrefPath = "";
57
+
58
+ switch (link?.referenceType) {
59
+ case "projects":
60
+ hrefPath = `/projects/${link?.internalLink}`;
61
+ break;
62
+ case "commercial":
63
+ hrefPath = `/projects/commercial/${link?.internalLink}`;
64
+ break;
65
+ case "residential":
66
+ hrefPath = `/projects/residential/${link?.internalLink}`;
67
+ break;
68
+ case "landscape":
69
+ hrefPath = `/projects/landscape/${link?.internalLink}`;
70
+ break;
71
+ case "public":
72
+ hrefPath = `/projects/public/${link?.internalLink}`;
73
+ break;
74
+ case "teaching":
75
+ hrefPath = `/projects/teaching/${link?.internalLink}`;
76
+ break;
77
+ case "designInMotion":
78
+ hrefPath = `/projects/future-projects/${link?.internalLink}`;
79
+ break;
80
+ case "renovation":
81
+ hrefPath = `/projects/residential/renovation/${link?.internalLink}`;
82
+ break;
83
+ case "newConstruction":
84
+ hrefPath = `/projects/residential/new-construction/${link?.internalLink}`;
85
+ break;
86
+ case "ourTeam":
87
+ hrefPath = `/our-team/${link?.internalLink}`;
88
+ break;
89
+ case "recognition":
90
+ hrefPath = `/recognition/${link?.internalLink}`;
91
+ break;
92
+
93
+ default:
94
+ hrefPath = `/${link?.internalLink}`;
95
+ }
96
+
97
+ return (
98
+ <Link
99
+ href={hrefPath}
100
+ aria-label={ariaLabel}
101
+ className={className ?? defaultStyle}
102
+ //style={style}
103
+ target={target}>
104
+ {children}
105
+ </Link>
106
+ );
107
+ } else if (link?.type === "linkExternal" || link?.linkType === "linkExternal") {
108
+ return (
109
+ <a
110
+ aria-label={ariaLabel}
111
+ className={className ?? defaultStyle}
112
+ //style={style}
113
+ href={link?.externalLink ?? ""}
114
+ target={target}
115
+ rel={link?.linkTarget === "_blank" ? "noopener noreferrer" : undefined}>
116
+ {children}
117
+ </a>
118
+ );
119
+ } else {
120
+ return (
121
+ <Link
122
+ href="/"
123
+ aria-label={ariaLabel}
124
+ className={className ?? defaultStyle}
125
+ //style={style}
126
+ target={target}>
127
+ {children}
128
+ </Link>
129
+ );
130
+ }
131
+ };
package/src/types.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { PortableTextComponents } from "@portabletext/react";
2
+
1
3
  export type StyleVariants<T extends string> = Record<T, string>;
2
4
 
3
5
  export type Socials = "facebook" | "instagram" | "youtube" | "linkedin" | "twitter";
@@ -6,6 +8,74 @@ export interface MainImage {
6
8
  alt?: string;
7
9
  }
8
10
 
11
+ export interface MegaMenu {
12
+ _type: string;
13
+ showcaseLink?: ShowcaseLink[];
14
+ links?: MegaMenuLink[];
15
+ _key: string;
16
+ title?: string;
17
+ groupOfLinks?: GroupOfLink[];
18
+ label?: string;
19
+ linkTarget?: string;
20
+ linkType?: string;
21
+ url?: string;
22
+ linkExternal?: string;
23
+ }
24
+
25
+ export interface Logo extends ConditionalLink {
26
+ alt?: string;
27
+ linkTarget?: string;
28
+ image?: string;
29
+ }
30
+
31
+ export interface Logos {
32
+ logo: Logo[];
33
+ }
34
+
35
+ export interface GroupOfLink {
36
+ _type: string;
37
+ links: GroupOfLinkRoot[];
38
+ _key: string;
39
+ title: string;
40
+ primaryButton: LabeledRouteWithKey;
41
+ }
42
+
43
+ export interface GroupOfLinkRoot {
44
+ title: string;
45
+ _type: string;
46
+ label?: string;
47
+ links: LabeledRouteWithKey[];
48
+ _key: string;
49
+ }
50
+ export interface MegaMenu {
51
+ _type: string;
52
+ showcaseLink?: ShowcaseLink[];
53
+ links?: MegaMenuLink[];
54
+ _key: string;
55
+ title?: string;
56
+ groupOfLinks?: GroupOfLink[];
57
+ label?: string;
58
+ linkTarget?: string;
59
+ linkType?: string;
60
+ url?: string;
61
+ }
62
+
63
+ export interface ShowcaseLink {
64
+ mainImage: MainImage;
65
+ _type: string;
66
+ primaryButton: LabeledRouteWithKey;
67
+ _key: string;
68
+ }
69
+
70
+ export interface MegaMenuLink {
71
+ _key: string;
72
+ title: string;
73
+ _type: string;
74
+ links: LabeledRouteWithKey[];
75
+ primaryButton: LabeledRouteWithKey;
76
+ label: string;
77
+ }
78
+
9
79
  export interface LabeledRoute extends ConditionalLink {
10
80
  ariaLabel?: string;
11
81
  label?: string;
@@ -13,6 +83,10 @@ export interface LabeledRoute extends ConditionalLink {
13
83
  linkType?: string;
14
84
  _type?: string;
15
85
  linkInternal?: any;
86
+ linkExternal?: any;
87
+ referenceType?: string;
88
+ multipleRoutes?: LabeledRouteWithKey[];
89
+ multipleInnerRoutes?: LabeledRouteWithKey[];
16
90
  }
17
91
  export interface ConditionalLink {
18
92
  type?: string;
@@ -28,10 +102,15 @@ export interface StatItems {
28
102
  _type?: string;
29
103
  }
30
104
 
31
- export interface Logo extends ConditionalLink {
105
+ export interface Logo {
32
106
  alt?: string;
33
107
  linkTarget?: string;
34
108
  image?: string;
109
+ type?: string;
110
+ internalLink?: string;
111
+ externalLink?: string;
112
+ linkExternal?: string;
113
+ linkInternal?: string;
35
114
  }
36
115
 
37
116
  export interface Images {
@@ -62,6 +141,17 @@ export interface SocialLink {
62
141
 
63
142
  export interface LabeledRouteWithKey extends LabeledRoute {
64
143
  _key?: string;
144
+ image?: string;
145
+ alt?: string;
146
+ multipleRoutes?: LabeledRouteWithKey[];
147
+ featuredRoute?: {
148
+ featuredLink: LabeledRoute;
149
+ mainImage: {
150
+ image: string;
151
+ alt: string;
152
+ };
153
+ };
154
+ routeType?: string;
65
155
  }
66
156
 
67
157
  export interface ArrayOfImageTitleAndText {
@@ -201,12 +291,17 @@ export interface Sections extends SanityBody {
201
291
  export interface Variants {
202
292
  template?: Template;
203
293
  multipleMenus?: any;
294
+ multipleLinks?: any;
295
+ megaMenu?: MegaMenu[];
204
296
  arrayOfTitleAndText?: ArrayOfTitleAndText[] | null;
205
297
  logo?: Logo | null;
298
+ logos?: Logos[] | null;
206
299
  primaryButton?: LabeledRoute | null;
207
300
  secondaryButton?: LabeledRoute | null;
208
301
  routes?: LabeledRouteWithKey[] | null;
209
302
  menu?: LabeledRouteWithKey[] | null;
303
+ dropdownMenu?: LabeledRouteWithKey[] | null;
304
+ iconLinks?: LabeledRouteWithKey[] | null;
210
305
  plans?: Plans[] | null;
211
306
  formLinks?: LabeledRouteWithKey[] | null;
212
307
  portfolios?: Portfolios[] | null;
@@ -230,6 +325,7 @@ export interface Variants {
230
325
  contactEmail?: string | null;
231
326
  contactNumber?: string | null;
232
327
  socialLinks?: SocialLink[] | null;
328
+ socialMedia?: SocialLink[] | null;
233
329
  block?: any;
234
330
  heading?: string | null;
235
331
  acceptButtonLabel?: string | null;
@@ -410,3 +506,24 @@ export declare interface Reference {
410
506
  };
411
507
  };
412
508
  }
509
+
510
+ export type MyPortableTextComponents = PortableTextComponents & {
511
+ code?: ({ value }: { value: { language?: string; code?: string } }) => JSX.Element;
512
+ };
513
+
514
+ export interface ConditionalLinkTypes {
515
+ className?: string;
516
+ ariaLabel: string; // required for A11Y
517
+ style?: any;
518
+ children: string | React.ReactNode;
519
+ link: LabeledRoute | LabeledRouteWithKey | undefined;
520
+ target?: string;
521
+ }
522
+
523
+ export interface IconLink {
524
+ _key: string;
525
+ image: string;
526
+ alt?: string;
527
+ linkExternal: string;
528
+ linkTarget?: "_blank" | "_self";
529
+ }