Skip to content

Commit

Permalink
change(tabs): use default edit for accordion tab edit
Browse files Browse the repository at this point in the history
- Within AccordionEdit inherit the default Edit adding only extra options classes coming from the form data
- modified Default tabs text to be inside a span within the tab link instead of a p tag.
  • Loading branch information
ichim-david committed Mar 6, 2024
1 parent ceb8ab7 commit 7ed5f4e
Show file tree
Hide file tree
Showing 7 changed files with 33 additions and 215 deletions.
221 changes: 16 additions & 205 deletions src/components/templates/accordion/Edit.jsx
Original file line number Diff line number Diff line change
@@ -1,214 +1,25 @@
import React from 'react';
import cx from 'classnames';
import { isEmpty } from 'lodash';
import { useIntl } from 'react-intl';
import Tabs from 'react-responsive-tabs';
import EditBlockWrapper from '@eeacms/volto-tabs-block/components/EditBlockWrapper';
import { MenuItem } from '@eeacms/volto-tabs-block/components/templates/default/Edit';
import { emptyBlocksForm } from '@plone/volto/helpers';
import { Icon } from 'semantic-ui-react';
import { Icon as VoltoIcon, BlocksForm } from '@plone/volto/components';
import config from '@plone/volto/registry';
import { TABS_BLOCK } from '@eeacms/volto-tabs-block/constants';
import { getParentTabFromHash } from '@eeacms/volto-tabs-block/helpers';
import noop from 'lodash/noop';

import '@eeacms/volto-tabs-block/less/menu.less';
import Edit from '@eeacms/volto-tabs-block/components/templates/default/Edit';
import { accordionSchemaEnhancer } from '@eeacms/volto-tabs-block/components/templates/accordion/schema';
import cx from 'classnames';

class Tab extends React.Component {
render() {
return this.props.children;
}
}

