Skip to content

Commit

Permalink
feat: add auto close to navigation-item inside header and main-naviga…
Browse files Browse the repository at this point in the history
…tion (#2344)
  • Loading branch information
nmerget authored Apr 11, 2024
1 parent b9b180c commit e6f091d
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 11 deletions.
17 changes: 14 additions & 3 deletions packages/components/src/components/header/header.lite.tsx
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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();
}
}
});

Expand Down Expand Up @@ -72,7 +77,13 @@ export default function DBHeader(props: DBHeaderProps) {
open={props.drawerOpen}
onClose={() => state.toggle()}>
<div class="db-header-drawer-navigation">
<div class="db-header-navigation">{props.children}</div>
<div
class="db-header-navigation"
onClick={(event) =>
state.handleNavigationItemClick(event)
}>
{props.children}
</div>
<div class="db-header-meta-navigation">
<Slot name="meta-navigation" />
</div>
Expand Down
4 changes: 3 additions & 1 deletion packages/components/src/components/header/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
GlobalProps,
GlobalState,
InitializedState,
NavigationBehaviourState,
ToggleEventProps,
ToggleEventState
} from '../../shared/model';
Expand Down Expand Up @@ -38,4 +39,5 @@ export interface DBHeaderDefaultState {
export type DBHeaderState = DBHeaderDefaultState &
GlobalState &
ToggleEventState<HTMLElement> &
InitializedState;
InitializedState &
NavigationBehaviourState;
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -17,20 +18,44 @@ export default function DBMainNavigation(props: DBMainNavigationProps) {
const ref = useRef<HTMLDivElement>(null);
// jscpd:ignore-start
const state = useStore<DBMainNavigationState>({
_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 (
<nav
ref={ref}
id={state._id}
class={cls('db-main-navigation', props.className)}>
class={cls('db-main-navigation', props.className)}
onClick={(event) => state.handleNavigationItemClick(event)}
data-force-close={state.forceClose}>
<menu>{props.children}</menu>
</nav>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,12 @@
}
}
}

&[data-force-close="true"] {
& > menu menu {
@include screen-sizes.screen("md") {
display: none;
}
}
}
}
16 changes: 13 additions & 3 deletions packages/components/src/components/main-navigation/model.ts
Original file line number Diff line number Diff line change
@@ -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;
4 changes: 4 additions & 0 deletions packages/components/src/shared/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
11 changes: 11 additions & 0 deletions packages/components/src/utils/navigation.ts
Original file line number Diff line number Diff line change
@@ -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
};

0 comments on commit e6f091d

Please sign in to comment.