Skip to content

Commit

Permalink
feat: add accordion variation for contextNavigation block
Browse files Browse the repository at this point in the history
  • Loading branch information
nileshgulia1 committed Jul 31, 2024
1 parent 4c984c8 commit a8fdad8
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 116 deletions.
115 changes: 0 additions & 115 deletions src/components/Blocks/ContextNavigation/ContextNavigation.jsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ const ContextNavigationView = (props) => {
const root_path = data?.root_node?.[0]?.['@id'];
if (root_path) navProps['root_path'] = flattenToAppURL(root_path);
const Renderer = variation?.view;
delete navProps.variation;
return (
<>
<Renderer {...props} params={navProps} />
<Renderer params={navProps} />
</>
);
};
Expand Down
136 changes: 136 additions & 0 deletions src/components/Blocks/ContextNavigation/variations/Accordion.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Accordion } from 'semantic-ui-react';
import { Link } from 'react-router-dom';
import { compose } from 'redux';
import { withRouter } from 'react-router';
import { defineMessages, useIntl } from 'react-intl';

import { flattenToAppURL } from '@plone/volto/helpers';
import { Icon, Image } from '@plone/volto/components';
import { withContentNavigation } from '@plone/volto/components/theme/Navigation/withContentNavigation';

import upIcon from '@plone/volto/icons/up-key.svg';
import rightIcon from '@plone/volto/icons/right-key.svg';

const messages = defineMessages({
navigation: {
id: 'Navigation',
defaultMessage: 'Navigation',
},
});

function renderItems({
item,
index,
activeItems,
handleTitleClick,
parentLevel,
}) {
const level = parentLevel + 1;
const {
title,
href,
thumb,
is_current,
type,
normalized_id,
items: childItems,
...rest
} = item;

const isActive = is_current || !!activeItems[normalized_id];
const hasChildItems = childItems && childItems.length > 0;
return (
<React.Fragment key={index}>
<Accordion.Title
active={isActive}
onClick={() => handleTitleClick(normalized_id, hasChildItems)}
>
{hasChildItems && (
<Icon size="24px" name={isActive ? upIcon : rightIcon} />
)}
{thumb ? <Image src={flattenToAppURL(thumb)} /> : ''}
<p>{title}</p>
</Accordion.Title>
<Accordion.Content active={isActive}>
{hasChildItems && (
<Accordion className="default">
{childItems.map((item, index) =>
renderItems({
item,
index,
activeItems,
handleTitleClick,
parentLevel: level,
}),
)}
</Accordion>
)}
</Accordion.Content>
</React.Fragment>
);
}

const AccordionNavigation = (props) => {
const { navigation = {} } = props;
const { items = [] } = navigation;
const intl = useIntl();
const [activeItems, setActiveItems] = React.useState({});

const handleTitleClick = (index, hasChildItems) => {
if (hasChildItems) {
setActiveItems((prevActiveItems) => ({
...prevActiveItems,
[index]: !prevActiveItems[index],
}));
}
};

return items.length ? (
<nav className="context-navigation">
{navigation.has_custom_name ? (
<div className="context-navigation-header">
<Link to={flattenToAppURL(navigation.url || '')}>
{navigation.title}
</Link>
</div>
) : (
<div className="context-navigation-header">
{intl.formatMessage(messages.navigation)}
</div>
)}
<Accordion className="default">
{items.map((item, index) =>
renderItems({
item,
index,
activeItems,
handleTitleClick,
parentLevel: 0,
}),
)}
</Accordion>
</nav>
) : (
''
);
};

AccordionNavigation.propTypes = {
/**
* Navigation tree returned from @contextnavigation restapi endpoint
*/
navigation: PropTypes.shape({
items: PropTypes.arrayOf(
PropTypes.shape({
title: PropTypes.string,
url: PropTypes.string,
}),
),
has_custom_name: PropTypes.bool,
title: PropTypes.string,
}),
};

export default compose(withRouter, withContentNavigation)(AccordionNavigation);

0 comments on commit a8fdad8

Please sign in to comment.