diff --git a/packages/components/src/components/header/header.lite.tsx b/packages/components/src/components/header/header.lite.tsx index 938947f0537..4d904364dbc 100644 --- a/packages/components/src/components/header/header.lite.tsx +++ b/packages/components/src/components/header/header.lite.tsx @@ -1,17 +1,17 @@ import { onMount, onUpdate, - Show, Slot, useMetadata, useRef, useStore } from '@builder.io/mitosis'; -import { DBHeaderState, DBHeaderProps } from './model'; +import { DBHeaderProps, DBHeaderState } from './model'; import { addAttributeToChildren, cls, uuid } from '../../utils'; import { DBButton } from '../button'; import { DBDrawer } from '../drawer'; import { DEFAULT_ID } from '../../shared/constants'; +import { isEventTargetNavigationItem } from '../../utils/navigation'; useMetadata({ isAttachedToShadowDom: true @@ -31,6 +31,11 @@ export default function DBHeader(props: DBHeaderProps) { if (props.onToggle) { props.onToggle(!props.drawerOpen); } + }, + handleNavigationItemClick: (event: unknown) => { + if (isEventTargetNavigationItem(event)) { + state.toggle(); + } } }); @@ -72,7 +77,13 @@ export default function DBHeader(props: DBHeaderProps) { open={props.drawerOpen} onClose={() => state.toggle()}>
-
{props.children}
+
+ state.handleNavigationItemClick(event) + }> + {props.children} +
diff --git a/packages/components/src/components/header/model.ts b/packages/components/src/components/header/model.ts index 0f83b7d4a9e..38baeaee0cf 100644 --- a/packages/components/src/components/header/model.ts +++ b/packages/components/src/components/header/model.ts @@ -2,6 +2,7 @@ import { GlobalProps, GlobalState, InitializedState, + NavigationBehaviourState, ToggleEventProps, ToggleEventState } from '../../shared/model'; @@ -38,4 +39,5 @@ export interface DBHeaderDefaultState { export type DBHeaderState = DBHeaderDefaultState & GlobalState & ToggleEventState & - InitializedState; + InitializedState & + NavigationBehaviourState; diff --git a/packages/components/src/components/main-navigation/main-navigation.lite.tsx b/packages/components/src/components/main-navigation/main-navigation.lite.tsx index 0a61b274f5a..2f2b6cad965 100644 --- a/packages/components/src/components/main-navigation/main-navigation.lite.tsx +++ b/packages/components/src/components/main-navigation/main-navigation.lite.tsx @@ -1,13 +1,14 @@ import { onMount, - Show, + onUpdate, useMetadata, useRef, useStore } from '@builder.io/mitosis'; -import { DBMainNavigationState, DBMainNavigationProps } from './model'; +import { DBMainNavigationProps, DBMainNavigationState } from './model'; import { cls, uuid } from '../../utils'; import { DEFAULT_ID } from '../../shared/constants'; +import { isEventTargetNavigationItem } from '../../utils/navigation'; useMetadata({ isAttachedToShadowDom: true @@ -17,20 +18,44 @@ export default function DBMainNavigation(props: DBMainNavigationProps) { const ref = useRef(null); // jscpd:ignore-start const state = useStore({ - _id: DEFAULT_ID + _id: DEFAULT_ID, + initialized: false, + forceClose: false, + handleNavigationItemClick: (event: unknown) => { + if (isEventTargetNavigationItem(event)) { + state.forceClose = true; + } + } }); onMount(() => { state._id = props.id || 'main-navigation-' + uuid(); + state.initialized = true; }); + onUpdate(() => { + if (ref && state.initialized) { + state.initialized = false; + } + }, [ref, state.initialized]); + + onUpdate(() => { + if (state.forceClose) { + requestAnimationFrame(() => { + state.forceClose = false; + }); + } + }, [state.forceClose]); + // jscpd:ignore-end return ( ); diff --git a/packages/components/src/components/main-navigation/main-navigation.scss b/packages/components/src/components/main-navigation/main-navigation.scss index 398f9902787..6b5135f4b77 100644 --- a/packages/components/src/components/main-navigation/main-navigation.scss +++ b/packages/components/src/components/main-navigation/main-navigation.scss @@ -89,4 +89,12 @@ } } } + + &[data-force-close="true"] { + & > menu menu { + @include screen-sizes.screen("md") { + display: none; + } + } + } } diff --git a/packages/components/src/components/main-navigation/model.ts b/packages/components/src/components/main-navigation/model.ts index 00b497d9644..3d70bd15474 100644 --- a/packages/components/src/components/main-navigation/model.ts +++ b/packages/components/src/components/main-navigation/model.ts @@ -1,9 +1,19 @@ -import { GlobalProps, GlobalState } from '../../shared/model'; +import { + GlobalProps, + GlobalState, + InitializedState, + NavigationBehaviourState +} from '../../shared/model'; export interface DBMainNavigationDefaultProps {} export type DBMainNavigationProps = DBMainNavigationDefaultProps & GlobalProps; -export interface DBMainNavigationDefaultState {} +export interface DBMainNavigationDefaultState { + forceClose: boolean; +} -export type DBMainNavigationState = DBMainNavigationDefaultState & GlobalState; +export type DBMainNavigationState = DBMainNavigationDefaultState & + InitializedState & + GlobalState & + NavigationBehaviourState; diff --git a/packages/components/src/shared/model.ts b/packages/components/src/shared/model.ts index 17ff80f84a7..d66ffdcb947 100644 --- a/packages/components/src/shared/model.ts +++ b/packages/components/src/shared/model.ts @@ -86,6 +86,10 @@ export type PlacementProps = { | 'bottom-end'; }; +export type NavigationBehaviourState = { + handleNavigationItemClick: (event: unknown) => void; +}; + export type GapProps = { /** * If the absolute element should have a gap between the parent element. diff --git a/packages/components/src/utils/navigation.ts b/packages/components/src/utils/navigation.ts new file mode 100644 index 00000000000..d10bdb6679c --- /dev/null +++ b/packages/components/src/utils/navigation.ts @@ -0,0 +1,11 @@ +export const isEventTargetNavigationItem = (event: unknown): boolean => { + const { target } = event as { target: HTMLElement }; + return Boolean( + !target?.classList?.contains('db-navigation-item-expand-button') && + target?.parentElement?.classList.contains('db-navigation-item') + ); +}; + +export default { + isEventTargetNavigationItem +};