Skip to content

Commit

Permalink
TASK: Decouple Drawer from redux store
Browse files Browse the repository at this point in the history
  • Loading branch information
grebaldi committed Jul 5, 2024
1 parent 40b2697 commit ebaf71e
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 41 deletions.
2 changes: 2 additions & 0 deletions packages/neos-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
"@fortawesome/free-regular-svg-icons": "^5.15.3",
"@fortawesome/free-solid-svg-icons": "^5.15.3",
"@friendsofreactjs/react-css-themr": "~4.2.0",
"@neos-project/framework-observable": "workspace:*",
"@neos-project/framework-observable-react": "workspace:*",
"@neos-project/neos-ts-interfaces": "workspace:*",
"@neos-project/neos-ui-backend-connector": "workspace:*",
"@neos-project/neos-ui-ckeditor5-bindings": "workspace:*",
Expand Down
60 changes: 37 additions & 23 deletions packages/neos-ui/src/Containers/Drawer/Drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,37 +9,49 @@
*/
import React from 'react';
import mergeClassNames from 'classnames';
// @ts-ignore
import {connect} from 'react-redux';

import {actions} from '@neos-project/neos-ui-redux-store';
import {neos} from '@neos-project/neos-ui-decorators';
import {GlobalState} from '@neos-project/neos-ui-redux-store/src/System';
import {SynchronousRegistry} from '@neos-project/neos-ui-extensibility';
import {createState} from '@neos-project/framework-observable';
import {useLatestState} from '@neos-project/framework-observable-react';

import MenuItemGroup from './MenuItemGroup/index';
import style from './style.module.css';
import {THRESHOLD_MOUSE_LEAVE} from './constants';

const withReduxState = connect((state: GlobalState) => ({
isHidden: state?.ui?.drawer?.isHidden,
collapsedMenuGroups: state?.ui?.drawer?.collapsedMenuGroups
}), {
hideDrawer: actions.UI.Drawer.hide,
toggleMenuGroup: actions.UI.Drawer.toggleMenuGroup
});

const withNeosGlobals = neos(globalRegistry => ({
containerRegistry: globalRegistry.get('containers')
}));