const Edit = (props) => {
const intl = useIntl();
const {
data = {},
tabsList = [],
tabs = {},
activeTabIndex = 0,
setActiveTab = noop,
editingTab = null,
activeBlock = null,
activeTab = null,
block = null,
setEditingTab = noop,
multiSelected = [],
manage = false,
metadata = null,
selected = false,
onChangeBlock = noop,
onChangeTabData = noop,
onSelectBlock = noop,
emptyTab = noop,
tabsData = {},
schema,
} = props;

const { menuInverted, menuSecondary, menuPointing } = data;
const accordionConfig = config.blocks.blocksConfig[
TABS_BLOCK
].variations.filter((v, _i) => v.id === data.variation);
const { icons, semanticIcon, transformWidth = 800 } =
accordionConfig?.[0] || {};

const tabsContainer = React.useRef();
const [mounted, setMounted] = React.useState(false);
const [hashTab, setHashTab] = React.useState(false);
const [initialWidth, setInitialWidth] = React.useState(transformWidth);

const items = tabsList.map((tab, index) => {
const active = activeTabIndex === index;

return {
title: (
<>
{semanticIcon ? (
<div className="tabs-icon">
<Icon
className={active ? semanticIcon.opened : semanticIcon.closed}
/>
</div>
) : (
<div className="tabs-icon">
<VoltoIcon
name={active ? icons.opened : icons.closed}
size={icons.size}
className="tabs-icon"
/>
</div>
)}
<MenuItem
{...props}
key={tab}
editingTab={editingTab}
index={index}
setEditingTab={setEditingTab}
tab={tab}
schema={schema}
/>
</>
),
content: (
<Tab {...props} tab={tab} content={tabs[tab]} aria-hidden={false}>
<BlocksForm
allowedBlocks={data?.allowedBlocks}
description={data?.instructions?.data}
manage={manage}
metadata={metadata}
pathname={props.pathname}
properties={isEmpty(tabs[tab]) ? emptyBlocksForm() : tabs[tab]}
selected={selected && activeTab === tab && activeBlock}
selectedBlock={
selected && activeTab === tab && activeBlock ? activeBlock : null
}
title={data?.placeholder}
onChangeField={onChangeTabData}
onChangeFormData={(newFormData) => {
onChangeBlock(block, {
...data,
data: {
...tabsData,
blocks: {
...tabsData.blocks,
[activeTab]: {
...(newFormData.blocks_layout.items.length > 0
? newFormData
: emptyTab({
schema: schema?.properties?.data?.schema || {},
intl,
})),
},
},
},
});
}}
onSelectBlock={(id, selected, e) => {
const isMultipleSelection = e
? e.shiftKey || e.ctrlKey || e.metaKey
: false;
onSelectBlock(
id,
activeBlock === id ? false : isMultipleSelection,
e,
);
setEditingTab(null);
}}
>
{({ draginfo }, editBlock, blockProps) => {
return (
<EditBlockWrapper
blockProps={blockProps}
draginfo={draginfo}
multiSelected={multiSelected.includes(blockProps.block)}
>
{editBlock}
</EditBlockWrapper>
);
}}
</BlocksForm>
</Tab>
),
key: tab,
tabClassName: cx('ui button item title', { active }, 'remove-menu'),
panelClassName: cx('ui bottom attached segment tab', {
active,
}),
};
});

React.useEffect(() => {
setMounted(true);
}, []);
React.useEffect(() => {
if (!mounted) return;
const { blockWidth, tabsTotalWidth } = tabsContainer.current?.state || {};
setInitialWidth(
tabsTotalWidth < blockWidth ? tabsTotalWidth + 1 : blockWidth + 1,
);
}, [mounted]);

const AccordionEdit = (props) => {
return (
<Tabs
ref={tabsContainer}
transformWidth={initialWidth}
selectedTabKey={tabsList[activeTabIndex]}
unmountOnExit={false}
items={items}
onChange={() => {
const { blockWidth } = tabsContainer.current?.state || {};
const tabWithHash = getParentTabFromHash(
data,
props?.location?.hash.substring(1),
);
if (tabWithHash === tabsList[activeTabIndex] && !hashTab) {
setHashTab(true);
} else if (blockWidth <= initialWidth) {
setActiveTab(null);
}
<Edit
skipColorOption={true}
{...props}
addTabsOptions={(data) => {
return cx(data?.theme ? `${data?.theme}` : '', {
RRT__tabs: true,
'tabs-accordion-icon-right': data.accordionIconRight,
'tabs-accessibility': true,
inverted: data.menuInverted,
pointing: data.menuPointing,
});
}}
tabsWrapperClass={cx(
props?.data?.accordionIconRight ? 'tabs-accordion-icon-right' : '',
'ui fluid menu tabs-secondary-variant',
'tabs-accessibility',
data?.theme ? `${data?.theme}` : '',
{
inverted: menuInverted,
},
{
pointing: menuPointing,
},
{
secondary: menuSecondary,
},
)}
showMore={false}
/>
);
};

Edit.schemaEnhancer = accordionSchemaEnhancer;
AccordionEdit.schemaEnhancer = accordionSchemaEnhancer;

export default Edit;
export default AccordionEdit;
7 changes: 5 additions & 2 deletions src/components/templates/accordion/View.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,11 @@ const View = (props) => {
const accordionConfig = config.blocks.blocksConfig[
TABS_BLOCK
].variations.filter((v, _i) => v.id === data.variation);
const { icons, semanticIcon, transformWidth = 800 } =
accordionConfig?.[0] || {};
const {
icons,
semanticIcon,
transformWidth = 800,
} = accordionConfig?.[0] || {};

const tabsContainer = React.useRef();
const [mounted, setMounted] = React.useState(false);
Expand Down
3 changes: 2 additions & 1 deletion src/components/templates/accordion/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import AccordionView from './View';
import AccordionEdit from './Edit';

export { AccordionView };
export { AccordionView, AccordionEdit };
8 changes: 5 additions & 3 deletions src/components/templates/default/Edit.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,8 @@ const Edit = (props) => {
onSelectBlock = noop,
setEditingTab = noop,
schema,
skipColorOption = false,
customTabsClass = '',
} = props;
const menuPosition = getMenuPosition(data);
const {
Expand Down Expand Up @@ -304,16 +306,15 @@ const Edit = (props) => {
},
};
});

return (
<>
<Tab
activeIndex={activeTabIndex}
className="default tabs"
className={cx('default tabs', customTabsClass)}
menu={{
attached: menuPosition.attached,
borderless: menuBorderless,
color: menuColor,
color: !skipColorOption && menuColor,
compact: menuCompact,
fluid: menuFluid,
inverted: menuInverted,
Expand All @@ -333,6 +334,7 @@ const Edit = (props) => {
menuPosition.direction === 'top' ? 'border-bottom' : '',
menuPosition.direction === 'bottom' ? 'border-top' : '',
{ container: isContainer },
props.addTabsOptions ? props.addTabsOptions(data) : '',
),
}}
menuPosition={menuPosition.direction}
Expand Down
2 changes: 1 addition & 1 deletion src/components/templates/default/View.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ const MenuItem = (props) => {
) : (
<>
<span className="menu-item-count">{tabIndex}</span>
<p className="menu-item-text">{tabTitle}</p>
<span className="menu-item-text">{tabTitle}</span>
</>
)}
</>
Expand Down
3 changes: 2 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
TabsView,
blockSchema,
} from '@eeacms/volto-tabs-block/components';

import { TABS_BLOCK } from './constants';
import { TabsWidget } from './widgets';

Expand Down Expand Up @@ -74,7 +75,7 @@ const applyConfig = (config) => {
{
id: 'accordion',
title: 'Accordion responsive',
edit: DefaultEdit,
edit: AccordionEdit,
view: AccordionView,
schemaEnhancer: AccordionEdit.schemaEnhancer,
transformWidth: 800,
Expand Down
4 changes: 2 additions & 2 deletions src/less/menu.less
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
border-width: 0 0 4px 0;
}

.ui.secondary.inverted.menu .active.item:not(.remove-margin) {
.ui.secondary.inverted.menu .active.item {
background-color: @menuItemInvertedActiveBackgroundColor !important;
}

Expand All @@ -43,7 +43,7 @@
cursor: pointer;
}

.ui.menu:not(.inverted, .pointing) .active.item:not(.remove-margin) {
.ui.menu:not(.inverted, .pointing) .active.item {
background-color: @menuItemActiveBackgroundColor;
}

Expand Down

0 comments on commit 7ed5f4e

Please sign in to comment.