@ilo-org/react 0.3.0 → 0.4.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/CHANGELOG.md +16 -0
- package/README.md +1 -1
- package/lib/cjs/{DailyMotion-2aa7f048.js → DailyMotion-5654fa6e.js} +1 -1
- package/lib/cjs/{Facebook-87e24af8.js → Facebook-1924e510.js} +1 -1
- package/lib/cjs/{FilePlayer-e1216cc8.js → FilePlayer-9c697e42.js} +1 -1
- package/lib/cjs/{Kaltura-a673a8e9.js → Kaltura-177bb003.js} +1 -1
- package/lib/cjs/{Mixcloud-f9575c31.js → Mixcloud-91a772a6.js} +1 -1
- package/lib/cjs/{Preview-468c3a7f.js → Preview-8e2afb6a.js} +1 -1
- package/lib/cjs/{SoundCloud-7c59f293.js → SoundCloud-089e0f30.js} +1 -1
- package/lib/cjs/{Streamable-83e516e5.js → Streamable-4ca5b9c7.js} +1 -1
- package/lib/cjs/{Twitch-fdfa1c77.js → Twitch-dbc5c387.js} +1 -1
- package/lib/cjs/{VideoPlayer-9ce35136.js → VideoPlayer-874a52b0.js} +21 -16
- package/lib/cjs/{Vidyard-096bba3c.js → Vidyard-371acdcb.js} +1 -1
- package/lib/cjs/{Vimeo-2cb7476f.js → Vimeo-4d2029a8.js} +1 -1
- package/lib/cjs/{Wistia-5e830ac8.js → Wistia-cd0799ad.js} +1 -1
- package/lib/cjs/{YouTube-25a1d9a0.js → YouTube-23b7ec9e.js} +1 -1
- package/lib/cjs/components/Card/Card.js +43 -0
- package/lib/cjs/components/Card/CardGroup.js +25 -0
- package/lib/cjs/components/Card/index.js +21 -0
- package/lib/cjs/components/LocalNav/LocalNav.js +5 -3
- package/lib/cjs/components/LocalNav/index.js +1 -0
- package/lib/cjs/components/Logo/Logo.js +153 -0
- package/lib/cjs/components/Logo/index.js +13 -0
- package/lib/cjs/components/Video/Video.js +1 -1
- package/lib/cjs/components/Video/VideoPlayer.js +1 -1
- package/lib/cjs/components/Video/index.js +1 -1
- package/lib/cjs/components/index.js +7 -1
- package/lib/cjs/index.js +7 -1
- package/lib/esm/{DailyMotion-66b6eff2.js → DailyMotion-88f6c379.js} +1 -1
- package/lib/esm/{Facebook-dbd1003d.js → Facebook-3a284039.js} +1 -1
- package/lib/esm/{FilePlayer-617ed2ce.js → FilePlayer-dee1f94b.js} +1 -1
- package/lib/esm/{Kaltura-bbcec33d.js → Kaltura-c5d42c88.js} +1 -1
- package/lib/esm/{Mixcloud-a681ec69.js → Mixcloud-430ab42a.js} +1 -1
- package/lib/esm/{Preview-407cc648.js → Preview-7f57e055.js} +1 -1
- package/lib/esm/{SoundCloud-16e78ee5.js → SoundCloud-d1ab591e.js} +1 -1
- package/lib/esm/{Streamable-ecb225c1.js → Streamable-042d61d5.js} +1 -1
- package/lib/esm/{Twitch-8d1b6769.js → Twitch-2f45534f.js} +1 -1
- package/lib/esm/{VideoPlayer-62e0ce79.js → VideoPlayer-719076c4.js} +21 -16
- package/lib/esm/{Vidyard-57e2834a.js → Vidyard-4625527b.js} +1 -1
- package/lib/esm/{Vimeo-faa058a2.js → Vimeo-03b960e6.js} +1 -1
- package/lib/esm/{Wistia-24fb5120.js → Wistia-48f9c303.js} +1 -1
- package/lib/esm/{YouTube-01b3e51f.js → YouTube-5b29a3d9.js} +1 -1
- package/lib/esm/components/Card/Card.js +41 -0
- package/lib/esm/components/Card/CardGroup.js +23 -0
- package/lib/esm/components/Card/index.js +14 -0
- package/lib/esm/components/LocalNav/LocalNav.js +5 -3
- package/lib/esm/components/LocalNav/index.js +1 -0
- package/lib/esm/components/Logo/Logo.js +151 -0
- package/lib/esm/components/Logo/index.js +7 -0
- package/lib/esm/components/Video/Video.js +1 -1
- package/lib/esm/components/Video/VideoPlayer.js +1 -1
- package/lib/esm/components/Video/index.js +1 -1
- package/lib/esm/components/index.js +5 -1
- package/lib/esm/index.js +5 -1
- package/lib/types/react/src/components/Card/Card.d.ts +4 -0
- package/lib/types/react/src/components/Card/Card.props.d.ts +110 -0
- package/lib/types/react/src/components/Card/CardGroup.d.ts +4 -0
- package/lib/types/react/src/components/Card/CardGroup.props.d.ts +16 -0
- package/lib/types/react/src/components/Card/index.d.ts +2 -0
- package/lib/types/react/src/components/LocalNav/LocalNav.props.d.ts +4 -7
- package/lib/types/react/src/components/Logo/Logo.d.ts +4 -0
- package/lib/types/react/src/components/Logo/Logo.props.d.ts +55 -0
- package/lib/types/react/src/components/Logo/index.d.ts +1 -0
- package/lib/types/react/src/components/index.d.ts +1 -0
- package/lib/types/react/src/types/index.d.ts +6 -0
- package/package.json +17 -17
- package/src/components/Accordion/Accordion.args.ts +1 -4
- package/src/components/Card/Card.args.ts +215 -0
- package/src/components/Card/Card.props.ts +142 -0
- package/src/components/Card/Card.tsx +183 -0
- package/src/components/Card/CardGroup.args.ts +945 -0
- package/src/components/Card/CardGroup.props.ts +19 -0
- package/src/components/Card/CardGroup.tsx +55 -0
- package/src/components/Card/index.ts +2 -0
- package/src/components/LocalNav/LocalNav.args.ts +6 -6
- package/src/components/LocalNav/LocalNav.props.ts +4 -8
- package/src/components/LocalNav/LocalNav.tsx +21 -15
- package/src/components/Logo/Logo.args.ts +45 -0
- package/src/components/Logo/Logo.props.ts +67 -0
- package/src/components/Logo/Logo.tsx +247 -0
- package/src/components/Logo/index.ts +1 -0
- package/src/components/index.ts +1 -0
- package/src/types/index.ts +14 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { CardProps } from "../Card/Card.props";
|
|
2
|
+
import { LinkProps } from "../LinkList/LinkList.props";
|
|
3
|
+
|
|
4
|
+
export interface CardGroupProps {
|
|
5
|
+
/**
|
|
6
|
+
* An array of card objects
|
|
7
|
+
*/
|
|
8
|
+
cards?: Required<CardProps>[];
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Number of cards in the group
|
|
12
|
+
*/
|
|
13
|
+
cardcount: Required<string>;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A Button to display after all the cards in the group
|
|
17
|
+
*/
|
|
18
|
+
cta?: LinkProps;
|
|
19
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { FC } from "react";
|
|
2
|
+
import classnames from "classnames";
|
|
3
|
+
import useGlobalSettings from "../../hooks/useGlobalSettings";
|
|
4
|
+
import { CardGroupProps } from "./CardGroup.props";
|
|
5
|
+
import { Card } from "../Card";
|
|
6
|
+
|
|
7
|
+
const CardGroup: FC<CardGroupProps> = ({ cards, cardcount, cta }) => {
|
|
8
|
+
const { prefix } = useGlobalSettings();
|
|
9
|
+
|
|
10
|
+
const baseClass = `${prefix}--cardgroup`;
|
|
11
|
+
const cardGroupClasses = classnames(baseClass, `${baseClass}--${cardcount}`);
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<div className={cardGroupClasses}>
|
|
15
|
+
<div className={`${baseClass}--inner`}>
|
|
16
|
+
{cards &&
|
|
17
|
+
cards.map((card) => (
|
|
18
|
+
<Card
|
|
19
|
+
title={card.title}
|
|
20
|
+
image={card.image}
|
|
21
|
+
intro={card.intro}
|
|
22
|
+
eyebrow={card.eyebrow}
|
|
23
|
+
date={card.date}
|
|
24
|
+
dataset={card.dataset}
|
|
25
|
+
link={card.link}
|
|
26
|
+
profile={card.profile}
|
|
27
|
+
cta={card.cta}
|
|
28
|
+
source={card.source}
|
|
29
|
+
listitems={card.listitems}
|
|
30
|
+
linklist={card.linklist}
|
|
31
|
+
color={card.color}
|
|
32
|
+
theme={card.theme}
|
|
33
|
+
cornercut={card.cornercut}
|
|
34
|
+
alignment={card.alignment}
|
|
35
|
+
variant={card.variant}
|
|
36
|
+
size={card.size}
|
|
37
|
+
/>
|
|
38
|
+
))}
|
|
39
|
+
|
|
40
|
+
{cta && (
|
|
41
|
+
<div className={`${baseClass}--button-wrap`}>
|
|
42
|
+
<a
|
|
43
|
+
className={`${prefix}--button ${prefix}--button--medium ${prefix}--button--secondary`}
|
|
44
|
+
href={cta.url}
|
|
45
|
+
>
|
|
46
|
+
<span className="button__label">{cta.label}</span>
|
|
47
|
+
</a>
|
|
48
|
+
</div>
|
|
49
|
+
)}
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export default CardGroup;
|
|
@@ -3,8 +3,12 @@ import ilo_logo_white from "@ilo-org/brand-assets/logo_en_horizontal_white.svg";
|
|
|
3
3
|
|
|
4
4
|
const basic: LocalNavProps = {
|
|
5
5
|
background: "#960A55",
|
|
6
|
-
logo:
|
|
7
|
-
|
|
6
|
+
logo: {
|
|
7
|
+
src: ilo_logo_white,
|
|
8
|
+
alt: "ILO Voices Logo",
|
|
9
|
+
subbrand: "Voices",
|
|
10
|
+
theme: "dark",
|
|
11
|
+
},
|
|
8
12
|
primarynav: {
|
|
9
13
|
navlabel: "Primary Nav Menu",
|
|
10
14
|
mobilecloselabel: "Close",
|
|
@@ -25,10 +29,6 @@ const basic: LocalNavProps = {
|
|
|
25
29
|
label: "Menu Item 4",
|
|
26
30
|
url: "https://www.ilo.org",
|
|
27
31
|
},
|
|
28
|
-
{
|
|
29
|
-
label: "Menu Item 5",
|
|
30
|
-
url: "https://www.ilo.org",
|
|
31
|
-
},
|
|
32
32
|
],
|
|
33
33
|
},
|
|
34
34
|
mainlink: {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { LinkProps, ContextMenuProps } from "../ContextMenu/ContextMenu.props";
|
|
2
|
+
import { LogoProps } from "../Logo/Logo.props";
|
|
2
3
|
|
|
3
4
|
export interface LocalNavProps {
|
|
4
5
|
/**
|
|
@@ -7,19 +8,14 @@ export interface LocalNavProps {
|
|
|
7
8
|
background?: string;
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
|
-
* Props for the
|
|
11
|
+
* Props for the Logo component of the LocalNav
|
|
11
12
|
*/
|
|
12
|
-
logo
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Props for the home url of the LocalNav
|
|
16
|
-
*/
|
|
17
|
-
siteurl?: Required<string>;
|
|
13
|
+
logo: LogoProps;
|
|
18
14
|
|
|
19
15
|
/**
|
|
20
16
|
* Specify the primary items for the LocalNav
|
|
21
17
|
*/
|
|
22
|
-
primarynav?:
|
|
18
|
+
primarynav?: PrimaryNavProps;
|
|
23
19
|
|
|
24
20
|
/**
|
|
25
21
|
* Specify the main link for the LocalNav
|
|
@@ -4,11 +4,13 @@ import { ContextMenu } from "../ContextMenu";
|
|
|
4
4
|
import { LocalNavProps } from "./LocalNav.props";
|
|
5
5
|
import { brand } from "@ilo-org/themes/tokens/brand/base.json";
|
|
6
6
|
import classnames from "classnames";
|
|
7
|
+
import { Logo } from "../Logo";
|
|
8
|
+
|
|
9
|
+
const DEFAULT_LOGO_SIZE = 280;
|
|
7
10
|
|
|
8
11
|
const LocalNav: FC<LocalNavProps> = ({
|
|
9
12
|
background,
|
|
10
13
|
logo,
|
|
11
|
-
siteurl,
|
|
12
14
|
primarynav,
|
|
13
15
|
mainlink,
|
|
14
16
|
menucloselabel,
|
|
@@ -43,13 +45,15 @@ const LocalNav: FC<LocalNavProps> = ({
|
|
|
43
45
|
>
|
|
44
46
|
<nav className={`${prefix}--nav--local`}>
|
|
45
47
|
<div className={`${prefix}--nav--local--logo-wrapper`}>
|
|
46
|
-
<
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
48
|
+
<Logo
|
|
49
|
+
url={logo.url}
|
|
50
|
+
src={logo.src}
|
|
51
|
+
alt={logo.alt}
|
|
52
|
+
className={`${prefix}--nav--local--logo`}
|
|
53
|
+
subbrand={logo.subbrand}
|
|
54
|
+
theme={logo.theme}
|
|
55
|
+
size={logo.size || DEFAULT_LOGO_SIZE}
|
|
56
|
+
/>
|
|
53
57
|
</div>
|
|
54
58
|
<ul className={`${prefix}--nav--local--set`}>
|
|
55
59
|
{primarynav?.items &&
|
|
@@ -90,13 +94,15 @@ const LocalNav: FC<LocalNavProps> = ({
|
|
|
90
94
|
<div className={`${baseClass}--inner`}>
|
|
91
95
|
<div className={`${prefix}--mobile--nav`}>
|
|
92
96
|
<div className={`${prefix}--mobile--nav--logo`}>
|
|
93
|
-
<
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
97
|
+
<Logo
|
|
98
|
+
url={logo.url}
|
|
99
|
+
src={logo.src}
|
|
100
|
+
alt={logo.alt}
|
|
101
|
+
className={`${prefix}--nav--local--logo`}
|
|
102
|
+
subbrand={logo.subbrand}
|
|
103
|
+
theme={logo.theme}
|
|
104
|
+
size={logo.size || DEFAULT_LOGO_SIZE}
|
|
105
|
+
/>
|
|
100
106
|
<button
|
|
101
107
|
className={`${baseClass}--menu--close`}
|
|
102
108
|
onClick={handleMenuToggle}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { LogoProps } from "./Logo.props";
|
|
2
|
+
import en_blue from "@ilo-org/brand-assets/logo_en_horizontal_blue.svg";
|
|
3
|
+
import en_white from "@ilo-org/brand-assets/logo_en_horizontal_white.svg";
|
|
4
|
+
|
|
5
|
+
export const basic: LogoProps = {
|
|
6
|
+
src: en_blue,
|
|
7
|
+
url: "https://www.ilo.org",
|
|
8
|
+
alt: "International Labour Organization",
|
|
9
|
+
size: 400,
|
|
10
|
+
target: "_blank",
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const withTheme: LogoProps = {
|
|
14
|
+
...basic,
|
|
15
|
+
theme: "light",
|
|
16
|
+
src: {
|
|
17
|
+
light: en_blue,
|
|
18
|
+
dark: en_white,
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const withSubBrand: LogoProps = {
|
|
23
|
+
...withTheme,
|
|
24
|
+
subbrand: "Voices",
|
|
25
|
+
url: "https://voices.ilo.org",
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const withDarkTheme: LogoProps = {
|
|
29
|
+
...withSubBrand,
|
|
30
|
+
subbrand: "Voices",
|
|
31
|
+
theme: "dark",
|
|
32
|
+
url: "https://live.ilo.org",
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const withLongSubbrand: LogoProps = {
|
|
36
|
+
...withTheme,
|
|
37
|
+
subbrand: "Digital Design System",
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const fluidWidth: LogoProps = {
|
|
41
|
+
...withDarkTheme,
|
|
42
|
+
url: "https://live.ilo.org",
|
|
43
|
+
size: "fluid",
|
|
44
|
+
subbrand: "Live",
|
|
45
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
type LogoSrc =
|
|
2
|
+
| string
|
|
3
|
+
| {
|
|
4
|
+
/**
|
|
5
|
+
* The url of the logo to use with light theme
|
|
6
|
+
*/
|
|
7
|
+
light: string;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The url of the logo to use with dark theme
|
|
11
|
+
*/
|
|
12
|
+
dark: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export interface LogoProps {
|
|
16
|
+
/**
|
|
17
|
+
* The location of the image file
|
|
18
|
+
*/
|
|
19
|
+
src: LogoSrc;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Alt text for the logo
|
|
23
|
+
*/
|
|
24
|
+
alt: string;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The name of the sub-brand if there is one
|
|
28
|
+
*/
|
|
29
|
+
subbrand?: string;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The width of the logo or 'fluid' width
|
|
33
|
+
*/
|
|
34
|
+
size?: number | "fluid";
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Styles to be applied to the outermost element
|
|
38
|
+
*/
|
|
39
|
+
style?: React.CSSProperties;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Optional className to be passed to the outermost element of the component
|
|
43
|
+
*/
|
|
44
|
+
className?: string;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Optional destination if the logo is a link
|
|
48
|
+
*/
|
|
49
|
+
url?: string;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Optional target if the logo is a link
|
|
53
|
+
*/
|
|
54
|
+
target?: "_blank" | "_self" | "_parent" | "_top";
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Theme of the logo component
|
|
58
|
+
*/
|
|
59
|
+
theme?: "light" | "dark";
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface InnerLogoProps extends LogoProps {
|
|
63
|
+
/**
|
|
64
|
+
* The base class of the logo component
|
|
65
|
+
*/
|
|
66
|
+
baseClass: string;
|
|
67
|
+
}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import React, { useEffect, useRef, useState } from "react";
|
|
2
|
+
import { useGlobalSettings } from "../../hooks";
|
|
3
|
+
import { InnerLogoProps, LogoProps } from "./Logo.props";
|
|
4
|
+
import classnames from "classnames";
|
|
5
|
+
|
|
6
|
+
const isOverflown = ({
|
|
7
|
+
clientHeight,
|
|
8
|
+
clientWidth,
|
|
9
|
+
scrollHeight,
|
|
10
|
+
scrollWidth,
|
|
11
|
+
}: HTMLElement) => scrollHeight > clientHeight || scrollWidth > clientWidth;
|
|
12
|
+
|
|
13
|
+
const getFullFontSize = (
|
|
14
|
+
container: HTMLElement,
|
|
15
|
+
{ maxSize = 600, startingHeight = 9, step = 0.5 }
|
|
16
|
+
) => {
|
|
17
|
+
let i = startingHeight;
|
|
18
|
+
let overflow = false;
|
|
19
|
+
|
|
20
|
+
while (!overflow && i < maxSize) {
|
|
21
|
+
container.style.fontSize = `${i}px`;
|
|
22
|
+
container.style.lineHeight = `${i}px`;
|
|
23
|
+
|
|
24
|
+
overflow = isOverflown(container);
|
|
25
|
+
if (!overflow) {
|
|
26
|
+
i = i + step;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Reset styles to the way they were
|
|
31
|
+
container.style.fontSize = "";
|
|
32
|
+
container.style.lineHeight = "";
|
|
33
|
+
|
|
34
|
+
// Return the ideal font size
|
|
35
|
+
return i - step;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const BaseLogo: React.FC<InnerLogoProps> = ({
|
|
39
|
+
baseClass,
|
|
40
|
+
className,
|
|
41
|
+
subbrand,
|
|
42
|
+
alt,
|
|
43
|
+
src,
|
|
44
|
+
style: userStyles,
|
|
45
|
+
size = "fluid",
|
|
46
|
+
theme = "light",
|
|
47
|
+
...props
|
|
48
|
+
}) => {
|
|
49
|
+
// The logo image element
|
|
50
|
+
const imageRef = useRef<HTMLImageElement>(null);
|
|
51
|
+
|
|
52
|
+
// The lockup container
|
|
53
|
+
const lockupRef = useRef<HTMLDivElement>(null);
|
|
54
|
+
|
|
55
|
+
// The lockup text
|
|
56
|
+
const lockupTextRef = useRef<HTMLSpanElement>(null);
|
|
57
|
+
|
|
58
|
+
// Has the image loaded or not
|
|
59
|
+
const [imageLoaded, setImageLoaded] = useState(false);
|
|
60
|
+
|
|
61
|
+
// Dynamic height of the image
|
|
62
|
+
const [imageHeight, setImageHeight] = useState(0);
|
|
63
|
+
|
|
64
|
+
// Ratio of the font size to the height of the logo image
|
|
65
|
+
const [fontSizeRatio, setfontSizeRatio] = useState<number>(0);
|
|
66
|
+
|
|
67
|
+
// Is the logo visible? Default to true if not a subbrand
|
|
68
|
+
const [isLogoVisible, setIsLogoVisible] = useState(!subbrand);
|
|
69
|
+
|
|
70
|
+
// Initial height of the image when it's loaded
|
|
71
|
+
const initialImageHeight = useRef<null | number>(null);
|
|
72
|
+
|
|
73
|
+
// Resize observer gets the initial height of the image when
|
|
74
|
+
// it loads and updates the height when it changes in state
|
|
75
|
+
const observer = useRef(
|
|
76
|
+
new ResizeObserver((entries) => {
|
|
77
|
+
const { height } = entries[0].contentRect;
|
|
78
|
+
if (!initialImageHeight.current) {
|
|
79
|
+
initialImageHeight.current = height;
|
|
80
|
+
}
|
|
81
|
+
setImageHeight(height);
|
|
82
|
+
})
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
// Make the logo visible for subrand when everything is ready
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
if (subbrand && imageLoaded && fontSizeRatio) {
|
|
88
|
+
setIsLogoVisible(true);
|
|
89
|
+
}
|
|
90
|
+
}, [imageLoaded, fontSizeRatio, subbrand]);
|
|
91
|
+
|
|
92
|
+
// Set up the Resize observer to watch the image
|
|
93
|
+
useEffect(() => {
|
|
94
|
+
if (imageLoaded && lockupRef.current && imageRef.current) {
|
|
95
|
+
const imageEl = imageRef.current;
|
|
96
|
+
observer.current.observe(imageEl);
|
|
97
|
+
return () => observer.current.unobserve(imageEl);
|
|
98
|
+
}
|
|
99
|
+
}, [imageLoaded]);
|
|
100
|
+
|
|
101
|
+
// Gets the font size necessary for the lockup text to fill the
|
|
102
|
+
// the lockup container as much as possible without overflowing.
|
|
103
|
+
// Then gets the ratio of full font size to image height which will
|
|
104
|
+
// be used to calculate the font size if the image gets resized
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
setFontSize();
|
|
107
|
+
}, [imageLoaded, initialImageHeight.current]);
|
|
108
|
+
|
|
109
|
+
// Adjust the font size if for some weird reason the subbrand changes
|
|
110
|
+
// This is mostly just to illustrate how the component works on Storybook
|
|
111
|
+
useEffect(() => {
|
|
112
|
+
setFontSize();
|
|
113
|
+
}, [subbrand]);
|
|
114
|
+
|
|
115
|
+
function setFontSize() {
|
|
116
|
+
if (
|
|
117
|
+
lockupRef.current &&
|
|
118
|
+
lockupTextRef.current &&
|
|
119
|
+
initialImageHeight.current
|
|
120
|
+
) {
|
|
121
|
+
const fullFontSize = getFullFontSize(lockupRef.current, {
|
|
122
|
+
maxSize: initialImageHeight.current,
|
|
123
|
+
});
|
|
124
|
+
const ratio = fullFontSize / initialImageHeight.current;
|
|
125
|
+
setfontSizeRatio(ratio);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Has the image loaded or not
|
|
130
|
+
function handleImageLoaded() {
|
|
131
|
+
setImageLoaded(true);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Conditions for different CSS classes
|
|
135
|
+
const hasSubbrand = !!subbrand;
|
|
136
|
+
const hasFluidWidth = size === "fluid";
|
|
137
|
+
const hasFixedWidth = !hasFluidWidth && typeof size === "number";
|
|
138
|
+
|
|
139
|
+
// Classes for the outer figure container
|
|
140
|
+
const subBrandClass = `${baseClass}--sub-brand`;
|
|
141
|
+
const fluidWidthClass = `${baseClass}--size--fluid`;
|
|
142
|
+
const visibilityHidden = `${baseClass}--visibility--hidden`;
|
|
143
|
+
|
|
144
|
+
// Outer figure classes
|
|
145
|
+
const classNames = classnames(
|
|
146
|
+
baseClass,
|
|
147
|
+
className,
|
|
148
|
+
`${baseClass}--theme--${theme}`,
|
|
149
|
+
{
|
|
150
|
+
[visibilityHidden]: !isLogoVisible,
|
|
151
|
+
[fluidWidthClass]: hasFluidWidth,
|
|
152
|
+
[subBrandClass]: hasSubbrand,
|
|
153
|
+
}
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
// Classes for the image element
|
|
157
|
+
const noSubBrandImageClass = `${baseClass}--image`;
|
|
158
|
+
const subBrandImageClass = `${subBrandClass}--image`;
|
|
159
|
+
|
|
160
|
+
// Set inline CSS including variables on the outer figure element
|
|
161
|
+
const getStyle = (): React.CSSProperties => {
|
|
162
|
+
const conditionalStyles: any = {};
|
|
163
|
+
// Add CSS vars if this is a sub-brand
|
|
164
|
+
if (hasSubbrand) {
|
|
165
|
+
conditionalStyles["--logo-image-height"] = `${imageHeight}px`;
|
|
166
|
+
conditionalStyles["--logo-font-size"] = `${
|
|
167
|
+
fontSizeRatio * imageHeight
|
|
168
|
+
}px`;
|
|
169
|
+
}
|
|
170
|
+
// Add fixed width if it has fixed width
|
|
171
|
+
if (hasFixedWidth) {
|
|
172
|
+
conditionalStyles.width = `${size}px`;
|
|
173
|
+
}
|
|
174
|
+
// User styles may be overriden
|
|
175
|
+
return { userStyles, ...conditionalStyles };
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
const getImageSrc = () => {
|
|
179
|
+
if (typeof src === "string") {
|
|
180
|
+
return src;
|
|
181
|
+
}
|
|
182
|
+
return src[theme];
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
return (
|
|
186
|
+
<figure className={classNames} style={getStyle()}>
|
|
187
|
+
<img
|
|
188
|
+
ref={imageRef}
|
|
189
|
+
alt={alt}
|
|
190
|
+
src={getImageSrc()}
|
|
191
|
+
className={classnames({
|
|
192
|
+
[subBrandImageClass]: hasSubbrand,
|
|
193
|
+
[noSubBrandImageClass]: !hasSubbrand,
|
|
194
|
+
})}
|
|
195
|
+
onLoad={handleImageLoaded}
|
|
196
|
+
{...props}
|
|
197
|
+
/>
|
|
198
|
+
{hasSubbrand && (
|
|
199
|
+
<div ref={lockupRef} className={`${subBrandClass}--lock-up`}>
|
|
200
|
+
<span className={`${subBrandClass}--lock-up--separator`} />
|
|
201
|
+
<span ref={lockupTextRef}>{subbrand}</span>
|
|
202
|
+
</div>
|
|
203
|
+
)}
|
|
204
|
+
</figure>
|
|
205
|
+
);
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
const Logo: React.FC<LogoProps> = ({
|
|
209
|
+
className,
|
|
210
|
+
url,
|
|
211
|
+
target,
|
|
212
|
+
style,
|
|
213
|
+
size,
|
|
214
|
+
...props
|
|
215
|
+
}) => {
|
|
216
|
+
const { prefix } = useGlobalSettings();
|
|
217
|
+
const baseClass = `${prefix}--logo`;
|
|
218
|
+
const linkClass = `${baseClass}--link`;
|
|
219
|
+
const fluidClass = `${baseClass}--size--fluid`;
|
|
220
|
+
|
|
221
|
+
if (url) {
|
|
222
|
+
return (
|
|
223
|
+
<a
|
|
224
|
+
href={url}
|
|
225
|
+
target={target}
|
|
226
|
+
className={classnames(linkClass, className, {
|
|
227
|
+
[fluidClass]: size === "fluid",
|
|
228
|
+
})}
|
|
229
|
+
style={style}
|
|
230
|
+
>
|
|
231
|
+
<BaseLogo {...props} baseClass={baseClass} size={size} />
|
|
232
|
+
</a>
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return (
|
|
237
|
+
<BaseLogo
|
|
238
|
+
baseClass={baseClass}
|
|
239
|
+
className={className}
|
|
240
|
+
style={style}
|
|
241
|
+
size={size}
|
|
242
|
+
{...props}
|
|
243
|
+
/>
|
|
244
|
+
);
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
export default Logo;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Logo } from "./Logo";
|
package/src/components/index.ts
CHANGED
package/src/types/index.ts
CHANGED
|
@@ -33,6 +33,7 @@ export type InputTypes =
|
|
|
33
33
|
| "tel"
|
|
34
34
|
| "text"
|
|
35
35
|
| "url";
|
|
36
|
+
export type Language = "en" | "fr" | "es";
|
|
36
37
|
export type LabelTypes = "default" | "actionable" | "light";
|
|
37
38
|
export type LinkTypes = "light" | "dark" | "footer" | "button";
|
|
38
39
|
export type LinkListThemes = "light" | "dark";
|
|
@@ -49,3 +50,16 @@ export type PositionTypes = "top" | "bottom" | "left" | "right";
|
|
|
49
50
|
export type SizeTypes = "small" | "medium" | "large";
|
|
50
51
|
export type TagTypes = "anchor" | "display" | "button";
|
|
51
52
|
export type SocialTypes = "instagram" | "facebook" | "twitter" | "youtube";
|
|
53
|
+
export type CardColor = "turquoise" | "green" | "yellow" | "blue";
|
|
54
|
+
export type CardSize = "wide" | "standard" | "narrow";
|
|
55
|
+
export type CardCornerType = "cornercut" | "corner";
|
|
56
|
+
export type CardAlignment = "left" | "right";
|
|
57
|
+
export type CardTypes =
|
|
58
|
+
| "stat"
|
|
59
|
+
| "multilink"
|
|
60
|
+
| "graphic"
|
|
61
|
+
| "graphicpromo"
|
|
62
|
+
| "feature"
|
|
63
|
+
| "detail"
|
|
64
|
+
| "factlist"
|
|
65
|
+
| "data";
|