const StatelessDrawer: React.FC<{
isHidden: boolean;
collapsedMenuGroups: string[],
export const drawer$ = createState({
isHidden: true,
collapsedMenuGroups: [] as string[]
});

hideDrawer: () => void;
toggleMenuGroup: (menuGroup: string) => void;
export function toggleDrawer() {
drawer$.update((state) => ({
...state,
isHidden: !state.isHidden
}));
}

function hideDrawer() {
drawer$.update((state) => ({
...state,
isHidden: true
}));
}

function toggleMenuGroup(menuGroupId: string) {
drawer$.update((state) => ({
...state,
collapsedMenuGroups: state.collapsedMenuGroups.includes(menuGroupId)
? state.collapsedMenuGroups.filter((m) => m !== menuGroupId)
: [...state.collapsedMenuGroups, menuGroupId]
}));
}

const StatelessDrawer: React.FC<{
containerRegistry: SynchronousRegistry<any>;

menuData: {
Expand All @@ -57,6 +69,7 @@ const StatelessDrawer: React.FC<{
}[];
}[];
}> = (props) => {
const {isHidden, collapsedMenuGroups} = useLatestState(drawer$);
const mouseLeaveTimeoutRef = React.useRef<null | ReturnType<typeof setTimeout>>(null);
const handleMouseEnter = React.useCallback(() => {
if (mouseLeaveTimeoutRef.current) {
Expand All @@ -67,12 +80,12 @@ const StatelessDrawer: React.FC<{
const handleMouseLeave = React.useCallback(() => {
if (!mouseLeaveTimeoutRef.current) {
mouseLeaveTimeoutRef.current = setTimeout(() => {
props.hideDrawer();
hideDrawer();
mouseLeaveTimeoutRef.current = null;
}, THRESHOLD_MOUSE_LEAVE);
}
}, [props.hideDrawer]);
const {isHidden, menuData, collapsedMenuGroups, toggleMenuGroup, containerRegistry} = props;
}, []);
const {menuData, containerRegistry} = props;
const classNames = mergeClassNames({
[style.drawer]: true,
[style['drawer--isHidden']]: isHidden
Expand All @@ -91,8 +104,9 @@ const StatelessDrawer: React.FC<{
{Object.entries(menuData).map(([menuGroup, menuGroupConfiguration]) => (
<MenuItemGroup
key={menuGroup}
collapsed={Boolean(collapsedMenuGroups.includes(menuGroup))}
handleMenuGroupToggle={() => toggleMenuGroup(menuGroup)}
id={menuGroup}
collapsed={collapsedMenuGroups.includes(menuGroup)}
onMenuGroupToggle={toggleMenuGroup}
{...menuGroupConfiguration}
/>
))}
Expand All @@ -104,4 +118,4 @@ const StatelessDrawer: React.FC<{
);
}

export const Drawer = withReduxState(withNeosGlobals(StatelessDrawer as any));
export const Drawer = withNeosGlobals(StatelessDrawer as any);
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ import MenuItem from '../MenuItem/index';
import style from '../style.module.css';

export const MenuItemGroup: React.FC<{
id: string;
icon?: string;
label: string;
uri: string;
target?: string;
collapsed: boolean;
handleMenuGroupToggle: () => void;
onMenuGroupToggle: (menuGroupId: string) => void;
children: {
icon?: string;
label: string;
Expand All @@ -31,7 +32,10 @@ export const MenuItemGroup: React.FC<{
skipI18n?: boolean;
}[];
}> = (props) => {
const {label, icon, children, uri, collapsed, handleMenuGroupToggle} = props;
const {label, icon, children, uri, collapsed} = props;
const handleMenuGroupToggle = React.useCallback(() => {
props.onMenuGroupToggle(props.id);
}, [props.id])

return (
<ToggablePanel onPanelToggle={handleMenuGroupToggle} isOpen={!collapsed} style="condensed" className={style.drawer__menuItem}>
Expand Down
2 changes: 1 addition & 1 deletion packages/neos-ui/src/Containers/Drawer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@
* information, please view the LICENSE file which was distributed with this
* source code.
*/
export {Drawer as default} from './Drawer';
export {Drawer as default, drawer$, toggleDrawer} from './Drawer';
Original file line number Diff line number Diff line change
Expand Up @@ -8,40 +8,32 @@
* source code.
*/
import React from 'react';
// @ts-ignore
import {connect} from 'react-redux';
import mergeClassNames from 'classnames';

import Button from '@neos-project/react-ui-components/src/Button/';
import {actions} from '@neos-project/neos-ui-redux-store';
import {GlobalState} from '@neos-project/neos-ui-redux-store/src/System';
import {neos} from '@neos-project/neos-ui-decorators';
import {I18nRegistry} from '@neos-project/neos-ts-interfaces';
import {useLatestState} from '@neos-project/framework-observable-react';

import {drawer$, toggleDrawer} from '../../Drawer';

import style from './style.module.css';

const withNeosGlobals = neos(globalRegistry => ({
i18nRegistry: globalRegistry.get('i18n')
}));

const withReduxState = connect((state: GlobalState) => ({
isMenuHidden: state?.ui?.drawer?.isHidden
}), {
toggleDrawer: actions.UI.Drawer.toggle
});

const StatelessMenuToggler: React.FC<{
i18nRegistry: I18nRegistry;

className?: string;
isMenuHidden: boolean;
toggleDrawer: () => void;
}> = (props) => {
const handleToggle = React.useCallback(() => {
props.toggleDrawer();
toggleDrawer();
}, []);

const {className, isMenuHidden, i18nRegistry} = props;
const {className, i18nRegistry} = props;
const {isHidden: isMenuHidden} = useLatestState(drawer$);
const isMenuVisible = !isMenuHidden;
const classNames = mergeClassNames({
[style.menuToggler]: true,
Expand Down Expand Up @@ -70,4 +62,4 @@ const StatelessMenuToggler: React.FC<{
);
}

export const MenuToggler = withNeosGlobals(withReduxState(StatelessMenuToggler));
export const MenuToggler = withNeosGlobals(StatelessMenuToggler as any);
2 changes: 2 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2632,6 +2632,8 @@ __metadata:
"@fortawesome/free-solid-svg-icons": ^5.15.3
"@friendsofreactjs/react-css-themr": ~4.2.0
"@neos-project/debug-reason-for-rendering": "workspace:*"
"@neos-project/framework-observable": "workspace:*"
"@neos-project/framework-observable-react": "workspace:*"
"@neos-project/jest-preset-neos-ui": "workspace:*"
"@neos-project/neos-ts-interfaces": "workspace:*"
"@neos-project/neos-ui-backend-connector": "workspace:*"
Expand Down

0 comments on commit ebaf71e

Please sign in to comment.