Skip to content

Commit

Permalink
docs(context-menu): add useContextMenuController story
Browse files Browse the repository at this point in the history
- refactored useContextMenuController hook to use other context menu related hooks.
- Updated story helpers and added new stories for demonstration.
- Adjusted context menu item handling, including pagination and selection features.

Signed-off-by: Wanjin Noh <wanjin@megazone.com>
  • Loading branch information
WANZARGEN committed Jan 2, 2025
1 parent 3dce230 commit 3a5e7d2
Show file tree
Hide file tree
Showing 14 changed files with 479 additions and 225 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { MenuItem } from '@/controls/context-menu/type';
import type { MenuAttachHandler, MenuAttachHandlerRes } from '@/hooks/use-context-menu-controller/use-context-menu-attach';
import type { MenuAttachHandler, MenuAttachHandlerRes } from '@/hooks/use-context-menu-attach/use-context-menu-attach';

export interface SelectDropdownMenuItem extends MenuItem {
name: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const getUseContextMenuAttachArgs = (): Args => ({
attachHandler: undefined,
menu: getContextMenuItems(),
searchText: '',
pageSize: undefined,
pageSize: 3,
filterItems: [],
});

Expand Down Expand Up @@ -70,7 +70,7 @@ export const getUseContextMenuAttachArgTypes = (): ArgTypes<UseContextMenuAttach
},
category: 'options',
defaultValue: {
summary: 'undefined',
summary: '10',
},
},
control: 'number',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,10 @@ const Template: Story = {
components: { PContextMenu, PButton },
template: `
<div>
<p-button @click="attachMenuItems()">Attach</p-button>
<p-button @click="resetMenuAndPagination()">Reset</p-button>
<div style="margin-bottom: 1rem;">
<p-button @click="attachMenuItems()">Attach</p-button>
<p-button @click="resetMenuAndPagination()">Reset Menu & Pagination</p-button>
</div>
<p-context-menu :loading="attachLoading"
:menu="attachedMenu" />
</div>
Expand Down Expand Up @@ -67,7 +69,7 @@ export const Basic: Story = {
<div>
<div style="margin-bottom: 1rem;">
<p-button @click="attachMenuItems()">Attach</p-button>
<p-button @click="resetMenuAndPagination()">Reset</p-button>
<p-button @click="resetMenuAndPagination()">Reset Menu & Pagination</p-button>
</div>
<p-context-menu :loading="attachLoading"
:menu="attachedMenu" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{/* useContextMenuController.mdx */}

import {Canvas, Meta, Controls} from '@storybook/blocks';

import * as useContextMenuControllerStories from './use-context-menu-controller.stories';

<Meta of={useContextMenuControllerStories}/>


# useContextMenuController

The main hook controlling the context menu, integrating item management and style.

## Type Declarations

```typescript
interface UseContextMenuControllerOptions<Item extends MenuItem = MenuItem> extends
Omit<UseContextMenuStyleOptions, 'visibleMenu'|'menuRef'|'useFixedMenuStyle'>,
UseContextMenuItemsOptions<Item> {
visibleMenu?: Ref<boolean>|boolean; // used for visibility control. related to fixed style feature and focusing feature. give this option or use returned value.
contextMenuRef: UseContextMenuStyleOptions['menuRef'];
useFixedStyle?: UseContextMenuStyleOptions['useFixedMenuStyle'];
}

interface UseContextMenuControllerReturns {
visibleMenu: Ref<boolean>;
refinedMenu: ReturnType<typeof useContextMenuItems>['refinedMenu'];
contextMenuStyle: ReturnType<typeof useContextMenuStyle>['contextMenuStyle'];
loading: ReturnType<typeof useContextMenuItems>['loading'];
showContextMenu: () => void;
hideContextMenu: () => void;
toggleContextMenu: () => void;
focusOnContextMenu: FocusOnContextMenu;
initiateMenu: ReturnType<typeof useContextMenuItems>['initiateMenu'];
reloadMenu: ReturnType<typeof useContextMenuItems>['reloadMenu'];
showMoreMenu: ReturnType<typeof useContextMenuItems>['showMoreMenu'];
}
```

## Usage
<br/>

### Basic
<Canvas of={useContextMenuControllerStories.Basic}/>

### Reorder by Selection
<Canvas of={useContextMenuControllerStories.ReorderBySelection}/>

### Playground
<Canvas of={useContextMenuControllerStories.Playground}/>
<Controls of={useContextMenuControllerStories.Playground}/>

<br/>
<br/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import type { ArgTypes, Parameters, Args } from '@storybook/vue';

import { getUseContextMenuItemsArgs, getUseContextMenuItemsArgTypes } from '@/hooks/use-context-menu-items/story-helper';
import { getUseContextMenuStyleArgs, getUseContextMenuStyleArgTypes } from '@/hooks/use-context-menu-style/story-helper';

import type { UseContextMenuControllerOptions } from './use-context-menu-controller';

export const getUseContextMenuControllerArgs = (): Args => {
const useContextMenuStyleArgs = getUseContextMenuStyleArgs();
const useContextMenuItemsArgs = getUseContextMenuItemsArgs();

useContextMenuStyleArgs.contextMenuRef = useContextMenuStyleArgs.menuRef;
delete useContextMenuStyleArgs.menuRef;

useContextMenuItemsArgs.useFixedStyle = useContextMenuStyleArgs.useFixedMenuStyle;
delete useContextMenuStyleArgs.useFixedMenuStyle;

const args: Args = {
...useContextMenuStyleArgs,
...useContextMenuItemsArgs,
};

return args;
};

export const getUseContextMenuControllerParameters = (): Parameters => ({});

export const getUseContextMenuControllerArgTypes = (): ArgTypes<UseContextMenuControllerOptions> => {
const useContextMenuStyleArgTypes: any = getUseContextMenuStyleArgTypes();
const useContextMenuItemsArgTypes = getUseContextMenuItemsArgTypes();

const contextMenuRefArgType = { ...useContextMenuStyleArgTypes.menuRef };
contextMenuRefArgType.name = 'contextMenuRef';
delete useContextMenuStyleArgTypes.menuRef;

const useFixedStyleArgType = { ...useContextMenuStyleArgTypes.useFixedMenuStyle };
useFixedStyleArgType.name = 'useFixedStyle';
delete useContextMenuStyleArgTypes.useFixedMenuStyle;

const argTypes: ArgTypes<UseContextMenuControllerOptions> = {
...useContextMenuStyleArgTypes,
...useContextMenuItemsArgTypes,
contextMenuRef: contextMenuRefArgType,
useFixedStyle: useFixedStyleArgType,
};

return argTypes;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
import { computed, ref } from 'vue';

import type { Meta, StoryObj } from '@storybook/vue';
import type { ComponentProps } from 'vue-component-type-helpers';

import PButton from '@/controls/buttons/button/PButton.vue';
import { getContextMenuItems } from '@/controls/context-menu/mock';
import PContextMenu from '@/controls/context-menu/PContextMenu.vue';
import type { MenuItem } from '@/controls/context-menu/type';

import {
getUseContextMenuControllerArgs, getUseContextMenuControllerArgTypes, getUseContextMenuControllerParameters,
} from './story-helper';
import type { UseContextMenuControllerOptions } from './use-context-menu-controller';
import { useContextMenuController } from './use-context-menu-controller';


type UseContextMenuControllerPropsAndCustomArgs = ComponentProps<UseContextMenuControllerOptions>;

const meta: Meta<UseContextMenuControllerPropsAndCustomArgs> = {
title: 'Hooks/useContextMenuController',
argTypes: {
...getUseContextMenuControllerArgTypes(),
},
parameters: {
...getUseContextMenuControllerParameters(),
},
args: {
...getUseContextMenuControllerArgs(),
},
};

export default meta;
type Story = StoryObj<typeof meta>;


const Template: Story = {
render: (args, { argTypes }) => ({
props: Object.keys(argTypes),
components: { PContextMenu, PButton },
template: `
<div>
<div style="margin-bottom: 1rem">
<p-button @click="showContextMenu()">Show Menu</p-button>
<p-button @click="hideContextMenu()">Hide Menu</p-button>
<p-button @click="toggleContextMenu()">Toggle Menu</p-button>
<p-button @click="initiateMenu()">Initiate</p-button>
<p-button @click="reloadMenu()">Reload</p-button>
</div>
<div>
<div ref="targetRef" style="position: relative">Target</div>
<p-context-menu ref="menuRef"
v-if="visibleMenu"
:loading="loading"
:selected="selected"
:menu="refinedMenu"
@click-show-more="showMoreMenu()"
/>
</div>
</div>
`,
setup(props) {
const targetRef = ref(null);
const menuRef = ref(null);
const visibleMenu = ref(false);
const selected = computed(() => props.selected ?? []);
const {
refinedMenu, loading, initiateMenu, reloadMenu, showMoreMenu, showContextMenu, hideContextMenu, toggleContextMenu,
} = useContextMenuController({
targetRef,
contextMenuRef: menuRef,
visibleMenu,
selected,
useFixedStyle: computed(() => props.useFixedStyle),
position: computed(() => props.position),
menuWidth: computed(() => props.menuWidth),
useReorderBySelection: props.useReorderBySelection,
useMenuFiltering: props.useMenuFiltering,
hideHeaderWithoutItems: props.hideHeaderWithoutItems,
menu: computed(() => props.menu),
searchText: computed(() => props.searchText),
pageSize: computed(() => props.pageSize),
});
return {
selected, targetRef, menuRef, visibleMenu, refinedMenu, loading, initiateMenu, reloadMenu, showMoreMenu, showContextMenu, hideContextMenu, toggleContextMenu,
};
},
}),
decorators: [() => ({
template: '<story style="height: 500px;" />',
})],
};

export const Basic: Story = {
render: () => ({
components: { PContextMenu, PButton },
template: `
<div>
<div style="margin-bottom: 1rem">
<p-button @click="showContextMenu()">Show Menu</p-button>
<p-button @click="hideContextMenu()">Hide Menu</p-button>
<p-button @click="toggleContextMenu()">Toggle Menu</p-button>
<p-button @click="initiateMenu()">Initiate</p-button>
<p-button @click="reloadMenu()">Reload</p-button>
<p-button @click="focusOnContextMenu()">Focus on Menu</p-button>
</div>
<div>
<div ref="targetRef" style="position: relative">Target</div>
<p-context-menu ref="menuRef"
v-if="visibleMenu"
:selected="selected"
:loading="loading"
:menu="refinedMenu"
@click-show-more="showMoreMenu()"
@select="handleSelect"
/>
</div>
</div>
`,
setup() {
const targetRef = ref(null);
const menuRef = ref(null);
const visibleMenu = ref(false);
const menu = ref(getContextMenuItems());
const selected = ref<MenuItem[]>([]);
const {
refinedMenu, loading, initiateMenu, reloadMenu, showMoreMenu, showContextMenu, hideContextMenu, toggleContextMenu, focusOnContextMenu,
} = useContextMenuController({
targetRef,
contextMenuRef: menuRef,
visibleMenu,
menu,
pageSize: 3,
selected,
});
const handleSelect = (item: MenuItem) => {
selected.value = [...selected.value, item];
};
return {
selected,
targetRef,
menuRef,
visibleMenu,
refinedMenu,
loading,
initiateMenu,
reloadMenu,
showMoreMenu,
showContextMenu,
hideContextMenu,
toggleContextMenu,
focusOnContextMenu,
handleSelect,
};
},
}),
decorators: [() => ({
template: '<story style="height: 500px;" />',
})],
};

export const ReorderBySelection: Story = {
render: () => ({
components: { PContextMenu, PButton },
template: `
<div>
<div style="margin-bottom: 1rem">
<p-button @click="showAndInitiate">Show Menu & Initiate & Reorder</p-button>
<p-button @click="hideContextMenu">Hide Menu</p-button>
<p-button @click="selected = []">Reset Selection</p-button>
</div>
<div>
<div ref="targetRef" style="position: relative">Target</div>
<p-context-menu ref="menuRef"
v-if="visibleMenu"
:selected="selected"
:loading="loading"
:menu="refinedMenu"
@click-show-more="showMoreMenu()"
@select="handleSelect"
/>
</div>
</div>
`,
setup() {
const targetRef = ref(null);
const menuRef = ref(null);
const visibleMenu = ref(false);
const menu = ref(getContextMenuItems());
const selected = ref<MenuItem[]>([]);
const {
refinedMenu, loading, initiateMenu, showMoreMenu, showContextMenu, hideContextMenu,
} = useContextMenuController({
targetRef,
contextMenuRef: menuRef,
visibleMenu,
menu,
pageSize: 3,
selected,
useReorderBySelection: true,
});
const handleSelect = (item: MenuItem) => {
selected.value = [...selected.value, item];
};
const showAndInitiate = () => {
showContextMenu();
initiateMenu();
};
return {
selected,
targetRef,
menuRef,
visibleMenu,
refinedMenu,
loading,
initiateMenu,
showMoreMenu,
showContextMenu,
hideContextMenu,
handleSelect,
showAndInitiate,
};
},
}),
decorators: [() => ({
template: '<story style="height: 500px;" />',
})],
};

export const Playground: Story = {
...Template,
};
Loading

0 comments on commit 3a5e7d2

Please sign in to comment.