diff --git a/package-lock.json b/package-lock.json index 9752a1a8c..80c9c8121 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "@openedx/frontend-plugin-framework": "^1.3.0", "axios-mock-adapter": "1.22.0", "babel-polyfill": "6.26.0", + "classnames": "^2.5.1", "jest-environment-jsdom": "^29.7.0", "react-responsive": "8.2.0", "react-transition-group": "4.4.5" diff --git a/package.json b/package.json index 7993a4ac5..35eaa9ab2 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "@openedx/frontend-plugin-framework": "^1.3.0", "axios-mock-adapter": "1.22.0", "babel-polyfill": "6.26.0", + "classnames": "^2.5.1", "jest-environment-jsdom": "^29.7.0", "react-responsive": "8.2.0", "react-transition-group": "4.4.5" diff --git a/src/studio-header/HeaderBody.jsx b/src/studio-header/HeaderBody.jsx index 7a4426d4b..536dca1e1 100644 --- a/src/studio-header/HeaderBody.jsx +++ b/src/studio-header/HeaderBody.jsx @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { useIntl } from '@edx/frontend-platform/i18n'; +import classNames from 'classnames'; import { ActionRow, Button, @@ -37,6 +38,7 @@ const HeaderBody = ({ mainMenuDropdowns, outlineLink, searchButtonAction, + containerProps, }) => { const intl = useIntl(); @@ -50,8 +52,14 @@ const HeaderBody = ({ /> ); + const { className: containerClassName, ...restContainerProps } = containerProps || {}; + return ( - + {isHiddenMainMenu ? ( @@ -110,6 +118,7 @@ const HeaderBody = ({ iconAs={Icon} onClick={searchButtonAction} aria-label={intl.formatMessage(messages['header.label.search.nav'])} + alt={intl.formatMessage(messages['header.label.search.nav'])} /> )} @@ -147,14 +156,15 @@ HeaderBody.propTypes = { isHiddenMainMenu: PropTypes.bool, mainMenuDropdowns: PropTypes.arrayOf(PropTypes.shape({ id: PropTypes.string, - buttonTitle: PropTypes.string, + buttonTitle: PropTypes.node, items: PropTypes.arrayOf(PropTypes.shape({ href: PropTypes.string, - title: PropTypes.string, + title: PropTypes.node, })), })), outlineLink: PropTypes.string, searchButtonAction: PropTypes.func, + containerProps: PropTypes.shape(Container.propTypes), }; HeaderBody.defaultProps = { @@ -174,6 +184,7 @@ HeaderBody.defaultProps = { mainMenuDropdowns: [], outlineLink: null, searchButtonAction: null, + containerProps: {}, }; export default HeaderBody; diff --git a/src/studio-header/MobileHeader.jsx b/src/studio-header/MobileHeader.jsx index f1aecd7f3..fd3cca1bf 100644 --- a/src/studio-header/MobileHeader.jsx +++ b/src/studio-header/MobileHeader.jsx @@ -48,10 +48,10 @@ MobileHeader.propTypes = { isAdmin: PropTypes.bool, mainMenuDropdowns: PropTypes.arrayOf(PropTypes.shape({ id: PropTypes.string, - buttonTitle: PropTypes.string, + buttonTitle: PropTypes.node, items: PropTypes.arrayOf(PropTypes.shape({ href: PropTypes.string, - title: PropTypes.string, + title: PropTypes.node, })), })), outlineLink: PropTypes.string, diff --git a/src/studio-header/MobileMenu.jsx b/src/studio-header/MobileMenu.jsx index 610321e66..892151cad 100644 --- a/src/studio-header/MobileMenu.jsx +++ b/src/studio-header/MobileMenu.jsx @@ -37,10 +37,10 @@ const MobileMenu = ({ MobileMenu.propTypes = { mainMenuDropdowns: PropTypes.arrayOf(PropTypes.shape({ id: PropTypes.string, - buttonTitle: PropTypes.string, + buttonTitle: PropTypes.node, items: PropTypes.arrayOf(PropTypes.shape({ href: PropTypes.string, - title: PropTypes.string, + title: PropTypes.node, })), })), }; diff --git a/src/studio-header/NavDropdownMenu.jsx b/src/studio-header/NavDropdownMenu.jsx index d8d9dd47a..e46c04908 100644 --- a/src/studio-header/NavDropdownMenu.jsx +++ b/src/studio-header/NavDropdownMenu.jsx @@ -30,10 +30,10 @@ const NavDropdownMenu = ({ NavDropdownMenu.propTypes = { id: PropTypes.string.isRequired, - buttonTitle: PropTypes.string.isRequired, + buttonTitle: PropTypes.node.isRequired, items: PropTypes.arrayOf(PropTypes.shape({ href: PropTypes.string, - title: PropTypes.string, + title: PropTypes.node, })).isRequired, }; diff --git a/src/studio-header/StudioHeader.jsx b/src/studio-header/StudioHeader.jsx index 886ad8411..0ee6d8539 100644 --- a/src/studio-header/StudioHeader.jsx +++ b/src/studio-header/StudioHeader.jsx @@ -16,7 +16,7 @@ ensureConfig([ ], 'Studio Header component'); const StudioHeader = ({ - number, org, title, isHiddenMainMenu, mainMenuDropdowns, outlineLink, searchButtonAction, + number, org, title, containerProps, isHiddenMainMenu, mainMenuDropdowns, outlineLink, searchButtonAction, }) => { const { authenticatedUser, config } = useContext(AppContext); const props = { @@ -25,6 +25,7 @@ const StudioHeader = ({ number, org, title, + containerProps, username: authenticatedUser?.username, isAdmin: authenticatedUser?.administrator, authenticatedUserAvatar: authenticatedUser?.avatar, @@ -53,13 +54,14 @@ StudioHeader.propTypes = { number: PropTypes.string, org: PropTypes.string, title: PropTypes.string.isRequired, + containerProps: HeaderBody.propTypes.containerProps, isHiddenMainMenu: PropTypes.bool, mainMenuDropdowns: PropTypes.arrayOf(PropTypes.shape({ id: PropTypes.string, - buttonTitle: PropTypes.string, + buttonTitle: PropTypes.node, items: PropTypes.arrayOf(PropTypes.shape({ href: PropTypes.string, - title: PropTypes.string, + title: PropTypes.node, })), })), outlineLink: PropTypes.string, @@ -69,6 +71,7 @@ StudioHeader.propTypes = { StudioHeader.defaultProps = { number: '', org: '', + containerProps: {}, isHiddenMainMenu: false, mainMenuDropdowns: [], outlineLink: null,