-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs(context-menu): add useContextMenuController story
- 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
Showing
14 changed files
with
479 additions
and
225 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
54 changes: 54 additions & 0 deletions
54
...ages/mirinae/src/hooks/use-context-menu-controller/UseContextMenuController.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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/> |
48 changes: 48 additions & 0 deletions
48
packages/mirinae/src/hooks/use-context-menu-controller/story-helper.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
}; |
232 changes: 232 additions & 0 deletions
232
...ages/mirinae/src/hooks/use-context-menu-controller/use-context-menu-controller.stories.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, | ||
}; |
Oops, something went wrong.