Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ const GaEventPropTypes = {
text: PropTypes.string,
};

const RfiLabel = ({ label, name, id = undefined, requiredIcon = undefined }) => (
const RfiLabel = ({
label,
name,
id = undefined,
requiredIcon = undefined,
}) => (
<label htmlFor={id || name}>
{requiredIcon && (
<>
Expand Down
1 change: 0 additions & 1 deletion packages/app-webdir-ui/src/QuickLinks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,3 @@ const QuickLinks = () => {
};

export { QuickLinks };

7 changes: 6 additions & 1 deletion packages/component-footer/src/components/Contact/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ import { ColumnSection } from "../ColumnSection";
*/

const Contact = ({
contact: { title = "", contactLink = "", contributionLink = "", columns = []},
contact: {
title = "",
contactLink = "",
contributionLink = "",
columns = [],
},
}) => {
return (
<div className="wrapper" id="wrapper-footer-columns" data-testid="contact">
Expand Down
8 changes: 3 additions & 5 deletions packages/component-footer/src/components/Social/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,9 @@ const DEF_MEDIA_LINKS = {
* @returns {JSX.Element}
*/

const Social = ({ social: {
logoUrl,
unitLogo = endorsedLogo,
mediaLinks = DEF_MEDIA_LINKS,
}, }) => {
const Social = ({
social: { logoUrl, unitLogo = endorsedLogo, mediaLinks = DEF_MEDIA_LINKS },
}) => {
return (
<div className="wrapper" id="wrapper-endorsed-footer" data-testid="social">
<div className="container" id="endorsed-footer">
Expand Down
24 changes: 23 additions & 1 deletion packages/component-header-footer/.storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,33 @@ const config = {
],
stories: ["../src/**/*.stories.js"],
core: {
builder: '@storybook/builder-vite'
builder: "@storybook/builder-vite",
},
framework: {
name: "@storybook/react-vite",
},
async viteFinal(config) {
// Configure optimizeDeps to handle JSX in .js files
config.optimizeDeps = {
...config.optimizeDeps,
esbuildOptions: {
...config.optimizeDeps?.esbuildOptions,
loader: {
".js": "jsx",
".jsx": "jsx",
},
},
};

// Configure esbuild for build
config.esbuild = {
...config.esbuild,
loader: "jsx",
include: /\.(jsx?|tsx?)$/,
};

return config;
},
};

export default config;
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { ButtonWrapper } from "./index.styles";
* @param {string} props.text - The text content to display inside the button
* @param {string} [props.classes] - Additional CSS classes to apply to the button
* @param {function} [props.onClick] - Event handler function called when the button is clicked
* @param {function} [props.onKeyDown] - Event handler function called when a key is pressed while the button is focused
* @param {function} [props.onFocus] - Event handler function called when the button receives focus
* @param {string|React.Component} [props.as] - The element type or component to render as
* @returns {JSX.Element} The rendered button component
Expand All @@ -27,6 +28,7 @@ const Button = ({
text,
classes,
onClick,
onKeyDown,
onFocus,
as,
...props
Expand All @@ -35,8 +37,9 @@ const Button = ({
<ButtonWrapper
href={href}
className={`button-${color} ${classes ?? ""}`}
onClick={onClick ? event => onClick(event) : undefined}
onFocus={onFocus ? event => onFocus(event) : undefined}
onClick={onClick}
onKeyDown={onKeyDown}
onFocus={onFocus}
as={as}
{...props}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,24 @@ const LINK_DEFAULT_PROPS = {
text: "",
};

const HeadingItem = ({ text }) => <h3 className={CLASS_NAMES.UL_HEADING}>{text}</h3>;
const HeadingItem = ({ text }) => (
<h3 className={CLASS_NAMES.UL_HEADING}>{text}</h3>
);

HeadingItem.propTypes = {
text: PropTypes.string,
};

const ButtonItem = ({ link, dropdownName, handleLinkEvent }) => (
<li className={CLASS_NAMES.NAV_BUTTON}>
<div className={CLASS_NAMES.NAV_BUTTON}>
<Button
text={link.text}
color={link.color || "dark"}
color={link.color || "maroon"}
href={link.href}
onClick={e => handleLinkEvent(e, link)}
onKeyDown={e => handleLinkEvent(e, link)}
/>
</li>
</div>
);

ButtonItem.propTypes = {
Expand Down Expand Up @@ -72,10 +75,11 @@ LinkItem.propTypes = {
* @typedef { import("../../../../core/models/types").Button } Button
* @typedef {{
* dropdownName: string
* items: [object][]
* items: Array<Array<object>>
* buttons: Button[]
* classes?: string,
* listId: string
* opened: boolean
* setItemOpened: Function
* parentLink: React.RefObject<HTMLElement> | null
* }} DropdownItemProps
Expand All @@ -91,11 +95,17 @@ const DropdownItem = ({
buttons,
classes,
listId,
opened,
setItemOpened,
parentLink,
}) => {
const { breakpoint } = useAppContext();
const isMega = items?.length > 2;
const { breakpoint, headerHeight } = useAppContext();
let cols = 0;
items.map(lists => {
cols += lists[0].span || 1;
});

const isMega = cols > 2;
/**
* @type {React.MutableRefObject<HTMLDivElement|null>}
*/
Expand All @@ -110,6 +120,16 @@ const DropdownItem = ({
setAlignedRight(elPosition > breakpointPosition);
}
}, []);
useEffect(() => {
if (opened && dropdownRef?.current?.parentElement) {
dropdownRef.current.parentElement.scrollIntoView(
/** @type {ScrollIntoViewOptions} */ {
behavior: "smooth",
block: "start",
}
);
}
}, [dropdownRef, opened]);

const stopPropagation = e => e.stopPropagation();

Expand All @@ -119,14 +139,13 @@ const DropdownItem = ({

const focusNextLink = () => {
const nextLink = parentElement.nextElementSibling?.firstChild;
if (nextLink) nextLink.focus();
if (typeof nextLink?.focus === "function") nextLink.focus();
};

const focusPrevLink = () => {
const prevLink = parentElement.previousElementSibling?.firstChild;
if (prevLink) prevLink.focus();
if (typeof prevLink?.focus === "function") prevLink.focus();
};

stopPropagation(e);

if (key === "ArrowDown") {
Expand All @@ -137,15 +156,17 @@ const DropdownItem = ({
focusPrevLink();
} else if (key === "Escape") {
setItemOpened();
if (parentLink?.current) parentLink.current.focus();
if (typeof parentLink?.current?.focus === "function") {
parentLink.current.focus();
}
} else if (key === "Enter" || key === " " || type === "click") {
link?.onClick?.(e);
trackGAEvent({ ...LINK_DEFAULT_PROPS, text: link.text });
}
};

const renderItem = (link, index) => {
const key = `${link.text}-${link.href || index}`;
const key = `${link.text}-${link.href}-${index}`;
if (link.type === "heading")
return <HeadingItem key={key} text={link.text} />;
if (link.type === "button")
Expand Down Expand Up @@ -174,17 +195,68 @@ const DropdownItem = ({
isMega ? " mega" : ""
}`}
breakpoint={breakpoint}
headerHeight={headerHeight}
>
<div id={MULTIPLE_SUBMENUS ? listId : ""} className={CLASS_NAMES.DROPDOWN_CONTAINER}>
{items?.map((item, index0) => {
const genKey = idGenerator(`dropdown-item-${index0}-`);
const key = genKey.next().value;
return (
<ul id={MULTIPLE_SUBMENUS ? `${listId}-${key}` : listId} key={key}>
{item.map((link, index) => renderItem(link, index))}
</ul>
);
})}
<div
style={{ "--cols": cols < 3 ? 4 : cols }}
id={MULTIPLE_SUBMENUS ? listId : ""}
className={CLASS_NAMES.DROPDOWN_CONTAINER}
>
<>
{items?.map((item, index0) => {
const genKey = idGenerator(`dropdown-item-${index0}-`);
const key = genKey.next().value;
return (
<div
className={CLASS_NAMES.DROPDOWN_CONTAINER_COLUMN}
style={{ "--span": item[0].span || 1 }}
key={`${listId}-${key}`}
id={MULTIPLE_SUBMENUS ? `${listId}-${key}` : listId}
>
{(() => {
let currentUl = [];
const uls = [];
item.forEach((link, index) => {
if (link.type === "heading") {
if (currentUl.length > 0) {
uls.push(currentUl);
currentUl = [];
}
uls.push([link]);
} else if (link.type === "button") {
if (currentUl.length > 0) {
uls.push(currentUl);
currentUl = [];
}
uls.push([link]);
} else {
currentUl.push(link);
}
});

if (currentUl.length > 0) {
uls.push(currentUl);
}

return uls.map((group, groupIndex) => {
const groupKey = `${key}-group-${groupIndex}`;
if (group.length === 1 && group[0].type === "heading") {
return renderItem(group[0], groupIndex);
}
if (group.length === 1 && group[0].type === "button") {
return renderItem(group[0], groupIndex);
}
return (
<ul key={groupKey}>
{group.map((link, index) => renderItem(link, index))}
</ul>
);
});
})()}
</div>
);
})}
</>
</div>
{buttons && (
<div className={CLASS_NAMES.DROPDOWN_BUTTON_CONTAINER}>
Expand All @@ -208,19 +280,21 @@ const DropdownItem = ({
DropdownItem.propTypes = {
dropdownName: PropTypes.string,
items: PropTypes.arrayOf(
PropTypes.shape({
text: PropTypes.string,
selected: PropTypes.bool,
onClick: PropTypes.func,
href: PropTypes.string,
})
PropTypes.arrayOf(
PropTypes.shape({
text: PropTypes.string,
selected: PropTypes.bool,
onClick: PropTypes.func,
href: PropTypes.string,
})
)
),
buttons: PropTypes.arrayOf(PropTypes.shape(ButtonPropTypes)),
classes: PropTypes.string,
listId: PropTypes.string,
opened: PropTypes.bool,
setItemOpened: PropTypes.func,
parentLink: PropTypes.shape({
focus: PropTypes.func,
current: PropTypes.instanceOf(HTMLElement),
}),
};
Expand Down
Loading